@analogjs/vite-plugin-angular 3.0.0-alpha.5 → 3.0.0-alpha.51
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -0
- package/migrations/migrate-setup-vitest/migrate-setup-vitest.d.ts +2 -0
- package/migrations/migrate-setup-vitest/migrate-setup-vitest.js +49 -0
- package/migrations/migrate-setup-vitest/migrate-setup-vitest.js.map +1 -0
- package/migrations/migration.json +7 -1
- package/migrations/migrations.json +9 -0
- package/migrations/update-3-0-0/migrate-setup-vitest.d.ts +2 -0
- package/migrations/update-3-0-0/migrate-setup-vitest.js +36 -0
- package/migrations/update-3-0-0/migrate-setup-vitest.js.map +1 -0
- package/package.json +41 -12
- package/src/index.d.ts +3 -2
- package/src/index.js +6 -2
- package/src/index.js.map +1 -1
- package/src/lib/angular-build-optimizer-plugin.d.ts +4 -4
- package/src/lib/angular-build-optimizer-plugin.js +48 -62
- package/src/lib/angular-build-optimizer-plugin.js.map +1 -1
- package/src/lib/angular-jit-plugin.d.ts +3 -3
- package/src/lib/angular-jit-plugin.js +39 -37
- package/src/lib/angular-jit-plugin.js.map +1 -1
- package/src/lib/angular-pending-tasks.plugin.d.ts +7 -7
- package/src/lib/angular-pending-tasks.plugin.js +17 -18
- package/src/lib/angular-pending-tasks.plugin.js.map +1 -1
- package/src/lib/angular-vite-plugin.d.ts +180 -44
- package/src/lib/angular-vite-plugin.js +1233 -969
- package/src/lib/angular-vite-plugin.js.map +1 -1
- package/src/lib/angular-vitest-plugin.d.ts +19 -15
- package/src/lib/angular-vitest-plugin.js +99 -114
- package/src/lib/angular-vitest-plugin.js.map +1 -1
- package/src/lib/compilation-api/compilation-api-plugin.d.ts +29 -0
- package/src/lib/compilation-api/compilation-api-plugin.js +480 -0
- package/src/lib/compilation-api/compilation-api-plugin.js.map +1 -0
- package/src/lib/compilation-api/index.d.ts +1 -0
- package/src/lib/compilation-api/index.js +1 -0
- package/src/lib/compiler/angular-version.d.ts +19 -0
- package/src/lib/compiler/angular-version.js +16 -0
- package/src/lib/compiler/angular-version.js.map +1 -0
- package/src/lib/compiler/class-field-lowering.d.ts +23 -0
- package/src/lib/compiler/class-field-lowering.js +131 -0
- package/src/lib/compiler/class-field-lowering.js.map +1 -0
- package/src/lib/compiler/compile.d.ts +44 -0
- package/src/lib/compiler/compile.js +731 -0
- package/src/lib/compiler/compile.js.map +1 -0
- package/src/lib/compiler/constants.d.ts +18 -0
- package/src/lib/compiler/constants.js +52 -0
- package/src/lib/compiler/constants.js.map +1 -0
- package/src/lib/compiler/debug.d.ts +22 -0
- package/src/lib/compiler/debug.js +20 -0
- package/src/lib/compiler/debug.js.map +1 -0
- package/src/lib/compiler/defer.d.ts +57 -0
- package/src/lib/compiler/defer.js +154 -0
- package/src/lib/compiler/defer.js.map +1 -0
- package/src/lib/compiler/dts-reader.d.ts +35 -0
- package/src/lib/compiler/dts-reader.js +365 -0
- package/src/lib/compiler/dts-reader.js.map +1 -0
- package/src/lib/compiler/hmr.d.ts +16 -0
- package/src/lib/compiler/hmr.js +69 -0
- package/src/lib/compiler/hmr.js.map +1 -0
- package/src/lib/compiler/index.d.ts +7 -0
- package/src/lib/compiler/index.js +7 -0
- package/src/lib/compiler/jit-metadata.d.ts +14 -0
- package/src/lib/compiler/jit-metadata.js +146 -0
- package/src/lib/compiler/jit-metadata.js.map +1 -0
- package/src/lib/compiler/jit-transform.d.ts +24 -0
- package/src/lib/compiler/jit-transform.js +200 -0
- package/src/lib/compiler/jit-transform.js.map +1 -0
- package/src/lib/compiler/js-emitter.d.ts +10 -0
- package/src/lib/compiler/js-emitter.js +445 -0
- package/src/lib/compiler/js-emitter.js.map +1 -0
- package/src/lib/compiler/metadata.d.ts +45 -0
- package/src/lib/compiler/metadata.js +633 -0
- package/src/lib/compiler/metadata.js.map +1 -0
- package/src/lib/compiler/registry.d.ts +49 -0
- package/src/lib/compiler/registry.js +164 -0
- package/src/lib/compiler/registry.js.map +1 -0
- package/src/lib/compiler/resource-inliner.d.ts +21 -0
- package/src/lib/compiler/resource-inliner.js +152 -0
- package/src/lib/compiler/resource-inliner.js.map +1 -0
- package/src/lib/compiler/style-ast.d.ts +8 -0
- package/src/lib/compiler/style-ast.js +54 -0
- package/src/lib/compiler/style-ast.js.map +1 -0
- package/src/lib/compiler/styles.d.ts +13 -0
- package/src/lib/compiler/test-helpers.d.ts +7 -0
- package/src/lib/compiler/type-elision.d.ts +26 -0
- package/src/lib/compiler/type-elision.js +211 -0
- package/src/lib/compiler/type-elision.js.map +1 -0
- package/src/lib/compiler/utils.d.ts +10 -0
- package/src/lib/compiler/utils.js +35 -0
- package/src/lib/compiler/utils.js.map +1 -0
- package/src/lib/compiler-plugin.d.ts +11 -11
- package/src/lib/compiler-plugin.js +43 -44
- package/src/lib/compiler-plugin.js.map +1 -1
- package/src/lib/component-resolvers.d.ts +23 -5
- package/src/lib/component-resolvers.js +153 -63
- package/src/lib/component-resolvers.js.map +1 -1
- package/src/lib/encapsulation-plugin.d.ts +13 -0
- package/src/lib/encapsulation-plugin.js +48 -0
- package/src/lib/encapsulation-plugin.js.map +1 -0
- package/src/lib/fast-compile-plugin.d.ts +28 -0
- package/src/lib/fast-compile-plugin.js +289 -0
- package/src/lib/fast-compile-plugin.js.map +1 -0
- package/src/lib/host.d.ts +10 -8
- package/src/lib/host.js +113 -101
- package/src/lib/host.js.map +1 -1
- package/src/lib/live-reload-plugin.d.ts +5 -5
- package/src/lib/live-reload-plugin.js +61 -62
- package/src/lib/live-reload-plugin.js.map +1 -1
- package/src/lib/models.d.ts +9 -9
- package/src/lib/nx-folder-plugin.d.ts +5 -5
- package/src/lib/nx-folder-plugin.js +18 -16
- package/src/lib/nx-folder-plugin.js.map +1 -1
- package/src/lib/plugins/file-replacements.plugin.d.ts +4 -4
- package/src/lib/plugins/file-replacements.plugin.js +40 -62
- package/src/lib/plugins/file-replacements.plugin.js.map +1 -1
- package/src/lib/router-plugin.d.ts +1 -1
- package/src/lib/router-plugin.js +23 -23
- package/src/lib/router-plugin.js.map +1 -1
- package/src/lib/style-pipeline.d.ts +15 -0
- package/src/lib/style-pipeline.js +31 -0
- package/src/lib/style-pipeline.js.map +1 -0
- package/src/lib/style-preprocessor.d.ts +35 -0
- package/src/lib/style-preprocessor.js +35 -0
- package/src/lib/style-preprocessor.js.map +1 -0
- package/src/lib/stylesheet-registry.d.ts +73 -0
- package/src/lib/stylesheet-registry.js +168 -0
- package/src/lib/stylesheet-registry.js.map +1 -0
- package/src/lib/tailwind-plugin.d.ts +34 -0
- package/src/lib/tailwind-plugin.js +116 -0
- package/src/lib/tailwind-plugin.js.map +1 -0
- package/src/lib/template-class-binding-guard-plugin.d.ts +30 -0
- package/src/lib/template-class-binding-guard-plugin.js +237 -0
- package/src/lib/template-class-binding-guard-plugin.js.map +1 -0
- package/src/lib/tools/package.json +2 -7
- package/src/lib/tools/src/builders/vite/vite-build.impl.js +31 -38
- package/src/lib/tools/src/builders/vite/vite-build.impl.js.map +1 -1
- package/src/lib/tools/src/builders/vite-dev-server/dev-server.impl.js +51 -62
- package/src/lib/tools/src/builders/vite-dev-server/dev-server.impl.js.map +1 -1
- package/src/lib/tools/src/index.js +0 -2
- package/src/lib/utils/compilation-shared.d.ts +58 -0
- package/src/lib/utils/compilation-shared.js +133 -0
- package/src/lib/utils/compilation-shared.js.map +1 -0
- package/src/lib/utils/compiler-plugin-options.d.ts +11 -11
- package/src/lib/utils/debug-harness.d.ts +23 -0
- package/src/lib/utils/debug-harness.js +88 -0
- package/src/lib/utils/debug-harness.js.map +1 -0
- package/src/lib/utils/debug-log-file.d.ts +5 -0
- package/src/lib/utils/debug-log-file.js +56 -0
- package/src/lib/utils/debug-log-file.js.map +1 -0
- package/src/lib/utils/debug.d.ts +28 -0
- package/src/lib/utils/debug.js +39 -0
- package/src/lib/utils/debug.js.map +1 -0
- package/src/lib/utils/devkit.d.ts +6 -6
- package/src/lib/utils/devkit.js +34 -38
- package/src/lib/utils/devkit.js.map +1 -1
- package/src/lib/utils/hmr-candidates.d.ts +28 -28
- package/src/lib/utils/plugin-config.d.ts +37 -0
- package/src/lib/utils/plugin-config.js +71 -0
- package/src/lib/utils/plugin-config.js.map +1 -0
- package/src/lib/utils/rolldown.d.ts +2 -0
- package/src/lib/utils/rolldown.js +12 -0
- package/src/lib/utils/rolldown.js.map +1 -0
- package/src/lib/utils/safe-module-paths.d.ts +16 -0
- package/src/lib/utils/safe-module-paths.js +29 -0
- package/src/lib/utils/safe-module-paths.js.map +1 -0
- package/src/lib/utils/source-file-cache.d.ts +8 -15
- package/src/lib/utils/source-file-cache.js +35 -37
- package/src/lib/utils/source-file-cache.js.map +1 -1
- package/src/lib/utils/tailwind-reference.d.ts +12 -0
- package/src/lib/utils/tailwind-reference.js +99 -0
- package/src/lib/utils/tailwind-reference.js.map +1 -0
- package/src/lib/utils/tsconfig-resolver.d.ts +28 -0
- package/src/lib/utils/tsconfig-resolver.js +191 -0
- package/src/lib/utils/tsconfig-resolver.js.map +1 -0
- package/src/lib/utils/virtual-ids.d.ts +4 -0
- package/src/lib/utils/virtual-ids.js +23 -0
- package/src/lib/utils/virtual-ids.js.map +1 -0
- package/src/lib/utils/virtual-resources.d.ts +19 -0
- package/src/lib/utils/virtual-resources.js +38 -0
- package/src/lib/utils/virtual-resources.js.map +1 -0
- package/src/lib/virtual-modules-plugin.d.ts +5 -0
- package/src/lib/virtual-modules-plugin.js +23 -0
- package/src/lib/virtual-modules-plugin.js.map +1 -0
- package/src/test-setup.d.ts +2 -0
- package/setup-vitest.d.ts +0 -4
- package/setup-vitest.js +0 -215
- package/setup-vitest.js.map +0 -1
- package/src/lib/models.js +0 -1
- package/src/lib/models.js.map +0 -1
- package/src/lib/tools/README.md +0 -3
- package/src/lib/tools/src/index.d.ts +0 -0
- package/src/lib/tools/src/index.js.map +0 -1
- package/src/lib/utils/compiler-plugin-options.js +0 -1
- package/src/lib/utils/compiler-plugin-options.js.map +0 -1
- package/src/lib/utils/hmr-candidates.js +0 -272
- package/src/lib/utils/hmr-candidates.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"style-ast.js","names":[],"sources":["../../../../src/lib/compiler/style-ast.ts"],"sourcesContent":["import { parseSync } from 'oxc-parser';\n\ntype ProgramNode = ReturnType<typeof parseSync>['program']['body'][number];\n\nfunction getClassDeclaration(node: ProgramNode): any {\n return node.type === 'ExportNamedDeclaration' ||\n node.type === 'ExportDefaultDeclaration'\n ? (node as any).declaration\n : node;\n}\n\nfunction getPropertyKey(prop: any): string | undefined {\n return prop.key?.name || prop.key?.value;\n}\n\nfunction getTemplateLiteralText(node: any): string | undefined {\n if (node?.type !== 'TemplateLiteral' || node.quasis?.length !== 1) {\n return undefined;\n }\n\n return node.quasis[0].value.cooked || node.quasis[0].value.raw;\n}\n\n/**\n * Extract styleUrl/styleUrls values from Angular @Component decorators.\n */\nexport function extractStyleUrls(code: string, fileName: string): string[] {\n const urls: string[] = [];\n const { program } = parseSync(fileName, code);\n\n for (const node of program.body) {\n const decl = getClassDeclaration(node);\n if (!decl || decl.type !== 'ClassDeclaration') continue;\n\n for (const dec of decl.decorators || []) {\n const expr = dec.expression;\n if (!expr || expr.type !== 'CallExpression') continue;\n if (expr.callee?.name !== 'Component') continue;\n\n const arg = expr.arguments?.[0];\n if (!arg || arg.type !== 'ObjectExpression') continue;\n\n for (const prop of arg.properties) {\n if (prop.type !== 'Property') continue;\n const key = getPropertyKey(prop);\n const val = prop.value;\n\n if (\n key === 'styleUrl' &&\n val?.type === 'Literal' &&\n typeof val.value === 'string'\n ) {\n urls.push(val.value);\n }\n\n if (key === 'styleUrls' && val?.type === 'ArrayExpression') {\n for (const el of val.elements) {\n if (el?.type === 'Literal' && typeof el.value === 'string') {\n urls.push(el.value);\n }\n }\n }\n }\n }\n }\n\n return urls;\n}\n\n/**\n * Extract inline style strings from Angular @Component decorators.\n */\nexport function extractInlineStyles(code: string, fileName: string): string[] {\n const styles: string[] = [];\n const { program } = parseSync(fileName, code);\n\n for (const node of program.body) {\n const decl = getClassDeclaration(node);\n if (!decl || decl.type !== 'ClassDeclaration') continue;\n\n for (const dec of decl.decorators || []) {\n const expr = dec.expression;\n if (!expr || expr.type !== 'CallExpression') continue;\n if (expr.callee?.name !== 'Component') continue;\n\n const arg = expr.arguments?.[0];\n if (!arg || arg.type !== 'ObjectExpression') continue;\n\n for (const prop of arg.properties) {\n if (prop.type !== 'Property') continue;\n const key = getPropertyKey(prop);\n const val = prop.value;\n\n if (key !== 'styles') continue;\n\n if (val?.type === 'ArrayExpression') {\n for (const el of val.elements) {\n if (el?.type === 'Literal' && typeof el.value === 'string') {\n styles.push(el.value);\n continue;\n }\n\n const templateText = getTemplateLiteralText(el);\n if (templateText !== undefined) {\n styles.push(templateText);\n }\n }\n } else if (val?.type === 'Literal' && typeof val.value === 'string') {\n styles.push(val.value);\n } else {\n const templateText = getTemplateLiteralText(val);\n if (templateText !== undefined) {\n styles.push(templateText);\n }\n }\n }\n }\n }\n\n return styles;\n}\n"],"mappings":";;AAIA,SAAS,oBAAoB,MAAwB;AACnD,QAAO,KAAK,SAAS,4BACnB,KAAK,SAAS,6BACX,KAAa,cACd;;AAGN,SAAS,eAAe,MAA+B;AACrD,QAAO,KAAK,KAAK,QAAQ,KAAK,KAAK;;AAGrC,SAAS,uBAAuB,MAA+B;AAC7D,KAAI,MAAM,SAAS,qBAAqB,KAAK,QAAQ,WAAW,EAC9D;AAGF,QAAO,KAAK,OAAO,GAAG,MAAM,UAAU,KAAK,OAAO,GAAG,MAAM;;;;;AAoD7D,SAAgB,oBAAoB,MAAc,UAA4B;CAC5E,MAAM,SAAmB,EAAE;CAC3B,MAAM,EAAE,YAAY,UAAU,UAAU,KAAK;AAE7C,MAAK,MAAM,QAAQ,QAAQ,MAAM;EAC/B,MAAM,OAAO,oBAAoB,KAAK;AACtC,MAAI,CAAC,QAAQ,KAAK,SAAS,mBAAoB;AAE/C,OAAK,MAAM,OAAO,KAAK,cAAc,EAAE,EAAE;GACvC,MAAM,OAAO,IAAI;AACjB,OAAI,CAAC,QAAQ,KAAK,SAAS,iBAAkB;AAC7C,OAAI,KAAK,QAAQ,SAAS,YAAa;GAEvC,MAAM,MAAM,KAAK,YAAY;AAC7B,OAAI,CAAC,OAAO,IAAI,SAAS,mBAAoB;AAE7C,QAAK,MAAM,QAAQ,IAAI,YAAY;AACjC,QAAI,KAAK,SAAS,WAAY;IAC9B,MAAM,MAAM,eAAe,KAAK;IAChC,MAAM,MAAM,KAAK;AAEjB,QAAI,QAAQ,SAAU;AAEtB,QAAI,KAAK,SAAS,kBAChB,MAAK,MAAM,MAAM,IAAI,UAAU;AAC7B,SAAI,IAAI,SAAS,aAAa,OAAO,GAAG,UAAU,UAAU;AAC1D,aAAO,KAAK,GAAG,MAAM;AACrB;;KAGF,MAAM,eAAe,uBAAuB,GAAG;AAC/C,SAAI,iBAAiB,KAAA,EACnB,QAAO,KAAK,aAAa;;aAGpB,KAAK,SAAS,aAAa,OAAO,IAAI,UAAU,SACzD,QAAO,KAAK,IAAI,MAAM;SACjB;KACL,MAAM,eAAe,uBAAuB,IAAI;AAChD,SAAI,iBAAiB,KAAA,EACnB,QAAO,KAAK,aAAa;;;;;AAOnC,QAAO"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type ResolvedConfig } from "vite";
|
|
2
|
+
/**
|
|
3
|
+
* Extract styleUrl/styleUrls from source using OXC parser,
|
|
4
|
+
* read and preprocess them via Vite.
|
|
5
|
+
* Returns a Map of absolute path → compiled CSS for the compiler to use.
|
|
6
|
+
*/
|
|
7
|
+
export declare function resolveStyleFiles(code: string, id: string, resolvedConfig: ResolvedConfig): Promise<Map<string, string> | undefined>;
|
|
8
|
+
/**
|
|
9
|
+
* Preprocess inline styles that contain SCSS/Sass syntax.
|
|
10
|
+
* Uses OXC parser to extract style strings from decorator arguments
|
|
11
|
+
* and runs them through Vite's preprocessCSS.
|
|
12
|
+
*/
|
|
13
|
+
export declare function preprocessInlineStyles(code: string, id: string, inlineStyleLanguage: string, resolvedConfig: ResolvedConfig): Promise<Map<number, string> | undefined>;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { ComponentRegistry } from "./registry";
|
|
2
|
+
export declare function buildRegistry(files: Record<string, string>): ComponentRegistry;
|
|
3
|
+
/** Convenience wrapper: compile and return just the code string. */
|
|
4
|
+
export declare function compileCode(sourceCode: string, fileName: string, registry?: ComponentRegistry): string;
|
|
5
|
+
/** Compile in partial mode and return just the code string. */
|
|
6
|
+
export declare function compilePartialCode(sourceCode: string, fileName: string, registry?: ComponentRegistry): string;
|
|
7
|
+
export declare function expectCompiles(result: string);
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import MagicString from "magic-string";
|
|
2
|
+
/**
|
|
3
|
+
* Analyse compiled TypeScript source and return the set of imported names
|
|
4
|
+
* that are only referenced in type positions (type annotations, implements
|
|
5
|
+
* clauses, generics, etc.) and can safely be elided.
|
|
6
|
+
*
|
|
7
|
+
* Uses oxc-parser for fast, Rust-based AST analysis — no type-checker needed.
|
|
8
|
+
*/
|
|
9
|
+
export declare function detectTypeOnlyImportNames(code: string): Set<string>;
|
|
10
|
+
/**
|
|
11
|
+
* Elide import specifiers (or entire import declarations) for names that are
|
|
12
|
+
* only used in type positions. Operates on the compiler's TypeScript output
|
|
13
|
+
* (before OXC strips remaining TS syntax).
|
|
14
|
+
*
|
|
15
|
+
* Returns the modified source code, or the original if nothing was elided.
|
|
16
|
+
*/
|
|
17
|
+
export declare function elideTypeOnlyImports(code: string): string;
|
|
18
|
+
/**
|
|
19
|
+
* Elide type-only imports directly on a MagicString instance, so that
|
|
20
|
+
* subsequent `ms.generateMap()` calls produce an accurate sourcemap.
|
|
21
|
+
*
|
|
22
|
+
* Detects type-only names from `ms.toString()` (the fully-mutated code),
|
|
23
|
+
* but reads import positions from `ms.original` (the coordinate system
|
|
24
|
+
* MagicString expects).
|
|
25
|
+
*/
|
|
26
|
+
export declare function elideTypeOnlyImportsMagicString(ms: MagicString): void;
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import { parseSync } from "oxc-parser";
|
|
2
|
+
import "magic-string";
|
|
3
|
+
//#region packages/vite-plugin-angular/src/lib/compiler/type-elision.ts
|
|
4
|
+
/**
|
|
5
|
+
* AST property keys that represent type-only positions in TypeScript.
|
|
6
|
+
* Identifiers found only under these keys are never emitted as runtime values.
|
|
7
|
+
*/
|
|
8
|
+
var TYPE_POSITION_KEYS = new Set([
|
|
9
|
+
"typeAnnotation",
|
|
10
|
+
"typeParameters",
|
|
11
|
+
"superTypeParameters",
|
|
12
|
+
"implements",
|
|
13
|
+
"returnType",
|
|
14
|
+
"typeArguments"
|
|
15
|
+
]);
|
|
16
|
+
/**
|
|
17
|
+
* AST node types that represent type-level constructs.
|
|
18
|
+
* Any identifier nested inside one of these nodes is in a type position.
|
|
19
|
+
*/
|
|
20
|
+
var TYPE_NODE_TYPES = new Set([
|
|
21
|
+
"TSTypeAnnotation",
|
|
22
|
+
"TSTypeReference",
|
|
23
|
+
"TSTypeParameterInstantiation",
|
|
24
|
+
"TSTypeParameterDeclaration",
|
|
25
|
+
"TSInterfaceDeclaration",
|
|
26
|
+
"TSTypeAliasDeclaration",
|
|
27
|
+
"TSAsExpression",
|
|
28
|
+
"TSSatisfiesExpression",
|
|
29
|
+
"TSUnionType",
|
|
30
|
+
"TSIntersectionType",
|
|
31
|
+
"TSArrayType",
|
|
32
|
+
"TSTupleType",
|
|
33
|
+
"TSFunctionType",
|
|
34
|
+
"TSConstructorType",
|
|
35
|
+
"TSMappedType",
|
|
36
|
+
"TSConditionalType",
|
|
37
|
+
"TSIndexedAccessType",
|
|
38
|
+
"TSTypeQuery",
|
|
39
|
+
"TSTypeLiteral",
|
|
40
|
+
"TSQualifiedName",
|
|
41
|
+
"TSInterfaceBody"
|
|
42
|
+
]);
|
|
43
|
+
/**
|
|
44
|
+
* Internal helper: parse code and return both the AST and the set of
|
|
45
|
+
* type-only imported names. Avoids double-parsing when both are needed.
|
|
46
|
+
*/
|
|
47
|
+
function analyzeTypeOnlyImports(code) {
|
|
48
|
+
const ast = parseSync("file.ts", code).program;
|
|
49
|
+
const importedNames = /* @__PURE__ */ new Set();
|
|
50
|
+
for (const node of ast.body) {
|
|
51
|
+
if (node.type !== "ImportDeclaration") continue;
|
|
52
|
+
if (node.importKind === "type") continue;
|
|
53
|
+
for (const spec of node.specifiers ?? []) {
|
|
54
|
+
if (spec.importKind === "type") continue;
|
|
55
|
+
importedNames.add(spec.local.name);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
if (importedNames.size === 0) return {
|
|
59
|
+
ast,
|
|
60
|
+
typeOnlyNames: /* @__PURE__ */ new Set()
|
|
61
|
+
};
|
|
62
|
+
const valueReferenced = /* @__PURE__ */ new Set();
|
|
63
|
+
collectConstructorDiTokens(ast, importedNames, valueReferenced);
|
|
64
|
+
function walk(node, inTypePosition) {
|
|
65
|
+
if (!node || typeof node !== "object") return;
|
|
66
|
+
if (Array.isArray(node)) {
|
|
67
|
+
for (const item of node) walk(item, inTypePosition);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
if (valueReferenced.size === importedNames.size) return;
|
|
71
|
+
if (!inTypePosition && TYPE_NODE_TYPES.has(node.type)) {
|
|
72
|
+
if (node.type === "TSAsExpression" || node.type === "TSSatisfiesExpression") {
|
|
73
|
+
walk(node.expression, false);
|
|
74
|
+
walk(node.typeAnnotation, true);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
inTypePosition = true;
|
|
78
|
+
}
|
|
79
|
+
if (!inTypePosition && node.type === "ExportNamedDeclaration" && !node.source) {
|
|
80
|
+
if (node.declaration) walk(node.declaration, false);
|
|
81
|
+
for (const spec of node.specifiers ?? []) {
|
|
82
|
+
if (node.exportKind === "type" || spec.exportKind === "type") continue;
|
|
83
|
+
walk(spec, false);
|
|
84
|
+
}
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
if (!inTypePosition && node.type === "Identifier" && importedNames.has(node.name)) {
|
|
88
|
+
valueReferenced.add(node.name);
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
for (const key of Object.keys(node)) {
|
|
92
|
+
if (key === "type" || key === "start" || key === "end" || key === "range" || key === "loc") continue;
|
|
93
|
+
const isTypePos = inTypePosition || TYPE_POSITION_KEYS.has(key);
|
|
94
|
+
walk(node[key], isTypePos);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
for (const node of ast.body) if (node.type !== "ImportDeclaration") walk(node, false);
|
|
98
|
+
const typeOnly = /* @__PURE__ */ new Set();
|
|
99
|
+
for (const name of importedNames) if (!valueReferenced.has(name)) typeOnly.add(name);
|
|
100
|
+
return {
|
|
101
|
+
ast,
|
|
102
|
+
typeOnlyNames: typeOnly
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Walk the program looking for decorated classes with constructors and add
|
|
107
|
+
* the type names from constructor parameter annotations to `valueReferenced`.
|
|
108
|
+
*
|
|
109
|
+
* Constructor parameter types are TypeScript type positions, but for decorated
|
|
110
|
+
* classes they double as runtime DI tokens — Angular's compiler reads them
|
|
111
|
+
* via `compileFactoryFunction` to wire `ɵɵdirectiveInject(...)` calls. The
|
|
112
|
+
* import of the type therefore must NOT be elided as type-only.
|
|
113
|
+
*/
|
|
114
|
+
function collectConstructorDiTokens(ast, importedNames, valueReferenced) {
|
|
115
|
+
for (const stmt of ast.body || []) {
|
|
116
|
+
const classNode = stmt.type === "ExportNamedDeclaration" || stmt.type === "ExportDefaultDeclaration" ? stmt.declaration : stmt;
|
|
117
|
+
if (!classNode || classNode.type !== "ClassDeclaration" && classNode.type !== "ClassExpression") continue;
|
|
118
|
+
if (!classNode.decorators?.length) continue;
|
|
119
|
+
const ctor = (classNode.body?.body || []).find((m) => m.type === "MethodDefinition" && m.kind === "constructor");
|
|
120
|
+
if (!ctor) continue;
|
|
121
|
+
const params = ctor.value?.params?.items || ctor.value?.params || [];
|
|
122
|
+
for (const param of params) {
|
|
123
|
+
const typeAnn = (param.type === "TSParameterProperty" ? param.parameter : param)?.typeAnnotation?.typeAnnotation ?? param?.typeAnnotation?.typeAnnotation;
|
|
124
|
+
if (!typeAnn) continue;
|
|
125
|
+
collectTypeReferenceNames(typeAnn, importedNames, valueReferenced);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Recursively extract identifier names from a TS type expression and mark
|
|
131
|
+
* any that match an imported name as value-referenced.
|
|
132
|
+
*/
|
|
133
|
+
function collectTypeReferenceNames(typeNode, importedNames, valueReferenced) {
|
|
134
|
+
if (!typeNode || typeof typeNode !== "object") return;
|
|
135
|
+
if (typeNode.type === "TSTypeReference" && typeNode.typeName) {
|
|
136
|
+
const name = typeNode.typeName.name;
|
|
137
|
+
if (name && importedNames.has(name)) valueReferenced.add(name);
|
|
138
|
+
if (typeNode.typeArguments) collectTypeReferenceNames(typeNode.typeArguments, importedNames, valueReferenced);
|
|
139
|
+
} else if (typeNode.type === "TSUnionType" || typeNode.type === "TSIntersectionType") for (const t of typeNode.types || []) collectTypeReferenceNames(t, importedNames, valueReferenced);
|
|
140
|
+
else if (Array.isArray(typeNode)) for (const t of typeNode) collectTypeReferenceNames(t, importedNames, valueReferenced);
|
|
141
|
+
else if (typeNode.params) for (const t of typeNode.params) collectTypeReferenceNames(t, importedNames, valueReferenced);
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Analyse compiled TypeScript source and return the set of imported names
|
|
145
|
+
* that are only referenced in type positions (type annotations, implements
|
|
146
|
+
* clauses, generics, etc.) and can safely be elided.
|
|
147
|
+
*
|
|
148
|
+
* Uses oxc-parser for fast, Rust-based AST analysis — no type-checker needed.
|
|
149
|
+
*/
|
|
150
|
+
function detectTypeOnlyImportNames(code) {
|
|
151
|
+
return analyzeTypeOnlyImports(code).typeOnlyNames;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Apply import elision edits to a MagicString instance using positions from
|
|
155
|
+
* a parsed AST. Shared logic for both the string-based and MagicString APIs.
|
|
156
|
+
*/
|
|
157
|
+
function applyElisionEdits(ms, ast, src, typeOnlyNames) {
|
|
158
|
+
let edited = false;
|
|
159
|
+
for (const node of ast.body) {
|
|
160
|
+
if (node.type !== "ImportDeclaration") continue;
|
|
161
|
+
if (node.importKind === "type") continue;
|
|
162
|
+
const allSpecs = node.specifiers ?? [];
|
|
163
|
+
const defaultSpec = allSpecs.find((s) => s.type === "ImportDefaultSpecifier");
|
|
164
|
+
const namedSpecs = allSpecs.filter((s) => s.type === "ImportSpecifier" && s.importKind !== "type");
|
|
165
|
+
const elideDefault = defaultSpec && typeOnlyNames.has(defaultSpec.local.name);
|
|
166
|
+
const keptNamed = namedSpecs.filter((s) => !typeOnlyNames.has(s.local.name));
|
|
167
|
+
const removingNamed = namedSpecs.length - keptNamed.length;
|
|
168
|
+
if (!elideDefault && removingNamed === 0) continue;
|
|
169
|
+
let declEnd = node.end;
|
|
170
|
+
while (declEnd < src.length && (src[declEnd] === "\n" || src[declEnd] === "\r")) declEnd++;
|
|
171
|
+
const keepDefault = defaultSpec && !elideDefault;
|
|
172
|
+
const hasKeptNamed = keptNamed.length > 0;
|
|
173
|
+
if (!keepDefault && !hasKeptNamed) {
|
|
174
|
+
ms.remove(node.start, declEnd);
|
|
175
|
+
edited = true;
|
|
176
|
+
} else {
|
|
177
|
+
const parts = [];
|
|
178
|
+
if (keepDefault) parts.push(defaultSpec.local.name);
|
|
179
|
+
if (hasKeptNamed) {
|
|
180
|
+
const namedList = keptNamed.map((s) => {
|
|
181
|
+
const imported = s.imported?.name ?? s.local.name;
|
|
182
|
+
return imported === s.local.name ? s.local.name : `${imported} as ${s.local.name}`;
|
|
183
|
+
});
|
|
184
|
+
parts.push(`{ ${namedList.join(", ")} }`);
|
|
185
|
+
}
|
|
186
|
+
const source = node.source.value;
|
|
187
|
+
const quote = src[node.source.start];
|
|
188
|
+
ms.overwrite(node.start, node.end, `import ${parts.join(", ")} from ${quote}${source}${quote};`);
|
|
189
|
+
edited = true;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
return edited;
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Elide type-only imports directly on a MagicString instance, so that
|
|
196
|
+
* subsequent `ms.generateMap()` calls produce an accurate sourcemap.
|
|
197
|
+
*
|
|
198
|
+
* Detects type-only names from `ms.toString()` (the fully-mutated code),
|
|
199
|
+
* but reads import positions from `ms.original` (the coordinate system
|
|
200
|
+
* MagicString expects).
|
|
201
|
+
*/
|
|
202
|
+
function elideTypeOnlyImportsMagicString(ms) {
|
|
203
|
+
const typeOnlyNames = detectTypeOnlyImportNames(ms.toString());
|
|
204
|
+
if (typeOnlyNames.size === 0) return;
|
|
205
|
+
const ast = parseSync("file.ts", ms.original).program;
|
|
206
|
+
applyElisionEdits(ms, ast, ms.original, typeOnlyNames);
|
|
207
|
+
}
|
|
208
|
+
//#endregion
|
|
209
|
+
export { detectTypeOnlyImportNames, elideTypeOnlyImportsMagicString };
|
|
210
|
+
|
|
211
|
+
//# sourceMappingURL=type-elision.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"type-elision.js","names":[],"sources":["../../../../src/lib/compiler/type-elision.ts"],"sourcesContent":["import MagicString from 'magic-string';\nimport { parseSync } from 'oxc-parser';\n\n// ── Type-only import elision via OXC AST ────────────────────────────────\n\n/**\n * AST property keys that represent type-only positions in TypeScript.\n * Identifiers found only under these keys are never emitted as runtime values.\n */\nconst TYPE_POSITION_KEYS = new Set([\n 'typeAnnotation',\n 'typeParameters',\n 'superTypeParameters',\n 'implements',\n 'returnType',\n 'typeArguments',\n]);\n\n/**\n * AST node types that represent type-level constructs.\n * Any identifier nested inside one of these nodes is in a type position.\n */\nconst TYPE_NODE_TYPES = new Set([\n 'TSTypeAnnotation',\n 'TSTypeReference',\n 'TSTypeParameterInstantiation',\n 'TSTypeParameterDeclaration',\n 'TSInterfaceDeclaration',\n 'TSTypeAliasDeclaration',\n 'TSAsExpression',\n 'TSSatisfiesExpression',\n 'TSUnionType',\n 'TSIntersectionType',\n 'TSArrayType',\n 'TSTupleType',\n 'TSFunctionType',\n 'TSConstructorType',\n 'TSMappedType',\n 'TSConditionalType',\n 'TSIndexedAccessType',\n 'TSTypeQuery',\n 'TSTypeLiteral',\n 'TSQualifiedName',\n 'TSInterfaceBody',\n]);\n\n/**\n * Internal helper: parse code and return both the AST and the set of\n * type-only imported names. Avoids double-parsing when both are needed.\n */\nfunction analyzeTypeOnlyImports(code: string): {\n ast: any;\n typeOnlyNames: Set<string>;\n} {\n const ast = parseSync('file.ts', code).program;\n\n // Step 1 – collect all value-imported names (skip `import type` / `{ type X }`)\n // Namespace imports (`import * as ns`) are intentionally skipped — they are\n // always value imports in TypeScript and cannot be type-only at the\n // declaration level.\n const importedNames = new Set<string>();\n for (const node of (ast as any).body) {\n if (node.type !== 'ImportDeclaration') continue;\n if (node.importKind === 'type') continue; // already type-only\n for (const spec of node.specifiers ?? []) {\n if (spec.importKind === 'type') continue; // already type-only\n importedNames.add(spec.local.name);\n }\n }\n if (importedNames.size === 0) return { ast, typeOnlyNames: new Set() };\n\n // Step 2 – walk AST and collect names referenced in value positions\n const valueReferenced = new Set<string>();\n\n // Pre-pass: constructor parameter types of decorated classes are DI tokens\n // and must be preserved as runtime values, even though they appear in\n // type-annotation positions. Without this, `constructor(svc: MyService)`\n // would erase the `MyService` import and `extractConstructorDeps` would\n // emit `ɵɵinvalidFactory()`.\n collectConstructorDiTokens(ast, importedNames, valueReferenced);\n\n function walk(node: any, inTypePosition: boolean): void {\n if (!node || typeof node !== 'object') return;\n if (Array.isArray(node)) {\n for (const item of node) walk(item, inTypePosition);\n return;\n }\n\n // Short-circuit: if we found every imported name in a value position, stop\n if (valueReferenced.size === importedNames.size) return;\n\n // If this node's type itself marks a type construct, everything below is type-only\n // Exception: TSAsExpression/TSSatisfiesExpression have a value `expression`\n // child that is NOT in a type position — only the type annotation is.\n if (!inTypePosition && TYPE_NODE_TYPES.has(node.type)) {\n if (\n node.type === 'TSAsExpression' ||\n node.type === 'TSSatisfiesExpression'\n ) {\n // Walk the expression child in value context, type annotation in type context\n walk(node.expression, false);\n walk(node.typeAnnotation, true);\n return;\n }\n inTypePosition = true;\n }\n\n // Type-only exports: `export type { Foo }` or `export { type Foo }`\n // Identifiers inside type-only export specifiers are not value references.\n if (\n !inTypePosition &&\n node.type === 'ExportNamedDeclaration' &&\n !node.source\n ) {\n // Walk the declaration (if any) in value context\n if (node.declaration) walk(node.declaration, false);\n // Walk each specifier, skipping type-only ones\n for (const spec of node.specifiers ?? []) {\n if (node.exportKind === 'type' || spec.exportKind === 'type') continue;\n walk(spec, false);\n }\n return;\n }\n\n if (\n !inTypePosition &&\n node.type === 'Identifier' &&\n importedNames.has(node.name)\n ) {\n valueReferenced.add(node.name);\n return;\n }\n\n for (const key of Object.keys(node)) {\n if (\n key === 'type' ||\n key === 'start' ||\n key === 'end' ||\n key === 'range' ||\n key === 'loc'\n )\n continue;\n const isTypePos = inTypePosition || TYPE_POSITION_KEYS.has(key);\n walk(node[key], isTypePos);\n }\n }\n\n for (const node of (ast as any).body) {\n // Skip import declarations themselves – we already processed them\n if (node.type !== 'ImportDeclaration') {\n walk(node, false);\n }\n }\n\n // Step 3 – names that were imported but never value-referenced are type-only\n const typeOnly = new Set<string>();\n for (const name of importedNames) {\n if (!valueReferenced.has(name)) typeOnly.add(name);\n }\n return { ast, typeOnlyNames: typeOnly };\n}\n\n/**\n * Walk the program looking for decorated classes with constructors and add\n * the type names from constructor parameter annotations to `valueReferenced`.\n *\n * Constructor parameter types are TypeScript type positions, but for decorated\n * classes they double as runtime DI tokens — Angular's compiler reads them\n * via `compileFactoryFunction` to wire `ɵɵdirectiveInject(...)` calls. The\n * import of the type therefore must NOT be elided as type-only.\n */\nfunction collectConstructorDiTokens(\n ast: any,\n importedNames: Set<string>,\n valueReferenced: Set<string>,\n): void {\n for (const stmt of (ast as any).body || []) {\n const classNode =\n stmt.type === 'ExportNamedDeclaration' ||\n stmt.type === 'ExportDefaultDeclaration'\n ? (stmt as any).declaration\n : stmt;\n if (\n !classNode ||\n (classNode.type !== 'ClassDeclaration' &&\n classNode.type !== 'ClassExpression')\n ) {\n continue;\n }\n if (!classNode.decorators?.length) continue;\n\n const ctor = (classNode.body?.body || []).find(\n (m: any) => m.type === 'MethodDefinition' && m.kind === 'constructor',\n );\n if (!ctor) continue;\n\n const params: any[] = ctor.value?.params?.items || ctor.value?.params || [];\n for (const param of params) {\n const actualParam =\n param.type === 'TSParameterProperty' ? param.parameter : param;\n const typeAnn =\n actualParam?.typeAnnotation?.typeAnnotation ??\n param?.typeAnnotation?.typeAnnotation;\n if (!typeAnn) continue;\n collectTypeReferenceNames(typeAnn, importedNames, valueReferenced);\n }\n }\n}\n\n/**\n * Recursively extract identifier names from a TS type expression and mark\n * any that match an imported name as value-referenced.\n */\nfunction collectTypeReferenceNames(\n typeNode: any,\n importedNames: Set<string>,\n valueReferenced: Set<string>,\n): void {\n if (!typeNode || typeof typeNode !== 'object') return;\n if (typeNode.type === 'TSTypeReference' && typeNode.typeName) {\n const name = typeNode.typeName.name;\n if (name && importedNames.has(name)) {\n valueReferenced.add(name);\n }\n // Walk type arguments too (e.g. Foo<Bar>)\n if (typeNode.typeArguments) {\n collectTypeReferenceNames(\n typeNode.typeArguments,\n importedNames,\n valueReferenced,\n );\n }\n } else if (\n typeNode.type === 'TSUnionType' ||\n typeNode.type === 'TSIntersectionType'\n ) {\n for (const t of typeNode.types || []) {\n collectTypeReferenceNames(t, importedNames, valueReferenced);\n }\n } else if (Array.isArray(typeNode)) {\n for (const t of typeNode) {\n collectTypeReferenceNames(t, importedNames, valueReferenced);\n }\n } else if (typeNode.params) {\n // TSTypeParameterInstantiation\n for (const t of typeNode.params) {\n collectTypeReferenceNames(t, importedNames, valueReferenced);\n }\n }\n}\n\n/**\n * Analyse compiled TypeScript source and return the set of imported names\n * that are only referenced in type positions (type annotations, implements\n * clauses, generics, etc.) and can safely be elided.\n *\n * Uses oxc-parser for fast, Rust-based AST analysis — no type-checker needed.\n */\nexport function detectTypeOnlyImportNames(code: string): Set<string> {\n return analyzeTypeOnlyImports(code).typeOnlyNames;\n}\n\n/**\n * Apply import elision edits to a MagicString instance using positions from\n * a parsed AST. Shared logic for both the string-based and MagicString APIs.\n */\nfunction applyElisionEdits(\n ms: MagicString,\n ast: any,\n src: string,\n typeOnlyNames: Set<string>,\n): boolean {\n let edited = false;\n\n for (const node of (ast as any).body) {\n if (node.type !== 'ImportDeclaration') continue;\n if (node.importKind === 'type') continue;\n\n const allSpecs = node.specifiers ?? [];\n\n // Separate default and named specifiers\n const defaultSpec = allSpecs.find(\n (s: any) => s.type === 'ImportDefaultSpecifier',\n );\n const namedSpecs = allSpecs.filter(\n (s: any) => s.type === 'ImportSpecifier' && s.importKind !== 'type',\n );\n\n const elideDefault =\n defaultSpec && typeOnlyNames.has(defaultSpec.local.name);\n const keptNamed = namedSpecs.filter(\n (s: any) => !typeOnlyNames.has(s.local.name),\n );\n const removingNamed = namedSpecs.length - keptNamed.length;\n\n // Nothing to elide from this declaration\n if (!elideDefault && removingNamed === 0) continue;\n\n // Find the end of the declaration including trailing newline\n let declEnd = node.end;\n while (\n declEnd < src.length &&\n (src[declEnd] === '\\n' || src[declEnd] === '\\r')\n )\n declEnd++;\n\n const keepDefault = defaultSpec && !elideDefault;\n const hasKeptNamed = keptNamed.length > 0;\n\n if (!keepDefault && !hasKeptNamed) {\n // Remove entire import declaration\n ms.remove(node.start, declEnd);\n edited = true;\n } else {\n // Rebuild with only the kept specifiers\n const parts: string[] = [];\n if (keepDefault) parts.push(defaultSpec.local.name);\n if (hasKeptNamed) {\n const namedList = keptNamed.map((s: any) => {\n const imported = s.imported?.name ?? s.local.name;\n return imported === s.local.name\n ? s.local.name\n : `${imported} as ${s.local.name}`;\n });\n parts.push(`{ ${namedList.join(', ')} }`);\n }\n const source = node.source.value;\n const quote = src[node.source.start]; // preserve original quote style\n ms.overwrite(\n node.start,\n node.end,\n `import ${parts.join(', ')} from ${quote}${source}${quote};`,\n );\n edited = true;\n }\n }\n\n return edited;\n}\n\n/**\n * Elide import specifiers (or entire import declarations) for names that are\n * only used in type positions. Operates on the compiler's TypeScript output\n * (before OXC strips remaining TS syntax).\n *\n * Returns the modified source code, or the original if nothing was elided.\n */\nexport function elideTypeOnlyImports(code: string): string {\n const { ast, typeOnlyNames } = analyzeTypeOnlyImports(code);\n if (typeOnlyNames.size === 0) return code;\n\n const ms = new MagicString(code);\n const edited = applyElisionEdits(ms, ast, code, typeOnlyNames);\n return edited ? ms.toString() : code;\n}\n\n/**\n * Elide type-only imports directly on a MagicString instance, so that\n * subsequent `ms.generateMap()` calls produce an accurate sourcemap.\n *\n * Detects type-only names from `ms.toString()` (the fully-mutated code),\n * but reads import positions from `ms.original` (the coordinate system\n * MagicString expects).\n */\nexport function elideTypeOnlyImportsMagicString(ms: MagicString): void {\n const typeOnlyNames = detectTypeOnlyImportNames(ms.toString());\n if (typeOnlyNames.size === 0) return;\n\n // Parse the original source to get positions in MagicString's coordinate system\n const ast = parseSync('file.ts', ms.original).program;\n applyElisionEdits(ms, ast, ms.original, typeOnlyNames);\n}\n"],"mappings":";;;;;;;AASA,IAAM,qBAAqB,IAAI,IAAI;CACjC;CACA;CACA;CACA;CACA;CACA;CACD,CAAC;;;;;AAMF,IAAM,kBAAkB,IAAI,IAAI;CAC9B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC;;;;;AAMF,SAAS,uBAAuB,MAG9B;CACA,MAAM,MAAM,UAAU,WAAW,KAAK,CAAC;CAMvC,MAAM,gCAAgB,IAAI,KAAa;AACvC,MAAK,MAAM,QAAS,IAAY,MAAM;AACpC,MAAI,KAAK,SAAS,oBAAqB;AACvC,MAAI,KAAK,eAAe,OAAQ;AAChC,OAAK,MAAM,QAAQ,KAAK,cAAc,EAAE,EAAE;AACxC,OAAI,KAAK,eAAe,OAAQ;AAChC,iBAAc,IAAI,KAAK,MAAM,KAAK;;;AAGtC,KAAI,cAAc,SAAS,EAAG,QAAO;EAAE;EAAK,+BAAe,IAAI,KAAK;EAAE;CAGtE,MAAM,kCAAkB,IAAI,KAAa;AAOzC,4BAA2B,KAAK,eAAe,gBAAgB;CAE/D,SAAS,KAAK,MAAW,gBAA+B;AACtD,MAAI,CAAC,QAAQ,OAAO,SAAS,SAAU;AACvC,MAAI,MAAM,QAAQ,KAAK,EAAE;AACvB,QAAK,MAAM,QAAQ,KAAM,MAAK,MAAM,eAAe;AACnD;;AAIF,MAAI,gBAAgB,SAAS,cAAc,KAAM;AAKjD,MAAI,CAAC,kBAAkB,gBAAgB,IAAI,KAAK,KAAK,EAAE;AACrD,OACE,KAAK,SAAS,oBACd,KAAK,SAAS,yBACd;AAEA,SAAK,KAAK,YAAY,MAAM;AAC5B,SAAK,KAAK,gBAAgB,KAAK;AAC/B;;AAEF,oBAAiB;;AAKnB,MACE,CAAC,kBACD,KAAK,SAAS,4BACd,CAAC,KAAK,QACN;AAEA,OAAI,KAAK,YAAa,MAAK,KAAK,aAAa,MAAM;AAEnD,QAAK,MAAM,QAAQ,KAAK,cAAc,EAAE,EAAE;AACxC,QAAI,KAAK,eAAe,UAAU,KAAK,eAAe,OAAQ;AAC9D,SAAK,MAAM,MAAM;;AAEnB;;AAGF,MACE,CAAC,kBACD,KAAK,SAAS,gBACd,cAAc,IAAI,KAAK,KAAK,EAC5B;AACA,mBAAgB,IAAI,KAAK,KAAK;AAC9B;;AAGF,OAAK,MAAM,OAAO,OAAO,KAAK,KAAK,EAAE;AACnC,OACE,QAAQ,UACR,QAAQ,WACR,QAAQ,SACR,QAAQ,WACR,QAAQ,MAER;GACF,MAAM,YAAY,kBAAkB,mBAAmB,IAAI,IAAI;AAC/D,QAAK,KAAK,MAAM,UAAU;;;AAI9B,MAAK,MAAM,QAAS,IAAY,KAE9B,KAAI,KAAK,SAAS,oBAChB,MAAK,MAAM,MAAM;CAKrB,MAAM,2BAAW,IAAI,KAAa;AAClC,MAAK,MAAM,QAAQ,cACjB,KAAI,CAAC,gBAAgB,IAAI,KAAK,CAAE,UAAS,IAAI,KAAK;AAEpD,QAAO;EAAE;EAAK,eAAe;EAAU;;;;;;;;;;;AAYzC,SAAS,2BACP,KACA,eACA,iBACM;AACN,MAAK,MAAM,QAAS,IAAY,QAAQ,EAAE,EAAE;EAC1C,MAAM,YACJ,KAAK,SAAS,4BACd,KAAK,SAAS,6BACT,KAAa,cACd;AACN,MACE,CAAC,aACA,UAAU,SAAS,sBAClB,UAAU,SAAS,kBAErB;AAEF,MAAI,CAAC,UAAU,YAAY,OAAQ;EAEnC,MAAM,QAAQ,UAAU,MAAM,QAAQ,EAAE,EAAE,MACvC,MAAW,EAAE,SAAS,sBAAsB,EAAE,SAAS,cACzD;AACD,MAAI,CAAC,KAAM;EAEX,MAAM,SAAgB,KAAK,OAAO,QAAQ,SAAS,KAAK,OAAO,UAAU,EAAE;AAC3E,OAAK,MAAM,SAAS,QAAQ;GAG1B,MAAM,WADJ,MAAM,SAAS,wBAAwB,MAAM,YAAY,QAE5C,gBAAgB,kBAC7B,OAAO,gBAAgB;AACzB,OAAI,CAAC,QAAS;AACd,6BAA0B,SAAS,eAAe,gBAAgB;;;;;;;;AASxE,SAAS,0BACP,UACA,eACA,iBACM;AACN,KAAI,CAAC,YAAY,OAAO,aAAa,SAAU;AAC/C,KAAI,SAAS,SAAS,qBAAqB,SAAS,UAAU;EAC5D,MAAM,OAAO,SAAS,SAAS;AAC/B,MAAI,QAAQ,cAAc,IAAI,KAAK,CACjC,iBAAgB,IAAI,KAAK;AAG3B,MAAI,SAAS,cACX,2BACE,SAAS,eACT,eACA,gBACD;YAGH,SAAS,SAAS,iBAClB,SAAS,SAAS,qBAElB,MAAK,MAAM,KAAK,SAAS,SAAS,EAAE,CAClC,2BAA0B,GAAG,eAAe,gBAAgB;UAErD,MAAM,QAAQ,SAAS,CAChC,MAAK,MAAM,KAAK,SACd,2BAA0B,GAAG,eAAe,gBAAgB;UAErD,SAAS,OAElB,MAAK,MAAM,KAAK,SAAS,OACvB,2BAA0B,GAAG,eAAe,gBAAgB;;;;;;;;;AAYlE,SAAgB,0BAA0B,MAA2B;AACnE,QAAO,uBAAuB,KAAK,CAAC;;;;;;AAOtC,SAAS,kBACP,IACA,KACA,KACA,eACS;CACT,IAAI,SAAS;AAEb,MAAK,MAAM,QAAS,IAAY,MAAM;AACpC,MAAI,KAAK,SAAS,oBAAqB;AACvC,MAAI,KAAK,eAAe,OAAQ;EAEhC,MAAM,WAAW,KAAK,cAAc,EAAE;EAGtC,MAAM,cAAc,SAAS,MAC1B,MAAW,EAAE,SAAS,yBACxB;EACD,MAAM,aAAa,SAAS,QACzB,MAAW,EAAE,SAAS,qBAAqB,EAAE,eAAe,OAC9D;EAED,MAAM,eACJ,eAAe,cAAc,IAAI,YAAY,MAAM,KAAK;EAC1D,MAAM,YAAY,WAAW,QAC1B,MAAW,CAAC,cAAc,IAAI,EAAE,MAAM,KAAK,CAC7C;EACD,MAAM,gBAAgB,WAAW,SAAS,UAAU;AAGpD,MAAI,CAAC,gBAAgB,kBAAkB,EAAG;EAG1C,IAAI,UAAU,KAAK;AACnB,SACE,UAAU,IAAI,WACb,IAAI,aAAa,QAAQ,IAAI,aAAa,MAE3C;EAEF,MAAM,cAAc,eAAe,CAAC;EACpC,MAAM,eAAe,UAAU,SAAS;AAExC,MAAI,CAAC,eAAe,CAAC,cAAc;AAEjC,MAAG,OAAO,KAAK,OAAO,QAAQ;AAC9B,YAAS;SACJ;GAEL,MAAM,QAAkB,EAAE;AAC1B,OAAI,YAAa,OAAM,KAAK,YAAY,MAAM,KAAK;AACnD,OAAI,cAAc;IAChB,MAAM,YAAY,UAAU,KAAK,MAAW;KAC1C,MAAM,WAAW,EAAE,UAAU,QAAQ,EAAE,MAAM;AAC7C,YAAO,aAAa,EAAE,MAAM,OACxB,EAAE,MAAM,OACR,GAAG,SAAS,MAAM,EAAE,MAAM;MAC9B;AACF,UAAM,KAAK,KAAK,UAAU,KAAK,KAAK,CAAC,IAAI;;GAE3C,MAAM,SAAS,KAAK,OAAO;GAC3B,MAAM,QAAQ,IAAI,KAAK,OAAO;AAC9B,MAAG,UACD,KAAK,OACL,KAAK,KACL,UAAU,MAAM,KAAK,KAAK,CAAC,QAAQ,QAAQ,SAAS,MAAM,GAC3D;AACD,YAAS;;;AAIb,QAAO;;;;;;;;;;AA2BT,SAAgB,gCAAgC,IAAuB;CACrE,MAAM,gBAAgB,0BAA0B,GAAG,UAAU,CAAC;AAC9D,KAAI,cAAc,SAAS,EAAG;CAG9B,MAAM,MAAM,UAAU,WAAW,GAAG,SAAS,CAAC;AAC9C,mBAAkB,IAAI,KAAK,GAAG,UAAU,cAAc"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import * as ts from "typescript";
|
|
2
|
+
/** Collect type-only imported names: `import type { X }` and `import { type X }`. */
|
|
3
|
+
export declare function collectTypeOnlyImports(sf: ts.SourceFile): Set<string>;
|
|
4
|
+
/** Recursively find all class declarations in a source file, including nested scopes. */
|
|
5
|
+
export declare function findAllClasses(sf: ts.SourceFile): ts.ClassDeclaration[];
|
|
6
|
+
/** Unwrap forwardRef(() => X) to X. Returns the original node if not a forwardRef call. */
|
|
7
|
+
export declare function unwrapForwardRef(node: ts.Expression): ts.Expression;
|
|
8
|
+
/** Unwrap forwardRef(() => X) to X for OXC AST nodes. Returns the original node if not a forwardRef call. */
|
|
9
|
+
export declare function unwrapForwardRefOxc(node: any): any;
|
|
10
|
+
export { ANGULAR_DECORATORS } from "./constants.js";
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import "./constants.js";
|
|
2
|
+
import * as ts from "typescript";
|
|
3
|
+
//#region packages/vite-plugin-angular/src/lib/compiler/utils.ts
|
|
4
|
+
/** Recursively find all class declarations in a source file, including nested scopes. */
|
|
5
|
+
function findAllClasses(sf) {
|
|
6
|
+
const result = [];
|
|
7
|
+
function walk(node) {
|
|
8
|
+
if (ts.isClassDeclaration(node)) result.push(node);
|
|
9
|
+
ts.forEachChild(node, walk);
|
|
10
|
+
}
|
|
11
|
+
walk(sf);
|
|
12
|
+
return result;
|
|
13
|
+
}
|
|
14
|
+
/** Unwrap forwardRef(() => X) to X for OXC AST nodes. Returns the original node if not a forwardRef call. */
|
|
15
|
+
function unwrapForwardRefOxc(node) {
|
|
16
|
+
if (node?.type === "CallExpression" && node.callee?.type === "Identifier" && node.callee.name === "forwardRef") {
|
|
17
|
+
const arg = node.arguments?.[0];
|
|
18
|
+
if (arg?.type === "ArrowFunctionExpression") if (arg.body?.type === "FunctionBody" || arg.body?.type === "BlockStatement") {
|
|
19
|
+
const stmt = (arg.body.statements || arg.body.body || [])[0];
|
|
20
|
+
if (stmt?.type === "ReturnStatement" && stmt.argument) return stmt.argument;
|
|
21
|
+
} else return arg.body;
|
|
22
|
+
if (arg?.type === "FunctionExpression") {
|
|
23
|
+
const stmts = arg.body?.statements || arg.body?.body || [];
|
|
24
|
+
if (stmts.length === 1) {
|
|
25
|
+
const stmt = stmts[0];
|
|
26
|
+
if (stmt?.type === "ReturnStatement" && stmt.argument) return stmt.argument;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return node;
|
|
31
|
+
}
|
|
32
|
+
//#endregion
|
|
33
|
+
export { findAllClasses, unwrapForwardRefOxc };
|
|
34
|
+
|
|
35
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","names":[],"sources":["../../../../src/lib/compiler/utils.ts"],"sourcesContent":["import * as ts from 'typescript';\n\n/** Collect type-only imported names: `import type { X }` and `import { type X }`. */\nexport function collectTypeOnlyImports(sf: ts.SourceFile): Set<string> {\n const result = new Set<string>();\n for (const stmt of sf.statements) {\n if (!ts.isImportDeclaration(stmt) || !stmt.importClause) continue;\n const clause = stmt.importClause;\n if (clause.isTypeOnly) {\n if (clause.namedBindings && ts.isNamedImports(clause.namedBindings)) {\n for (const el of clause.namedBindings.elements)\n result.add(el.name.text);\n }\n if (clause.name) result.add(clause.name.text);\n } else if (\n clause.namedBindings &&\n ts.isNamedImports(clause.namedBindings)\n ) {\n for (const el of clause.namedBindings.elements) {\n if (el.isTypeOnly) result.add(el.name.text);\n }\n }\n }\n return result;\n}\n\n/** Recursively find all class declarations in a source file, including nested scopes. */\nexport function findAllClasses(sf: ts.SourceFile): ts.ClassDeclaration[] {\n const result: ts.ClassDeclaration[] = [];\n function walk(node: ts.Node) {\n if (ts.isClassDeclaration(node)) result.push(node);\n ts.forEachChild(node, walk);\n }\n walk(sf);\n return result;\n}\n\n/** Unwrap forwardRef(() => X) to X. Returns the original node if not a forwardRef call. */\nexport function unwrapForwardRef(node: ts.Expression): ts.Expression {\n if (\n ts.isCallExpression(node) &&\n ts.isIdentifier(node.expression) &&\n node.expression.text === 'forwardRef'\n ) {\n const arg = node.arguments[0];\n if (arg && ts.isArrowFunction(arg)) {\n if (ts.isBlock(arg.body)) {\n const stmt = arg.body.statements[0];\n if (stmt && ts.isReturnStatement(stmt) && stmt.expression)\n return stmt.expression;\n } else {\n return arg.body;\n }\n }\n if (\n arg &&\n ts.isFunctionExpression(arg) &&\n arg.body.statements.length === 1\n ) {\n const stmt = arg.body.statements[0];\n if (ts.isReturnStatement(stmt) && stmt.expression) return stmt.expression;\n }\n }\n return node;\n}\n\n/** Unwrap forwardRef(() => X) to X for OXC AST nodes. Returns the original node if not a forwardRef call. */\nexport function unwrapForwardRefOxc(node: any): any {\n if (\n node?.type === 'CallExpression' &&\n node.callee?.type === 'Identifier' &&\n node.callee.name === 'forwardRef'\n ) {\n const arg = node.arguments?.[0];\n if (arg?.type === 'ArrowFunctionExpression') {\n if (\n arg.body?.type === 'FunctionBody' ||\n arg.body?.type === 'BlockStatement'\n ) {\n const stmts = arg.body.statements || arg.body.body || [];\n const stmt = stmts[0];\n if (stmt?.type === 'ReturnStatement' && stmt.argument)\n return stmt.argument;\n } else {\n // Expression body: forwardRef(() => X)\n return arg.body;\n }\n }\n if (arg?.type === 'FunctionExpression') {\n const stmts = arg.body?.statements || arg.body?.body || [];\n if (stmts.length === 1) {\n const stmt = stmts[0];\n if (stmt?.type === 'ReturnStatement' && stmt.argument)\n return stmt.argument;\n }\n }\n }\n return node;\n}\n\nexport { ANGULAR_DECORATORS } from './constants.js';\n"],"mappings":";;;;AA2BA,SAAgB,eAAe,IAA0C;CACvE,MAAM,SAAgC,EAAE;CACxC,SAAS,KAAK,MAAe;AAC3B,MAAI,GAAG,mBAAmB,KAAK,CAAE,QAAO,KAAK,KAAK;AAClD,KAAG,aAAa,MAAM,KAAK;;AAE7B,MAAK,GAAG;AACR,QAAO;;;AAiCT,SAAgB,oBAAoB,MAAgB;AAClD,KACE,MAAM,SAAS,oBACf,KAAK,QAAQ,SAAS,gBACtB,KAAK,OAAO,SAAS,cACrB;EACA,MAAM,MAAM,KAAK,YAAY;AAC7B,MAAI,KAAK,SAAS,0BAChB,KACE,IAAI,MAAM,SAAS,kBACnB,IAAI,MAAM,SAAS,kBACnB;GAEA,MAAM,QADQ,IAAI,KAAK,cAAc,IAAI,KAAK,QAAQ,EAAE,EACrC;AACnB,OAAI,MAAM,SAAS,qBAAqB,KAAK,SAC3C,QAAO,KAAK;QAGd,QAAO,IAAI;AAGf,MAAI,KAAK,SAAS,sBAAsB;GACtC,MAAM,QAAQ,IAAI,MAAM,cAAc,IAAI,MAAM,QAAQ,EAAE;AAC1D,OAAI,MAAM,WAAW,GAAG;IACtB,MAAM,OAAO,MAAM;AACnB,QAAI,MAAM,SAAS,qBAAqB,KAAK,SAC3C,QAAO,KAAK;;;;AAIpB,QAAO"}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
import type { DepOptimizationConfig, Rolldown } from
|
|
9
|
-
import { CompilerPluginOptions } from
|
|
10
|
-
type EsbuildOptions = NonNullable<DepOptimizationConfig[
|
|
11
|
-
type EsbuildPlugin = NonNullable<EsbuildOptions[
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright Google LLC All Rights Reserved.
|
|
4
|
+
*
|
|
5
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
6
|
+
* found in the LICENSE file at https://angular.dev/license
|
|
7
|
+
*/
|
|
8
|
+
import type { DepOptimizationConfig, Rolldown } from "vite";
|
|
9
|
+
import { CompilerPluginOptions } from "./utils/devkit.js";
|
|
10
|
+
type EsbuildOptions = NonNullable<DepOptimizationConfig["esbuildOptions"]>;
|
|
11
|
+
type EsbuildPlugin = NonNullable<EsbuildOptions["plugins"]>[number];
|
|
12
12
|
export declare function createCompilerPlugin(pluginOptions: CompilerPluginOptions, isTest: boolean, closeTransformer: boolean): EsbuildPlugin;
|
|
13
|
-
export declare function createRolldownCompilerPlugin(pluginOptions: CompilerPluginOptions): Rolldown.Plugin;
|
|
13
|
+
export declare function createRolldownCompilerPlugin(pluginOptions: CompilerPluginOptions, closeTransformer: boolean): Rolldown.Plugin;
|
|
14
14
|
export {};
|
|
@@ -1,47 +1,46 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
};
|
|
21
|
-
});
|
|
22
|
-
}
|
|
23
|
-
if (closeTransformer) {
|
|
24
|
-
build.onEnd(() => javascriptTransformer.close());
|
|
25
|
-
}
|
|
26
|
-
},
|
|
27
|
-
};
|
|
1
|
+
import { jt } from "./utils/devkit.js";
|
|
2
|
+
//#region packages/vite-plugin-angular/src/lib/compiler-plugin.ts
|
|
3
|
+
function createCompilerPlugin(pluginOptions, isTest, closeTransformer) {
|
|
4
|
+
const javascriptTransformer = new jt({
|
|
5
|
+
...pluginOptions,
|
|
6
|
+
jit: true
|
|
7
|
+
}, 1);
|
|
8
|
+
return {
|
|
9
|
+
name: "analogjs-angular-esbuild-deps-optimizer-plugin",
|
|
10
|
+
async setup(build) {
|
|
11
|
+
if (!isTest) build.onLoad({ filter: /\.[cm]?js$/ }, async (args) => {
|
|
12
|
+
return {
|
|
13
|
+
contents: await javascriptTransformer.transformFile(args.path),
|
|
14
|
+
loader: "js"
|
|
15
|
+
};
|
|
16
|
+
});
|
|
17
|
+
if (closeTransformer) build.onEnd(() => javascriptTransformer.close());
|
|
18
|
+
}
|
|
19
|
+
};
|
|
28
20
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
21
|
+
function createRolldownCompilerPlugin(pluginOptions, closeTransformer) {
|
|
22
|
+
const javascriptTransformer = new jt({
|
|
23
|
+
...pluginOptions,
|
|
24
|
+
jit: true
|
|
25
|
+
}, 1);
|
|
26
|
+
return {
|
|
27
|
+
name: "analogjs-rolldown-deps-optimizer-plugin",
|
|
28
|
+
load: {
|
|
29
|
+
filter: { id: /\.[cm]?js$/ },
|
|
30
|
+
async handler(id) {
|
|
31
|
+
const contents = await javascriptTransformer.transformFile(id);
|
|
32
|
+
return {
|
|
33
|
+
code: Buffer.from(contents).toString("utf-8"),
|
|
34
|
+
loader: "js"
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
buildEnd() {
|
|
39
|
+
if (closeTransformer) javascriptTransformer.close();
|
|
40
|
+
}
|
|
41
|
+
};
|
|
46
42
|
}
|
|
43
|
+
//#endregion
|
|
44
|
+
export { createCompilerPlugin, createRolldownCompilerPlugin };
|
|
45
|
+
|
|
47
46
|
//# sourceMappingURL=compiler-plugin.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compiler-plugin.js","
|
|
1
|
+
{"version":3,"file":"compiler-plugin.js","names":[],"sources":["../../../src/lib/compiler-plugin.ts"],"sourcesContent":["/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\nimport type { DepOptimizationConfig, Rolldown } from 'vite';\nimport type { PluginBuild } from 'esbuild';\n\nimport {\n CompilerPluginOptions,\n JavaScriptTransformer,\n} from './utils/devkit.js';\n\ntype EsbuildOptions = NonNullable<DepOptimizationConfig['esbuildOptions']>;\ntype EsbuildPlugin = NonNullable<EsbuildOptions['plugins']>[number];\n\nexport function createCompilerPlugin(\n pluginOptions: CompilerPluginOptions,\n isTest: boolean,\n closeTransformer: boolean,\n): EsbuildPlugin {\n const javascriptTransformer = new JavaScriptTransformer(\n { ...pluginOptions, jit: true },\n 1,\n );\n\n return {\n name: 'analogjs-angular-esbuild-deps-optimizer-plugin',\n async setup(build: PluginBuild) {\n if (!isTest) {\n build.onLoad({ filter: /\\.[cm]?js$/ }, async (args) => {\n const contents = await javascriptTransformer.transformFile(args.path);\n\n return {\n contents,\n loader: 'js',\n };\n });\n }\n\n if (closeTransformer) {\n build.onEnd(() => javascriptTransformer.close());\n }\n },\n };\n}\n\nexport function createRolldownCompilerPlugin(\n pluginOptions: CompilerPluginOptions,\n closeTransformer: boolean,\n): Rolldown.Plugin {\n const javascriptTransformer = new JavaScriptTransformer(\n { ...pluginOptions, jit: true },\n 1,\n );\n return {\n name: 'analogjs-rolldown-deps-optimizer-plugin',\n load: {\n filter: {\n id: /\\.[cm]?js$/,\n },\n async handler(id) {\n const contents = await javascriptTransformer.transformFile(id);\n\n return {\n code: Buffer.from(contents).toString('utf-8'),\n loader: 'js',\n } as any;\n },\n },\n // Close the JavaScriptTransformer worker pool when Rolldown finishes to\n // prevent leaked handles. Skipped for Astro, which owns the lifecycle.\n buildEnd() {\n if (closeTransformer) {\n javascriptTransformer.close();\n }\n },\n };\n}\n"],"mappings":";;AAmBA,SAAgB,qBACd,eACA,QACA,kBACe;CACf,MAAM,wBAAwB,IAAI,GAChC;EAAE,GAAG;EAAe,KAAK;EAAM,EAC/B,EACD;AAED,QAAO;EACL,MAAM;EACN,MAAM,MAAM,OAAoB;AAC9B,OAAI,CAAC,OACH,OAAM,OAAO,EAAE,QAAQ,cAAc,EAAE,OAAO,SAAS;AAGrD,WAAO;KACL,UAHe,MAAM,sBAAsB,cAAc,KAAK,KAAK;KAInE,QAAQ;KACT;KACD;AAGJ,OAAI,iBACF,OAAM,YAAY,sBAAsB,OAAO,CAAC;;EAGrD;;AAGH,SAAgB,6BACd,eACA,kBACiB;CACjB,MAAM,wBAAwB,IAAI,GAChC;EAAE,GAAG;EAAe,KAAK;EAAM,EAC/B,EACD;AACD,QAAO;EACL,MAAM;EACN,MAAM;GACJ,QAAQ,EACN,IAAI,cACL;GACD,MAAM,QAAQ,IAAI;IAChB,MAAM,WAAW,MAAM,sBAAsB,cAAc,GAAG;AAE9D,WAAO;KACL,MAAM,OAAO,KAAK,SAAS,CAAC,SAAS,QAAQ;KAC7C,QAAQ;KACT;;GAEJ;EAGD,WAAW;AACT,OAAI,iBACF,uBAAsB,OAAO;;EAGlC"}
|
|
@@ -1,10 +1,28 @@
|
|
|
1
|
-
export
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
export interface AngularComponentMetadata {
|
|
2
|
+
className: string;
|
|
3
|
+
selector?: string;
|
|
4
|
+
styleUrls: string[];
|
|
5
|
+
templateUrls: string[];
|
|
6
|
+
inlineTemplates: string[];
|
|
4
7
|
}
|
|
8
|
+
/**
|
|
9
|
+
* Extract Angular component identities from raw source code before Angular's
|
|
10
|
+
* compilation pipeline strips decorators. This is used for dev-time
|
|
11
|
+
* diagnostics such as duplicate selectors, duplicate component class names,
|
|
12
|
+
* selectorless shared components, and inline-template validation.
|
|
13
|
+
*/
|
|
14
|
+
export declare function getAngularComponentMetadata(code: string): AngularComponentMetadata[];
|
|
15
|
+
/** Extract all `styleUrl` / `styleUrls` values from Angular component source. */
|
|
5
16
|
export declare function getStyleUrls(code: string): string[];
|
|
17
|
+
/** Extract all `templateUrl` values from Angular component source. */
|
|
6
18
|
export declare function getTemplateUrls(code: string): string[];
|
|
19
|
+
/** Extract inline `template` strings from Angular component source. */
|
|
20
|
+
export declare function getInlineTemplates(code: string): string[];
|
|
21
|
+
export declare class StyleUrlsResolver {
|
|
22
|
+
private readonly styleUrlsCache;
|
|
23
|
+
resolve(code: string, id: string): string[];
|
|
24
|
+
}
|
|
7
25
|
export declare class TemplateUrlsResolver {
|
|
8
|
-
|
|
9
|
-
|
|
26
|
+
private readonly templateUrlsCache;
|
|
27
|
+
resolve(code: string, id: string): string[];
|
|
10
28
|
}
|