@analogjs/vite-plugin-angular 3.0.0-alpha.36 → 3.0.0-alpha.38

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 (69) hide show
  1. package/README.md +22 -0
  2. package/package.json +3 -4
  3. package/src/lib/angular-jit-plugin.js +3 -0
  4. package/src/lib/angular-jit-plugin.js.map +1 -1
  5. package/src/lib/angular-vite-plugin.d.ts +12 -7
  6. package/src/lib/angular-vite-plugin.js +7 -5
  7. package/src/lib/angular-vite-plugin.js.map +1 -1
  8. package/src/lib/compiler/angular-version.d.ts +19 -0
  9. package/src/lib/compiler/angular-version.js +16 -0
  10. package/src/lib/compiler/angular-version.js.map +1 -0
  11. package/src/lib/compiler/class-field-lowering.d.ts +23 -0
  12. package/src/lib/compiler/class-field-lowering.js +131 -0
  13. package/src/lib/compiler/class-field-lowering.js.map +1 -0
  14. package/src/lib/compiler/compile.d.ts +44 -0
  15. package/src/lib/compiler/compile.js +731 -0
  16. package/src/lib/compiler/compile.js.map +1 -0
  17. package/src/lib/compiler/constants.d.ts +18 -0
  18. package/src/lib/compiler/constants.js +52 -0
  19. package/src/lib/compiler/constants.js.map +1 -0
  20. package/src/lib/compiler/debug.d.ts +22 -0
  21. package/src/lib/compiler/debug.js +20 -0
  22. package/src/lib/compiler/debug.js.map +1 -0
  23. package/src/lib/compiler/defer.d.ts +47 -0
  24. package/src/lib/compiler/defer.js +138 -0
  25. package/src/lib/compiler/defer.js.map +1 -0
  26. package/src/lib/compiler/dts-reader.d.ts +35 -0
  27. package/src/lib/compiler/dts-reader.js +365 -0
  28. package/src/lib/compiler/dts-reader.js.map +1 -0
  29. package/src/lib/compiler/hmr.d.ts +16 -0
  30. package/src/lib/compiler/hmr.js +69 -0
  31. package/src/lib/compiler/hmr.js.map +1 -0
  32. package/src/lib/compiler/index.d.ts +7 -0
  33. package/src/lib/compiler/index.js +7 -0
  34. package/src/lib/compiler/jit-metadata.d.ts +14 -0
  35. package/src/lib/compiler/jit-metadata.js +146 -0
  36. package/src/lib/compiler/jit-metadata.js.map +1 -0
  37. package/src/lib/compiler/jit-transform.d.ts +24 -0
  38. package/src/lib/compiler/jit-transform.js +200 -0
  39. package/src/lib/compiler/jit-transform.js.map +1 -0
  40. package/src/lib/compiler/js-emitter.d.ts +10 -0
  41. package/src/lib/compiler/js-emitter.js +420 -0
  42. package/src/lib/compiler/js-emitter.js.map +1 -0
  43. package/src/lib/compiler/metadata.d.ts +45 -0
  44. package/src/lib/compiler/metadata.js +633 -0
  45. package/src/lib/compiler/metadata.js.map +1 -0
  46. package/src/lib/compiler/registry.d.ts +49 -0
  47. package/src/lib/compiler/registry.js +164 -0
  48. package/src/lib/compiler/registry.js.map +1 -0
  49. package/src/lib/compiler/resource-inliner.d.ts +21 -0
  50. package/src/lib/compiler/resource-inliner.js +152 -0
  51. package/src/lib/compiler/resource-inliner.js.map +1 -0
  52. package/src/lib/compiler/style-ast.d.ts +8 -0
  53. package/src/lib/compiler/style-ast.js +54 -0
  54. package/src/lib/compiler/style-ast.js.map +1 -0
  55. package/src/lib/compiler/styles.d.ts +13 -0
  56. package/src/lib/compiler/test-helpers.d.ts +7 -0
  57. package/src/lib/compiler/type-elision.d.ts +26 -0
  58. package/src/lib/compiler/type-elision.js +211 -0
  59. package/src/lib/compiler/type-elision.js.map +1 -0
  60. package/src/lib/compiler/utils.d.ts +10 -0
  61. package/src/lib/compiler/utils.js +35 -0
  62. package/src/lib/compiler/utils.js.map +1 -0
  63. package/src/lib/{analog-compiler-plugin.d.ts → fast-compile-plugin.d.ts} +3 -3
  64. package/src/lib/{analog-compiler-plugin.js → fast-compile-plugin.js} +46 -33
  65. package/src/lib/fast-compile-plugin.js.map +1 -0
  66. package/src/lib/utils/virtual-resources.d.ts +16 -0
  67. package/src/lib/utils/virtual-resources.js +31 -2
  68. package/src/lib/utils/virtual-resources.js.map +1 -1
  69. package/src/lib/analog-compiler-plugin.js.map +0 -1
