@analogjs/vite-plugin-angular 3.0.0-alpha.99 → 3.0.0-beta.2

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.
Files changed (85) hide show
  1. package/migrations/migrate-setup-vitest/migrate-setup-vitest.js.map +1 -1
  2. package/migrations/update-3-0-0/migrate-setup-vitest.js +3 -2
  3. package/migrations/update-3-0-0/migrate-setup-vitest.js.map +1 -1
  4. package/package.json +1 -1
  5. package/src/lib/analog-plugin-interop.js +1 -1
  6. package/src/lib/analog-plugin-interop.js.map +1 -1
  7. package/src/lib/angular-build-optimizer-plugin.js +1 -1
  8. package/src/lib/angular-build-optimizer-plugin.js.map +1 -1
  9. package/src/lib/angular-jit-plugin.js.map +1 -1
  10. package/src/lib/angular-vite-plugin.js +20 -7
  11. package/src/lib/angular-vite-plugin.js.map +1 -1
  12. package/src/lib/angular-vitest-plugin.js +1 -1
  13. package/src/lib/angular-vitest-plugin.js.map +1 -1
  14. package/src/lib/compilation-api/compilation-api-plugin.js +6 -5
  15. package/src/lib/compilation-api/compilation-api-plugin.js.map +1 -1
  16. package/src/lib/compilation-api/index.js +2 -1
  17. package/src/lib/compiler/angular-version.js +1 -1
  18. package/src/lib/compiler/angular-version.js.map +1 -1
  19. package/src/lib/compiler/class-field-lowering.js.map +1 -1
  20. package/src/lib/compiler/compile.js +22 -19
  21. package/src/lib/compiler/compile.js.map +1 -1
  22. package/src/lib/compiler/constants.js +4 -4
  23. package/src/lib/compiler/constants.js.map +1 -1
  24. package/src/lib/compiler/debug.js.map +1 -1
  25. package/src/lib/compiler/defer.js +1 -1
  26. package/src/lib/compiler/defer.js.map +1 -1
  27. package/src/lib/compiler/dts-reader.js +1 -1
  28. package/src/lib/compiler/dts-reader.js.map +1 -1
  29. package/src/lib/compiler/hmr.js.map +1 -1
  30. package/src/lib/compiler/index.js +9 -8
  31. package/src/lib/compiler/jit-metadata.js.map +1 -1
  32. package/src/lib/compiler/jit-transform.js +3 -5
  33. package/src/lib/compiler/jit-transform.js.map +1 -1
  34. package/src/lib/compiler/js-emitter.js +2 -4
  35. package/src/lib/compiler/js-emitter.js.map +1 -1
  36. package/src/lib/compiler/metadata.js +10 -12
  37. package/src/lib/compiler/metadata.js.map +1 -1
  38. package/src/lib/compiler/registry.js.map +1 -1
  39. package/src/lib/compiler/resource-inliner.js.map +1 -1
  40. package/src/lib/compiler/style-ast.js.map +1 -1
  41. package/src/lib/compiler/type-elision.js +2 -2
  42. package/src/lib/compiler/type-elision.js.map +1 -1
  43. package/src/lib/compiler/utils.js +7 -5
  44. package/src/lib/compiler/utils.js.map +1 -1
  45. package/src/lib/compiler-plugin.js +7 -0
  46. package/src/lib/compiler-plugin.js.map +1 -1
  47. package/src/lib/component-resolvers.js +1 -1
  48. package/src/lib/component-resolvers.js.map +1 -1
  49. package/src/lib/encapsulation-plugin.js +3 -2
  50. package/src/lib/encapsulation-plugin.js.map +1 -1
  51. package/src/lib/fast-compile-plugin.js +3 -2
  52. package/src/lib/fast-compile-plugin.js.map +1 -1
  53. package/src/lib/host.js.map +1 -1
  54. package/src/lib/hot-update-batch.js +1 -1
  55. package/src/lib/hot-update-batch.js.map +1 -1
  56. package/src/lib/live-reload-plugin.js.map +1 -1
  57. package/src/lib/nx-folder-plugin.js.map +1 -1
  58. package/src/lib/plugins/file-replacements.plugin.js.map +1 -1
  59. package/src/lib/router-plugin.js.map +1 -1
  60. package/src/lib/style-preprocessor.js.map +1 -1
  61. package/src/lib/stylesheet-registry.js.map +1 -1
  62. package/src/lib/tools/src/builders/vite/vite-build.impl.js +2 -1
  63. package/src/lib/tools/src/builders/vite/vite-build.impl.js.map +1 -1
  64. package/src/lib/tools/src/builders/vite-dev-server/dev-server.impl.js +2 -1
  65. package/src/lib/tools/src/builders/vite-dev-server/dev-server.impl.js.map +1 -1
  66. package/src/lib/utils/compilation-shared.js.map +1 -1
  67. package/src/lib/utils/css-extension-resolver.js.map +1 -1
  68. package/src/lib/utils/css-preprocessor-workers.js.map +1 -1
  69. package/src/lib/utils/debug-harness.js.map +1 -1
  70. package/src/lib/utils/debug-log-file.js +2 -1
  71. package/src/lib/utils/debug-log-file.js.map +1 -1
  72. package/src/lib/utils/debug.js.map +1 -1
  73. package/src/lib/utils/devkit.js +1 -1
  74. package/src/lib/utils/devkit.js.map +1 -1
  75. package/src/lib/utils/jit-inline-styles.js.map +1 -1
  76. package/src/lib/utils/plugin-config.js.map +1 -1
  77. package/src/lib/utils/rolldown.js.map +1 -1
  78. package/src/lib/utils/safe-module-paths.js.map +1 -1
  79. package/src/lib/utils/transform-cache.js.map +1 -1
  80. package/src/lib/utils/tsconfig-resolver.js +2 -1
  81. package/src/lib/utils/tsconfig-resolver.js.map +1 -1
  82. package/src/lib/utils/virtual-ids.js.map +1 -1
  83. package/src/lib/utils/virtual-resources.js.map +1 -1
  84. package/src/lib/virtual-modules-plugin.js +4 -1
  85. package/src/lib/virtual-modules-plugin.js.map +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"dts-reader.js","names":[],"sources":["../../../../src/lib/compiler/dts-reader.ts"],"sourcesContent":["import { parseSync } from 'oxc-parser';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { RegistryEntry, RegistryInput } from './registry.js';\n\n/**\n * Scan a single .d.ts file and extract Angular directive/component/pipe\n * metadata from the static ɵdir / ɵcmp / ɵpipe type declarations.\n *\n * This mirrors what ngtsc's DtsMetadataReader does: it reads the type\n * parameters of ɵɵDirectiveDeclaration / ɵɵComponentDeclaration /\n * ɵɵPipeDeclaration to discover selectors, inputs, and outputs for\n * pre-compiled Angular packages.\n */\nexport function scanDtsFile(code: string, fileName: string): RegistryEntry[] {\n // Fast pre-filter — skip files that can't contain Angular declarations\n if (\n !code.includes('DirectiveDeclaration') &&\n !code.includes('ComponentDeclaration') &&\n !code.includes('PipeDeclaration') &&\n !code.includes('NgModuleDeclaration')\n )\n return [];\n\n const { program } = parseSync(fileName, code);\n const entries: RegistryEntry[] = [];\n\n visitStatements(program.body, fileName, entries);\n return entries;\n}\n\n/**\n * Resolve a package's directory in node_modules, scan all its .d.ts files,\n * and return RegistryEntry[] for every Angular declaration found.\n *\n * @param packageName e.g. \"@angular/router\"\n * @param basePath project root (where node_modules lives)\n */\nexport function scanPackageDts(\n packageName: string,\n basePath: string,\n visited?: Set<string>,\n): RegistryEntry[] {\n // Walk up from basePath to find the nearest node_modules containing the package.\n // This handles monorepos where node_modules is at the workspace root,\n // not in the project subdirectory.\n let pkgDir = '';\n let searchBase = basePath;\n while (searchBase !== path.dirname(searchBase)) {\n const candidate = path.join(searchBase, 'node_modules', packageName);\n if (fs.existsSync(candidate)) {\n pkgDir = candidate;\n break;\n }\n searchBase = path.dirname(searchBase);\n }\n if (!pkgDir) return [];\n\n // Build a map from className → correct import path using package.json exports.\n // This handles packages with sub-entry points (e.g. @angular/material/tabs)\n // where re-exported classes must be imported from their origin entry point.\n const classToImportPath = buildClassToImportMap(packageName, pkgDir);\n\n // Check for a \"types\" directory first (Angular packages use this),\n // then fall back to the package root.\n const typesDir = path.join(pkgDir, 'types');\n const searchDir = fs.existsSync(typesDir) ? typesDir : pkgDir;\n\n const dtsFiles = collectDtsFiles(searchDir);\n const entries: RegistryEntry[] = [];\n // Packages re-exported by this package's NgModule declarations. A library\n // NgModule can re-export another package's module (e.g. BrowserModule exports\n // CommonModule), so those packages must be scanned too or their directives\n // (NgIf, NgForOf, …) never reach the registry.\n const referencedPackages = new Set<string>();\n\n for (const file of dtsFiles) {\n try {\n const code = fs.readFileSync(file, 'utf-8');\n const fileEntries = scanDtsFile(code, file);\n for (const entry of fileEntries) {\n entry.sourcePackage =\n classToImportPath.get(entry.className) ||\n subEntryFromFilePath(packageName, pkgDir, file) ||\n packageName;\n }\n entries.push(...fileEntries);\n // Only follow cross-package imports of declaration files that actually\n // contain an NgModule — those are the ones whose exports can pull in\n // another package's directives/pipes. This keeps the walk bounded.\n if (visited && fileEntries.some((e) => e.kind === 'ngmodule')) {\n for (const p of collectImportedPackages(code, file)) {\n referencedPackages.add(p);\n }\n }\n } catch {\n // Skip unreadable files\n }\n }\n\n if (visited) {\n for (const p of referencedPackages) {\n if (p === packageName || visited.has(p)) continue;\n visited.add(p);\n try {\n entries.push(...scanPackageDts(p, basePath, visited));\n } catch {\n // Package may not have .d.ts or not be Angular\n }\n }\n }\n\n return entries;\n}\n\n/**\n * Read package.json exports to build a map from class name to the correct\n * sub-entry import path (e.g. \"MatTabNav\" → \"@angular/material/tabs\").\n *\n * For each sub-entry that has a \"types\" field, the corresponding .d.ts file\n * is read to collect declared class names and re-exported names.\n */\nfunction buildClassToImportMap(\n packageName: string,\n pkgDir: string,\n): Map<string, string> {\n const map = new Map<string, string>();\n try {\n const pkgJson = JSON.parse(\n fs.readFileSync(path.join(pkgDir, 'package.json'), 'utf-8'),\n );\n if (!pkgJson.exports) return map;\n\n for (const [key, value] of Object.entries(pkgJson.exports) as [\n string,\n any,\n ][]) {\n if (key !== '.' && !key.startsWith('./')) continue;\n // Resolve types from the export entry. Some packages declare\n // `types` only at the package root (top-level package.json `types`\n // field) rather than per-export, so fall back to that for `.`.\n let typesFile: string | undefined =\n typeof value === 'object' && value !== null && value.types;\n if (!typesFile && key === '.' && typeof pkgJson.types === 'string') {\n typesFile = pkgJson.types;\n }\n if (!typesFile) continue;\n\n // Root entry (`.`) maps classes to the bare package name; sub-entries\n // (`./tabs`) map to `${packageName}/tabs`. Mapping root-exported\n // classes prevents `subEntryFromFilePath` from deriving an invalid\n // subpath like `ngx-scrollbar/lib` for files that physically live in\n // a `lib/` subdirectory but are only re-exported from the root entry.\n const importPath =\n key === '.' ? packageName : packageName + '/' + key.slice(2);\n const fullTypesPath = path.resolve(pkgDir, typesFile);\n if (!fs.existsSync(fullTypesPath)) continue;\n\n collectExportedClassesFromDts(fullTypesPath, importPath, map);\n }\n } catch {\n // No package.json or no exports — fall back to packageName\n }\n return map;\n}\n\n/**\n * Read a `.d.ts` entry file and add every class it exports to `map`,\n * following `export * from './rel'` chains so re-exported classes from\n * physically nested files (e.g. `lib/foo.d.ts`) are still mapped to the\n * exporting entry's import path.\n *\n * Without this, packages whose root `index.d.ts` is just a barrel of\n * `export * from './lib/...'` would never get their classes mapped, and the\n * `subEntryFromFilePath` fallback would derive an invalid `${pkg}/lib`\n * import for files living under `lib/`.\n */\nfunction collectExportedClassesFromDts(\n filePath: string,\n importPath: string,\n map: Map<string, string>,\n visited: Set<string> = new Set(),\n): void {\n if (visited.has(filePath)) return;\n visited.add(filePath);\n let code: string;\n try {\n code = fs.readFileSync(filePath, 'utf-8');\n } catch {\n return;\n }\n\n let program: any;\n try {\n program = parseSync(filePath, code).program;\n } catch {\n return;\n }\n\n const dir = path.dirname(filePath);\n for (const stmt of program.body || []) {\n // `declare class Foo` (top-level)\n if (stmt.type === 'ClassDeclaration' && stmt.id?.name) {\n map.set(stmt.id.name, importPath);\n continue;\n }\n\n // `export declare class Foo` / `export class Foo` /\n // `export { A, B as C } from '...'` / `export { A, B }`\n if (stmt.type === 'ExportNamedDeclaration') {\n if (\n stmt.declaration?.type === 'ClassDeclaration' &&\n stmt.declaration.id?.name\n ) {\n map.set(stmt.declaration.id.name, importPath);\n }\n for (const spec of stmt.specifiers || []) {\n // ExportSpecifier: { local, exported }\n const exportedNode = spec.exported;\n const exportedName =\n exportedNode?.type === 'Identifier'\n ? exportedNode.name\n : exportedNode?.type === 'Literal'\n ? exportedNode.value\n : undefined;\n if (typeof exportedName === 'string') {\n map.set(exportedName, importPath);\n }\n }\n continue;\n }\n\n // `export * from './rel'` and `export * as Ns from './rel'`\n if (stmt.type === 'ExportAllDeclaration') {\n const rel: string | undefined = stmt.source?.value;\n if (!rel || !rel.startsWith('.')) continue;\n // TypeScript preserves the original specifier text in emitted\n // `.d.ts` files, so NodeNext-style packages keep their `.js`\n // (or `.mjs`) extensions in re-exports — but the actual\n // declaration is at `foo.d.ts` / `foo/index.d.ts`. Strip the\n // ESM extension before probing.\n const normalizedRel = rel.replace(/\\.(?:js|mjs)$/u, '');\n const candidates = [\n path.resolve(dir, normalizedRel + '.d.ts'),\n path.resolve(dir, normalizedRel, 'index.d.ts'),\n ];\n for (const candidate of candidates) {\n if (fs.existsSync(candidate)) {\n collectExportedClassesFromDts(candidate, importPath, map, visited);\n break;\n }\n }\n continue;\n }\n }\n}\n\n/**\n * Derive a sub-entry import path from a .d.ts file's location relative to the\n * package root. This handles older Angular packages that keep .d.ts files in\n * subdirectories (e.g. `@angular/material/tabs/index.d.ts`) instead of a\n * top-level `types/` folder.\n *\n * Returns `undefined` when no sub-entry can be determined (e.g. file is at the\n * package root, inside `types/`, or in a non-entry directory).\n */\nfunction subEntryFromFilePath(\n packageName: string,\n pkgDir: string,\n filePath: string,\n): string | undefined {\n const NON_ENTRY_DIRS = new Set([\n 'types',\n 'fesm2022',\n 'fesm2020',\n 'fesm2015',\n 'esm2022',\n 'esm2020',\n 'esm2015',\n 'bundles',\n 'schematics',\n 'node_modules',\n ]);\n const rel = path.relative(pkgDir, filePath);\n const segments = rel.split(path.sep);\n // File directly in pkgDir (no subdirectory) → no sub-entry\n if (segments.length < 2) return undefined;\n const firstDir = segments[0];\n // Skip internal/build directories and chunk files\n if (NON_ENTRY_DIRS.has(firstDir) || firstDir.startsWith('_'))\n return undefined;\n return packageName + '/' + firstDir;\n}\n\n/**\n * Parse a source file with OXC and return the set of bare-specifier package\n * names it imports (e.g. \"@angular/router\", \"rxjs\"). Relative imports are\n * skipped.\n */\nexport function collectImportedPackages(\n code: string,\n fileName: string,\n program?: ReturnType<typeof parseSync>['program'],\n): Set<string> {\n const packages = new Set<string>();\n program ??= parseSync(fileName, code).program;\n\n for (const stmt of program.body) {\n if (stmt.type !== 'ImportDeclaration') continue;\n const specifier: string = stmt.source?.value;\n if (!specifier || specifier.startsWith('.')) continue;\n\n const parts = specifier.split('/');\n packages.add(\n specifier.startsWith('@') ? parts.slice(0, 2).join('/') : parts[0],\n );\n }\n\n return packages;\n}\n\n/**\n * Parse a source file with OXC and return the relative-path specifiers it\n * re-exports via `export * from './x'`, `export * as Ns from './x'`, or\n * `export { … } from './x'`. Bare-specifier re-exports are skipped.\n *\n * Used by the analog Vite plugin to walk library entry barrels at startup\n * (e.g. `helm/select/src/index.ts` → `./lib/hlm-select`) so the underlying\n * directive classes land in the registry before any consumer is compiled.\n */\nexport function collectRelativeReExports(\n code: string,\n fileName: string,\n program?: ReturnType<typeof parseSync>['program'],\n): string[] {\n if (!program) {\n try {\n program = parseSync(fileName, code).program;\n } catch {\n return [];\n }\n }\n const result: string[] = [];\n for (const stmt of program.body || []) {\n if (\n stmt.type !== 'ExportAllDeclaration' &&\n stmt.type !== 'ExportNamedDeclaration'\n ) {\n continue;\n }\n // ExportNamedDeclaration without `source` is `export { x }` (no\n // re-export), which we don't care about here.\n const specifier: string | undefined = stmt.source?.value;\n if (!specifier || !specifier.startsWith('.')) continue;\n result.push(specifier);\n }\n return result;\n}\n\n/**\n * Parse a source file with OXC and return every module specifier it imports or\n * re-exports from (relative AND bare), including `import`, `export * from`, and\n * `export { … } from`. Used to walk the transitive import graph at startup so\n * the registry contains components/directives/pipes/modules from files not\n * directly listed in tsconfig `files`/`include` (transitively-imported app\n * sources) or behind wildcard `paths` (workspace libraries).\n */\nexport function collectAllImports(\n code: string,\n fileName: string,\n program?: ReturnType<typeof parseSync>['program'],\n): string[] {\n if (!program) {\n try {\n program = parseSync(fileName, code).program;\n } catch {\n return [];\n }\n }\n const result: string[] = [];\n for (const stmt of program.body || []) {\n if (\n stmt.type === 'ImportDeclaration' ||\n stmt.type === 'ExportAllDeclaration' ||\n stmt.type === 'ExportNamedDeclaration'\n ) {\n const specifier: string | undefined = stmt.source?.value;\n if (specifier) result.push(specifier);\n }\n }\n return result;\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nfunction visitStatements(\n stmts: any[],\n fileName: string,\n entries: RegistryEntry[],\n) {\n for (const stmt of stmts) {\n // Unwrap exports: `export declare class ...` / `export default class ...`\n const decl =\n stmt.type === 'ExportNamedDeclaration' ||\n stmt.type === 'ExportDefaultDeclaration'\n ? stmt.declaration\n : stmt;\n\n if (!decl) continue;\n\n // Recurse into `declare module \"...\" { ... }` blocks\n if (decl.type === 'TSModuleDeclaration' && decl.body?.body) {\n visitStatements(decl.body.body, fileName, entries);\n continue;\n }\n\n if (decl.type !== 'ClassDeclaration' || !decl.id?.name) continue;\n const className: string = decl.id.name;\n const members: any[] = decl.body?.body || [];\n\n for (const member of members) {\n if (member.type !== 'PropertyDefinition' || !member.static) continue;\n const propName: string | undefined = member.key?.name;\n\n // Read the type annotation: e.g. `i0.ɵɵDirectiveDeclaration<...>`\n const typeRef = member.typeAnnotation?.typeAnnotation;\n if (!typeRef || typeRef.type !== 'TSTypeReference') continue;\n\n const typeName = qualifiedName(typeRef.typeName);\n const typeParams: any[] | undefined = typeRef.typeArguments?.params;\n\n if (\n (propName === 'ɵdir' || propName === 'ɵcmp') &&\n (typeName.includes('DirectiveDeclaration') ||\n typeName.includes('ComponentDeclaration')) &&\n typeParams &&\n typeParams.length >= 5\n ) {\n const selector = literalString(typeParams[1]);\n if (!selector) continue;\n\n const inputs = extractInputs(typeParams[3]);\n const outputs = extractOutputs(typeParams[4]);\n\n entries.push({\n selector: selector.split(',')[0].trim(),\n kind: propName === 'ɵcmp' ? 'component' : 'directive',\n fileName,\n className,\n ...(Object.keys(inputs).length > 0 ? { inputs } : {}),\n ...(Object.keys(outputs).length > 0 ? { outputs } : {}),\n });\n } else if (\n propName === 'ɵpipe' &&\n typeName.includes('PipeDeclaration') &&\n typeParams &&\n typeParams.length >= 2\n ) {\n const pipeName = literalString(typeParams[1]);\n if (!pipeName) continue;\n\n entries.push({\n selector: pipeName,\n kind: 'pipe',\n pipeName,\n fileName,\n className,\n });\n } else if (\n propName === 'ɵmod' &&\n typeName.includes('NgModuleDeclaration') &&\n typeParams &&\n typeParams.length >= 4\n ) {\n // ɵɵNgModuleDeclaration<Module, Declarations, Imports, Exports>\n // Extract exported class names from the 4th type param (index 3).\n const exportsParam = typeParams[3];\n const exportedNames: string[] = [];\n if (exportsParam?.type === 'TSTupleType' && exportsParam.elementTypes) {\n for (const el of exportsParam.elementTypes) {\n if (\n el.type === 'TSTypeQuery' &&\n el.exprName?.type === 'Identifier'\n ) {\n exportedNames.push(el.exprName.name);\n } else if (\n el.type === 'TSTypeQuery' &&\n el.exprName?.type === 'TSQualifiedName'\n ) {\n // e.g. typeof i2.BidiModule → extract \"BidiModule\"\n const right = el.exprName.right;\n if (right?.type === 'Identifier') {\n exportedNames.push(right.name);\n }\n }\n }\n }\n entries.push({\n selector: className,\n kind: 'ngmodule',\n exports: exportedNames,\n fileName,\n className,\n });\n }\n }\n }\n}\n\n/**\n * Extract inputs from the type-argument at position [3].\n *\n * Handles two formats:\n * v16+: { \"prop\": { \"alias\": \"binding\"; \"required\": false; \"isSignal\"?: true } }\n * pre-v16: { \"prop\": \"binding\" }\n */\nfunction extractInputs(node: any): Record<string, RegistryInput> {\n const inputs: Record<string, RegistryInput> = {};\n if (node?.type !== 'TSTypeLiteral') return inputs;\n\n for (const member of node.members) {\n if (member.type !== 'TSPropertySignature') continue;\n const propName = keyName(member.key);\n const innerType = member.typeAnnotation?.typeAnnotation;\n if (!propName || !innerType) continue;\n\n if (innerType.type === 'TSTypeLiteral') {\n // v16+ object format\n let alias = propName;\n let required = false;\n let isSignal = false;\n\n for (const inner of innerType.members) {\n if (inner.type !== 'TSPropertySignature') continue;\n const key = keyName(inner.key);\n const val = inner.typeAnnotation?.typeAnnotation;\n if (!key || !val) continue;\n\n if (key === 'alias') {\n alias = literalString(val) ?? propName;\n } else if (key === 'required') {\n required = literalBoolean(val) === true;\n } else if (key === 'isSignal') {\n isSignal = literalBoolean(val) === true;\n }\n }\n\n inputs[propName] = {\n classPropertyName: propName,\n bindingPropertyName: alias,\n isSignal,\n required,\n };\n } else {\n // pre-v16 string format\n const alias = literalString(innerType);\n if (alias) {\n inputs[propName] = {\n classPropertyName: propName,\n bindingPropertyName: alias,\n isSignal: false,\n required: false,\n };\n }\n }\n }\n\n return inputs;\n}\n\n/**\n * Extract outputs from the type-argument at position [4].\n * Format: { \"propName\": \"eventName\" }\n */\nfunction extractOutputs(node: any): Record<string, string> {\n const outputs: Record<string, string> = {};\n if (node?.type !== 'TSTypeLiteral') return outputs;\n\n for (const member of node.members) {\n if (member.type !== 'TSPropertySignature') continue;\n const propName = keyName(member.key);\n const val = member.typeAnnotation?.typeAnnotation;\n if (!propName || !val) continue;\n\n const value = literalString(val);\n if (value) outputs[propName] = value;\n }\n\n return outputs;\n}\n\n/** Get the string name from a property key (Identifier or Literal). */\nfunction keyName(key: any): string | undefined {\n if (!key) return undefined;\n if (key.type === 'Identifier') return key.name;\n if (key.type === 'Literal' && typeof key.value === 'string') return key.value;\n return undefined;\n}\n\n/** Build a dotted name from an Identifier or TSQualifiedName. */\nfunction qualifiedName(node: any): string {\n if (!node) return '';\n if (node.type === 'Identifier') return node.name;\n if (node.type === 'TSQualifiedName')\n return qualifiedName(node.left) + '.' + qualifiedName(node.right);\n return '';\n}\n\n/** Extract a string value from a TSLiteralType node. */\nfunction literalString(node: any): string | undefined {\n if (\n node?.type === 'TSLiteralType' &&\n node.literal?.type === 'Literal' &&\n typeof node.literal.value === 'string'\n ) {\n return node.literal.value;\n }\n return undefined;\n}\n\n/** Extract a boolean value from a TSLiteralType node. */\nfunction literalBoolean(node: any): boolean | undefined {\n if (\n node?.type === 'TSLiteralType' &&\n node.literal?.type === 'Literal' &&\n typeof node.literal.value === 'boolean'\n ) {\n return node.literal.value;\n }\n return undefined;\n}\n\n/** Recursively collect all .d.ts files under a directory. */\nfunction collectDtsFiles(dir: string): string[] {\n const results: string[] = [];\n let entries: fs.Dirent[];\n try {\n entries = fs.readdirSync(dir, { withFileTypes: true });\n } catch {\n return results;\n }\n\n for (const entry of entries) {\n const full = path.join(dir, entry.name);\n if (entry.isDirectory() && entry.name !== 'node_modules') {\n results.push(...collectDtsFiles(full));\n } else if (entry.isFile() && entry.name.endsWith('.d.ts')) {\n results.push(full);\n }\n }\n\n return results;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"dts-reader.js","names":[],"sources":["../../../../src/lib/compiler/dts-reader.ts"],"sourcesContent":["import { parseSync } from 'oxc-parser';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { RegistryEntry, RegistryInput } from './registry.js';\n\n/**\n * Scan a single .d.ts file and extract Angular directive/component/pipe\n * metadata from the static ɵdir / ɵcmp / ɵpipe type declarations.\n *\n * This mirrors what ngtsc's DtsMetadataReader does: it reads the type\n * parameters of ɵɵDirectiveDeclaration / ɵɵComponentDeclaration /\n * ɵɵPipeDeclaration to discover selectors, inputs, and outputs for\n * pre-compiled Angular packages.\n */\nexport function scanDtsFile(code: string, fileName: string): RegistryEntry[] {\n // Fast pre-filter — skip files that can't contain Angular declarations\n if (\n !code.includes('DirectiveDeclaration') &&\n !code.includes('ComponentDeclaration') &&\n !code.includes('PipeDeclaration') &&\n !code.includes('NgModuleDeclaration')\n )\n return [];\n\n const { program } = parseSync(fileName, code);\n const entries: RegistryEntry[] = [];\n\n visitStatements(program.body, fileName, entries);\n return entries;\n}\n\n/**\n * Resolve a package's directory in node_modules, scan all its .d.ts files,\n * and return RegistryEntry[] for every Angular declaration found.\n *\n * @param packageName e.g. \"@angular/router\"\n * @param basePath project root (where node_modules lives)\n */\nexport function scanPackageDts(\n packageName: string,\n basePath: string,\n visited?: Set<string>,\n): RegistryEntry[] {\n // Walk up from basePath to find the nearest node_modules containing the package.\n // This handles monorepos where node_modules is at the workspace root,\n // not in the project subdirectory.\n let pkgDir = '';\n let searchBase = basePath;\n while (searchBase !== path.dirname(searchBase)) {\n const candidate = path.join(searchBase, 'node_modules', packageName);\n if (fs.existsSync(candidate)) {\n pkgDir = candidate;\n break;\n }\n searchBase = path.dirname(searchBase);\n }\n if (!pkgDir) return [];\n\n // Build a map from className → correct import path using package.json exports.\n // This handles packages with sub-entry points (e.g. @angular/material/tabs)\n // where re-exported classes must be imported from their origin entry point.\n const classToImportPath = buildClassToImportMap(packageName, pkgDir);\n\n // Check for a \"types\" directory first (Angular packages use this),\n // then fall back to the package root.\n const typesDir = path.join(pkgDir, 'types');\n const searchDir = fs.existsSync(typesDir) ? typesDir : pkgDir;\n\n const dtsFiles = collectDtsFiles(searchDir);\n const entries: RegistryEntry[] = [];\n // Packages re-exported by this package's NgModule declarations. A library\n // NgModule can re-export another package's module (e.g. BrowserModule exports\n // CommonModule), so those packages must be scanned too or their directives\n // (NgIf, NgForOf, …) never reach the registry.\n const referencedPackages = new Set<string>();\n\n for (const file of dtsFiles) {\n try {\n const code = fs.readFileSync(file, 'utf-8');\n const fileEntries = scanDtsFile(code, file);\n for (const entry of fileEntries) {\n entry.sourcePackage =\n classToImportPath.get(entry.className) ||\n subEntryFromFilePath(packageName, pkgDir, file) ||\n packageName;\n }\n entries.push(...fileEntries);\n // Only follow cross-package imports of declaration files that actually\n // contain an NgModule — those are the ones whose exports can pull in\n // another package's directives/pipes. This keeps the walk bounded.\n if (visited && fileEntries.some((e) => e.kind === 'ngmodule')) {\n for (const p of collectImportedPackages(code, file)) {\n referencedPackages.add(p);\n }\n }\n } catch {\n // Skip unreadable files\n }\n }\n\n if (visited) {\n for (const p of referencedPackages) {\n if (p === packageName || visited.has(p)) continue;\n visited.add(p);\n try {\n entries.push(...scanPackageDts(p, basePath, visited));\n } catch {\n // Package may not have .d.ts or not be Angular\n }\n }\n }\n\n return entries;\n}\n\n/**\n * Read package.json exports to build a map from class name to the correct\n * sub-entry import path (e.g. \"MatTabNav\" → \"@angular/material/tabs\").\n *\n * For each sub-entry that has a \"types\" field, the corresponding .d.ts file\n * is read to collect declared class names and re-exported names.\n */\nfunction buildClassToImportMap(\n packageName: string,\n pkgDir: string,\n): Map<string, string> {\n const map = new Map<string, string>();\n try {\n const pkgJson = JSON.parse(\n fs.readFileSync(path.join(pkgDir, 'package.json'), 'utf-8'),\n );\n if (!pkgJson.exports) return map;\n\n for (const [key, value] of Object.entries(pkgJson.exports) as [\n string,\n any,\n ][]) {\n if (key !== '.' && !key.startsWith('./')) continue;\n // Resolve types from the export entry. Some packages declare\n // `types` only at the package root (top-level package.json `types`\n // field) rather than per-export, so fall back to that for `.`.\n let typesFile: string | undefined =\n typeof value === 'object' && value !== null && value.types;\n if (!typesFile && key === '.' && typeof pkgJson.types === 'string') {\n typesFile = pkgJson.types;\n }\n if (!typesFile) continue;\n\n // Root entry (`.`) maps classes to the bare package name; sub-entries\n // (`./tabs`) map to `${packageName}/tabs`. Mapping root-exported\n // classes prevents `subEntryFromFilePath` from deriving an invalid\n // subpath like `ngx-scrollbar/lib` for files that physically live in\n // a `lib/` subdirectory but are only re-exported from the root entry.\n const importPath =\n key === '.' ? packageName : packageName + '/' + key.slice(2);\n const fullTypesPath = path.resolve(pkgDir, typesFile);\n if (!fs.existsSync(fullTypesPath)) continue;\n\n collectExportedClassesFromDts(fullTypesPath, importPath, map);\n }\n } catch {\n // No package.json or no exports — fall back to packageName\n }\n return map;\n}\n\n/**\n * Read a `.d.ts` entry file and add every class it exports to `map`,\n * following `export * from './rel'` chains so re-exported classes from\n * physically nested files (e.g. `lib/foo.d.ts`) are still mapped to the\n * exporting entry's import path.\n *\n * Without this, packages whose root `index.d.ts` is just a barrel of\n * `export * from './lib/...'` would never get their classes mapped, and the\n * `subEntryFromFilePath` fallback would derive an invalid `${pkg}/lib`\n * import for files living under `lib/`.\n */\nfunction collectExportedClassesFromDts(\n filePath: string,\n importPath: string,\n map: Map<string, string>,\n visited: Set<string> = new Set(),\n): void {\n if (visited.has(filePath)) return;\n visited.add(filePath);\n let code: string;\n try {\n code = fs.readFileSync(filePath, 'utf-8');\n } catch {\n return;\n }\n\n let program: any;\n try {\n program = parseSync(filePath, code).program;\n } catch {\n return;\n }\n\n const dir = path.dirname(filePath);\n for (const stmt of program.body || []) {\n // `declare class Foo` (top-level)\n if (stmt.type === 'ClassDeclaration' && stmt.id?.name) {\n map.set(stmt.id.name, importPath);\n continue;\n }\n\n // `export declare class Foo` / `export class Foo` /\n // `export { A, B as C } from '...'` / `export { A, B }`\n if (stmt.type === 'ExportNamedDeclaration') {\n if (\n stmt.declaration?.type === 'ClassDeclaration' &&\n stmt.declaration.id?.name\n ) {\n map.set(stmt.declaration.id.name, importPath);\n }\n for (const spec of stmt.specifiers || []) {\n // ExportSpecifier: { local, exported }\n const exportedNode = spec.exported;\n const exportedName =\n exportedNode?.type === 'Identifier'\n ? exportedNode.name\n : exportedNode?.type === 'Literal'\n ? exportedNode.value\n : undefined;\n if (typeof exportedName === 'string') {\n map.set(exportedName, importPath);\n }\n }\n continue;\n }\n\n // `export * from './rel'` and `export * as Ns from './rel'`\n if (stmt.type === 'ExportAllDeclaration') {\n const rel: string | undefined = stmt.source?.value;\n if (!rel || !rel.startsWith('.')) continue;\n // TypeScript preserves the original specifier text in emitted\n // `.d.ts` files, so NodeNext-style packages keep their `.js`\n // (or `.mjs`) extensions in re-exports — but the actual\n // declaration is at `foo.d.ts` / `foo/index.d.ts`. Strip the\n // ESM extension before probing.\n const normalizedRel = rel.replace(/\\.(?:js|mjs)$/u, '');\n const candidates = [\n path.resolve(dir, normalizedRel + '.d.ts'),\n path.resolve(dir, normalizedRel, 'index.d.ts'),\n ];\n for (const candidate of candidates) {\n if (fs.existsSync(candidate)) {\n collectExportedClassesFromDts(candidate, importPath, map, visited);\n break;\n }\n }\n continue;\n }\n }\n}\n\n/**\n * Derive a sub-entry import path from a .d.ts file's location relative to the\n * package root. This handles older Angular packages that keep .d.ts files in\n * subdirectories (e.g. `@angular/material/tabs/index.d.ts`) instead of a\n * top-level `types/` folder.\n *\n * Returns `undefined` when no sub-entry can be determined (e.g. file is at the\n * package root, inside `types/`, or in a non-entry directory).\n */\nfunction subEntryFromFilePath(\n packageName: string,\n pkgDir: string,\n filePath: string,\n): string | undefined {\n const NON_ENTRY_DIRS = new Set([\n 'types',\n 'fesm2022',\n 'fesm2020',\n 'fesm2015',\n 'esm2022',\n 'esm2020',\n 'esm2015',\n 'bundles',\n 'schematics',\n 'node_modules',\n ]);\n const rel = path.relative(pkgDir, filePath);\n const segments = rel.split(path.sep);\n // File directly in pkgDir (no subdirectory) → no sub-entry\n if (segments.length < 2) return undefined;\n const firstDir = segments[0];\n // Skip internal/build directories and chunk files\n if (NON_ENTRY_DIRS.has(firstDir) || firstDir.startsWith('_'))\n return undefined;\n return packageName + '/' + firstDir;\n}\n\n/**\n * Parse a source file with OXC and return the set of bare-specifier package\n * names it imports (e.g. \"@angular/router\", \"rxjs\"). Relative imports are\n * skipped.\n */\nexport function collectImportedPackages(\n code: string,\n fileName: string,\n program?: ReturnType<typeof parseSync>['program'],\n): Set<string> {\n const packages = new Set<string>();\n program ??= parseSync(fileName, code).program;\n\n for (const stmt of program.body) {\n if (stmt.type !== 'ImportDeclaration') continue;\n const specifier: string = stmt.source?.value;\n if (!specifier || specifier.startsWith('.')) continue;\n\n const parts = specifier.split('/');\n packages.add(\n specifier.startsWith('@') ? parts.slice(0, 2).join('/') : parts[0],\n );\n }\n\n return packages;\n}\n\n/**\n * Parse a source file with OXC and return the relative-path specifiers it\n * re-exports via `export * from './x'`, `export * as Ns from './x'`, or\n * `export { … } from './x'`. Bare-specifier re-exports are skipped.\n *\n * Used by the analog Vite plugin to walk library entry barrels at startup\n * (e.g. `helm/select/src/index.ts` → `./lib/hlm-select`) so the underlying\n * directive classes land in the registry before any consumer is compiled.\n */\nexport function collectRelativeReExports(\n code: string,\n fileName: string,\n program?: ReturnType<typeof parseSync>['program'],\n): string[] {\n if (!program) {\n try {\n program = parseSync(fileName, code).program;\n } catch {\n return [];\n }\n }\n const result: string[] = [];\n for (const stmt of program.body || []) {\n if (\n stmt.type !== 'ExportAllDeclaration' &&\n stmt.type !== 'ExportNamedDeclaration'\n ) {\n continue;\n }\n // ExportNamedDeclaration without `source` is `export { x }` (no\n // re-export), which we don't care about here.\n const specifier: string | undefined = stmt.source?.value;\n if (!specifier || !specifier.startsWith('.')) continue;\n result.push(specifier);\n }\n return result;\n}\n\n/**\n * Parse a source file with OXC and return every module specifier it imports or\n * re-exports from (relative AND bare), including `import`, `export * from`, and\n * `export { … } from`. Used to walk the transitive import graph at startup so\n * the registry contains components/directives/pipes/modules from files not\n * directly listed in tsconfig `files`/`include` (transitively-imported app\n * sources) or behind wildcard `paths` (workspace libraries).\n */\nexport function collectAllImports(\n code: string,\n fileName: string,\n program?: ReturnType<typeof parseSync>['program'],\n): string[] {\n if (!program) {\n try {\n program = parseSync(fileName, code).program;\n } catch {\n return [];\n }\n }\n const result: string[] = [];\n for (const stmt of program.body || []) {\n if (\n stmt.type === 'ImportDeclaration' ||\n stmt.type === 'ExportAllDeclaration' ||\n stmt.type === 'ExportNamedDeclaration'\n ) {\n const specifier: string | undefined = stmt.source?.value;\n if (specifier) result.push(specifier);\n }\n }\n return result;\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nfunction visitStatements(\n stmts: any[],\n fileName: string,\n entries: RegistryEntry[],\n) {\n for (const stmt of stmts) {\n // Unwrap exports: `export declare class ...` / `export default class ...`\n const decl =\n stmt.type === 'ExportNamedDeclaration' ||\n stmt.type === 'ExportDefaultDeclaration'\n ? stmt.declaration\n : stmt;\n\n if (!decl) continue;\n\n // Recurse into `declare module \"...\" { ... }` blocks\n if (decl.type === 'TSModuleDeclaration' && decl.body?.body) {\n visitStatements(decl.body.body, fileName, entries);\n continue;\n }\n\n if (decl.type !== 'ClassDeclaration' || !decl.id?.name) continue;\n const className: string = decl.id.name;\n const members: any[] = decl.body?.body || [];\n\n for (const member of members) {\n if (member.type !== 'PropertyDefinition' || !member.static) continue;\n const propName: string | undefined = member.key?.name;\n\n // Read the type annotation: e.g. `i0.ɵɵDirectiveDeclaration<...>`\n const typeRef = member.typeAnnotation?.typeAnnotation;\n if (!typeRef || typeRef.type !== 'TSTypeReference') continue;\n\n const typeName = qualifiedName(typeRef.typeName);\n const typeParams: any[] | undefined = typeRef.typeArguments?.params;\n\n if (\n (propName === 'ɵdir' || propName === 'ɵcmp') &&\n (typeName.includes('DirectiveDeclaration') ||\n typeName.includes('ComponentDeclaration')) &&\n typeParams &&\n typeParams.length >= 5\n ) {\n const selector = literalString(typeParams[1]);\n if (!selector) continue;\n\n const inputs = extractInputs(typeParams[3]);\n const outputs = extractOutputs(typeParams[4]);\n\n entries.push({\n selector: selector.split(',')[0].trim(),\n kind: propName === 'ɵcmp' ? 'component' : 'directive',\n fileName,\n className,\n ...(Object.keys(inputs).length > 0 ? { inputs } : {}),\n ...(Object.keys(outputs).length > 0 ? { outputs } : {}),\n });\n } else if (\n propName === 'ɵpipe' &&\n typeName.includes('PipeDeclaration') &&\n typeParams &&\n typeParams.length >= 2\n ) {\n const pipeName = literalString(typeParams[1]);\n if (!pipeName) continue;\n\n entries.push({\n selector: pipeName,\n kind: 'pipe',\n pipeName,\n fileName,\n className,\n });\n } else if (\n propName === 'ɵmod' &&\n typeName.includes('NgModuleDeclaration') &&\n typeParams &&\n typeParams.length >= 4\n ) {\n // ɵɵNgModuleDeclaration<Module, Declarations, Imports, Exports>\n // Extract exported class names from the 4th type param (index 3).\n const exportsParam = typeParams[3];\n const exportedNames: string[] = [];\n if (exportsParam?.type === 'TSTupleType' && exportsParam.elementTypes) {\n for (const el of exportsParam.elementTypes) {\n if (\n el.type === 'TSTypeQuery' &&\n el.exprName?.type === 'Identifier'\n ) {\n exportedNames.push(el.exprName.name);\n } else if (\n el.type === 'TSTypeQuery' &&\n el.exprName?.type === 'TSQualifiedName'\n ) {\n // e.g. typeof i2.BidiModule → extract \"BidiModule\"\n const right = el.exprName.right;\n if (right?.type === 'Identifier') {\n exportedNames.push(right.name);\n }\n }\n }\n }\n entries.push({\n selector: className,\n kind: 'ngmodule',\n exports: exportedNames,\n fileName,\n className,\n });\n }\n }\n }\n}\n\n/**\n * Extract inputs from the type-argument at position [3].\n *\n * Handles two formats:\n * v16+: { \"prop\": { \"alias\": \"binding\"; \"required\": false; \"isSignal\"?: true } }\n * pre-v16: { \"prop\": \"binding\" }\n */\nfunction extractInputs(node: any): Record<string, RegistryInput> {\n const inputs: Record<string, RegistryInput> = {};\n if (node?.type !== 'TSTypeLiteral') return inputs;\n\n for (const member of node.members) {\n if (member.type !== 'TSPropertySignature') continue;\n const propName = keyName(member.key);\n const innerType = member.typeAnnotation?.typeAnnotation;\n if (!propName || !innerType) continue;\n\n if (innerType.type === 'TSTypeLiteral') {\n // v16+ object format\n let alias = propName;\n let required = false;\n let isSignal = false;\n\n for (const inner of innerType.members) {\n if (inner.type !== 'TSPropertySignature') continue;\n const key = keyName(inner.key);\n const val = inner.typeAnnotation?.typeAnnotation;\n if (!key || !val) continue;\n\n if (key === 'alias') {\n alias = literalString(val) ?? propName;\n } else if (key === 'required') {\n required = literalBoolean(val) === true;\n } else if (key === 'isSignal') {\n isSignal = literalBoolean(val) === true;\n }\n }\n\n inputs[propName] = {\n classPropertyName: propName,\n bindingPropertyName: alias,\n isSignal,\n required,\n };\n } else {\n // pre-v16 string format\n const alias = literalString(innerType);\n if (alias) {\n inputs[propName] = {\n classPropertyName: propName,\n bindingPropertyName: alias,\n isSignal: false,\n required: false,\n };\n }\n }\n }\n\n return inputs;\n}\n\n/**\n * Extract outputs from the type-argument at position [4].\n * Format: { \"propName\": \"eventName\" }\n */\nfunction extractOutputs(node: any): Record<string, string> {\n const outputs: Record<string, string> = {};\n if (node?.type !== 'TSTypeLiteral') return outputs;\n\n for (const member of node.members) {\n if (member.type !== 'TSPropertySignature') continue;\n const propName = keyName(member.key);\n const val = member.typeAnnotation?.typeAnnotation;\n if (!propName || !val) continue;\n\n const value = literalString(val);\n if (value) outputs[propName] = value;\n }\n\n return outputs;\n}\n\n/** Get the string name from a property key (Identifier or Literal). */\nfunction keyName(key: any): string | undefined {\n if (!key) return undefined;\n if (key.type === 'Identifier') return key.name;\n if (key.type === 'Literal' && typeof key.value === 'string') return key.value;\n return undefined;\n}\n\n/** Build a dotted name from an Identifier or TSQualifiedName. */\nfunction qualifiedName(node: any): string {\n if (!node) return '';\n if (node.type === 'Identifier') return node.name;\n if (node.type === 'TSQualifiedName')\n return qualifiedName(node.left) + '.' + qualifiedName(node.right);\n return '';\n}\n\n/** Extract a string value from a TSLiteralType node. */\nfunction literalString(node: any): string | undefined {\n if (\n node?.type === 'TSLiteralType' &&\n node.literal?.type === 'Literal' &&\n typeof node.literal.value === 'string'\n ) {\n return node.literal.value;\n }\n return undefined;\n}\n\n/** Extract a boolean value from a TSLiteralType node. */\nfunction literalBoolean(node: any): boolean | undefined {\n if (\n node?.type === 'TSLiteralType' &&\n node.literal?.type === 'Literal' &&\n typeof node.literal.value === 'boolean'\n ) {\n return node.literal.value;\n }\n return undefined;\n}\n\n/** Recursively collect all .d.ts files under a directory. */\nfunction collectDtsFiles(dir: string): string[] {\n const results: string[] = [];\n let entries: fs.Dirent[];\n try {\n entries = fs.readdirSync(dir, { withFileTypes: true });\n } catch {\n return results;\n }\n\n for (const entry of entries) {\n const full = path.join(dir, entry.name);\n if (entry.isDirectory() && entry.name !== 'node_modules') {\n results.push(...collectDtsFiles(full));\n } else if (entry.isFile() && entry.name.endsWith('.d.ts')) {\n results.push(full);\n }\n }\n\n return results;\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"hmr.js","names":[],"sources":["../../../../src/lib/compiler/hmr.ts"],"sourcesContent":["import type { RegistryEntry } from './registry.js';\n\n/**\n * Generate HMR code using Angular's ɵɵreplaceMetadata for components,\n * and simple field-swap + invalidation for directives/pipes.\n *\n * The applyMetadata callback dynamically copies all ɵ-prefixed static\n * fields (ɵcmp, ɵfac, ɵdir, ɵpipe, etc.) from the newly compiled class\n * to the old class reference that Angular's runtime is tracking.\n *\n * For components, ɵɵreplaceMetadata then merges the old/new definitions\n * and recreates matching LViews in the component tree.\n *\n * For directives and pipes, ɵɵreplaceMetadata does not support them, so\n * we fall back to a full page reload via import.meta.hot.invalidate().\n */\nexport function generateHmrCode(\n declarations: RegistryEntry[],\n localDepClassNames: string[] = [],\n): string {\n const components = declarations.filter((d) => d.kind === 'component');\n const nonComponents = declarations.filter((d) => d.kind !== 'component');\n\n // Export applyMetadata functions so the accept callback can access them.\n // Dynamically copy all ɵ-prefixed static fields to handle ɵcmp, ɵfac,\n // ɵdir, ɵpipe, ɵmod, ɵinj, ɵprov, and any future Ivy fields.\n const applyFns = declarations\n .map(\n (c) => `\nexport function ɵhmr_${c.className}(type) {\n for (const key of Object.getOwnPropertyNames(${c.className})) {\n if (key.startsWith('ɵ')) type[key] = ${c.className}[key];\n }\n}`,\n )\n .join('\\n');\n\n // Components: use ɵɵreplaceMetadata for full LView recreation\n const localDepsArray =\n localDepClassNames.length > 0 ? `[${localDepClassNames.join(', ')}]` : '[]';\n\n const replaceBlocks = components\n .map(\n (c) => `\n try {\n i0.ɵɵreplaceMetadata(\n ${c.className},\n newModule.ɵhmr_${c.className},\n { i0 },\n ${localDepsArray},\n import.meta,\n \"${c.className}\"\n );\n replaced = true;\n } catch(e) {\n // ɵɵreplaceMetadata failed — will fall back to page reload\n }`,\n )\n .join('\\n');\n\n // Directives/pipes: swap static fields and invalidate\n const swapBlocks = nonComponents\n .map(\n (c) => `\n try {\n newModule.ɵhmr_${c.className}(${c.className});\n swapped = true;\n } catch(e) {}`,\n )\n .join('\\n');\n\n let acceptBody = `\n if (!newModule) return;`;\n\n if (components.length > 0) {\n acceptBody += `\n let replaced = false;${replaceBlocks}\n if (!replaced) {\n import.meta.hot.invalidate('Component HMR failed, reloading');\n return;\n }`;\n }\n\n if (nonComponents.length > 0) {\n acceptBody += `\n let swapped = false;${swapBlocks}\n if (swapped) {\n // Directive/pipe definitions updated — full reload needed for Angular\n // to pick up the new behavior since ɵɵreplaceMetadata only supports components.\n import.meta.hot.invalidate('Directive/pipe changed, reloading');\n }`;\n }\n\n return `\\n${applyFns}\nif (import.meta.hot) {\n import.meta.hot.accept((newModule) => {${acceptBody}\n });\n}`;\n}\n"],"mappings":";;;;;;;;;;;;;;;AAgBA,SAAgB,gBACd,cACA,qBAA+B,EAAE,EACzB;CACR,MAAM,aAAa,aAAa,QAAQ,MAAM,EAAE,SAAS,YAAY;CACrE,MAAM,gBAAgB,aAAa,QAAQ,MAAM,EAAE,SAAS,YAAY;CAKxE,MAAM,WAAW,aACd,KACE,MAAM;uBACU,EAAE,UAAU;iDACc,EAAE,UAAU;2CAClB,EAAE,UAAU;;GAGlD,CACA,KAAK,KAAK;CAGb,MAAM,iBACJ,mBAAmB,SAAS,IAAI,IAAI,mBAAmB,KAAK,KAAK,CAAC,KAAK;CAEzE,MAAM,gBAAgB,WACnB,KACE,MAAM;;;YAGD,EAAE,UAAU;2BACG,EAAE,UAAU;;YAE3B,eAAe;;aAEd,EAAE,UAAU;;;;;SAMpB,CACA,KAAK,KAAK;CAGb,MAAM,aAAa,cAChB,KACE,MAAM;;yBAEY,EAAE,UAAU,GAAG,EAAE,UAAU;;qBAG/C,CACA,KAAK,KAAK;CAEb,IAAI,aAAa;;AAGjB,KAAI,WAAW,SAAS,EACtB,eAAc;2BACS,cAAc;;;;;AAOvC,KAAI,cAAc,SAAS,EACzB,eAAc;0BACQ,WAAW;;;;;;AAQnC,QAAO,KAAK,SAAS;;2CAEoB,WAAW"}
1
+ {"version":3,"file":"hmr.js","names":[],"sources":["../../../../src/lib/compiler/hmr.ts"],"sourcesContent":["import type { RegistryEntry } from './registry.js';\n\n/**\n * Generate HMR code using Angular's ɵɵreplaceMetadata for components,\n * and simple field-swap + invalidation for directives/pipes.\n *\n * The applyMetadata callback dynamically copies all ɵ-prefixed static\n * fields (ɵcmp, ɵfac, ɵdir, ɵpipe, etc.) from the newly compiled class\n * to the old class reference that Angular's runtime is tracking.\n *\n * For components, ɵɵreplaceMetadata then merges the old/new definitions\n * and recreates matching LViews in the component tree.\n *\n * For directives and pipes, ɵɵreplaceMetadata does not support them, so\n * we fall back to a full page reload via import.meta.hot.invalidate().\n */\nexport function generateHmrCode(\n declarations: RegistryEntry[],\n localDepClassNames: string[] = [],\n): string {\n const components = declarations.filter((d) => d.kind === 'component');\n const nonComponents = declarations.filter((d) => d.kind !== 'component');\n\n // Export applyMetadata functions so the accept callback can access them.\n // Dynamically copy all ɵ-prefixed static fields to handle ɵcmp, ɵfac,\n // ɵdir, ɵpipe, ɵmod, ɵinj, ɵprov, and any future Ivy fields.\n const applyFns = declarations\n .map(\n (c) => `\nexport function ɵhmr_${c.className}(type) {\n for (const key of Object.getOwnPropertyNames(${c.className})) {\n if (key.startsWith('ɵ')) type[key] = ${c.className}[key];\n }\n}`,\n )\n .join('\\n');\n\n // Components: use ɵɵreplaceMetadata for full LView recreation\n const localDepsArray =\n localDepClassNames.length > 0 ? `[${localDepClassNames.join(', ')}]` : '[]';\n\n const replaceBlocks = components\n .map(\n (c) => `\n try {\n i0.ɵɵreplaceMetadata(\n ${c.className},\n newModule.ɵhmr_${c.className},\n { i0 },\n ${localDepsArray},\n import.meta,\n \"${c.className}\"\n );\n replaced = true;\n } catch(e) {\n // ɵɵreplaceMetadata failed — will fall back to page reload\n }`,\n )\n .join('\\n');\n\n // Directives/pipes: swap static fields and invalidate\n const swapBlocks = nonComponents\n .map(\n (c) => `\n try {\n newModule.ɵhmr_${c.className}(${c.className});\n swapped = true;\n } catch(e) {}`,\n )\n .join('\\n');\n\n let acceptBody = `\n if (!newModule) return;`;\n\n if (components.length > 0) {\n acceptBody += `\n let replaced = false;${replaceBlocks}\n if (!replaced) {\n import.meta.hot.invalidate('Component HMR failed, reloading');\n return;\n }`;\n }\n\n if (nonComponents.length > 0) {\n acceptBody += `\n let swapped = false;${swapBlocks}\n if (swapped) {\n // Directive/pipe definitions updated — full reload needed for Angular\n // to pick up the new behavior since ɵɵreplaceMetadata only supports components.\n import.meta.hot.invalidate('Directive/pipe changed, reloading');\n }`;\n }\n\n return `\\n${applyFns}\nif (import.meta.hot) {\n import.meta.hot.accept((newModule) => {${acceptBody}\n });\n}`;\n}\n"],"mappings":";;;;;;;;;;;;;;;AAgBA,SAAgB,gBACd,cACA,qBAA+B,CAAC,GACxB;CACR,MAAM,aAAa,aAAa,QAAQ,MAAM,EAAE,SAAS,WAAW;CACpE,MAAM,gBAAgB,aAAa,QAAQ,MAAM,EAAE,SAAS,WAAW;CAKvE,MAAM,WAAW,aACd,KACE,MAAM;uBACU,EAAE,UAAU;iDACc,EAAE,UAAU;2CAClB,EAAE,UAAU;;EAGnD,CAAC,CACA,KAAK,IAAI;CAGZ,MAAM,iBACJ,mBAAmB,SAAS,IAAI,IAAI,mBAAmB,KAAK,IAAI,EAAE,KAAK;CAEzE,MAAM,gBAAgB,WACnB,KACE,MAAM;;;YAGD,EAAE,UAAU;2BACG,EAAE,UAAU;;YAE3B,eAAe;;aAEd,EAAE,UAAU;;;;;QAMrB,CAAC,CACA,KAAK,IAAI;CAGZ,MAAM,aAAa,cAChB,KACE,MAAM;;yBAEY,EAAE,UAAU,GAAG,EAAE,UAAU;;oBAGhD,CAAC,CACA,KAAK,IAAI;CAEZ,IAAI,aAAa;;CAGjB,IAAI,WAAW,SAAS,GACtB,cAAc;2BACS,cAAc;;;;;CAOvC,IAAI,cAAc,SAAS,GACzB,cAAc;0BACQ,WAAW;;;;;;CAQnC,OAAO,KAAK,SAAS;;2CAEoB,WAAW;;;AAGtD"}
@@ -1,8 +1,9 @@
1
- import "./constants.js";
2
- import "./debug.js";
3
- import "./compile.js";
4
- import "./registry.js";
5
- import "./dts-reader.js";
6
- import "./jit-transform.js";
7
- import "./hmr.js";
8
- import "./resource-inliner.js";
1
+ import { ANGULAR_DECORATOR_CALL_RE } from "./constants.js";
2
+ import { debugCompile, debugRegistry } from "./debug.js";
3
+ import { compile } from "./compile.js";
4
+ import { scanFile } from "./registry.js";
5
+ import { collectAllImports, collectImportedPackages, collectRelativeReExports, scanPackageDts } from "./dts-reader.js";
6
+ import { jitTransform } from "./jit-transform.js";
7
+ import { generateHmrCode } from "./hmr.js";
8
+ import { extractInlineStyles, inlineResourceUrls } from "./resource-inliner.js";
9
+ export { ANGULAR_DECORATOR_CALL_RE, collectAllImports, collectImportedPackages, collectRelativeReExports, compile, debugCompile, debugRegistry, extractInlineStyles, generateHmrCode, inlineResourceUrls, jitTransform, scanFile, scanPackageDts };
@@ -1 +1 @@
1
- {"version":3,"file":"jit-metadata.js","names":[],"sources":["../../../../src/lib/compiler/jit-metadata.ts"],"sourcesContent":["/**\n * JIT metadata helpers — OXC AST edition.\n *\n * Builds static metadata arrays that Angular's ReflectionCapabilities reads\n * at runtime for JIT compilation (ctorParameters, propDecorators).\n *\n * Uses source-position slicing instead of AST getText() for speed.\n */\nimport { FIELD_DECORATORS } from './constants.js';\n\nfunction getCallApi(call: any): { api: string; required: boolean } | null {\n const callee = call.callee;\n if (!callee) return null;\n\n if (callee.type === 'Identifier') {\n return { api: callee.name, required: false };\n }\n\n if (\n (callee.type === 'StaticMemberExpression' ||\n callee.type === 'MemberExpression') &&\n callee.object?.type === 'Identifier' &&\n callee.property?.name === 'required'\n ) {\n return { api: callee.object.name, required: true };\n }\n\n return null;\n}\n\n/**\n * Read a string-literal `alias` value out of an OXC ObjectExpression.\n * Returns null when the arg isn't an object literal, has no alias, or\n * the alias value isn't a static string. Shorthand `{alias}` is skipped\n * because the identifier wouldn't be in scope when the propDecorators\n * static block is evaluated at class top level.\n */\nfunction extractAlias(optArg: any): string | null {\n if (!optArg || optArg.type !== 'ObjectExpression') return null;\n for (const p of optArg.properties || []) {\n if (p.type !== 'ObjectProperty' && p.type !== 'Property') continue;\n if (p.shorthand) continue;\n const pKey = p.key?.name || p.key?.value;\n if (pKey !== 'alias') continue;\n const v = p.value;\n if (v?.type === 'StringLiteral') return v.value;\n if (v?.type === 'Literal' && typeof v.value === 'string') return v.value;\n }\n return null;\n}\n\nfunction escapeStringLiteral(s: string): string {\n return s.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, \"\\\\'\");\n}\n\n/** The constructor implementation, skipping overload signatures. */\nexport function findConstructor(classNode: any): any {\n return (classNode.body?.body || []).find(\n (m: any) =>\n m.type === 'MethodDefinition' &&\n m.kind === 'constructor' &&\n m.value?.body,\n );\n}\n\n/**\n * Build ctorParameters for constructor DI in JIT format:\n * [{ type: ServiceA }, { type: ServiceB, decorators: [{type: Optional}] }]\n *\n * Accepts an OXC ClassDeclaration node and the original source string.\n */\nexport function buildCtorParameters(\n classNode: any,\n sourceCode: string,\n typeOnlyImports: Set<string>,\n): string | null {\n const ctor = findConstructor(classNode);\n if (!ctor) return null;\n\n const params: any[] = ctor.value?.params?.items || ctor.value?.params || [];\n if (params.length === 0) return null;\n\n const result: string[] = [];\n for (const param of params) {\n const parts: string[] = [];\n\n // Handle TSParameterProperty (e.g., constructor(private foo: Bar))\n const actualParam =\n param.type === 'TSParameterProperty' ? param.parameter : param;\n const typeAnn =\n actualParam?.typeAnnotation?.typeAnnotation ??\n param?.typeAnnotation?.typeAnnotation;\n\n // Extract type name from annotation\n let typeName: string | null = null;\n if (typeAnn) {\n if (typeAnn.type === 'TSTypeReference' && typeAnn.typeName) {\n typeName =\n typeAnn.typeName.name ??\n sourceCode.slice(typeAnn.typeName.start, typeAnn.typeName.end);\n } else if (typeAnn.type === 'TSUnionType') {\n for (const t of typeAnn.types || []) {\n if (t.type === 'TSTypeReference' && t.typeName) {\n typeName =\n t.typeName.name ??\n sourceCode.slice(t.typeName.start, t.typeName.end);\n break;\n }\n }\n }\n }\n\n // Extract parameter decorators (may live on TSParameterProperty or the param itself)\n const paramDecs: any[] = param.decorators || actualParam?.decorators || [];\n // @Inject supplies the token, so its annotation may be an interface\n // with no runtime value; referencing it would throw.\n const hasInject = paramDecs.some(\n (dec: any) => dec.expression?.callee?.name === 'Inject',\n );\n\n if (typeName && !hasInject && !typeOnlyImports.has(typeName)) {\n parts.push(`type: ${typeName}`);\n } else {\n parts.push(`type: undefined`);\n }\n\n if (paramDecs.length > 0) {\n const decEntries = paramDecs\n .map((dec: any) => {\n const expr = dec.expression;\n if (!expr || expr.type !== 'CallExpression') return '';\n const name = expr.callee?.name;\n if (!name) return '';\n const args: any[] = expr.arguments || [];\n if (args.length > 0) {\n return `{type: ${name}, args: [${args.map((a: any) => sourceCode.slice(a.start, a.end)).join(', ')}]}`;\n }\n return `{type: ${name}}`;\n })\n .filter(Boolean);\n if (decEntries.length > 0) {\n parts.push(`decorators: [${decEntries.join(', ')}]`);\n }\n }\n\n result.push(`{${parts.join(', ')}}`);\n }\n\n return result.join(', ');\n}\n\n/**\n * Build propDecorators for field decorators + signal API downleveling.\n * Returns a JS object literal string or null if no props.\n *\n * Accepts an OXC ClassDeclaration node and the original source string.\n */\nexport function buildPropDecorators(\n classNode: any,\n sourceCode: string,\n): string | null {\n const props: Record<string, string[]> = {};\n const members: any[] = classNode.body?.body || [];\n\n for (const member of members) {\n const memberName: string | undefined = member.key?.name;\n if (!memberName) continue;\n\n // Check for field decorators (@Input, @Output, @ViewChild, etc.)\n const explicitDecoratorNames = new Set<string>();\n const decorators: any[] = member.decorators || [];\n for (const dec of decorators) {\n const expr = dec.expression;\n if (!expr || expr.type !== 'CallExpression') continue;\n const decName: string | undefined = expr.callee?.name;\n if (!decName || !FIELD_DECORATORS.has(decName)) continue;\n\n explicitDecoratorNames.add(decName);\n if (!props[memberName]) props[memberName] = [];\n const args: any[] = expr.arguments || [];\n if (args.length > 0) {\n props[memberName].push(\n `{type: ${decName}, args: [${args.map((a: any) => sourceCode.slice(a.start, a.end)).join(', ')}]}`,\n );\n } else {\n props[memberName].push(`{type: ${decName}}`);\n }\n }\n\n // Signal API downleveling. Skip when a matching explicit decorator\n // is already on the field — Angular's transform bails in that case\n // (input_function.ts, model_function.ts, output_function.ts,\n // query_functions.ts) to avoid duplicate metadata entries.\n if (\n member.type === 'PropertyDefinition' &&\n member.value?.type === 'CallExpression'\n ) {\n const signalCall = getCallApi(member.value);\n if (!signalCall) continue;\n\n const { api, required } = signalCall;\n const args: any[] = member.value.arguments || [];\n\n const hasInput = explicitDecoratorNames.has('Input');\n const hasOutput = explicitDecoratorNames.has('Output');\n const hasQuery =\n explicitDecoratorNames.has('ViewChild') ||\n explicitDecoratorNames.has('ViewChildren') ||\n explicitDecoratorNames.has('ContentChild') ||\n explicitDecoratorNames.has('ContentChildren');\n\n if (api === 'input' && hasInput) continue;\n if (api === 'model' && (hasInput || hasOutput)) continue;\n if ((api === 'output' || api === 'outputFromObservable') && hasOutput) {\n continue;\n }\n if (\n (api === 'viewChild' ||\n api === 'viewChildren' ||\n api === 'contentChild' ||\n api === 'contentChildren') &&\n hasQuery\n ) {\n continue;\n }\n\n if (api === 'input') {\n if (!props[memberName]) props[memberName] = [];\n // Preserve original options from the input() call and overlay\n // isSignal/required. `transform` is dropped: the input signal\n // already applies it internally, so forwarding it to the\n // decorator would make Angular's runtime JIT wrap it a second\n // time via the directive metadata's transformFunction slot.\n // Shorthand props ({alias}) are skipped — the identifier\n // wouldn't be in scope when the propDecorators block runs at\n // class top level.\n const optArg = required ? args[0] : args[1];\n const optParts: string[] = [];\n if (optArg?.type === 'ObjectExpression') {\n for (const p of optArg.properties || []) {\n if (p.type !== 'ObjectProperty' && p.type !== 'Property') continue;\n if (p.shorthand) continue;\n const pKey = p.key?.name || p.key?.value;\n if (\n pKey === 'isSignal' ||\n pKey === 'required' ||\n pKey === 'transform'\n ) {\n continue;\n }\n optParts.push(sourceCode.slice(p.start, p.end));\n }\n }\n optParts.push(`isSignal: true`, `required: ${required}`);\n props[memberName].push(\n `{type: Input, args: [{${optParts.join(', ')}}]}`,\n );\n } else if (api === 'model') {\n // Both Input and Output must live on the SAME propDecorators key\n // (the class field name). Angular's JIT facade indexes outputs by\n // classPropertyName and reads `instance[classPropertyName]` for\n // the EventEmitter — for a model that's the signal itself, which\n // exposes the emitter via [SIGNAL]. Splitting Output onto a\n // synthetic `<name>Change` key would point at a field that does\n // not exist on the class, breaking two-way bindings.\n if (!props[memberName]) props[memberName] = [];\n const optArg = required ? args[0] : args[1];\n const alias = extractAlias(optArg);\n const bindingName = alias ?? memberName;\n props[memberName].push(\n `{type: Input, args: [{isSignal: true, alias: '${escapeStringLiteral(bindingName)}', required: ${required}}]}`,\n );\n props[memberName].push(\n `{type: Output, args: ['${escapeStringLiteral(bindingName + 'Change')}']}`,\n );\n } else if (api === 'output' || api === 'outputFromObservable') {\n if (!props[memberName]) props[memberName] = [];\n // outputFromObservable(observable, options) — options is args[1].\n // output(options) — options is args[0].\n const optArg = api === 'outputFromObservable' ? args[1] : args[0];\n const alias = extractAlias(optArg);\n if (alias !== null) {\n props[memberName].push(\n `{type: Output, args: ['${escapeStringLiteral(alias)}']}`,\n );\n } else {\n props[memberName].push(`{type: Output}`);\n }\n } else if (\n api === 'viewChild' ||\n api === 'viewChildren' ||\n api === 'contentChild' ||\n api === 'contentChildren'\n ) {\n if (!props[memberName]) props[memberName] = [];\n const queryType =\n api === 'viewChildren'\n ? 'ViewChildren'\n : api === 'viewChild'\n ? 'ViewChild'\n : api === 'contentChildren'\n ? 'ContentChildren'\n : 'ContentChild';\n // Signal queries need `isSignal: true` so the runtime JIT compiler\n // wires them through the signal query infrastructure rather than\n // treating them as plain @ViewChild/@ContentChild assignments.\n // Mirrors Angular's own JIT transform in\n // compiler-cli/.../initializer_api_transforms/query_functions.ts.\n if (args.length > 0) {\n const opts =\n args.length > 1\n ? `{...${sourceCode.slice(args[1].start, args[1].end)}, isSignal: true}`\n : `{isSignal: true}`;\n props[memberName].push(\n `{type: ${queryType}, args: [${sourceCode.slice(args[0].start, args[0].end)}, ${opts}]}`,\n );\n } else {\n props[memberName].push(\n `{type: ${queryType}, args: [undefined, {isSignal: true}]}`,\n );\n }\n }\n }\n }\n\n const entries = Object.entries(props);\n if (entries.length === 0) return null;\n\n const propsStr = entries\n .map(([key, decs]) => `${key}: [${decs.join(', ')}]`)\n .join(', ');\n return `{${propsStr}}`;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"jit-metadata.js","names":[],"sources":["../../../../src/lib/compiler/jit-metadata.ts"],"sourcesContent":["/**\n * JIT metadata helpers — OXC AST edition.\n *\n * Builds static metadata arrays that Angular's ReflectionCapabilities reads\n * at runtime for JIT compilation (ctorParameters, propDecorators).\n *\n * Uses source-position slicing instead of AST getText() for speed.\n */\nimport { FIELD_DECORATORS } from './constants.js';\n\nfunction getCallApi(call: any): { api: string; required: boolean } | null {\n const callee = call.callee;\n if (!callee) return null;\n\n if (callee.type === 'Identifier') {\n return { api: callee.name, required: false };\n }\n\n if (\n (callee.type === 'StaticMemberExpression' ||\n callee.type === 'MemberExpression') &&\n callee.object?.type === 'Identifier' &&\n callee.property?.name === 'required'\n ) {\n return { api: callee.object.name, required: true };\n }\n\n return null;\n}\n\n/**\n * Read a string-literal `alias` value out of an OXC ObjectExpression.\n * Returns null when the arg isn't an object literal, has no alias, or\n * the alias value isn't a static string. Shorthand `{alias}` is skipped\n * because the identifier wouldn't be in scope when the propDecorators\n * static block is evaluated at class top level.\n */\nfunction extractAlias(optArg: any): string | null {\n if (!optArg || optArg.type !== 'ObjectExpression') return null;\n for (const p of optArg.properties || []) {\n if (p.type !== 'ObjectProperty' && p.type !== 'Property') continue;\n if (p.shorthand) continue;\n const pKey = p.key?.name || p.key?.value;\n if (pKey !== 'alias') continue;\n const v = p.value;\n if (v?.type === 'StringLiteral') return v.value;\n if (v?.type === 'Literal' && typeof v.value === 'string') return v.value;\n }\n return null;\n}\n\nfunction escapeStringLiteral(s: string): string {\n return s.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, \"\\\\'\");\n}\n\n/** The constructor implementation, skipping overload signatures. */\nexport function findConstructor(classNode: any): any {\n return (classNode.body?.body || []).find(\n (m: any) =>\n m.type === 'MethodDefinition' &&\n m.kind === 'constructor' &&\n m.value?.body,\n );\n}\n\n/**\n * Build ctorParameters for constructor DI in JIT format:\n * [{ type: ServiceA }, { type: ServiceB, decorators: [{type: Optional}] }]\n *\n * Accepts an OXC ClassDeclaration node and the original source string.\n */\nexport function buildCtorParameters(\n classNode: any,\n sourceCode: string,\n typeOnlyImports: Set<string>,\n): string | null {\n const ctor = findConstructor(classNode);\n if (!ctor) return null;\n\n const params: any[] = ctor.value?.params?.items || ctor.value?.params || [];\n if (params.length === 0) return null;\n\n const result: string[] = [];\n for (const param of params) {\n const parts: string[] = [];\n\n // Handle TSParameterProperty (e.g., constructor(private foo: Bar))\n const actualParam =\n param.type === 'TSParameterProperty' ? param.parameter : param;\n const typeAnn =\n actualParam?.typeAnnotation?.typeAnnotation ??\n param?.typeAnnotation?.typeAnnotation;\n\n // Extract type name from annotation\n let typeName: string | null = null;\n if (typeAnn) {\n if (typeAnn.type === 'TSTypeReference' && typeAnn.typeName) {\n typeName =\n typeAnn.typeName.name ??\n sourceCode.slice(typeAnn.typeName.start, typeAnn.typeName.end);\n } else if (typeAnn.type === 'TSUnionType') {\n for (const t of typeAnn.types || []) {\n if (t.type === 'TSTypeReference' && t.typeName) {\n typeName =\n t.typeName.name ??\n sourceCode.slice(t.typeName.start, t.typeName.end);\n break;\n }\n }\n }\n }\n\n // Extract parameter decorators (may live on TSParameterProperty or the param itself)\n const paramDecs: any[] = param.decorators || actualParam?.decorators || [];\n // @Inject supplies the token, so its annotation may be an interface\n // with no runtime value; referencing it would throw.\n const hasInject = paramDecs.some(\n (dec: any) => dec.expression?.callee?.name === 'Inject',\n );\n\n if (typeName && !hasInject && !typeOnlyImports.has(typeName)) {\n parts.push(`type: ${typeName}`);\n } else {\n parts.push(`type: undefined`);\n }\n\n if (paramDecs.length > 0) {\n const decEntries = paramDecs\n .map((dec: any) => {\n const expr = dec.expression;\n if (!expr || expr.type !== 'CallExpression') return '';\n const name = expr.callee?.name;\n if (!name) return '';\n const args: any[] = expr.arguments || [];\n if (args.length > 0) {\n return `{type: ${name}, args: [${args.map((a: any) => sourceCode.slice(a.start, a.end)).join(', ')}]}`;\n }\n return `{type: ${name}}`;\n })\n .filter(Boolean);\n if (decEntries.length > 0) {\n parts.push(`decorators: [${decEntries.join(', ')}]`);\n }\n }\n\n result.push(`{${parts.join(', ')}}`);\n }\n\n return result.join(', ');\n}\n\n/**\n * Build propDecorators for field decorators + signal API downleveling.\n * Returns a JS object literal string or null if no props.\n *\n * Accepts an OXC ClassDeclaration node and the original source string.\n */\nexport function buildPropDecorators(\n classNode: any,\n sourceCode: string,\n): string | null {\n const props: Record<string, string[]> = {};\n const members: any[] = classNode.body?.body || [];\n\n for (const member of members) {\n const memberName: string | undefined = member.key?.name;\n if (!memberName) continue;\n\n // Check for field decorators (@Input, @Output, @ViewChild, etc.)\n const explicitDecoratorNames = new Set<string>();\n const decorators: any[] = member.decorators || [];\n for (const dec of decorators) {\n const expr = dec.expression;\n if (!expr || expr.type !== 'CallExpression') continue;\n const decName: string | undefined = expr.callee?.name;\n if (!decName || !FIELD_DECORATORS.has(decName)) continue;\n\n explicitDecoratorNames.add(decName);\n if (!props[memberName]) props[memberName] = [];\n const args: any[] = expr.arguments || [];\n if (args.length > 0) {\n props[memberName].push(\n `{type: ${decName}, args: [${args.map((a: any) => sourceCode.slice(a.start, a.end)).join(', ')}]}`,\n );\n } else {\n props[memberName].push(`{type: ${decName}}`);\n }\n }\n\n // Signal API downleveling. Skip when a matching explicit decorator\n // is already on the field — Angular's transform bails in that case\n // (input_function.ts, model_function.ts, output_function.ts,\n // query_functions.ts) to avoid duplicate metadata entries.\n if (\n member.type === 'PropertyDefinition' &&\n member.value?.type === 'CallExpression'\n ) {\n const signalCall = getCallApi(member.value);\n if (!signalCall) continue;\n\n const { api, required } = signalCall;\n const args: any[] = member.value.arguments || [];\n\n const hasInput = explicitDecoratorNames.has('Input');\n const hasOutput = explicitDecoratorNames.has('Output');\n const hasQuery =\n explicitDecoratorNames.has('ViewChild') ||\n explicitDecoratorNames.has('ViewChildren') ||\n explicitDecoratorNames.has('ContentChild') ||\n explicitDecoratorNames.has('ContentChildren');\n\n if (api === 'input' && hasInput) continue;\n if (api === 'model' && (hasInput || hasOutput)) continue;\n if ((api === 'output' || api === 'outputFromObservable') && hasOutput) {\n continue;\n }\n if (\n (api === 'viewChild' ||\n api === 'viewChildren' ||\n api === 'contentChild' ||\n api === 'contentChildren') &&\n hasQuery\n ) {\n continue;\n }\n\n if (api === 'input') {\n if (!props[memberName]) props[memberName] = [];\n // Preserve original options from the input() call and overlay\n // isSignal/required. `transform` is dropped: the input signal\n // already applies it internally, so forwarding it to the\n // decorator would make Angular's runtime JIT wrap it a second\n // time via the directive metadata's transformFunction slot.\n // Shorthand props ({alias}) are skipped — the identifier\n // wouldn't be in scope when the propDecorators block runs at\n // class top level.\n const optArg = required ? args[0] : args[1];\n const optParts: string[] = [];\n if (optArg?.type === 'ObjectExpression') {\n for (const p of optArg.properties || []) {\n if (p.type !== 'ObjectProperty' && p.type !== 'Property') continue;\n if (p.shorthand) continue;\n const pKey = p.key?.name || p.key?.value;\n if (\n pKey === 'isSignal' ||\n pKey === 'required' ||\n pKey === 'transform'\n ) {\n continue;\n }\n optParts.push(sourceCode.slice(p.start, p.end));\n }\n }\n optParts.push(`isSignal: true`, `required: ${required}`);\n props[memberName].push(\n `{type: Input, args: [{${optParts.join(', ')}}]}`,\n );\n } else if (api === 'model') {\n // Both Input and Output must live on the SAME propDecorators key\n // (the class field name). Angular's JIT facade indexes outputs by\n // classPropertyName and reads `instance[classPropertyName]` for\n // the EventEmitter — for a model that's the signal itself, which\n // exposes the emitter via [SIGNAL]. Splitting Output onto a\n // synthetic `<name>Change` key would point at a field that does\n // not exist on the class, breaking two-way bindings.\n if (!props[memberName]) props[memberName] = [];\n const optArg = required ? args[0] : args[1];\n const alias = extractAlias(optArg);\n const bindingName = alias ?? memberName;\n props[memberName].push(\n `{type: Input, args: [{isSignal: true, alias: '${escapeStringLiteral(bindingName)}', required: ${required}}]}`,\n );\n props[memberName].push(\n `{type: Output, args: ['${escapeStringLiteral(bindingName + 'Change')}']}`,\n );\n } else if (api === 'output' || api === 'outputFromObservable') {\n if (!props[memberName]) props[memberName] = [];\n // outputFromObservable(observable, options) — options is args[1].\n // output(options) — options is args[0].\n const optArg = api === 'outputFromObservable' ? args[1] : args[0];\n const alias = extractAlias(optArg);\n if (alias !== null) {\n props[memberName].push(\n `{type: Output, args: ['${escapeStringLiteral(alias)}']}`,\n );\n } else {\n props[memberName].push(`{type: Output}`);\n }\n } else if (\n api === 'viewChild' ||\n api === 'viewChildren' ||\n api === 'contentChild' ||\n api === 'contentChildren'\n ) {\n if (!props[memberName]) props[memberName] = [];\n const queryType =\n api === 'viewChildren'\n ? 'ViewChildren'\n : api === 'viewChild'\n ? 'ViewChild'\n : api === 'contentChildren'\n ? 'ContentChildren'\n : 'ContentChild';\n // Signal queries need `isSignal: true` so the runtime JIT compiler\n // wires them through the signal query infrastructure rather than\n // treating them as plain @ViewChild/@ContentChild assignments.\n // Mirrors Angular's own JIT transform in\n // compiler-cli/.../initializer_api_transforms/query_functions.ts.\n if (args.length > 0) {\n const opts =\n args.length > 1\n ? `{...${sourceCode.slice(args[1].start, args[1].end)}, isSignal: true}`\n : `{isSignal: true}`;\n props[memberName].push(\n `{type: ${queryType}, args: [${sourceCode.slice(args[0].start, args[0].end)}, ${opts}]}`,\n );\n } else {\n props[memberName].push(\n `{type: ${queryType}, args: [undefined, {isSignal: true}]}`,\n );\n }\n }\n }\n }\n\n const entries = Object.entries(props);\n if (entries.length === 0) return null;\n\n const propsStr = entries\n .map(([key, decs]) => `${key}: [${decs.join(', ')}]`)\n .join(', ');\n return `{${propsStr}}`;\n}\n"],"mappings":"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"}
@@ -37,7 +37,7 @@ function removeDecorator(ms, sourceCode, dec) {
37
37
  while (trimEnd < sourceCode.length && /\s/.test(sourceCode[trimEnd])) trimEnd++;
38
38
  ms.remove(dec.start, trimEnd);
39
39
  }
40
- var DI_PARAM_DECORATORS = new Set([
40
+ var DI_PARAM_DECORATORS = /* @__PURE__ */ new Set([
41
41
  "Inject",
42
42
  "Optional",
43
43
  "Self",
@@ -45,7 +45,7 @@ var DI_PARAM_DECORATORS = new Set([
45
45
  "Host",
46
46
  "Attribute"
47
47
  ]);
48
- var PROVIDER_KEYS = new Set([
48
+ var PROVIDER_KEYS = /* @__PURE__ */ new Set([
49
49
  "useClass",
50
50
  "useExisting",
51
51
  "useFactory",
@@ -184,9 +184,7 @@ function jitTransform(sourceCode, fileName) {
184
184
  case "Pipe":
185
185
  classStatements.push(`_jitCompilePipe(${className}, ${dm.argsText});`);
186
186
  break;
187
- case "NgModule":
188
- classStatements.push(`_jitCompileNgModule(${className}, ${dm.argsText});`);
189
- break;
187
+ case "NgModule": classStatements.push(`_jitCompileNgModule(${className}, ${dm.argsText});`);
190
188
  }
191
189
  }
192
190
  const ctorParams = buildCtorParameters(node, sourceCode, typeOnlyImports);
@@ -1 +1 @@
1
- {"version":3,"file":"jit-transform.js","names":[],"sources":["../../../../src/lib/compiler/jit-transform.ts"],"sourcesContent":["import { parseSync } from 'oxc-parser';\nimport MagicString from 'magic-string';\nimport { detectTypeOnlyImportNames } from './type-elision.js';\nimport {\n buildCtorParameters,\n buildPropDecorators,\n findConstructor,\n} from './jit-metadata.js';\nimport { ANGULAR_DECORATORS, FIELD_DECORATORS } from './constants.js';\n\nexport interface JitTransformResult {\n code: string;\n map: any;\n}\n\n/**\n * Recursively find all ClassDeclaration nodes in an OXC AST.\n * Handles top-level, exported, and nested classes (e.g. inside function scopes).\n */\nfunction findAllClasses(node: any): any[] {\n const result: any[] = [];\n if (!node || typeof node !== 'object') return result;\n if (Array.isArray(node)) {\n for (const item of node) {\n result.push(...findAllClasses(item));\n }\n return result;\n }\n if (node.type === 'ClassDeclaration' || node.type === 'ClassExpression') {\n result.push(node);\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 result.push(...findAllClasses(node[key]));\n }\n return result;\n}\n\n/**\n * `@Injectable` and `@Service` stay on the class — their decorator functions\n * self-register ɵprov/ɵfac at class definition time and there is no JIT\n * compile entry point to call instead.\n */\nfunction isSelfRegisteringDecorator(dec: any): boolean {\n const name: string | undefined = dec.expression?.callee?.name;\n return name === 'Injectable' || name === 'Service';\n}\n\n/** Remove a decorator along with its trailing whitespace. */\nfunction removeDecorator(ms: MagicString, sourceCode: string, dec: any): void {\n let trimEnd: number = dec.end;\n while (trimEnd < sourceCode.length && /\\s/.test(sourceCode[trimEnd]))\n trimEnd++;\n ms.remove(dec.start, trimEnd);\n}\n\nconst DI_PARAM_DECORATORS = new Set([\n 'Inject',\n 'Optional',\n 'Self',\n 'SkipSelf',\n 'Host',\n 'Attribute',\n]);\nconst PROVIDER_KEYS = new Set([\n 'useClass',\n 'useExisting',\n 'useFactory',\n 'useValue',\n]);\n\nfunction ctorParamDecorators(classNode: any): any[] {\n const ctor = findConstructor(classNode);\n const params: any[] = ctor?.value?.params?.items || ctor?.value?.params || [];\n // Decorators may live on the TSParameterProperty wrapper or the inner param\n return params.flatMap((param: any) => [\n ...(param.decorators || []),\n ...(param.type === 'TSParameterProperty' && param.parameter?.decorators\n ? param.parameter.decorators\n : []),\n ]);\n}\n\n/**\n * Whether an @Injectable/@Service class needs ctorParameters. Skipped when a\n * provider option replaces the constructor, or when a non-DI parameter\n * decorator must keep running as written.\n */\nfunction needsInjectableCtorParameters(node: any, decorators: any[]): boolean {\n const dec = decorators.find(isSelfRegisteringDecorator);\n const options = dec?.expression.arguments?.[0];\n return (\n !!dec &&\n node.type === 'ClassDeclaration' &&\n !options?.properties?.some((p: any) => PROVIDER_KEYS.has(p.key?.name)) &&\n ctorParamDecorators(node).every((d: any) =>\n DI_PARAM_DECORATORS.has(d.expression?.callee?.name),\n )\n );\n}\n\n/**\n * JIT transform for Angular files.\n *\n * Converts Angular decorators to static metadata arrays that Angular's\n * runtime JIT compiler reads via ReflectionCapabilities:\n *\n * - Class.decorators = [{ type: Component, args: [{...}] }]\n * - Class.ctorParameters = () => [{ type: ServiceA, decorators: [{type: Optional}] }]\n * - Class.propDecorators = { name: [{ type: Input }], ... }\n *\n * Also emits ɵfac (factory function) with constructor DI and downlevels\n * signal APIs (input, model, output, viewChild, etc.) to propDecorators.\n *\n * No template compilation — Angular's JIT compiler handles that at runtime.\n * Requires `import '@angular/compiler'` in main.ts for the browser JIT.\n *\n * Uses OXC's native Rust parser instead of TypeScript's parser for ~1.5x\n * faster parsing and source-position slicing instead of getText() calls.\n */\nexport function jitTransform(\n sourceCode: string,\n fileName: string,\n): JitTransformResult {\n const { program } = parseSync(fileName, sourceCode);\n const ms = new MagicString(sourceCode, { filename: fileName });\n const typeOnlyImports = detectTypeOnlyImportNames(sourceCode, program);\n let hasAngularClass = false;\n\n const allClasses = findAllClasses(program.body);\n\n // Accumulates every class's emitted statements so the post-loop import\n // detection (missing field-decorator imports) can scan all of them.\n // The statements themselves are inserted in-scope after each class via\n // `ms.appendLeft(node.end, ...)` rather than dumped at the end of the\n // file — a class declared inside a function/callback scope (e.g. a host\n // `@Component` defined inside a `describe(...)`/`it(...)` block in a test)\n // is not in scope at module end, so a file-end emit would reference an\n // undefined name (#2360).\n const allEmittedStatements: string[] = [];\n let importCounter = 0;\n const resourceImports: string[] = [];\n let needsJitImport = false;\n\n for (const node of allClasses) {\n const decorators: any[] = node.decorators || [];\n\n const angularDecs = decorators.filter((dec: any) => {\n const expr = dec.expression;\n if (!expr || expr.type !== 'CallExpression') return false;\n const name: string | undefined = expr.callee?.name;\n if (isSelfRegisteringDecorator(dec)) return false;\n return name !== undefined && ANGULAR_DECORATORS.has(name);\n });\n const className: string | undefined = node.id?.name;\n if (!className) continue;\n\n if (angularDecs.length === 0) {\n // @Injectable/@Service keep their decorator, but without a type\n // checker or emitDecoratorMetadata a param typed only by annotation\n // has no runtime DI token unless captured in ctorParameters. A class\n // expression's name is not in scope after it, so only declarations.\n const ctorParams =\n needsInjectableCtorParameters(node, decorators) &&\n buildCtorParameters(node, sourceCode, typeOnlyImports);\n if (ctorParams) {\n hasAngularClass = true;\n for (const dec of ctorParamDecorators(node)) {\n removeDecorator(ms, sourceCode, dec);\n }\n ms.appendLeft(\n node.end,\n `\\n${className}.ctorParameters = () => [${ctorParams}];\\n`,\n );\n }\n continue;\n }\n hasAngularClass = true;\n\n // Statements emitted for THIS class. Inserted directly after the class\n // body (see end of loop) so they run in the class's own lexical scope.\n const classStatements: string[] = [];\n\n // 1. Remove Angular decorators from source\n for (const dec of angularDecs) {\n removeDecorator(ms, sourceCode, dec);\n }\n\n // 2. Emit Class.decorators = [{ type: DecName, args: [...] }]\n // For @Component: convert templateUrl/styleUrl/styleUrls to ESM imports\n const decoratorMeta: { name: string; argsText: string }[] = [];\n const decoratorEntries = angularDecs.map((dec: any) => {\n const call = dec.expression;\n const decName: string = call.callee.name;\n const args: any[] = call.arguments || [];\n\n if (\n args.length > 0 &&\n decName === 'Component' &&\n args[0].type === 'ObjectExpression'\n ) {\n // Rewrite component metadata: convert external resources to imports\n const obj = args[0];\n const rewrittenProps: string[] = [];\n\n for (const prop of obj.properties) {\n if (prop.type !== 'ObjectProperty' && prop.type !== 'Property') {\n rewrittenProps.push(sourceCode.slice(prop.start, prop.end));\n continue;\n }\n const key: string = prop.key?.name || prop.key?.value;\n const val = prop.value;\n\n if (\n key === 'templateUrl' &&\n (val?.type === 'StringLiteral' ||\n (val?.type === 'Literal' && typeof val.value === 'string'))\n ) {\n // templateUrl: './foo.html' → template: _tpl0 (with import)\n const varName = `_jit_tpl_${importCounter++}`;\n resourceImports.push(`import ${varName} from '${val.value}?raw';`);\n rewrittenProps.push(`template: ${varName}`);\n } else if (\n key === 'styleUrl' &&\n (val?.type === 'StringLiteral' ||\n (val?.type === 'Literal' && typeof val.value === 'string'))\n ) {\n // styleUrl: './foo.scss' → styles: [_style0]\n const varName = `_jit_style_${importCounter++}`;\n resourceImports.push(\n `import ${varName} from '${val.value}?inline';`,\n );\n rewrittenProps.push(`styles: [${varName}]`);\n } else if (key === 'styleUrls' && val?.type === 'ArrayExpression') {\n // styleUrls: ['./a.scss', './b.css'] → styles: [_style0, _style1]\n const vars: string[] = [];\n for (const el of val.elements) {\n if (\n el?.type === 'StringLiteral' ||\n (el?.type === 'Literal' && typeof el.value === 'string')\n ) {\n const varName = `_jit_style_${importCounter++}`;\n resourceImports.push(\n `import ${varName} from '${el.value}?inline';`,\n );\n vars.push(varName);\n }\n }\n rewrittenProps.push(`styles: [${vars.join(', ')}]`);\n } else {\n rewrittenProps.push(sourceCode.slice(prop.start, prop.end));\n }\n }\n const rewrittenArgsText = `{${rewrittenProps.join(', ')}}`;\n decoratorMeta.push({ name: decName, argsText: rewrittenArgsText });\n return `{ type: ${decName}, args: [${rewrittenArgsText}] }`;\n }\n\n if (args.length > 0) {\n const argsText = args\n .map((a: any) => sourceCode.slice(a.start, a.end))\n .join(', ');\n decoratorMeta.push({ name: decName, argsText });\n return `{ type: ${decName}, args: [${argsText}] }`;\n }\n decoratorMeta.push({ name: decName, argsText: '{}' });\n return `{ type: ${decName} }`;\n });\n classStatements.push(\n `${className}.decorators = [${decoratorEntries.join(', ')}];`,\n );\n\n // 2b. Trigger JIT compilation with the rewritten decorator metadata\n for (const dm of decoratorMeta) {\n needsJitImport = true;\n switch (dm.name) {\n case 'Component':\n classStatements.push(\n `_jitCompileComponent(${className}, ${dm.argsText});`,\n );\n break;\n case 'Directive':\n classStatements.push(\n `_jitCompileDirective(${className}, ${dm.argsText});`,\n );\n break;\n case 'Pipe':\n classStatements.push(\n `_jitCompilePipe(${className}, ${dm.argsText});`,\n );\n break;\n case 'NgModule':\n classStatements.push(\n `_jitCompileNgModule(${className}, ${dm.argsText});`,\n );\n break;\n }\n }\n\n // 3. Emit Class.ctorParameters for constructor DI\n const ctorParams = buildCtorParameters(node, sourceCode, typeOnlyImports);\n if (ctorParams) {\n classStatements.push(\n `${className}.ctorParameters = () => [${ctorParams}];`,\n );\n }\n\n // 4. Emit Class.propDecorators for field decorators + signal APIs\n const propDecorators = buildPropDecorators(node, sourceCode);\n if (propDecorators) {\n classStatements.push(`${className}.propDecorators = ${propDecorators};`);\n }\n\n // 5. Remove member and parameter decorators from source now that\n // they have been extracted into static metadata above.\n const members: any[] = node.body?.body || [];\n for (const member of members) {\n for (const dec of member.decorators || []) {\n removeDecorator(ms, sourceCode, dec);\n }\n }\n for (const dec of ctorParamDecorators(node)) {\n removeDecorator(ms, sourceCode, dec);\n }\n\n // Insert this class's metadata statements directly after the class body\n // so they execute in the class's own lexical scope. `node.end` is the\n // position just past the closing brace (decorators were stripped before\n // `node.start`), so for a top-level class this is module scope and for a\n // class nested in a function/callback it is that enclosing scope —\n // keeping the class identifier in scope either way (#2360).\n if (classStatements.length > 0) {\n allEmittedStatements.push(...classStatements);\n ms.appendLeft(node.end, '\\n' + classStatements.join('\\n') + '\\n');\n }\n }\n\n if (!hasAngularClass) {\n return { code: sourceCode, map: null };\n }\n\n // Prepend ESM imports for external templates/styles\n if (resourceImports.length > 0) {\n ms.prepend(resourceImports.join('\\n') + '\\n');\n }\n\n // Prepend imports for decorator classes referenced by signal API downleveling\n // (e.g. input() → {type: Input}, model() → {type: Input} + {type: Output})\n const existingImports = new Set<string>();\n for (const stmt of program.body) {\n if (\n (stmt as any).type === 'ImportDeclaration' &&\n (stmt as any).source?.value === '@angular/core'\n ) {\n for (const spec of (stmt as any).specifiers || []) {\n if (spec.type === 'ImportSpecifier') {\n existingImports.add(spec.local?.name || spec.imported?.name);\n }\n }\n }\n }\n const allPostCode = allEmittedStatements.join('\\n');\n const missingDecorators: string[] = [];\n for (const dec of FIELD_DECORATORS) {\n if (allPostCode.includes(`type: ${dec}`) && !existingImports.has(dec)) {\n missingDecorators.push(dec);\n }\n }\n if (missingDecorators.length > 0) {\n ms.prepend(\n `import { ${missingDecorators.join(', ')} } from '@angular/core';\\n`,\n );\n }\n\n // Prepend JIT compiler imports\n if (needsJitImport) {\n ms.prepend(\n `import { ɵcompileComponent as _jitCompileComponent, ɵcompileDirective as _jitCompileDirective, ɵcompilePipe as _jitCompilePipe, ɵcompileNgModule as _jitCompileNgModule } from '@angular/core';\\n`,\n );\n }\n\n const map = ms.generateMap({\n source: fileName,\n file: fileName + '.js',\n includeContent: true,\n hires: 'boundary',\n });\n\n return { code: ms.toString(), map };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"jit-transform.js","names":[],"sources":["../../../../src/lib/compiler/jit-transform.ts"],"sourcesContent":["import { parseSync } from 'oxc-parser';\nimport MagicString from 'magic-string';\nimport { detectTypeOnlyImportNames } from './type-elision.js';\nimport {\n buildCtorParameters,\n buildPropDecorators,\n findConstructor,\n} from './jit-metadata.js';\nimport { ANGULAR_DECORATORS, FIELD_DECORATORS } from './constants.js';\n\nexport interface JitTransformResult {\n code: string;\n map: any;\n}\n\n/**\n * Recursively find all ClassDeclaration nodes in an OXC AST.\n * Handles top-level, exported, and nested classes (e.g. inside function scopes).\n */\nfunction findAllClasses(node: any): any[] {\n const result: any[] = [];\n if (!node || typeof node !== 'object') return result;\n if (Array.isArray(node)) {\n for (const item of node) {\n result.push(...findAllClasses(item));\n }\n return result;\n }\n if (node.type === 'ClassDeclaration' || node.type === 'ClassExpression') {\n result.push(node);\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 result.push(...findAllClasses(node[key]));\n }\n return result;\n}\n\n/**\n * `@Injectable` and `@Service` stay on the class — their decorator functions\n * self-register ɵprov/ɵfac at class definition time and there is no JIT\n * compile entry point to call instead.\n */\nfunction isSelfRegisteringDecorator(dec: any): boolean {\n const name: string | undefined = dec.expression?.callee?.name;\n return name === 'Injectable' || name === 'Service';\n}\n\n/** Remove a decorator along with its trailing whitespace. */\nfunction removeDecorator(ms: MagicString, sourceCode: string, dec: any): void {\n let trimEnd: number = dec.end;\n while (trimEnd < sourceCode.length && /\\s/.test(sourceCode[trimEnd]))\n trimEnd++;\n ms.remove(dec.start, trimEnd);\n}\n\nconst DI_PARAM_DECORATORS = new Set([\n 'Inject',\n 'Optional',\n 'Self',\n 'SkipSelf',\n 'Host',\n 'Attribute',\n]);\nconst PROVIDER_KEYS = new Set([\n 'useClass',\n 'useExisting',\n 'useFactory',\n 'useValue',\n]);\n\nfunction ctorParamDecorators(classNode: any): any[] {\n const ctor = findConstructor(classNode);\n const params: any[] = ctor?.value?.params?.items || ctor?.value?.params || [];\n // Decorators may live on the TSParameterProperty wrapper or the inner param\n return params.flatMap((param: any) => [\n ...(param.decorators || []),\n ...(param.type === 'TSParameterProperty' && param.parameter?.decorators\n ? param.parameter.decorators\n : []),\n ]);\n}\n\n/**\n * Whether an @Injectable/@Service class needs ctorParameters. Skipped when a\n * provider option replaces the constructor, or when a non-DI parameter\n * decorator must keep running as written.\n */\nfunction needsInjectableCtorParameters(node: any, decorators: any[]): boolean {\n const dec = decorators.find(isSelfRegisteringDecorator);\n const options = dec?.expression.arguments?.[0];\n return (\n !!dec &&\n node.type === 'ClassDeclaration' &&\n !options?.properties?.some((p: any) => PROVIDER_KEYS.has(p.key?.name)) &&\n ctorParamDecorators(node).every((d: any) =>\n DI_PARAM_DECORATORS.has(d.expression?.callee?.name),\n )\n );\n}\n\n/**\n * JIT transform for Angular files.\n *\n * Converts Angular decorators to static metadata arrays that Angular's\n * runtime JIT compiler reads via ReflectionCapabilities:\n *\n * - Class.decorators = [{ type: Component, args: [{...}] }]\n * - Class.ctorParameters = () => [{ type: ServiceA, decorators: [{type: Optional}] }]\n * - Class.propDecorators = { name: [{ type: Input }], ... }\n *\n * Also emits ɵfac (factory function) with constructor DI and downlevels\n * signal APIs (input, model, output, viewChild, etc.) to propDecorators.\n *\n * No template compilation — Angular's JIT compiler handles that at runtime.\n * Requires `import '@angular/compiler'` in main.ts for the browser JIT.\n *\n * Uses OXC's native Rust parser instead of TypeScript's parser for ~1.5x\n * faster parsing and source-position slicing instead of getText() calls.\n */\nexport function jitTransform(\n sourceCode: string,\n fileName: string,\n): JitTransformResult {\n const { program } = parseSync(fileName, sourceCode);\n const ms = new MagicString(sourceCode, { filename: fileName });\n const typeOnlyImports = detectTypeOnlyImportNames(sourceCode, program);\n let hasAngularClass = false;\n\n const allClasses = findAllClasses(program.body);\n\n // Accumulates every class's emitted statements so the post-loop import\n // detection (missing field-decorator imports) can scan all of them.\n // The statements themselves are inserted in-scope after each class via\n // `ms.appendLeft(node.end, ...)` rather than dumped at the end of the\n // file — a class declared inside a function/callback scope (e.g. a host\n // `@Component` defined inside a `describe(...)`/`it(...)` block in a test)\n // is not in scope at module end, so a file-end emit would reference an\n // undefined name (#2360).\n const allEmittedStatements: string[] = [];\n let importCounter = 0;\n const resourceImports: string[] = [];\n let needsJitImport = false;\n\n for (const node of allClasses) {\n const decorators: any[] = node.decorators || [];\n\n const angularDecs = decorators.filter((dec: any) => {\n const expr = dec.expression;\n if (!expr || expr.type !== 'CallExpression') return false;\n const name: string | undefined = expr.callee?.name;\n if (isSelfRegisteringDecorator(dec)) return false;\n return name !== undefined && ANGULAR_DECORATORS.has(name);\n });\n const className: string | undefined = node.id?.name;\n if (!className) continue;\n\n if (angularDecs.length === 0) {\n // @Injectable/@Service keep their decorator, but without a type\n // checker or emitDecoratorMetadata a param typed only by annotation\n // has no runtime DI token unless captured in ctorParameters. A class\n // expression's name is not in scope after it, so only declarations.\n const ctorParams =\n needsInjectableCtorParameters(node, decorators) &&\n buildCtorParameters(node, sourceCode, typeOnlyImports);\n if (ctorParams) {\n hasAngularClass = true;\n for (const dec of ctorParamDecorators(node)) {\n removeDecorator(ms, sourceCode, dec);\n }\n ms.appendLeft(\n node.end,\n `\\n${className}.ctorParameters = () => [${ctorParams}];\\n`,\n );\n }\n continue;\n }\n hasAngularClass = true;\n\n // Statements emitted for THIS class. Inserted directly after the class\n // body (see end of loop) so they run in the class's own lexical scope.\n const classStatements: string[] = [];\n\n // 1. Remove Angular decorators from source\n for (const dec of angularDecs) {\n removeDecorator(ms, sourceCode, dec);\n }\n\n // 2. Emit Class.decorators = [{ type: DecName, args: [...] }]\n // For @Component: convert templateUrl/styleUrl/styleUrls to ESM imports\n const decoratorMeta: { name: string; argsText: string }[] = [];\n const decoratorEntries = angularDecs.map((dec: any) => {\n const call = dec.expression;\n const decName: string = call.callee.name;\n const args: any[] = call.arguments || [];\n\n if (\n args.length > 0 &&\n decName === 'Component' &&\n args[0].type === 'ObjectExpression'\n ) {\n // Rewrite component metadata: convert external resources to imports\n const obj = args[0];\n const rewrittenProps: string[] = [];\n\n for (const prop of obj.properties) {\n if (prop.type !== 'ObjectProperty' && prop.type !== 'Property') {\n rewrittenProps.push(sourceCode.slice(prop.start, prop.end));\n continue;\n }\n const key: string = prop.key?.name || prop.key?.value;\n const val = prop.value;\n\n if (\n key === 'templateUrl' &&\n (val?.type === 'StringLiteral' ||\n (val?.type === 'Literal' && typeof val.value === 'string'))\n ) {\n // templateUrl: './foo.html' → template: _tpl0 (with import)\n const varName = `_jit_tpl_${importCounter++}`;\n resourceImports.push(`import ${varName} from '${val.value}?raw';`);\n rewrittenProps.push(`template: ${varName}`);\n } else if (\n key === 'styleUrl' &&\n (val?.type === 'StringLiteral' ||\n (val?.type === 'Literal' && typeof val.value === 'string'))\n ) {\n // styleUrl: './foo.scss' → styles: [_style0]\n const varName = `_jit_style_${importCounter++}`;\n resourceImports.push(\n `import ${varName} from '${val.value}?inline';`,\n );\n rewrittenProps.push(`styles: [${varName}]`);\n } else if (key === 'styleUrls' && val?.type === 'ArrayExpression') {\n // styleUrls: ['./a.scss', './b.css'] → styles: [_style0, _style1]\n const vars: string[] = [];\n for (const el of val.elements) {\n if (\n el?.type === 'StringLiteral' ||\n (el?.type === 'Literal' && typeof el.value === 'string')\n ) {\n const varName = `_jit_style_${importCounter++}`;\n resourceImports.push(\n `import ${varName} from '${el.value}?inline';`,\n );\n vars.push(varName);\n }\n }\n rewrittenProps.push(`styles: [${vars.join(', ')}]`);\n } else {\n rewrittenProps.push(sourceCode.slice(prop.start, prop.end));\n }\n }\n const rewrittenArgsText = `{${rewrittenProps.join(', ')}}`;\n decoratorMeta.push({ name: decName, argsText: rewrittenArgsText });\n return `{ type: ${decName}, args: [${rewrittenArgsText}] }`;\n }\n\n if (args.length > 0) {\n const argsText = args\n .map((a: any) => sourceCode.slice(a.start, a.end))\n .join(', ');\n decoratorMeta.push({ name: decName, argsText });\n return `{ type: ${decName}, args: [${argsText}] }`;\n }\n decoratorMeta.push({ name: decName, argsText: '{}' });\n return `{ type: ${decName} }`;\n });\n classStatements.push(\n `${className}.decorators = [${decoratorEntries.join(', ')}];`,\n );\n\n // 2b. Trigger JIT compilation with the rewritten decorator metadata\n for (const dm of decoratorMeta) {\n needsJitImport = true;\n switch (dm.name) {\n case 'Component':\n classStatements.push(\n `_jitCompileComponent(${className}, ${dm.argsText});`,\n );\n break;\n case 'Directive':\n classStatements.push(\n `_jitCompileDirective(${className}, ${dm.argsText});`,\n );\n break;\n case 'Pipe':\n classStatements.push(\n `_jitCompilePipe(${className}, ${dm.argsText});`,\n );\n break;\n case 'NgModule':\n classStatements.push(\n `_jitCompileNgModule(${className}, ${dm.argsText});`,\n );\n break;\n }\n }\n\n // 3. Emit Class.ctorParameters for constructor DI\n const ctorParams = buildCtorParameters(node, sourceCode, typeOnlyImports);\n if (ctorParams) {\n classStatements.push(\n `${className}.ctorParameters = () => [${ctorParams}];`,\n );\n }\n\n // 4. Emit Class.propDecorators for field decorators + signal APIs\n const propDecorators = buildPropDecorators(node, sourceCode);\n if (propDecorators) {\n classStatements.push(`${className}.propDecorators = ${propDecorators};`);\n }\n\n // 5. Remove member and parameter decorators from source now that\n // they have been extracted into static metadata above.\n const members: any[] = node.body?.body || [];\n for (const member of members) {\n for (const dec of member.decorators || []) {\n removeDecorator(ms, sourceCode, dec);\n }\n }\n for (const dec of ctorParamDecorators(node)) {\n removeDecorator(ms, sourceCode, dec);\n }\n\n // Insert this class's metadata statements directly after the class body\n // so they execute in the class's own lexical scope. `node.end` is the\n // position just past the closing brace (decorators were stripped before\n // `node.start`), so for a top-level class this is module scope and for a\n // class nested in a function/callback it is that enclosing scope —\n // keeping the class identifier in scope either way (#2360).\n if (classStatements.length > 0) {\n allEmittedStatements.push(...classStatements);\n ms.appendLeft(node.end, '\\n' + classStatements.join('\\n') + '\\n');\n }\n }\n\n if (!hasAngularClass) {\n return { code: sourceCode, map: null };\n }\n\n // Prepend ESM imports for external templates/styles\n if (resourceImports.length > 0) {\n ms.prepend(resourceImports.join('\\n') + '\\n');\n }\n\n // Prepend imports for decorator classes referenced by signal API downleveling\n // (e.g. input() → {type: Input}, model() → {type: Input} + {type: Output})\n const existingImports = new Set<string>();\n for (const stmt of program.body) {\n if (\n (stmt as any).type === 'ImportDeclaration' &&\n (stmt as any).source?.value === '@angular/core'\n ) {\n for (const spec of (stmt as any).specifiers || []) {\n if (spec.type === 'ImportSpecifier') {\n existingImports.add(spec.local?.name || spec.imported?.name);\n }\n }\n }\n }\n const allPostCode = allEmittedStatements.join('\\n');\n const missingDecorators: string[] = [];\n for (const dec of FIELD_DECORATORS) {\n if (allPostCode.includes(`type: ${dec}`) && !existingImports.has(dec)) {\n missingDecorators.push(dec);\n }\n }\n if (missingDecorators.length > 0) {\n ms.prepend(\n `import { ${missingDecorators.join(', ')} } from '@angular/core';\\n`,\n );\n }\n\n // Prepend JIT compiler imports\n if (needsJitImport) {\n ms.prepend(\n `import { ɵcompileComponent as _jitCompileComponent, ɵcompileDirective as _jitCompileDirective, ɵcompilePipe as _jitCompilePipe, ɵcompileNgModule as _jitCompileNgModule } from '@angular/core';\\n`,\n );\n }\n\n const map = ms.generateMap({\n source: fileName,\n file: fileName + '.js',\n includeContent: true,\n hires: 'boundary',\n });\n\n return { code: ms.toString(), map };\n}\n"],"mappings":"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"}
@@ -162,7 +162,7 @@ var OP_DEFINITIONS = [
162
162
  ]
163
163
  ];
164
164
  /** Operator integer values that represent assignment forms (`=`, `+=`, etc.). */
165
- var ASSIGNMENT_OP_NAMES = new Set([
165
+ var ASSIGNMENT_OP_NAMES = /* @__PURE__ */ new Set([
166
166
  "Assign",
167
167
  "AdditionAssignment",
168
168
  "SubtractionAssignment",
@@ -239,8 +239,6 @@ function emitReceiverForMemberAccess(receiver, emitted) {
239
239
  if (receiver instanceof o.LiteralExpr && typeof receiver.value === "number" && receiver.value >= 0) return "(" + emitted + ")";
240
240
  return emitted;
241
241
  }
242
- /** Polyfill for `__makeTemplateObject` used in downleveled `$localize` calls. */
243
- var MAKE_TEMPLATE_OBJECT_POLYFILL = "(this&&this.__makeTemplateObject||function(e,t){return Object.defineProperty?Object.defineProperty(e,\"raw\",{value:t}):e.raw=t,e})";
244
242
  var SINGLE_QUOTE_ESCAPE_RE = /[\\'\n\r]/g;
245
243
  /** Escape a string for use as a single-quoted string literal. */
246
244
  function escapeForLocalize(input) {
@@ -411,7 +409,7 @@ var JSEmitter = class JSEmitter {
411
409
  const cooked = parts.map((p) => escapeForLocalize(p.cooked)).join(", ");
412
410
  const raw = parts.map((p) => escapeForLocalize(p.raw)).join(", ");
413
411
  const exprs = ast.expressions.map((e) => this.emitExpr(e));
414
- return "$localize(" + MAKE_TEMPLATE_OBJECT_POLYFILL + "([" + cooked + "], [" + raw + "])" + (exprs.length > 0 ? ", " + exprs.join(", ") : "") + ")";
412
+ return "$localize((this&&this.__makeTemplateObject||function(e,t){return Object.defineProperty?Object.defineProperty(e,\"raw\",{value:t}):e.raw=t,e})([" + cooked + "], [" + raw + "])" + (exprs.length > 0 ? ", " + exprs.join(", ") : "") + ")";
415
413
  }
416
414
  visitRegularExpressionLiteral(ast) {
417
415
  return "/" + (ast.body ?? ast.pattern) + "/" + ast.flags;