From 46d3bb56ea56608ae1ad7910188371470921dc64 Mon Sep 17 00:00:00 2001 From: Matthieu Riegler Date: Tue, 10 Jun 2025 20:45:44 -0400 Subject: [PATCH] docs(docs-infra): generate llms-full.txt at build time (#61864) PR Close #61864 --- adev/BUILD.bazel | 1 + adev/angular.json | 10 +- adev/src/content/BUILD.bazel | 13 + adev/src/content/ai/develop-with-ai.md | 2 +- adev/src/content/best-practices/BUILD.bazel | 7 + adev/src/content/ecosystem/BUILD.bazel | 7 + .../ecosystem/rxjs-interop/BUILD.bazel | 7 + adev/src/content/guide/BUILD.bazel | 20 + adev/src/content/guide/animations/BUILD.bazel | 7 + adev/src/content/guide/components/BUILD.bazel | 7 + adev/src/content/guide/di/BUILD.bazel | 7 + adev/src/content/guide/directives/BUILD.bazel | 7 + adev/src/content/guide/forms/BUILD.bazel | 7 + adev/src/content/guide/http/BUILD.bazel | 7 + adev/src/content/guide/i18n/BUILD.bazel | 7 + adev/src/content/guide/ngmodules/BUILD.bazel | 7 + .../src/content/guide/performance/BUILD.bazel | 7 + adev/src/content/guide/routing/BUILD.bazel | 7 + adev/src/content/guide/signals/BUILD.bazel | 7 + adev/src/content/guide/templates/BUILD.bazel | 7 + adev/src/content/guide/testing/BUILD.bazel | 7 + adev/src/content/introduction/BUILD.bazel | 7 + .../introduction/essentials/BUILD.bazel | 7 + adev/src/content/reference/BUILD.bazel | 7 + adev/src/context/BUILD.bazel | 46 + .../shared => src/context}/llms-list.md | 0 .../shared/llms.mjs => src/context/llms.mts} | 44 +- adev/src/context/tsconfig.json | 13 + adev/src/llms-full.txt | 14036 ---------------- 29 files changed, 253 insertions(+), 14065 deletions(-) rename adev/{scripts/shared => src/context}/llms-list.md (100%) rename adev/{scripts/shared/llms.mjs => src/context/llms.mts} (78%) create mode 100644 adev/src/context/tsconfig.json delete mode 100644 adev/src/llms-full.txt diff --git a/adev/BUILD.bazel b/adev/BUILD.bazel index 8efcfec68f9..0ebe5fecb5f 100644 --- a/adev/BUILD.bazel +++ b/adev/BUILD.bazel @@ -15,6 +15,7 @@ exports_files([ ]) APPLICATION_FILES = [ + "//adev/src/context:llms_full", "//adev/src/assets/images", "//adev/src/assets/others", "//adev/src/assets/previews", diff --git a/adev/angular.json b/adev/angular.json index 8fd21e8f1d6..c4f3bab1d52 100644 --- a/adev/angular.json +++ b/adev/angular.json @@ -32,14 +32,10 @@ "src/favicon.ico", "src/robots.txt", "src/assets", - "src/llms.txt", - "src/llms-full.txt", - "src/context" - ], - "styles": [ - "@angular/docs/styles/global-styles.scss", - "./src/local-styles.scss" + "src/context", + "src/llms.txt" ], + "styles": ["@angular/docs/styles/global-styles.scss", "./src/local-styles.scss"], "scripts": [], "webWorkerTsConfig": "tsconfig.worker.json", "optimization": { diff --git a/adev/src/content/BUILD.bazel b/adev/src/content/BUILD.bazel index 6de43a09b81..b992559abc5 100644 --- a/adev/src/content/BUILD.bazel +++ b/adev/src/content/BUILD.bazel @@ -1,3 +1,4 @@ +load("@build_bazel_rules_nodejs//:index.bzl", "js_library") load("//adev/shared-docs:index.bzl", "generate_guides") generate_guides( @@ -8,3 +9,15 @@ generate_guides( data = [], visibility = ["//adev:__subpackages__"], ) + +js_library( + name = "guide_files", + srcs = [ + "//adev/src/content/best-practices:guide_files", + "//adev/src/content/ecosystem:guide_files", + "//adev/src/content/guide:guide_files", + "//adev/src/content/introduction:guide_files", + "//adev/src/content/reference:guide_files", + ] + glob(["**/*.md"]), + visibility = ["//visibility:public"], +) diff --git a/adev/src/content/ai/develop-with-ai.md b/adev/src/content/ai/develop-with-ai.md index 8c75f8e4f5a..ccb7584b0b7 100644 --- a/adev/src/content/ai/develop-with-ai.md +++ b/adev/src/content/ai/develop-with-ai.md @@ -31,6 +31,6 @@ Several editors, such as llms.txt - an index file providing links to key files and resources. -* llms-full.txt - a more robust compiled set of resources describing how Angular works and how to build Angular applications. +* llms-full.txt - a more robust compiled set of resources describing how Angular works and how to build Angular applications. Be sure [to check out the overview page](/ai) for more information on how to integrate AI into your Angular applications. diff --git a/adev/src/content/best-practices/BUILD.bazel b/adev/src/content/best-practices/BUILD.bazel index 83df125c7fe..bc0812bea24 100644 --- a/adev/src/content/best-practices/BUILD.bazel +++ b/adev/src/content/best-practices/BUILD.bazel @@ -1,3 +1,4 @@ +load("@build_bazel_rules_nodejs//:index.bzl", "js_library") load("//adev/shared-docs:index.bzl", "generate_guides") generate_guides( @@ -11,3 +12,9 @@ generate_guides( ], visibility = ["//adev:__subpackages__"], ) + +js_library( + name = "guide_files", + srcs = glob(["**/*.md"]), + visibility = ["//adev:__subpackages__"], +) diff --git a/adev/src/content/ecosystem/BUILD.bazel b/adev/src/content/ecosystem/BUILD.bazel index fc869b67ad8..826351823cb 100644 --- a/adev/src/content/ecosystem/BUILD.bazel +++ b/adev/src/content/ecosystem/BUILD.bazel @@ -1,3 +1,4 @@ +load("@build_bazel_rules_nodejs//:index.bzl", "js_library") load("//adev/shared-docs:index.bzl", "generate_guides") generate_guides( @@ -7,3 +8,9 @@ generate_guides( ]), visibility = ["//adev:__subpackages__"], ) + +js_library( + name = "guide_files", + srcs = ["//adev/src/content/ecosystem/rxjs-interop:guide_files"] + glob(["**/*.md"]), + visibility = ["//adev:__subpackages__"], +) diff --git a/adev/src/content/ecosystem/rxjs-interop/BUILD.bazel b/adev/src/content/ecosystem/rxjs-interop/BUILD.bazel index 73d85c91898..b3fe83db6ab 100644 --- a/adev/src/content/ecosystem/rxjs-interop/BUILD.bazel +++ b/adev/src/content/ecosystem/rxjs-interop/BUILD.bazel @@ -1,3 +1,4 @@ +load("@build_bazel_rules_nodejs//:index.bzl", "js_library") load("//adev/shared-docs:index.bzl", "generate_guides") generate_guides( @@ -7,3 +8,9 @@ generate_guides( ]), visibility = ["//adev:__subpackages__"], ) + +js_library( + name = "guide_files", + srcs = glob(["**/*.md"]), + visibility = ["//adev:__subpackages__"], +) diff --git a/adev/src/content/guide/BUILD.bazel b/adev/src/content/guide/BUILD.bazel index 8be5db6ec36..33333067d20 100644 --- a/adev/src/content/guide/BUILD.bazel +++ b/adev/src/content/guide/BUILD.bazel @@ -1,3 +1,4 @@ +load("@aspect_bazel_lib//lib:copy_to_bin.bzl", "copy_to_bin") load("//adev/shared-docs:index.bzl", "generate_guides") generate_guides( @@ -10,3 +11,22 @@ generate_guides( ], visibility = ["//adev:__subpackages__"], ) + +copy_to_bin( + name = "guide_files", + srcs = [ + "//adev/src/content/guide/animations:guide_files", + "//adev/src/content/guide/components:guide_files", + "//adev/src/content/guide/di:guide_files", + "//adev/src/content/guide/directives:guide_files", + "//adev/src/content/guide/forms:guide_files", + "//adev/src/content/guide/http:guide_files", + "//adev/src/content/guide/i18n:guide_files", + "//adev/src/content/guide/performance:guide_files", + "//adev/src/content/guide/routing:guide_files", + "//adev/src/content/guide/signals:guide_files", + "//adev/src/content/guide/templates:guide_files", + "//adev/src/content/guide/testing:guide_files", + ] + glob(["**/*.md"]), + visibility = ["//adev:__subpackages__"], +) diff --git a/adev/src/content/guide/animations/BUILD.bazel b/adev/src/content/guide/animations/BUILD.bazel index 3c76e01e3b4..e95e2d75637 100644 --- a/adev/src/content/guide/animations/BUILD.bazel +++ b/adev/src/content/guide/animations/BUILD.bazel @@ -1,3 +1,4 @@ +load("@aspect_bazel_lib//lib:copy_to_bin.bzl", "copy_to_bin") load("//adev/shared-docs:index.bzl", "generate_guides") generate_guides( @@ -10,3 +11,9 @@ generate_guides( ], visibility = ["//adev:__subpackages__"], ) + +copy_to_bin( + name = "guide_files", + srcs = glob(["**/*.md"]), + visibility = ["//adev:__subpackages__"], +) diff --git a/adev/src/content/guide/components/BUILD.bazel b/adev/src/content/guide/components/BUILD.bazel index a829bf72640..3bdd931e648 100644 --- a/adev/src/content/guide/components/BUILD.bazel +++ b/adev/src/content/guide/components/BUILD.bazel @@ -1,3 +1,4 @@ +load("@aspect_bazel_lib//lib:copy_to_bin.bzl", "copy_to_bin") load("//adev/shared-docs:index.bzl", "generate_guides") generate_guides( @@ -11,3 +12,9 @@ generate_guides( mermaid_blocks = True, visibility = ["//adev:__subpackages__"], ) + +copy_to_bin( + name = "guide_files", + srcs = glob(["**/*.md"]), + visibility = ["//adev:__subpackages__"], +) diff --git a/adev/src/content/guide/di/BUILD.bazel b/adev/src/content/guide/di/BUILD.bazel index 04e0e769274..5c0a2d60c1e 100644 --- a/adev/src/content/guide/di/BUILD.bazel +++ b/adev/src/content/guide/di/BUILD.bazel @@ -1,3 +1,4 @@ +load("@aspect_bazel_lib//lib:copy_to_bin.bzl", "copy_to_bin") load("//adev/shared-docs:index.bzl", "generate_guides") generate_guides( @@ -12,3 +13,9 @@ generate_guides( mermaid_blocks = True, visibility = ["//adev:__subpackages__"], ) + +copy_to_bin( + name = "guide_files", + srcs = glob(["**/*.md"]), + visibility = ["//adev:__subpackages__"], +) diff --git a/adev/src/content/guide/directives/BUILD.bazel b/adev/src/content/guide/directives/BUILD.bazel index 53d938f9608..8845504a718 100644 --- a/adev/src/content/guide/directives/BUILD.bazel +++ b/adev/src/content/guide/directives/BUILD.bazel @@ -1,3 +1,4 @@ +load("@aspect_bazel_lib//lib:copy_to_bin.bzl", "copy_to_bin") load("//adev/shared-docs:index.bzl", "generate_guides") generate_guides( @@ -11,3 +12,9 @@ generate_guides( ], visibility = ["//adev:__subpackages__"], ) + +copy_to_bin( + name = "guide_files", + srcs = glob(["**/*.md"]), + visibility = ["//adev:__subpackages__"], +) diff --git a/adev/src/content/guide/forms/BUILD.bazel b/adev/src/content/guide/forms/BUILD.bazel index 04205e7125c..beb4188c3fd 100644 --- a/adev/src/content/guide/forms/BUILD.bazel +++ b/adev/src/content/guide/forms/BUILD.bazel @@ -1,3 +1,4 @@ +load("@aspect_bazel_lib//lib:copy_to_bin.bzl", "copy_to_bin") load("//adev/shared-docs:index.bzl", "generate_guides") generate_guides( @@ -12,3 +13,9 @@ generate_guides( mermaid_blocks = True, visibility = ["//adev:__subpackages__"], ) + +copy_to_bin( + name = "guide_files", + srcs = glob(["**/*.md"]), + visibility = ["//adev:__subpackages__"], +) diff --git a/adev/src/content/guide/http/BUILD.bazel b/adev/src/content/guide/http/BUILD.bazel index 2099955305d..b6f533909ac 100644 --- a/adev/src/content/guide/http/BUILD.bazel +++ b/adev/src/content/guide/http/BUILD.bazel @@ -1,3 +1,4 @@ +load("@aspect_bazel_lib//lib:copy_to_bin.bzl", "copy_to_bin") load("//adev/shared-docs:index.bzl", "generate_guides") generate_guides( @@ -7,3 +8,9 @@ generate_guides( ]), visibility = ["//adev:__subpackages__"], ) + +copy_to_bin( + name = "guide_files", + srcs = glob(["**/*.md"]), + visibility = ["//adev:__subpackages__"], +) diff --git a/adev/src/content/guide/i18n/BUILD.bazel b/adev/src/content/guide/i18n/BUILD.bazel index 1595e50aef4..80fb2c6752f 100644 --- a/adev/src/content/guide/i18n/BUILD.bazel +++ b/adev/src/content/guide/i18n/BUILD.bazel @@ -1,3 +1,4 @@ +load("@aspect_bazel_lib//lib:copy_to_bin.bzl", "copy_to_bin") load("//adev/shared-docs:index.bzl", "generate_guides") generate_guides( @@ -10,3 +11,9 @@ generate_guides( ], visibility = ["//adev:__subpackages__"], ) + +copy_to_bin( + name = "guide_files", + srcs = glob(["**/*.md"]), + visibility = ["//adev:__subpackages__"], +) diff --git a/adev/src/content/guide/ngmodules/BUILD.bazel b/adev/src/content/guide/ngmodules/BUILD.bazel index 52abb97fde4..7ee907fe5f9 100644 --- a/adev/src/content/guide/ngmodules/BUILD.bazel +++ b/adev/src/content/guide/ngmodules/BUILD.bazel @@ -1,3 +1,4 @@ +load("@aspect_bazel_lib//lib:copy_to_bin.bzl", "copy_to_bin") load("//adev/shared-docs:index.bzl", "generate_guides") generate_guides( @@ -9,3 +10,9 @@ generate_guides( ], visibility = ["//adev:__subpackages__"], ) + +copy_to_bin( + name = "guide_files", + srcs = glob(["**/*.md"]), + visibility = ["//adev:__subpackages__"], +) diff --git a/adev/src/content/guide/performance/BUILD.bazel b/adev/src/content/guide/performance/BUILD.bazel index c2a80708eea..1de2a0fc9fb 100644 --- a/adev/src/content/guide/performance/BUILD.bazel +++ b/adev/src/content/guide/performance/BUILD.bazel @@ -1,3 +1,4 @@ +load("@aspect_bazel_lib//lib:copy_to_bin.bzl", "copy_to_bin") load("//adev/shared-docs:index.bzl", "generate_guides") generate_guides( @@ -10,3 +11,9 @@ generate_guides( ], visibility = ["//adev:__subpackages__"], ) + +copy_to_bin( + name = "guide_files", + srcs = glob(["**/*.md"]), + visibility = ["//adev:__subpackages__"], +) diff --git a/adev/src/content/guide/routing/BUILD.bazel b/adev/src/content/guide/routing/BUILD.bazel index ea16c3c07a9..235ac567616 100644 --- a/adev/src/content/guide/routing/BUILD.bazel +++ b/adev/src/content/guide/routing/BUILD.bazel @@ -1,3 +1,4 @@ +load("@aspect_bazel_lib//lib:copy_to_bin.bzl", "copy_to_bin") load("//adev/shared-docs:index.bzl", "generate_guides") generate_guides( @@ -11,3 +12,9 @@ generate_guides( ], visibility = ["//adev:__subpackages__"], ) + +copy_to_bin( + name = "guide_files", + srcs = glob(["**/*.md"]), + visibility = ["//adev:__subpackages__"], +) diff --git a/adev/src/content/guide/signals/BUILD.bazel b/adev/src/content/guide/signals/BUILD.bazel index a52dbe5d4d4..47152ad9535 100644 --- a/adev/src/content/guide/signals/BUILD.bazel +++ b/adev/src/content/guide/signals/BUILD.bazel @@ -1,3 +1,4 @@ +load("@aspect_bazel_lib//lib:copy_to_bin.bzl", "copy_to_bin") load("//adev/shared-docs:index.bzl", "generate_guides") generate_guides( @@ -10,3 +11,9 @@ generate_guides( ], visibility = ["//adev:__subpackages__"], ) + +copy_to_bin( + name = "guide_files", + srcs = glob(["**/*.md"]), + visibility = ["//adev:__subpackages__"], +) diff --git a/adev/src/content/guide/templates/BUILD.bazel b/adev/src/content/guide/templates/BUILD.bazel index 1202778b911..92bfa79bc4b 100644 --- a/adev/src/content/guide/templates/BUILD.bazel +++ b/adev/src/content/guide/templates/BUILD.bazel @@ -1,3 +1,4 @@ +load("@aspect_bazel_lib//lib:copy_to_bin.bzl", "copy_to_bin") load("//adev/shared-docs:index.bzl", "generate_guides") generate_guides( @@ -10,3 +11,9 @@ generate_guides( ], visibility = ["//adev:__subpackages__"], ) + +copy_to_bin( + name = "guide_files", + srcs = glob(["**/*.md"]), + visibility = ["//adev:__subpackages__"], +) diff --git a/adev/src/content/guide/testing/BUILD.bazel b/adev/src/content/guide/testing/BUILD.bazel index 60e51080067..4e1f4c44e36 100644 --- a/adev/src/content/guide/testing/BUILD.bazel +++ b/adev/src/content/guide/testing/BUILD.bazel @@ -1,3 +1,4 @@ +load("@aspect_bazel_lib//lib:copy_to_bin.bzl", "copy_to_bin") load("//adev/shared-docs:index.bzl", "generate_guides") generate_guides( @@ -10,3 +11,9 @@ generate_guides( ], visibility = ["//adev:__subpackages__"], ) + +copy_to_bin( + name = "guide_files", + srcs = glob(["**/*.md"]), + visibility = ["//adev:__subpackages__"], +) diff --git a/adev/src/content/introduction/BUILD.bazel b/adev/src/content/introduction/BUILD.bazel index 7e941428227..3e63bde41ce 100644 --- a/adev/src/content/introduction/BUILD.bazel +++ b/adev/src/content/introduction/BUILD.bazel @@ -1,3 +1,4 @@ +load("@build_bazel_rules_nodejs//:index.bzl", "js_library") load("//adev/shared-docs:index.bzl", "generate_guides") generate_guides( @@ -10,3 +11,9 @@ generate_guides( ], visibility = ["//adev:__subpackages__"], ) + +js_library( + name = "guide_files", + srcs = ["//adev/src/content/introduction/essentials:guide_files"] + glob(["**/*.md"]), + visibility = ["//adev:__subpackages__"], +) diff --git a/adev/src/content/introduction/essentials/BUILD.bazel b/adev/src/content/introduction/essentials/BUILD.bazel index 2a51f05d1b1..ff80ac97ab9 100644 --- a/adev/src/content/introduction/essentials/BUILD.bazel +++ b/adev/src/content/introduction/essentials/BUILD.bazel @@ -1,3 +1,4 @@ +load("@build_bazel_rules_nodejs//:index.bzl", "js_library") load("//adev/shared-docs:index.bzl", "generate_guides") generate_guides( @@ -18,3 +19,9 @@ generate_guides( mermaid_blocks = True, visibility = ["//adev:__subpackages__"], ) + +js_library( + name = "guide_files", + srcs = glob(["**/*.md"]), + visibility = ["//adev:__subpackages__"], +) diff --git a/adev/src/content/reference/BUILD.bazel b/adev/src/content/reference/BUILD.bazel index 569863d4e2f..28e33f7df3a 100644 --- a/adev/src/content/reference/BUILD.bazel +++ b/adev/src/content/reference/BUILD.bazel @@ -1,3 +1,4 @@ +load("@build_bazel_rules_nodejs//:index.bzl", "js_library") load("//adev/shared-docs:index.bzl", "generate_guides") generate_guides( @@ -10,3 +11,9 @@ generate_guides( ], visibility = ["//adev:__subpackages__"], ) + +js_library( + name = "guide_files", + srcs = glob(["**/*.md"]), + visibility = ["//adev:__subpackages__"], +) diff --git a/adev/src/context/BUILD.bazel b/adev/src/context/BUILD.bazel index d784cf58737..c9186f38605 100644 --- a/adev/src/context/BUILD.bazel +++ b/adev/src/context/BUILD.bazel @@ -1,3 +1,7 @@ +load("@aspect_bazel_lib//lib:copy_to_directory.bzl", "copy_to_directory") +load("@aspect_rules_js//js:defs.bzl", "js_binary", "js_run_binary") +load("//tools:defaults2.bzl", "ts_config", "ts_project") + package(default_visibility = ["//adev:__subpackages__"]) filegroup( @@ -5,3 +9,45 @@ filegroup( srcs = glob(["**"]), visibility = ["//visibility:public"], ) + +ts_config( + name = "tsconfig_build", + src = "tsconfig.json", + deps = ["//tools:tsconfig_build"], +) + +filegroup( + name = "llms_src", + srcs = ["llms-list.md"], + visibility = ["//visibility:public"], +) + +ts_project( + name = "llms_lib", + srcs = ["llms.mts"], + tsconfig = ":tsconfig_build", + deps = [":llms_src"], +) + +js_binary( + name = "generate_llms_full", + data = [ + "llms.mjs", + "llms-list.md", + ":llms_lib_rjs", + "//adev/src/content:guide_files", + ], + entry_point = ":llms.mjs", +) + +js_run_binary( + name = "run_generate_llms_full", + outs = ["llms-full.txt"], + tool = ":generate_llms_full", +) + +copy_to_directory( + name = "llms_full", + srcs = [":run_generate_llms_full"], + out = "llm-files", +) diff --git a/adev/scripts/shared/llms-list.md b/adev/src/context/llms-list.md similarity index 100% rename from adev/scripts/shared/llms-list.md rename to adev/src/context/llms-list.md diff --git a/adev/scripts/shared/llms.mjs b/adev/src/context/llms.mts similarity index 78% rename from adev/scripts/shared/llms.mjs rename to adev/src/context/llms.mts index 13bf058ee2c..9f69e06ed26 100644 --- a/adev/scripts/shared/llms.mjs +++ b/adev/src/context/llms.mts @@ -10,15 +10,15 @@ // Run with `node adev/scripts/shared/llms.mjs` to generate llms-full.txt from the list in llms-list.md //tslint:disable:no-console -import fs from 'fs/promises'; -import path from 'path'; +import {readFile, writeFile} from 'fs/promises'; +import {resolve, dirname} from 'path'; -const INPUT_MD_FILENAME = 'adev/scripts/shared/llms-list.md'; -const OUTPUT_FILENAME = 'adev/src/llms-full.txt'; +const INPUT_MD_FILENAME = 'adev/src/context/llms-list.md'; +const OUTPUT_FILENAME = 'adev/src/context/llms-full.txt'; -function postProcessOutputContent(content) { +function postProcessOutputContent(content: string) { // Helper to map custom languages to standard Markdown languages - const mapLanguage = (lang) => { + const mapLanguage = (lang: string) => { if (!lang) return ''; // For code blocks without a specified language const lowerLang = lang.trim().toLowerCase(); if (lowerLang === 'angular-ts') return 'typescript'; @@ -88,21 +88,21 @@ function postProcessOutputContent(content) { } async function main() { - const inputFilePath = path.resolve(process.cwd(), INPUT_MD_FILENAME); - const baseDirForIncludes = path.dirname(inputFilePath); + const inputFilePath = resolve(process.cwd(), INPUT_MD_FILENAME); + const baseDirForIncludes = dirname(inputFilePath); console.log(`Starting processing of: ${inputFilePath}`); - let mainFileContent; + let mainFileContent: string; try { - mainFileContent = await fs.readFile(inputFilePath, 'utf-8'); - } catch (error) { + mainFileContent = await readFile(inputFilePath, 'utf-8'); + } catch (error: unknown) { console.error(`Error: Failed to read input file "${inputFilePath}".`); - console.error(error.message); + console.error((error as Error).message); process.exit(1); // Exit with error code } - let processedContent = mainFileContent; + let processedContent: string = mainFileContent; const matches = [...mainFileContent.matchAll(/(.*\.md)/g)]; console.log(`Found ${matches.length} files`); @@ -111,28 +111,30 @@ async function main() { for (const match of matches) { const filePath = match[0]; - const absolutePathToIncludeFile = path.resolve(filePath); + const absolutePathToIncludeFile = resolve(filePath); try { console.log(` Including content from: ${absolutePathToIncludeFile}`); - const includedFileContent = await fs.readFile(absolutePathToIncludeFile, 'utf-8'); + const includedFileContent = await readFile(absolutePathToIncludeFile, 'utf-8'); const processedFile = postProcessOutputContent(includedFileContent); resultString += processedFile; // Append the content of the included file - } catch (fileReadError) { - console.warn(` Warning: Could not read file "${absolutePathToIncludeFile}"`); + } catch (fileReadError: any) { + console.warn( + ` Warning: Could not read file "${absolutePathToIncludeFile}" - ${fileReadError.message}`, + ); } } // Basic cleanup of blank lines processedContent = resultString.replace(/(?:\s*\n){3,}/g, '\n'); - const outputFilePath = path.resolve(process.cwd(), OUTPUT_FILENAME); + const outputFilePath = resolve(process.cwd(), OUTPUT_FILENAME); try { - await fs.writeFile(outputFilePath, processedContent, 'utf-8'); + await writeFile(outputFilePath, processedContent, 'utf-8'); console.log(`Successfully generated combined file: ${outputFilePath}`); - } catch (error) { + } catch (error: unknown) { console.error(`Error: Failed to write output file "${outputFilePath}".`); - console.error(error.message); + console.error((error as Error).message); process.exit(1); // Exit with error code } } diff --git a/adev/src/context/tsconfig.json b/adev/src/context/tsconfig.json new file mode 100644 index 00000000000..a093b9356f8 --- /dev/null +++ b/adev/src/context/tsconfig.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "strict": true, + "skipLibCheck": true, + "declaration": true, + "sourceMap": true, + "module": "esnext", + "moduleResolution": "node", + "target": "esnext", + "types": ["node"], + "paths": {} + } +} diff --git a/adev/src/llms-full.txt b/adev/src/llms-full.txt deleted file mode 100644 index e7549963392..00000000000 --- a/adev/src/llms-full.txt +++ /dev/null @@ -1,14036 +0,0 @@ - - - -Angular is a web framework that empowers developers to build fast, reliable applications. - - -Maintained by a dedicated team at Google, Angular provides a broad suite of tools, APIs, and -libraries to simplify and streamline your development workflow. Angular gives you -a solid platform on which to build fast, reliable applications that scale with both the size of -your team and the size of your codebase. - -**Want to see some code?** Jump over to our [Essentials](essentials) for a quick overview of -what it's like to use Angular, or get started in the [Tutorial](tutorials/learn-angular) if you -prefer following step-by-step instructions. - -## Features that power your development -## Develop applications faster than ever -## Ship with confidence -## Works at any scale -## Open-source first -## A thriving community -Get started with Angular quickly with online starters or locally with your terminal. - -## Play Online - -If you just want to play around with Angular in your browser without setting up a project, you can use our online sandbox: -## Set up a new project locally - -If you're starting a new project, you'll most likely want to create a local project so that you can use tooling such as Git. - -### Prerequisites - -- **Node.js** - [v20.11.1 or newer](/reference/versions) -- **Text editor** - We recommend [Visual Studio Code](https://code.visualstudio.com/) -- **Terminal** - Required for running Angular CLI commands -- **Development Tool** - To improve your development workflow, we recommend the [Angular Language Service](/tools/language-service) - -### Instructions - -The following guide will walk you through setting up a local Angular project. - -#### Install Angular CLI - -Open a terminal (if you're using [Visual Studio Code](https://code.visualstudio.com/), you can open an [integrated terminal](https://code.visualstudio.com/docs/editor/integrated-terminal)) and run the following command: - -``` -// npm -npm install -g @angular/cli -``` -``` -// pnpm -pnpm install -g @angular/cli -``` -``` -// yarn -yarn global add @angular/cli -``` -``` -// bun -bun install -g @angular/cli -``` -If you are having issues running this command in Windows or Unix, check out the [CLI docs](/tools/cli/setup-local#install-the-angular-cli) for more info. - -#### Create a new project - -In your terminal, run the CLI command `ng new` with the desired project name. In the following examples, we'll be using the example project name of `my-first-angular-app`. - -```shell -ng new -``` -You will be presented with some configuration options for your project. Use the arrow and enter keys to navigate and select which options you desire. - -If you don't have any preferences, just hit the enter key to take the default options and continue with the setup. - -After you select the configuration options and the CLI runs through the setup, you should see the following message: - -```shell -✔ Packages installed successfully. - Successfully initialized git. -``` - -At this point, you're now ready to run your project locally! - -#### Running your new project locally - -In your terminal, switch to your new Angular project. - -```shell -cd my-first-angular-app -``` -All of your dependencies should be installed at this point (which you can verify by checking for the existent for a `node_modules` folder in your project), so you can start your project by running the command: - -```shell -npm start -``` -If everything is successful, you should see a similar confirmation message in your terminal: - -```shell -Watch mode enabled. Watching for file changes... -NOTE: Raw file sizes do not reflect development server per-request transformations. - ➜ Local: http://localhost:4200/ - ➜ press h + enter to show help -``` - -And now you can visit the path in `Local` (e.g., `http://localhost:4200`) to see your application. Happy coding! 🎉 - -## Next steps - -Now that you've created your Angular project, you can learn more about Angular in our [Essentials guide](/essentials) or choose a topic in our in-depth guides! -# Angular coding style guide - -## Introduction - -This guide covers a range of style conventions for Angular application code. These recommendations -are not required for Angular to work, but instead establish a set of coding practices that promote -consistency across the Angular ecosystem. A consistent set of practices makes it easier to share -code and move between projects. - -This guide does _not_ cover TypeScript or general coding practices unrelated to Angular. For -TypeScript, check -out [Google's TypeScript style guide](https://google.github.io/styleguide/tsguide.html). - -### When in doubt, prefer consistency - -Whenever you encounter a situation in which these rules contradict the style of a particular file, -prioritize maintaining consistency within a file. Mixing different style conventions in a single -file creates more confusion than diverging from the recommendations in this guide. - -## Naming - -### Separate words in file names with hyphens - -Separate words within a file name with hyphens (`-`). For example, a component named `UserProfile` -has a file name `user-profile.ts`. - -### Use the same name for a file's tests with `.spec` at the end - -For unit tests, end file names with `.spec.ts`. For example, the unit test file for -the `UserProfile` component has the file name `user-profile.spec.ts`. - -### Match file names to the TypeScript identifier within - -File names should generally describe the contents of the code in the file. When the file contains a -TypeScript class, the file name should reflect that class name. For example, a file containing a -component named `UserProfile` has the name `user-profile.ts`. - -If the file contains more than one primary namable identifier, choose a name that describes the -common theme to the code within. If the code in a file does not fit within a common theme or feature -area, consider breaking the code up into different files. Avoid overly generic file names -like `helpers.ts`, `utils.ts`, or `common.ts`. - -### Use the same file name for a component's TypeScript, template, and styles - -Components typically consist of one TypeScript file, one template file, and one style file. These -files should share the same name with different file extensions. For example, a `UserProfile` -component can have the files `user-profile.ts`, `user-profile.html`, and `user-profile.css`. - -If a component has more than one style file, append the name with additional words that describe the -styles specific to that file. For example, `UserProfile` might have style -files `user-profile-settings.css` and `user-profile-subscription.css`. - -## Project structure - -### All the application's code goes in a directory named `src` - -All of your Angular UI code (TypeScript, HTML, and styles) should live inside a directory -named `src`. Code that's not related to UI, such as configuration files or scripts, should live -outside the `src` directory. - -This keeps the root application directory consistent between different Angular projects and creates -a clear separation between UI code and other code in your project. - -### Bootstrap your application in a file named `main.ts` directly inside `src` - -The code to start up, or **bootstrap**, an Angular application should always live in a file -named `main.ts`. This represents the primary entry point to the application. - -### Group closely related files together in the same directory - -Angular components consist of a TypeScript file and, optionally, a template and one or more style -files. You should group these together in the same directory. - -Unit tests should live in the same directory as the code-under-test. Avoid collecting unrelated -tests into a single `tests` directory. - -### Organize your project by feature areas - -Organize your project into subdirectories based on the features or your application or common themes -to the code in those directories. For example, the project structure for a movie theater site, -MovieReel, might look like this: - -``` -src/ -├─ movie-reel/ -│ ├─ show-times/ -│ │ ├─ film-calendar/ -│ │ ├─ film-details/ -│ ├─ reserve-tickets/ -│ │ ├─ payment-info/ -│ │ ├─ purchase-confirmation/ -``` - -Avoid creating subdirectories based on the type of code that lives in those directories. For -example, avoid creating directories like `components`, `directives`, and `services`. - -Avoid putting so many files into one directory that it becomes hard to read or navigate. As the -number files in a directory grows, consider splitting further into additional sub-directories. - -### One concept per file - -Prefer focusing source files on a single _concept_. For Angular classes specifically, this usually -means one component, directive, or service per file. However, it's okay if a file contains more than -one component or directive if your classes are relatively small and they tie together as part of a -single concept. - -When in doubt, go with the approach that leads to smaller files. - -## Dependency injection - -### Prefer the `inject` function over constructor parameter injection - -Prefer using the `inject` function over injecting constructor parameters. The `inject` function works the same way as constructor parameter injection, but offers several style advantages: - -* `inject` is generally more readable, especially when a class injects many dependencies. -* It's more syntactically straightforward to add comments to injected dependencies -* `inject` offers better type inference. -* When targeting ES2022+ with [`useDefineForClassFields`](https://www.typescriptlang.org/tsconfig/#useDefineForClassFields), you can avoid separating field declaration and initialization when fields read on injected dependencies. - -[You can refactor existing code to `inject` with an automatic tool](reference/migrations/inject-function). - -## Components and directives - -### Choosing component selectors - -See -the [Components guide for details on choosing component selectors](guide/components/selectors#choosing-a-selector). - -### Naming component and directive members - -See the Components guide for details -on [naming input properties](guide/components/inputs#choosing-input-names) -and [naming output properties](guide/components/outputs#choosing-event-names). - -### Choosing directive selectors - -Directives should use the -same [application-specific prefix](guide/components/selectors#selector-prefixes) -as your components. - -When using an attribute selector for a directive, use a camelCase attribute name. For example, if -your application is named "MovieReel" and you build a directive that adds a tooltip to an element, -you might use the selector `[mrTooltip]`. - -### Group Angular-specific properties before methods - -Components and directives should group Angular-specific properties together, typically near the top -of the class declaration. This includes injected dependencies, inputs, outputs, and queries. Define -these and other properties before the class's methods. - -This practice makes it easier to find the class's template APIs and dependencies. - -### Keep components and directives focused on presentation - -Code inside your components and directives should generally relate to the UI shown on the page. For -code that makes sense on its own, decoupled from the UI, prefer refactoring to other files. For -example, you can factor form validation rules or data transformations into separate functions or -classes. - -### Avoid overly complex logic in templates - -Angular templates are designed to -accommodate [JavaScript-like expressions](guide/templates/expression-syntax). -You should take advantage of these expressions to capture relatively straightforward logic directly -in template expressions. - -When the code in a template gets too complex, though, refactor logic into the TypeScript code ( -typically with a [computed](guide/signals#computed-signals)). - -There's no one hard-and-fast rule that determines what constitutes "complex". Use your best -judgement. - -### Use `protected` on class members that are only used by a component's template - -A component class's public members intrinsically define a public API that's accessible via -dependency injection and [queries](guide/components/queries). Prefer `protected` -access for any members that are meant to be read from the component's template. - -```ts -@Component({ - ..., - template: `

{{ fullName() }}

`, -}) -export class UserProfile { - firstName = input(); - lastName = input(); - -// `fullName` is not part of the component's public API, but is used in the template. - protected fullName = computed(() => `${this.firstName()} ${this.lastName()}`); -} -``` - -### Use `readonly` on properties that are initialized by Angular - -Mark component and directive properties initialized by Angular as `readonly`. This includes -properties initialized by `input`, `model`, `output`, and queries. The readonly access modifier -ensures that the value set by Angular is not overwritten. - -```ts -@Component({/* ... */}) -export class UserProfile { - readonly userId = input(); - readonly userSaved = output(); -} -``` - -For components and directives that use the decorator-based `@Input`, `@Output`, and query APIs, this -advice applies to output properties and queries, but not input properties. - -```ts -@Component({/* ... */}) -export class UserProfile { - @Output() readonly userSaved = new EventEmitter(); - @ViewChildren(PaymentMethod) readonly paymentMethods?: QueryList; -} -``` - -### Prefer `class` and `style` over `ngClass` and `ngStyle` - -Prefer `class` and `style` bindings over using the `NgClass` and `NgStyle` directives. - -```html - -
- - -
-``` - -Both `class` and `style` bindings use a more straightforward syntax that aligns closely with -standard HTML attributes. This makes your templates easier to read and understand, especially for -developers familiar with basic HTML. - -Additionally, the `NgClass` and `NgStyle` directives incur an additional performance cost compared -to the built-in `class` and `style` binding syntax. - -### Name event handlers for what they _do_, not for the triggering event - -Prefer naming event handlers for the action they perform rather than for the triggering event: - -```html - - - - - -``` - -Using meaningful names like this makes it easier to tell what an event does from reading the -template. - -For keyboard events, you can use Angular's key event modifiers with specific handler names: - -```html -