@@ -0,0 +1,19 @@
1
+ /**
2
+ * The major version of the installed `@angular/compiler` package, parsed
3
+ * from `o.VERSION.major`. Falls back to `DEFAULT_ASSUMED_MAJOR` when the
4
+ * version is unavailable.
5
+ */
6
+ export declare const ANGULAR_MAJOR: number;
7
+ /**
8
+ * Returns `true` when the installed Angular major is at least `major`.
9
+ * Use this to gate code paths that depend on APIs introduced in a
10
+ * specific Angular release.
11
+ *
12
+ * @example
13
+ * if (angularVersionAtLeast(21)) {
14
+ * // Use Angular 21+ API
15
+ * } else {
16
+ * // Fall back to v19/v20 behavior
17
+ * }
18
+ */
19
+ export declare function angularVersionAtLeast(major: number): boolean;
@@ -0,0 +1,16 @@
1
+ import * as o from "@angular/compiler";
2
+ //#region packages/vite-plugin-angular/src/lib/compiler/angular-version.ts
3
+ var DEFAULT_ASSUMED_MAJOR = 22;
4
+ /**
5
+ * The major version of the installed `@angular/compiler` package, parsed
6
+ * from `o.VERSION.major`. Falls back to `DEFAULT_ASSUMED_MAJOR` when the
7
+ * version is unavailable.
8
+ */
9
+ var ANGULAR_MAJOR = (() => {
10
+ const major = Number.parseInt(o.VERSION?.major ?? "", 10);
11
+ return Number.isFinite(major) && major > 0 ? major : DEFAULT_ASSUMED_MAJOR;
12
+ })();
13
+ //#endregion
14
+ export { ANGULAR_MAJOR };
15
+
16
+ //# sourceMappingURL=angular-version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"angular-version.js","names":[],"sources":["../../../../src/lib/compiler/angular-version.ts"],"sourcesContent":["import * as o from '@angular/compiler';\n\n// Detect the installed @angular/compiler major version once at module load\n// time and expose helpers for version-aware code paths.\n//\n// Why this matters: Angular's compiler API surface (enum members,\n// metadata shapes, output formats) shifts between major versions in ways\n// that can't always be papered over with duck typing. The compatibility\n// matrix in .github/workflows/compiler-compat.yml runs the test\n// suite against multiple installed versions to catch this drift, and the\n// version-aware code paths in compile.ts / js-emitter.ts / metadata.ts\n// gate behavior on `ANGULAR_MAJOR` to keep the compiler working across\n// the supported `peerDependencies` range (currently >=19.0.0).\n//\n// Default fallback: when the version string is missing or unparseable\n// (vendored builds, monkey-patched test environments), assume the latest\n// known major. This biases toward the most-tested code path.\nconst DEFAULT_ASSUMED_MAJOR = 22;\n\n/**\n * The major version of the installed `@angular/compiler` package, parsed\n * from `o.VERSION.major`. Falls back to `DEFAULT_ASSUMED_MAJOR` when the\n * version is unavailable.\n */\nexport const ANGULAR_MAJOR: number = (() => {\n const major = Number.parseInt(o.VERSION?.major ?? '', 10);\n return Number.isFinite(major) && major > 0 ? major : DEFAULT_ASSUMED_MAJOR;\n})();\n\n/**\n * Returns `true` when the installed Angular major is at least `major`.\n * Use this to gate code paths that depend on APIs introduced in a\n * specific Angular release.\n *\n * @example\n * if (angularVersionAtLeast(21)) {\n * // Use Angular 21+ API\n * } else {\n * // Fall back to v19/v20 behavior\n * }\n */\nexport function angularVersionAtLeast(major: number): boolean {\n return ANGULAR_MAJOR >= major;\n}\n"],"mappings":";;AAiBA,IAAM,wBAAwB;;;;;;AAO9B,IAAa,uBAA+B;CAC1C,MAAM,QAAQ,OAAO,SAAS,EAAE,SAAS,SAAS,IAAI,GAAG;AACzD,QAAO,OAAO,SAAS,MAAM,IAAI,QAAQ,IAAI,QAAQ;IACnD"}
@@ -0,0 +1,23 @@
1
+ import MagicString from "magic-string";
2
+ /**
3
+ * Lower instance class field initializers into constructor assignments.
4
+ *
5
+ * When `useDefineForClassFields` is `false` (the standard Angular tsconfig),
6
+ * field initializers must run as assignments inside the constructor body
7
+ * rather than as native ES class field initializers. This ensures:
8
+ *
9
+ * 1. `inject()` calls in fields have an active injection context
10
+ * 2. Fields referencing other injected fields work (sequential assignment)
11
+ * 3. Constructor parameter properties are available to field initializers
12
+ * 4. Inheritance works (parent constructor runs before child field assignments)
13
+ *
14
+ * Rules:
15
+ * - Regular fields with initializers: remove declaration, add `this.field = value;`
16
+ * - Private fields (`#field`) with initializers: keep `#field;` declaration, add `this.#field = value;`
17
+ * - Static fields: not lowered
18
+ * - Fields without initializers: not lowered
19
+ * - `declare` fields: not lowered
20
+ * - Assignments are inserted after `super()` (if present), before existing constructor body
21
+ * - If no constructor exists, one is created (with `super(...args)` for subclasses)
22
+ */
23
+ export declare function lowerClassFields(ms: MagicString, sourceCode: string, oxcProgram: any): void;
@@ -0,0 +1,131 @@
1
+ //#region packages/vite-plugin-angular/src/lib/compiler/class-field-lowering.ts
2
+ /**
3
+ * Lower instance class field initializers into constructor assignments.
4
+ *
5
+ * When `useDefineForClassFields` is `false` (the standard Angular tsconfig),
6
+ * field initializers must run as assignments inside the constructor body
7
+ * rather than as native ES class field initializers. This ensures:
8
+ *
9
+ * 1. `inject()` calls in fields have an active injection context
10
+ * 2. Fields referencing other injected fields work (sequential assignment)
11
+ * 3. Constructor parameter properties are available to field initializers
12
+ * 4. Inheritance works (parent constructor runs before child field assignments)
13
+ *
14
+ * Rules:
15
+ * - Regular fields with initializers: remove declaration, add `this.field = value;`
16
+ * - Private fields (`#field`) with initializers: keep `#field;` declaration, add `this.#field = value;`
17
+ * - Static fields: not lowered
18
+ * - Fields without initializers: not lowered
19
+ * - `declare` fields: not lowered
20
+ * - Assignments are inserted after `super()` (if present), before existing constructor body
21
+ * - If no constructor exists, one is created (with `super(...args)` for subclasses)
22
+ */
23
+ function lowerClassFields(ms, sourceCode, oxcProgram) {
24
+ for (const stmt of oxcProgram.body) {
25
+ const decl = stmt.type === "ExportNamedDeclaration" || stmt.type === "ExportDefaultDeclaration" ? stmt.declaration : stmt;
26
+ if (!decl || decl.type !== "ClassDeclaration" && decl.type !== "ClassExpression" || !decl.body) continue;
27
+ lowerClassFieldsForClass(ms, sourceCode, decl);
28
+ }
29
+ }
30
+ function lowerClassFieldsForClass(ms, sourceCode, classNode) {
31
+ const body = classNode.body;
32
+ const members = body.body;
33
+ const fieldsToLower = [];
34
+ for (const member of members) {
35
+ if (!shouldLowerField(member)) continue;
36
+ const accessor = getFieldAccessor(member, sourceCode);
37
+ const initializer = sourceCode.slice(member.value.start, member.value.end);
38
+ fieldsToLower.push({
39
+ node: member,
40
+ accessor,
41
+ initializer,
42
+ isPrivate: member.type === "PropertyDefinition" && member.key?.type === "PrivateIdentifier"
43
+ });
44
+ }
45
+ if (fieldsToLower.length === 0) return;
46
+ const assignments = fieldsToLower.map((f) => ` this${f.accessor} = ${f.initializer};`);
47
+ const ctor = members.find((m) => m.type === "MethodDefinition" && m.kind === "constructor");
48
+ const hasSuperClass = !!classNode.superClass;
49
+ if (ctor) insertIntoExistingConstructor(ms, sourceCode, ctor, assignments);
50
+ else createConstructorWithAssignments(ms, sourceCode, body, members, assignments, hasSuperClass);
51
+ for (const field of fieldsToLower) if (field.isPrivate) {
52
+ const eqStart = findEqualsSign(sourceCode, field.node.typeAnnotation ? field.node.typeAnnotation.end : field.node.key.end, field.node.value.start);
53
+ ms.remove(eqStart, field.node.value.end);
54
+ } else {
55
+ let end = field.node.end;
56
+ const nextChar = sourceCode[end];
57
+ const charAfterNewline = nextChar === "\n" ? sourceCode[end + 1] : nextChar === "\r" && sourceCode[end + 1] === "\n" ? sourceCode[end + 2] : null;
58
+ if (charAfterNewline !== null && charAfterNewline !== "}") {
59
+ if (nextChar === "\n") end++;
60
+ else if (nextChar === "\r" && sourceCode[end + 1] === "\n") end += 2;
61
+ }
62
+ ms.remove(field.node.start, end);
63
+ }
64
+ }
65
+ function shouldLowerField(member) {
66
+ if (member.type !== "PropertyDefinition") return false;
67
+ if (!member.value) return false;
68
+ if (member.static) return false;
69
+ if (member.declare) return false;
70
+ return true;
71
+ }
72
+ /**
73
+ * Build the member-access expression to append after `this` for a class field
74
+ * being lowered. Returns the accessor with its leading punctuation:
75
+ *
76
+ * - `.name` — non-computed identifier key
77
+ * - `.#priv` — private identifier key
78
+ * - `[expr]` — computed key (square brackets in source)
79
+ * - `['some-key']` — string literal key
80
+ * - `[123]` — numeric literal key
81
+ *
82
+ * Without this, fields with non-identifier keys produced invalid syntax like
83
+ * `this.'some-key' = …` which OXC parses as "Cannot assign to this expression".
84
+ */
85
+ function getFieldAccessor(member, sourceCode) {
86
+ const key = member.key;
87
+ if (key.type === "PrivateIdentifier") return ".#" + key.name;
88
+ if (member.computed) return "[" + sourceCode.slice(key.start, key.end) + "]";
89
+ if (key.type === "Identifier") return "." + key.name;
90
+ if (key.type === "StringLiteral" || key.type === "Literal" && typeof key.value === "string") return "[" + JSON.stringify(key.value) + "]";
91
+ if (key.type === "NumericLiteral" || key.type === "Literal" && typeof key.value === "number") return "[" + key.value + "]";
92
+ return "[" + sourceCode.slice(key.start, key.end) + "]";
93
+ }
94
+ function findEqualsSign(sourceCode, from, to) {
95
+ for (let i = from; i < to; i++) if (sourceCode[i] === "=") return i;
96
+ return from;
97
+ }
98
+ function insertIntoExistingConstructor(ms, sourceCode, ctor, assignments) {
99
+ const ctorBody = ctor.value.body;
100
+ if (!ctorBody) return;
101
+ const bodyStatements = ctorBody.body;
102
+ const assignmentBlock = "\n" + assignments.join("\n");
103
+ let insertPos = null;
104
+ for (const stmt of bodyStatements) if (isSuperCall(stmt)) {
105
+ insertPos = stmt.end;
106
+ break;
107
+ }
108
+ if (insertPos !== null) ms.appendRight(insertPos, assignmentBlock);
109
+ else if (bodyStatements.length > 0) ms.appendRight(bodyStatements[0].start, assignments.join("\n") + "\n ");
110
+ else ms.appendRight(ctorBody.start + 1, assignmentBlock + "\n ");
111
+ }
112
+ function createConstructorWithAssignments(ms, sourceCode, classBody, members, assignments, hasSuperClass) {
113
+ const superCall = hasSuperClass ? " super(...args);\n" : "";
114
+ const ctorCode = [
115
+ ` constructor(${hasSuperClass ? "...args" : ""}) {`,
116
+ superCall ? superCall.trimEnd() : null,
117
+ ...assignments,
118
+ " }"
119
+ ].filter((l) => l !== null).join("\n");
120
+ ms.appendRight(classBody.start + 1, "\n" + ctorCode + "\n");
121
+ }
122
+ function isSuperCall(stmt) {
123
+ if (stmt.type !== "ExpressionStatement") return false;
124
+ const expr = stmt.expression;
125
+ if (expr.type !== "CallExpression") return false;
126
+ return expr.callee?.type === "Super";
127
+ }
128
+ //#endregion
129
+ export { lowerClassFields };
130
+
131
+ //# sourceMappingURL=class-field-lowering.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"class-field-lowering.js","names":[],"sources":["../../../../src/lib/compiler/class-field-lowering.ts"],"sourcesContent":["import MagicString from 'magic-string';\n\n/**\n * Lower instance class field initializers into constructor assignments.\n *\n * When `useDefineForClassFields` is `false` (the standard Angular tsconfig),\n * field initializers must run as assignments inside the constructor body\n * rather than as native ES class field initializers. This ensures:\n *\n * 1. `inject()` calls in fields have an active injection context\n * 2. Fields referencing other injected fields work (sequential assignment)\n * 3. Constructor parameter properties are available to field initializers\n * 4. Inheritance works (parent constructor runs before child field assignments)\n *\n * Rules:\n * - Regular fields with initializers: remove declaration, add `this.field = value;`\n * - Private fields (`#field`) with initializers: keep `#field;` declaration, add `this.#field = value;`\n * - Static fields: not lowered\n * - Fields without initializers: not lowered\n * - `declare` fields: not lowered\n * - Assignments are inserted after `super()` (if present), before existing constructor body\n * - If no constructor exists, one is created (with `super(...args)` for subclasses)\n */\nexport function lowerClassFields(\n ms: MagicString,\n sourceCode: string,\n oxcProgram: any,\n): void {\n for (const stmt of oxcProgram.body) {\n const decl =\n stmt.type === 'ExportNamedDeclaration' ||\n stmt.type === 'ExportDefaultDeclaration'\n ? (stmt as any).declaration\n : stmt;\n\n if (\n !decl ||\n (decl.type !== 'ClassDeclaration' && decl.type !== 'ClassExpression') ||\n !decl.body\n ) {\n continue;\n }\n\n lowerClassFieldsForClass(ms, sourceCode, decl);\n }\n}\n\ninterface FieldToLower {\n /** The full property definition node */\n node: any;\n /** The member access expression to append after `this`, e.g. `.name`, `.#priv`, `[expr]`, `['some-key']`, `[123]` */\n accessor: string;\n /** The initializer source text */\n initializer: string;\n /** Whether this is a private field (#field) */\n isPrivate: boolean;\n}\n\nfunction lowerClassFieldsForClass(\n ms: MagicString,\n sourceCode: string,\n classNode: any,\n): void {\n const body = classNode.body;\n const members: any[] = body.body;\n const fieldsToLower: FieldToLower[] = [];\n\n for (const member of members) {\n if (!shouldLowerField(member)) continue;\n\n const accessor = getFieldAccessor(member, sourceCode);\n const initializer = sourceCode.slice(member.value.start, member.value.end);\n\n fieldsToLower.push({\n node: member,\n accessor,\n initializer,\n isPrivate:\n member.type === 'PropertyDefinition' &&\n member.key?.type === 'PrivateIdentifier',\n });\n }\n\n if (fieldsToLower.length === 0) return;\n\n // Build assignment statements\n const assignments = fieldsToLower.map(\n (f) => ` this${f.accessor} = ${f.initializer};`,\n );\n\n // Find existing constructor\n const ctor = members.find(\n (m: any) => m.type === 'MethodDefinition' && m.kind === 'constructor',\n );\n\n // Check if class has a superclass\n const hasSuperClass = !!classNode.superClass;\n\n if (ctor) {\n insertIntoExistingConstructor(ms, sourceCode, ctor, assignments);\n } else {\n createConstructorWithAssignments(\n ms,\n sourceCode,\n body,\n members,\n assignments,\n hasSuperClass,\n );\n }\n\n // Remove or strip field declarations\n for (const field of fieldsToLower) {\n if (field.isPrivate) {\n // Keep declaration without initializer: `#field;`\n // Start scanning after the type annotation (if present) to avoid\n // matching `=` inside `=>` of arrow function type annotations.\n const scanFrom = field.node.typeAnnotation\n ? field.node.typeAnnotation.end\n : field.node.key.end;\n const eqStart = findEqualsSign(\n sourceCode,\n scanFrom,\n field.node.value.start,\n );\n ms.remove(eqStart, field.node.value.end);\n } else {\n // Remove the field declaration. Include the trailing newline to avoid\n // leaving blank lines, BUT only if the character after the newline isn't\n // the closing `}` of the class. Otherwise the removal range ends at the\n // same position where Ivy static definitions are appendLeft-inserted,\n // and MagicString consumes those insertions as part of the removed range.\n let end = field.node.end;\n const nextChar = sourceCode[end];\n const charAfterNewline =\n nextChar === '\\n'\n ? sourceCode[end + 1]\n : nextChar === '\\r' && sourceCode[end + 1] === '\\n'\n ? sourceCode[end + 2]\n : null;\n // Only consume newline(s) when the next non-whitespace char is not `}`\n const safeToConsumeNewline =\n charAfterNewline !== null && charAfterNewline !== '}';\n if (safeToConsumeNewline) {\n if (nextChar === '\\n') end++;\n else if (nextChar === '\\r' && sourceCode[end + 1] === '\\n') end += 2;\n }\n ms.remove(field.node.start, end);\n }\n }\n}\n\nfunction shouldLowerField(member: any): boolean {\n // Must be a PropertyDefinition with an initializer (value)\n if (member.type !== 'PropertyDefinition') return false;\n if (!member.value) return false;\n // Don't lower static fields\n if (member.static) return false;\n // Don't lower declare fields\n if (member.declare) return false;\n\n return true;\n}\n\n/**\n * Build the member-access expression to append after `this` for a class field\n * being lowered. Returns the accessor with its leading punctuation:\n *\n * - `.name` — non-computed identifier key\n * - `.#priv` — private identifier key\n * - `[expr]` — computed key (square brackets in source)\n * - `['some-key']` — string literal key\n * - `[123]` — numeric literal key\n *\n * Without this, fields with non-identifier keys produced invalid syntax like\n * `this.'some-key' = …` which OXC parses as \"Cannot assign to this expression\".\n */\nfunction getFieldAccessor(member: any, sourceCode: string): string {\n const key = member.key;\n if (key.type === 'PrivateIdentifier') {\n return '.#' + key.name;\n }\n // Computed key: `[expr] = value` → `this[expr] = value`\n // OXC marks the parent PropertyDefinition with `computed: true`.\n if (member.computed) {\n return '[' + sourceCode.slice(key.start, key.end) + ']';\n }\n if (key.type === 'Identifier') {\n return '.' + key.name;\n }\n // String literal key: `'some-key' = value` → `this['some-key'] = value`\n if (\n key.type === 'StringLiteral' ||\n (key.type === 'Literal' && typeof key.value === 'string')\n ) {\n return '[' + JSON.stringify(key.value) + ']';\n }\n // Numeric literal key: `123 = value` → `this[123] = value`\n if (\n key.type === 'NumericLiteral' ||\n (key.type === 'Literal' && typeof key.value === 'number')\n ) {\n return '[' + key.value + ']';\n }\n // Fallback: bracket-access with the original source text\n return '[' + sourceCode.slice(key.start, key.end) + ']';\n}\n\nfunction findEqualsSign(sourceCode: string, from: number, to: number): number {\n for (let i = from; i < to; i++) {\n if (sourceCode[i] === '=') return i;\n }\n return from;\n}\n\nfunction insertIntoExistingConstructor(\n ms: MagicString,\n sourceCode: string,\n ctor: any,\n assignments: string[],\n): void {\n const ctorBody = ctor.value.body;\n if (!ctorBody) return;\n\n const bodyStatements: any[] = ctorBody.body;\n const assignmentBlock = '\\n' + assignments.join('\\n');\n\n // Find the position after super() call (if any)\n let insertPos: number | null = null;\n for (const stmt of bodyStatements) {\n if (isSuperCall(stmt)) {\n // Insert after super() statement including its semicolon\n insertPos = stmt.end;\n break;\n }\n }\n\n if (insertPos !== null) {\n ms.appendRight(insertPos, assignmentBlock);\n } else if (bodyStatements.length > 0) {\n // Insert before the first statement\n ms.appendRight(bodyStatements[0].start, assignments.join('\\n') + '\\n ');\n } else {\n // Empty constructor body — insert after opening {\n ms.appendRight(ctorBody.start + 1, assignmentBlock + '\\n ');\n }\n}\n\nfunction createConstructorWithAssignments(\n ms: MagicString,\n sourceCode: string,\n classBody: any,\n members: any[],\n assignments: string[],\n hasSuperClass: boolean,\n): void {\n const superCall = hasSuperClass ? ' super(...args);\\n' : '';\n const args = hasSuperClass ? '...args' : '';\n const ctorCode = [\n ` constructor(${args}) {`,\n superCall ? superCall.trimEnd() : null,\n ...assignments,\n ' }',\n ]\n .filter((l) => l !== null)\n .join('\\n');\n\n // Insert constructor at the beginning of the class body (after opening {)\n ms.appendRight(classBody.start + 1, '\\n' + ctorCode + '\\n');\n}\n\nfunction isSuperCall(stmt: any): boolean {\n if (stmt.type !== 'ExpressionStatement') return false;\n const expr = stmt.expression;\n if (expr.type !== 'CallExpression') return false;\n return expr.callee?.type === 'Super';\n}\n"],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ import MagicString from "magic-string";
2
+ import { ComponentRegistry } from "./registry.js";
3
+ /**
4
+ * COMPLETE EXHAUSTIVE ANGULAR LITE COMPILER
5
+ * Translates Angular Decorators + Signals to Ivy Static Definitions.
6
+ *
7
+ * @param registry - Optional external registry from the global analysis plugin.
8
+ * When provided, used to resolve component/directive selectors for template compilation.
9
+ */
10
+ export interface CompileResult {
11
+ code: string;
12
+ /** Source map for the transformation */
13
+ map: ReturnType<MagicString["generateMap"]>;
14
+ /** Absolute paths of external resources (templateUrl, styleUrl) read during compilation */
15
+ resourceDependencies: string[];
16
+ }
17
+ export interface CompileOptions {
18
+ registry?: ComponentRegistry;
19
+ /** Pre-resolved style contents keyed by absolute file path (e.g. SCSS already compiled to CSS). */
20
+ resolvedStyles?: Map<string, string>;
21
+ /** Pre-processed inline styles (index in styles array → compiled CSS). */
22
+ resolvedInlineStyles?: Map<number, string>;
23
+ /**
24
+ * When `false` (default), instance class field initializers are lowered to
25
+ * constructor assignments (matching TypeScript's `useDefineForClassFields: false`
26
+ * behavior). This is required for Angular's `inject()` and constructor DI to
27
+ * work correctly with the standard Angular tsconfig.
28
+ */
29
+ useDefineForClassFields?: boolean;
30
+ /** Enable legacy i18n message ID format (default: true). */
31
+ enableI18nLegacyMessageIdFormat?: boolean;
32
+ /** Normalize line endings in ICU expressions (default: true). */
33
+ i18nNormalizeLineEndingsInICUs?: boolean;
34
+ /** Use external IDs in `$localize` calls (for Closure Compiler compatibility). */
35
+ i18nUseExternalIds?: boolean;
36
+ /**
37
+ * Compilation output mode.
38
+ * - `'full'` (default): Emit final Ivy definitions (`ɵɵdefineComponent`) for application builds.
39
+ * - `'partial'`: Emit partial declarations (`ɵɵngDeclareComponent`) for library publishing.
40
+ * Partial output is version-stable and linked at application build time.
41
+ */
42
+ compilationMode?: "full" | "partial";
43
+ }
44
+ export declare function compile(sourceCode: string, fileName: string, optionsOrRegistry?: CompileOptions | ComponentRegistry): CompileResult;