@analogjs/vite-plugin-angular 3.0.0-alpha.5 → 3.0.0-alpha.50

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 (194) hide show
  1. package/README.md +30 -0
  2. package/migrations/migrate-setup-vitest/migrate-setup-vitest.d.ts +2 -0
  3. package/migrations/migrate-setup-vitest/migrate-setup-vitest.js +49 -0
  4. package/migrations/migrate-setup-vitest/migrate-setup-vitest.js.map +1 -0
  5. package/migrations/migration.json +7 -1
  6. package/migrations/migrations.json +9 -0
  7. package/migrations/update-3-0-0/migrate-setup-vitest.d.ts +2 -0
  8. package/migrations/update-3-0-0/migrate-setup-vitest.js +36 -0
  9. package/migrations/update-3-0-0/migrate-setup-vitest.js.map +1 -0
  10. package/package.json +41 -12
  11. package/src/index.d.ts +3 -2
  12. package/src/index.js +6 -2
  13. package/src/index.js.map +1 -1
  14. package/src/lib/angular-build-optimizer-plugin.d.ts +4 -4
  15. package/src/lib/angular-build-optimizer-plugin.js +48 -62
  16. package/src/lib/angular-build-optimizer-plugin.js.map +1 -1
  17. package/src/lib/angular-jit-plugin.d.ts +3 -3
  18. package/src/lib/angular-jit-plugin.js +39 -37
  19. package/src/lib/angular-jit-plugin.js.map +1 -1
  20. package/src/lib/angular-pending-tasks.plugin.d.ts +7 -7
  21. package/src/lib/angular-pending-tasks.plugin.js +17 -18
  22. package/src/lib/angular-pending-tasks.plugin.js.map +1 -1
  23. package/src/lib/angular-vite-plugin.d.ts +180 -44
  24. package/src/lib/angular-vite-plugin.js +1233 -969
  25. package/src/lib/angular-vite-plugin.js.map +1 -1
  26. package/src/lib/angular-vitest-plugin.d.ts +19 -15
  27. package/src/lib/angular-vitest-plugin.js +99 -114
  28. package/src/lib/angular-vitest-plugin.js.map +1 -1
  29. package/src/lib/compilation-api/compilation-api-plugin.d.ts +29 -0
  30. package/src/lib/compilation-api/compilation-api-plugin.js +469 -0
  31. package/src/lib/compilation-api/compilation-api-plugin.js.map +1 -0
  32. package/src/lib/compilation-api/index.d.ts +1 -0
  33. package/src/lib/compilation-api/index.js +1 -0
  34. package/src/lib/compiler/angular-version.d.ts +19 -0
  35. package/src/lib/compiler/angular-version.js +16 -0
  36. package/src/lib/compiler/angular-version.js.map +1 -0
  37. package/src/lib/compiler/class-field-lowering.d.ts +23 -0
  38. package/src/lib/compiler/class-field-lowering.js +131 -0
  39. package/src/lib/compiler/class-field-lowering.js.map +1 -0
  40. package/src/lib/compiler/compile.d.ts +44 -0
  41. package/src/lib/compiler/compile.js +731 -0
  42. package/src/lib/compiler/compile.js.map +1 -0
  43. package/src/lib/compiler/constants.d.ts +18 -0
  44. package/src/lib/compiler/constants.js +52 -0
  45. package/src/lib/compiler/constants.js.map +1 -0
  46. package/src/lib/compiler/debug.d.ts +22 -0
  47. package/src/lib/compiler/debug.js +20 -0
  48. package/src/lib/compiler/debug.js.map +1 -0
  49. package/src/lib/compiler/defer.d.ts +57 -0
  50. package/src/lib/compiler/defer.js +154 -0
  51. package/src/lib/compiler/defer.js.map +1 -0
  52. package/src/lib/compiler/dts-reader.d.ts +35 -0
  53. package/src/lib/compiler/dts-reader.js +365 -0
  54. package/src/lib/compiler/dts-reader.js.map +1 -0
  55. package/src/lib/compiler/hmr.d.ts +16 -0
  56. package/src/lib/compiler/hmr.js +69 -0
  57. package/src/lib/compiler/hmr.js.map +1 -0
  58. package/src/lib/compiler/index.d.ts +7 -0
  59. package/src/lib/compiler/index.js +7 -0
  60. package/src/lib/compiler/jit-metadata.d.ts +14 -0
  61. package/src/lib/compiler/jit-metadata.js +146 -0
  62. package/src/lib/compiler/jit-metadata.js.map +1 -0
  63. package/src/lib/compiler/jit-transform.d.ts +24 -0
  64. package/src/lib/compiler/jit-transform.js +200 -0
  65. package/src/lib/compiler/jit-transform.js.map +1 -0
  66. package/src/lib/compiler/js-emitter.d.ts +10 -0
  67. package/src/lib/compiler/js-emitter.js +445 -0
  68. package/src/lib/compiler/js-emitter.js.map +1 -0
  69. package/src/lib/compiler/metadata.d.ts +45 -0
  70. package/src/lib/compiler/metadata.js +633 -0
  71. package/src/lib/compiler/metadata.js.map +1 -0
  72. package/src/lib/compiler/registry.d.ts +49 -0
  73. package/src/lib/compiler/registry.js +164 -0
  74. package/src/lib/compiler/registry.js.map +1 -0
  75. package/src/lib/compiler/resource-inliner.d.ts +21 -0
  76. package/src/lib/compiler/resource-inliner.js +152 -0
  77. package/src/lib/compiler/resource-inliner.js.map +1 -0
  78. package/src/lib/compiler/style-ast.d.ts +8 -0
  79. package/src/lib/compiler/style-ast.js +54 -0
  80. package/src/lib/compiler/style-ast.js.map +1 -0
  81. package/src/lib/compiler/styles.d.ts +13 -0
  82. package/src/lib/compiler/test-helpers.d.ts +7 -0
  83. package/src/lib/compiler/type-elision.d.ts +26 -0
  84. package/src/lib/compiler/type-elision.js +211 -0
  85. package/src/lib/compiler/type-elision.js.map +1 -0
  86. package/src/lib/compiler/utils.d.ts +10 -0
  87. package/src/lib/compiler/utils.js +35 -0
  88. package/src/lib/compiler/utils.js.map +1 -0
  89. package/src/lib/compiler-plugin.d.ts +11 -11
  90. package/src/lib/compiler-plugin.js +43 -44
  91. package/src/lib/compiler-plugin.js.map +1 -1
  92. package/src/lib/component-resolvers.d.ts +23 -5
  93. package/src/lib/component-resolvers.js +153 -63
  94. package/src/lib/component-resolvers.js.map +1 -1
  95. package/src/lib/encapsulation-plugin.d.ts +13 -0
  96. package/src/lib/encapsulation-plugin.js +48 -0
  97. package/src/lib/encapsulation-plugin.js.map +1 -0
  98. package/src/lib/fast-compile-plugin.d.ts +28 -0
  99. package/src/lib/fast-compile-plugin.js +289 -0
  100. package/src/lib/fast-compile-plugin.js.map +1 -0
  101. package/src/lib/host.d.ts +10 -8
  102. package/src/lib/host.js +113 -101
  103. package/src/lib/host.js.map +1 -1
  104. package/src/lib/live-reload-plugin.d.ts +5 -5
  105. package/src/lib/live-reload-plugin.js +61 -62
  106. package/src/lib/live-reload-plugin.js.map +1 -1
  107. package/src/lib/models.d.ts +9 -9
  108. package/src/lib/nx-folder-plugin.d.ts +5 -5
  109. package/src/lib/nx-folder-plugin.js +18 -16
  110. package/src/lib/nx-folder-plugin.js.map +1 -1
  111. package/src/lib/plugins/file-replacements.plugin.d.ts +4 -4
  112. package/src/lib/plugins/file-replacements.plugin.js +40 -62
  113. package/src/lib/plugins/file-replacements.plugin.js.map +1 -1
  114. package/src/lib/router-plugin.d.ts +1 -1
  115. package/src/lib/router-plugin.js +23 -23
  116. package/src/lib/router-plugin.js.map +1 -1
  117. package/src/lib/style-pipeline.d.ts +15 -0
  118. package/src/lib/style-pipeline.js +31 -0
  119. package/src/lib/style-pipeline.js.map +1 -0
  120. package/src/lib/style-preprocessor.d.ts +35 -0
  121. package/src/lib/style-preprocessor.js +35 -0
  122. package/src/lib/style-preprocessor.js.map +1 -0
  123. package/src/lib/stylesheet-registry.d.ts +73 -0
  124. package/src/lib/stylesheet-registry.js +168 -0
  125. package/src/lib/stylesheet-registry.js.map +1 -0
  126. package/src/lib/tailwind-plugin.d.ts +34 -0
  127. package/src/lib/tailwind-plugin.js +116 -0
  128. package/src/lib/tailwind-plugin.js.map +1 -0
  129. package/src/lib/template-class-binding-guard-plugin.d.ts +30 -0
  130. package/src/lib/template-class-binding-guard-plugin.js +237 -0
  131. package/src/lib/template-class-binding-guard-plugin.js.map +1 -0
  132. package/src/lib/tools/package.json +2 -7
  133. package/src/lib/tools/src/builders/vite/vite-build.impl.js +31 -38
  134. package/src/lib/tools/src/builders/vite/vite-build.impl.js.map +1 -1
  135. package/src/lib/tools/src/builders/vite-dev-server/dev-server.impl.js +51 -62
  136. package/src/lib/tools/src/builders/vite-dev-server/dev-server.impl.js.map +1 -1
  137. package/src/lib/tools/src/index.js +0 -2
  138. package/src/lib/utils/compilation-shared.d.ts +58 -0
  139. package/src/lib/utils/compilation-shared.js +133 -0
  140. package/src/lib/utils/compilation-shared.js.map +1 -0
  141. package/src/lib/utils/compiler-plugin-options.d.ts +11 -11
  142. package/src/lib/utils/debug-harness.d.ts +23 -0
  143. package/src/lib/utils/debug-harness.js +88 -0
  144. package/src/lib/utils/debug-harness.js.map +1 -0
  145. package/src/lib/utils/debug-log-file.d.ts +5 -0
  146. package/src/lib/utils/debug-log-file.js +56 -0
  147. package/src/lib/utils/debug-log-file.js.map +1 -0
  148. package/src/lib/utils/debug.d.ts +28 -0
  149. package/src/lib/utils/debug.js +39 -0
  150. package/src/lib/utils/debug.js.map +1 -0
  151. package/src/lib/utils/devkit.d.ts +6 -6
  152. package/src/lib/utils/devkit.js +34 -38
  153. package/src/lib/utils/devkit.js.map +1 -1
  154. package/src/lib/utils/hmr-candidates.d.ts +28 -28
  155. package/src/lib/utils/plugin-config.d.ts +37 -0
  156. package/src/lib/utils/plugin-config.js +71 -0
  157. package/src/lib/utils/plugin-config.js.map +1 -0
  158. package/src/lib/utils/rolldown.d.ts +2 -0
  159. package/src/lib/utils/rolldown.js +12 -0
  160. package/src/lib/utils/rolldown.js.map +1 -0
  161. package/src/lib/utils/safe-module-paths.d.ts +16 -0
  162. package/src/lib/utils/safe-module-paths.js +29 -0
  163. package/src/lib/utils/safe-module-paths.js.map +1 -0
  164. package/src/lib/utils/source-file-cache.d.ts +8 -15
  165. package/src/lib/utils/source-file-cache.js +35 -37
  166. package/src/lib/utils/source-file-cache.js.map +1 -1
  167. package/src/lib/utils/tailwind-reference.d.ts +12 -0
  168. package/src/lib/utils/tailwind-reference.js +99 -0
  169. package/src/lib/utils/tailwind-reference.js.map +1 -0
  170. package/src/lib/utils/tsconfig-resolver.d.ts +28 -0
  171. package/src/lib/utils/tsconfig-resolver.js +191 -0
  172. package/src/lib/utils/tsconfig-resolver.js.map +1 -0
  173. package/src/lib/utils/virtual-ids.d.ts +4 -0
  174. package/src/lib/utils/virtual-ids.js +23 -0
  175. package/src/lib/utils/virtual-ids.js.map +1 -0
  176. package/src/lib/utils/virtual-resources.d.ts +19 -0
  177. package/src/lib/utils/virtual-resources.js +38 -0
  178. package/src/lib/utils/virtual-resources.js.map +1 -0
  179. package/src/lib/virtual-modules-plugin.d.ts +5 -0
  180. package/src/lib/virtual-modules-plugin.js +23 -0
  181. package/src/lib/virtual-modules-plugin.js.map +1 -0
  182. package/src/test-setup.d.ts +2 -0
  183. package/setup-vitest.d.ts +0 -4
  184. package/setup-vitest.js +0 -215
  185. package/setup-vitest.js.map +0 -1
  186. package/src/lib/models.js +0 -1
  187. package/src/lib/models.js.map +0 -1
  188. package/src/lib/tools/README.md +0 -3
  189. package/src/lib/tools/src/index.d.ts +0 -0
  190. package/src/lib/tools/src/index.js.map +0 -1
  191. package/src/lib/utils/compiler-plugin-options.js +0 -1
  192. package/src/lib/utils/compiler-plugin-options.js.map +0 -1
  193. package/src/lib/utils/hmr-candidates.js +0 -272
  194. package/src/lib/utils/hmr-candidates.js.map +0 -1
@@ -0,0 +1,469 @@
1
+ import { angularFullVersion, createAngularCompilation, sourceFileCache } from "../utils/devkit.js";
2
+ import { activateDeferredDebug, debugCompilationApi, debugCompiler, debugEmit, debugHmr, debugHmrV, debugStyles } from "../utils/debug.js";
3
+ import { isTailwindReferenceError } from "../utils/tailwind-reference.js";
4
+ import { normalizeStylesheetDependencies } from "../style-preprocessor.js";
5
+ import { AnalogStylesheetRegistry, preprocessStylesheetResult, registerStylesheetContent, rewriteRelativeCssImports } from "../stylesheet-registry.js";
6
+ import { TS_EXT_REGEX, getTsConfigPath } from "../utils/plugin-config.js";
7
+ import { TsconfigResolver } from "../utils/tsconfig-resolver.js";
8
+ import { configureStylePipelineRegistry } from "../style-pipeline.js";
9
+ import { DiagnosticModes, injectViteIgnoreForHmrMetadata, isIgnoredHmrFile, isTestWatchMode, mapTemplateUpdatesToFiles, refreshStylesheetRegistryForFile, toAngularCompilationFileReplacements } from "../utils/compilation-shared.js";
10
+ import { loadVirtualRawModule } from "../utils/virtual-resources.js";
11
+ import { union } from "es-toolkit";
12
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
13
+ import { basename, isAbsolute, join, relative, resolve } from "node:path";
14
+ import { createRequire } from "node:module";
15
+ import { normalizePath, preprocessCSS } from "vite";
16
+ import { createHash } from "node:crypto";
17
+ //#region packages/vite-plugin-angular/src/lib/compilation-api/compilation-api-plugin.ts
18
+ var ts = createRequire(import.meta.url)("typescript");
19
+ function compilationAPIPlugin(pluginOptions) {
20
+ let resolvedConfig;
21
+ let tsConfigResolutionContext = null;
22
+ let watchMode = false;
23
+ let angularCompilation;
24
+ const sourceFileCache$1 = new sourceFileCache();
25
+ const outputFiles = /* @__PURE__ */ new Map();
26
+ const classNames = /* @__PURE__ */ new Map();
27
+ let stylesheetRegistry;
28
+ let compilationLock = Promise.resolve();
29
+ let pendingCompilation = null;
30
+ let initialCompilation = false;
31
+ let viteServer;
32
+ const isTest = process.env.NODE_ENV === "test" || !!process.env["VITEST"];
33
+ const tsconfigResolver = new TsconfigResolver({
34
+ workspaceRoot: pluginOptions.workspaceRoot,
35
+ include: pluginOptions.include,
36
+ liveReload: pluginOptions.liveReload,
37
+ hasTailwindCss: pluginOptions.hasTailwindCss,
38
+ isTest
39
+ });
40
+ const isVitestVscode = !!process.env["VITEST_VSCODE"];
41
+ let testWatchMode = isTestWatchMode();
42
+ function hasViteHmrTransport() {
43
+ return resolvedConfig ? resolvedConfig.server.hmr !== false : true;
44
+ }
45
+ function shouldEnableLiveReload() {
46
+ return !!((isTest ? testWatchMode : watchMode) && pluginOptions.liveReload && hasViteHmrTransport());
47
+ }
48
+ function shouldExternalizeStyles() {
49
+ if (!(isTest ? testWatchMode : watchMode)) return false;
50
+ return !!(shouldEnableLiveReload() || pluginOptions.hasTailwindCss);
51
+ }
52
+ function resolveTsConfigPath() {
53
+ const tsconfigValue = pluginOptions.tsconfigGetter();
54
+ return getTsConfigPath(tsConfigResolutionContext.root, tsconfigValue, tsConfigResolutionContext.isProd, isTest, tsConfigResolutionContext.isLib);
55
+ }
56
+ function resolveCompilationApiTsConfigPath(resolvedTsConfigPath, config) {
57
+ const includedFiles = tsconfigResolver.ensureIncludeCache();
58
+ const cached = tsconfigResolver.getCachedTsconfigOptions(resolvedTsConfigPath, config);
59
+ const expandedGraphRoots = tsconfigResolver.collectExpandedTsconfigRoots(resolvedTsConfigPath, config);
60
+ const mergedRootNames = union(cached.rootNames, expandedGraphRoots, includedFiles).map((file) => normalizePath(file));
61
+ if (mergedRootNames.length === cached.rootNames.length) return resolvedTsConfigPath;
62
+ const wrapperDir = join(isAbsolute(config.cacheDir) ? config.cacheDir : resolve(config.root, config.cacheDir), "analog-angular", "compilation-api");
63
+ const rawTsconfig = ts.readConfigFile(resolvedTsConfigPath, ts.sys.readFile).config ?? {};
64
+ const wrapperPayload = {
65
+ extends: normalizePath(resolvedTsConfigPath),
66
+ files: [...mergedRootNames].sort(),
67
+ ...rawTsconfig.references ? { references: rawTsconfig.references } : {}
68
+ };
69
+ const wrapperPath = join(wrapperDir, `tsconfig.includes.${createHash("sha1").update(JSON.stringify(wrapperPayload)).digest("hex").slice(0, 12)}.json`);
70
+ mkdirSync(wrapperDir, { recursive: true });
71
+ if (!existsSync(wrapperPath)) writeFileSync(wrapperPath, `${JSON.stringify(wrapperPayload, null, 2)}\n`, "utf-8");
72
+ debugCompilationApi("generated include wrapper tsconfig", {
73
+ originalTsconfig: resolvedTsConfigPath,
74
+ wrapperTsconfig: wrapperPath,
75
+ includeCount: includedFiles.length,
76
+ rootNameCount: mergedRootNames.length
77
+ });
78
+ return wrapperPath;
79
+ }
80
+ const normalizeEmitterLookupId = (file) => {
81
+ const normalizedFile = normalizePath(file);
82
+ if (!normalizedFile.startsWith("/@fs/")) return normalizedFile;
83
+ return normalizePath(normalizedFile.slice(4).replace(/^\/([A-Za-z]:\/)/, "$1"));
84
+ };
85
+ let outputFile;
86
+ const fileEmitter = (file) => {
87
+ const normalizedFile = normalizeEmitterLookupId(file);
88
+ outputFile?.(normalizedFile);
89
+ return outputFiles.get(normalizedFile);
90
+ };
91
+ async function performAngularCompilation(config, ids) {
92
+ const compilation = angularCompilation ??= await createAngularCompilation(!!pluginOptions.jit, false);
93
+ const modifiedFiles = ids?.length ? new Set(ids.map((file) => normalizePath(file))) : void 0;
94
+ if (modifiedFiles?.size) sourceFileCache$1.invalidate(modifiedFiles);
95
+ if (modifiedFiles?.size && compilation.update) {
96
+ debugCompilationApi("incremental update", { files: [...modifiedFiles] });
97
+ await compilation.update(modifiedFiles);
98
+ }
99
+ const resolvedTsConfigPath = resolveTsConfigPath();
100
+ const compilationApiTsConfigPath = resolveCompilationApiTsConfigPath(resolvedTsConfigPath, config);
101
+ debugEmit("compilation initialize", {
102
+ resolvedTsConfigPath,
103
+ compilationApiTsConfigPath,
104
+ modifiedFileCount: modifiedFiles?.size ?? 0
105
+ });
106
+ const compilationResult = await compilation.initialize(compilationApiTsConfigPath, {
107
+ fileReplacements: toAngularCompilationFileReplacements(pluginOptions.fileReplacements, pluginOptions.workspaceRoot),
108
+ modifiedFiles,
109
+ async transformStylesheet(data, containingFile, resourceFile, order, className) {
110
+ const filename = resourceFile ?? containingFile.replace(".ts", `.${pluginOptions.inlineStylesExtension}`);
111
+ const preprocessed = preprocessStylesheetResult(data, filename, pluginOptions.stylePreprocessor, {
112
+ filename,
113
+ containingFile,
114
+ resourceFile,
115
+ className,
116
+ order,
117
+ inline: !resourceFile
118
+ });
119
+ if (shouldEnableLiveReload() && className && containingFile) classNames.set(normalizePath(containingFile), className);
120
+ if (shouldExternalizeStyles()) {
121
+ const stylesheetId = registerStylesheetContent(stylesheetRegistry, {
122
+ code: preprocessed.code,
123
+ dependencies: normalizeStylesheetDependencies(preprocessed.dependencies),
124
+ diagnostics: preprocessed.diagnostics,
125
+ tags: preprocessed.tags,
126
+ containingFile,
127
+ className,
128
+ order,
129
+ inlineStylesExtension: pluginOptions.inlineStylesExtension,
130
+ resourceFile: resourceFile ?? void 0
131
+ });
132
+ debugStyles("stylesheet deferred to Vite pipeline", {
133
+ stylesheetId,
134
+ resourceFile: resourceFile ?? "(inline)"
135
+ });
136
+ return stylesheetId;
137
+ }
138
+ debugStyles("stylesheet processed inline via preprocessCSS", {
139
+ filename,
140
+ resourceFile: resourceFile ?? "(inline)",
141
+ dataLength: preprocessed.code.length
142
+ });
143
+ let stylesheetResult;
144
+ try {
145
+ stylesheetResult = await preprocessCSS(preprocessed.code, `${filename}?direct`, resolvedConfig);
146
+ } catch (e) {
147
+ if (isTailwindReferenceError(e)) throw e;
148
+ debugStyles("preprocessCSS error", {
149
+ filename,
150
+ resourceFile: resourceFile ?? "(inline)",
151
+ error: String(e)
152
+ });
153
+ }
154
+ return stylesheetResult?.code || "";
155
+ },
156
+ processWebWorker(_workerFile, _containingFile) {
157
+ return "";
158
+ }
159
+ }, (tsCompilerOptions) => {
160
+ if (shouldExternalizeStyles()) tsCompilerOptions["externalRuntimeStyles"] = true;
161
+ if (shouldEnableLiveReload()) {
162
+ tsCompilerOptions["_enableHmr"] = true;
163
+ tsCompilerOptions["supportTestBed"] = true;
164
+ }
165
+ debugCompiler("tsCompilerOptions (compilation API)", {
166
+ liveReload: pluginOptions.liveReload,
167
+ viteHmr: hasViteHmrTransport(),
168
+ hasTailwindCss: pluginOptions.hasTailwindCss,
169
+ watchMode,
170
+ shouldExternalize: shouldExternalizeStyles(),
171
+ externalRuntimeStyles: !!tsCompilerOptions["externalRuntimeStyles"],
172
+ hmrEnabled: !!tsCompilerOptions["_enableHmr"]
173
+ });
174
+ if (tsCompilerOptions["compilationMode"] === "partial") {
175
+ tsCompilerOptions["supportTestBed"] = true;
176
+ tsCompilerOptions["supportJitMode"] = true;
177
+ }
178
+ if (!isTest && resolvedConfig.build?.lib) {
179
+ tsCompilerOptions["declaration"] = true;
180
+ tsCompilerOptions["declarationMap"] = watchMode;
181
+ tsCompilerOptions["inlineSources"] = true;
182
+ }
183
+ if (isTest) tsCompilerOptions["supportTestBed"] = true;
184
+ return tsCompilerOptions;
185
+ });
186
+ debugStyles("external stylesheets from compilation API", {
187
+ count: compilationResult.externalStylesheets?.size ?? 0,
188
+ hasPreprocessor: !!pluginOptions.stylePreprocessor,
189
+ hasInlineMap: !!stylesheetRegistry
190
+ });
191
+ const preprocessStats = {
192
+ total: 0,
193
+ injected: 0,
194
+ skipped: 0,
195
+ errors: 0
196
+ };
197
+ for (const [key, value] of compilationResult.externalStylesheets ?? []) {
198
+ preprocessStats.total++;
199
+ const angularHash = `${value}.css`;
200
+ stylesheetRegistry?.registerExternalRequest(angularHash, key);
201
+ if (stylesheetRegistry && pluginOptions.stylePreprocessor && existsSync(key)) try {
202
+ const rawCss = readFileSync(key, "utf-8");
203
+ const preprocessed = preprocessStylesheetResult(rawCss, key, pluginOptions.stylePreprocessor);
204
+ const servedCss = rewriteRelativeCssImports(preprocessed.code, key);
205
+ stylesheetRegistry.registerServedStylesheet({
206
+ publicId: angularHash,
207
+ sourcePath: key,
208
+ originalCode: rawCss,
209
+ normalizedCode: servedCss,
210
+ dependencies: normalizeStylesheetDependencies(preprocessed.dependencies),
211
+ diagnostics: preprocessed.diagnostics,
212
+ tags: preprocessed.tags
213
+ }, [
214
+ key,
215
+ normalizePath(key),
216
+ basename(key),
217
+ key.replace(/^\//, "")
218
+ ]);
219
+ if (servedCss && servedCss !== rawCss) preprocessStats.injected++;
220
+ else preprocessStats.skipped++;
221
+ } catch (e) {
222
+ preprocessStats.errors++;
223
+ console.warn(`[@analogjs/vite-plugin-angular] failed to preprocess external stylesheet: ${key}: ${e}`);
224
+ }
225
+ else preprocessStats.skipped++;
226
+ }
227
+ debugStyles("external stylesheet preprocessing complete", preprocessStats);
228
+ const diagnostics = await compilation.diagnoseFiles(pluginOptions.disableTypeChecking ? DiagnosticModes.All & ~DiagnosticModes.Semantic : DiagnosticModes.All);
229
+ const errors = diagnostics.errors?.length ? diagnostics.errors : [];
230
+ const warnings = diagnostics.warnings?.length ? diagnostics.warnings : [];
231
+ const templateUpdates = mapTemplateUpdatesToFiles(compilationResult.templateUpdates);
232
+ if (templateUpdates.size > 0) debugHmr("compilation API template updates", {
233
+ count: templateUpdates.size,
234
+ files: [...templateUpdates.keys()]
235
+ });
236
+ const affectedFiles = await compilation.emitAffectedFiles();
237
+ debugEmit("emitAffectedFiles summary", {
238
+ count: affectedFiles.length,
239
+ templateUpdateCount: templateUpdates.size,
240
+ knownOutputCountBefore: outputFiles.size
241
+ });
242
+ for (const file of affectedFiles) {
243
+ const normalizedFilename = normalizePath(file.filename);
244
+ const templateUpdate = templateUpdates.get(normalizedFilename);
245
+ if (templateUpdate) classNames.set(normalizedFilename, templateUpdate.className);
246
+ outputFiles.set(normalizedFilename, {
247
+ content: file.contents,
248
+ dependencies: [],
249
+ errors: errors.map((error) => error.text || ""),
250
+ warnings: warnings.map((warning) => warning.text || ""),
251
+ hmrUpdateCode: templateUpdate?.code,
252
+ hmrEligible: !!templateUpdate?.code
253
+ });
254
+ }
255
+ }
256
+ async function performCompilation(config, ids) {
257
+ let resolve;
258
+ const previousLock = compilationLock;
259
+ compilationLock = new Promise((r) => {
260
+ resolve = r;
261
+ });
262
+ try {
263
+ await previousLock;
264
+ await performAngularCompilation(config, ids);
265
+ } finally {
266
+ resolve();
267
+ }
268
+ }
269
+ function isComponentStyleSheet(id) {
270
+ return id.includes("ngcomp=");
271
+ }
272
+ function getFilenameFromPath(id) {
273
+ try {
274
+ return new URL(id, "http://localhost").pathname.replace(/^\//, "");
275
+ } catch {
276
+ const queryIndex = id.indexOf("?");
277
+ return (queryIndex >= 0 ? id.slice(0, queryIndex) : id).replace(/^\//, "");
278
+ }
279
+ }
280
+ function sendHMRComponentUpdate(server, id) {
281
+ debugHmrV("ws send: angular component update", {
282
+ id,
283
+ timestamp: Date.now()
284
+ });
285
+ server.ws.send("angular:component-update", {
286
+ id: encodeURIComponent(id),
287
+ timestamp: Date.now()
288
+ });
289
+ classNames.delete(id);
290
+ }
291
+ return {
292
+ name: "@analogjs/vite-plugin-angular-compilation-api",
293
+ enforce: "pre",
294
+ async config(config, { command }) {
295
+ activateDeferredDebug(command);
296
+ watchMode = command === "serve";
297
+ const isProd = config.mode === "production" || process.env.NODE_ENV === "production";
298
+ tsConfigResolutionContext = {
299
+ root: config.root || ".",
300
+ isProd,
301
+ isLib: !!config?.build?.lib
302
+ };
303
+ if (angularFullVersion < 200100) console.warn("[@analogjs/vite-plugin-angular]: The Angular Compilation API is only available with Angular v20.1 and later");
304
+ else debugCompilationApi("enabled (Angular %s)", angularFullVersion);
305
+ debugCompilationApi("esbuild/oxc disabled, Angular handles transforms");
306
+ return {
307
+ esbuild: void 0,
308
+ oxc: void 0,
309
+ optimizeDeps: {
310
+ include: [
311
+ "rxjs/operators",
312
+ "rxjs",
313
+ "tslib"
314
+ ],
315
+ exclude: ["@angular/platform-server"]
316
+ },
317
+ resolve: { conditions: ["style", ...config.resolve?.conditions ?? []] }
318
+ };
319
+ },
320
+ configResolved(config) {
321
+ resolvedConfig = config;
322
+ stylesheetRegistry = new AnalogStylesheetRegistry();
323
+ configureStylePipelineRegistry(pluginOptions.stylePipeline, stylesheetRegistry, { workspaceRoot: pluginOptions.workspaceRoot });
324
+ debugStyles("stylesheet registry initialized (Angular Compilation API)");
325
+ if (isTest) testWatchMode = !(config.server.watch === null) || config.test?.watch === true || testWatchMode;
326
+ },
327
+ configureServer(server) {
328
+ viteServer = server;
329
+ const invalidateCompilation = async () => {
330
+ tsconfigResolver.invalidateAll();
331
+ await performCompilation(resolvedConfig);
332
+ };
333
+ server.watcher.on("add", invalidateCompilation);
334
+ server.watcher.on("unlink", invalidateCompilation);
335
+ server.watcher.on("change", (file) => {
336
+ if (file.includes("tsconfig")) tsconfigResolver.invalidateTsconfigCaches();
337
+ });
338
+ },
339
+ async buildStart() {
340
+ if (!isVitestVscode) {
341
+ await performCompilation(resolvedConfig);
342
+ pendingCompilation = null;
343
+ initialCompilation = true;
344
+ }
345
+ },
346
+ async handleHotUpdate(ctx) {
347
+ if (isIgnoredHmrFile(ctx.file)) {
348
+ debugHmr("ignored file change", { file: ctx.file });
349
+ return [];
350
+ }
351
+ if (TS_EXT_REGEX.test(ctx.file)) {
352
+ const [fileId] = ctx.file.split("?");
353
+ debugHmr("TS file changed", {
354
+ file: ctx.file,
355
+ fileId
356
+ });
357
+ pendingCompilation = performCompilation(resolvedConfig, [fileId]);
358
+ let result;
359
+ if (shouldEnableLiveReload()) {
360
+ await pendingCompilation;
361
+ pendingCompilation = null;
362
+ result = fileEmitter(fileId);
363
+ debugHmr("TS file emitted", {
364
+ fileId,
365
+ hmrEligible: !!result?.hmrEligible,
366
+ hasClassName: !!classNames.get(fileId)
367
+ });
368
+ }
369
+ if (shouldEnableLiveReload() && result?.hmrEligible && classNames.get(fileId)) {
370
+ const relativeFileId = `${normalizePath(relative(process.cwd(), fileId))}@${classNames.get(fileId)}`;
371
+ debugHmr("sending component update", { relativeFileId });
372
+ sendHMRComponentUpdate(ctx.server, relativeFileId);
373
+ return ctx.modules.map((mod) => {
374
+ if (mod.id === ctx.file) mod.isSelfAccepting = true;
375
+ return mod;
376
+ });
377
+ }
378
+ }
379
+ if (/\.(html|htm)$/.test(ctx.file)) {
380
+ debugHmr("template file changed", { file: ctx.file });
381
+ pendingCompilation = performCompilation(resolvedConfig);
382
+ }
383
+ if (/\.(css|less|sass|scss)$/.test(ctx.file)) {
384
+ debugHmr("stylesheet file changed", { file: ctx.file });
385
+ refreshStylesheetRegistryForFile(ctx.file, stylesheetRegistry, pluginOptions.stylePreprocessor);
386
+ }
387
+ return ctx.modules;
388
+ },
389
+ resolveId(id) {
390
+ if (isComponentStyleSheet(id)) {
391
+ const filename = getFilenameFromPath(id);
392
+ if (stylesheetRegistry?.hasServed(filename)) return id;
393
+ const componentStyles = stylesheetRegistry?.resolveExternalSource(filename);
394
+ if (componentStyles) return componentStyles + new URL(id, "http://localhost").search;
395
+ }
396
+ },
397
+ async load(id) {
398
+ const rawModule = await loadVirtualRawModule(this, id);
399
+ if (rawModule !== void 0) return rawModule;
400
+ if (isComponentStyleSheet(id)) {
401
+ const filename = getFilenameFromPath(id);
402
+ const componentStyles = stylesheetRegistry?.getServedContent(filename);
403
+ if (componentStyles) {
404
+ stylesheetRegistry?.registerActiveRequest(id);
405
+ return componentStyles;
406
+ }
407
+ }
408
+ },
409
+ transform: {
410
+ filter: { id: {
411
+ include: [TS_EXT_REGEX],
412
+ exclude: [
413
+ /node_modules/,
414
+ "type=script",
415
+ "@ng/component"
416
+ ]
417
+ } },
418
+ async handler(code, id) {
419
+ if (pluginOptions.transformFilter && !(pluginOptions.transformFilter(code, id) ?? true)) return;
420
+ const isAngular = /(Component|Directive|Pipe|Injectable|NgModule)\(/.test(code);
421
+ if (!isAngular) {
422
+ debugCompilationApi("transform skip (non-Angular file)", { id });
423
+ return;
424
+ }
425
+ if (id.includes("?") && id.includes("analog-content-")) return;
426
+ if (id.includes(".ts?")) id = id.replace(/\?(.*)/, "");
427
+ if (isTest) {
428
+ if (isVitestVscode && !initialCompilation) {
429
+ pendingCompilation = performCompilation(resolvedConfig);
430
+ initialCompilation = true;
431
+ }
432
+ const tsMod = viteServer?.moduleGraph.getModuleById(id);
433
+ if (tsMod) {
434
+ const invalidated = tsMod.lastInvalidationTimestamp;
435
+ if (testWatchMode && invalidated) pendingCompilation = performCompilation(resolvedConfig, [id]);
436
+ }
437
+ }
438
+ if (pendingCompilation) {
439
+ await pendingCompilation;
440
+ pendingCompilation = null;
441
+ }
442
+ const typescriptResult = fileEmitter(id);
443
+ if (!typescriptResult) {
444
+ debugCompilationApi("transform skip (file not emitted)", { id });
445
+ if (isAngular) this.warn(`[@analogjs/vite-plugin-angular]: "${id}" contains Angular decorators but is not in the TypeScript program. Ensure it is included in your tsconfig.`);
446
+ return;
447
+ }
448
+ if (typescriptResult.warnings && typescriptResult.warnings.length > 0) this.warn(`${typescriptResult.warnings.join("\n")}`);
449
+ if (typescriptResult.errors && typescriptResult.errors.length > 0) this.error(`${typescriptResult.errors.join("\n")}`);
450
+ let data = typescriptResult.content ?? "";
451
+ if (data.includes("HmrLoad")) {
452
+ if (data.includes("getReplaceMetadataURL")) data = injectViteIgnoreForHmrMetadata(data);
453
+ }
454
+ return {
455
+ code: data,
456
+ map: null
457
+ };
458
+ }
459
+ },
460
+ closeBundle() {
461
+ angularCompilation?.close?.();
462
+ angularCompilation = void 0;
463
+ }
464
+ };
465
+ }
466
+ //#endregion
467
+ export { compilationAPIPlugin };
468
+
469
+ //# sourceMappingURL=compilation-api-plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compilation-api-plugin.js","names":[],"sources":["../../../../src/lib/compilation-api/compilation-api-plugin.ts"],"sourcesContent":["import { type createAngularCompilation as createAngularCompilationType } from '@angular/build/private';\nimport { union } from 'es-toolkit';\nimport { createHash } from 'node:crypto';\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { basename, isAbsolute, join, relative, resolve } from 'node:path';\nimport { createRequire } from 'node:module';\nimport {\n normalizePath,\n Plugin,\n preprocessCSS,\n ResolvedConfig,\n ViteDevServer,\n} from 'vite';\n\nimport {\n createAngularCompilation,\n SourceFileCache,\n angularFullVersion,\n} from '../utils/devkit.js';\nimport {\n activateDeferredDebug,\n debugCompilationApi,\n debugCompiler,\n debugEmit,\n debugHmr,\n debugHmrV,\n debugStyles,\n type DebugOption,\n} from '../utils/debug.js';\nimport {\n getTsConfigPath,\n TS_EXT_REGEX,\n type TsConfigResolutionContext,\n} from '../utils/plugin-config.js';\nimport { TsconfigResolver } from '../utils/tsconfig-resolver.js';\nimport { isTailwindReferenceError } from '../utils/tailwind-reference.js';\nimport {\n AnalogStylesheetRegistry,\n preprocessStylesheetResult,\n registerStylesheetContent,\n rewriteRelativeCssImports,\n} from '../stylesheet-registry.js';\nimport { normalizeStylesheetDependencies } from '../style-preprocessor.js';\nimport type { StylePreprocessor } from '../style-preprocessor.js';\nimport {\n AngularStylePipelineOptions,\n configureStylePipelineRegistry,\n} from '../style-pipeline.js';\nimport { type FileReplacement } from '../plugins/file-replacements.plugin.js';\nimport type { EmitFileResult } from '../models.js';\nimport type { SourceFileCache as SourceFileCacheType } from '../utils/source-file-cache.js';\nimport {\n injectViteIgnoreForHmrMetadata,\n isIgnoredHmrFile,\n toAngularCompilationFileReplacements,\n mapTemplateUpdatesToFiles,\n refreshStylesheetRegistryForFile,\n DiagnosticModes,\n isTestWatchMode,\n} from '../utils/compilation-shared.js';\nimport { loadVirtualRawModule } from '../utils/virtual-resources.js';\n\nconst require = createRequire(import.meta.url);\nconst ts = require('typescript');\n\nexport interface CompilationAPIPluginOptions {\n tsconfigGetter: () => string;\n workspaceRoot: string;\n inlineStylesExtension: string;\n jit: boolean;\n liveReload: boolean;\n disableTypeChecking: boolean;\n supportedBrowsers: string[];\n transformFilter?: (code: string, id: string) => boolean;\n fileReplacements: FileReplacement[];\n stylePreprocessor?: StylePreprocessor;\n stylePipeline?: AngularStylePipelineOptions;\n hasTailwindCss: boolean;\n tailwindCss?: {\n rootStylesheet: string;\n prefixes?: string[];\n };\n isTest: boolean;\n isAstroIntegration: boolean;\n include: string[];\n additionalContentDirs: string[];\n debug?: DebugOption;\n}\n\nexport function compilationAPIPlugin(\n pluginOptions: CompilationAPIPluginOptions,\n): Plugin {\n let resolvedConfig: ResolvedConfig;\n let tsConfigResolutionContext: TsConfigResolutionContext | null = null;\n let watchMode = false;\n\n // Persistent compilation instance — kept alive across rebuilds so Angular\n // can diff prior state and emit `templateUpdates` for HMR.\n let angularCompilation:\n | Awaited<ReturnType<typeof createAngularCompilationType>>\n | undefined;\n const sourceFileCache: SourceFileCacheType = new SourceFileCache();\n const outputFiles = new Map<string, EmitFileResult>();\n const classNames = new Map<string, string>();\n let stylesheetRegistry: AnalogStylesheetRegistry | undefined;\n let compilationLock = Promise.resolve();\n let pendingCompilation: Promise<void> | null = null;\n let initialCompilation = false;\n let viteServer: ViteDevServer | undefined;\n\n const isTest = process.env['NODE_ENV'] === 'test' || !!process.env['VITEST'];\n const tsconfigResolver = new TsconfigResolver({\n workspaceRoot: pluginOptions.workspaceRoot,\n include: pluginOptions.include,\n liveReload: pluginOptions.liveReload,\n hasTailwindCss: pluginOptions.hasTailwindCss,\n isTest,\n });\n const isVitestVscode = !!process.env['VITEST_VSCODE'];\n let testWatchMode = isTestWatchMode();\n\n function hasViteHmrTransport(): boolean {\n return resolvedConfig ? resolvedConfig.server.hmr !== false : true;\n }\n\n function shouldEnableLiveReload(): boolean {\n const effectiveWatchMode = isTest ? testWatchMode : watchMode;\n return !!(\n effectiveWatchMode &&\n pluginOptions.liveReload &&\n hasViteHmrTransport()\n );\n }\n\n function shouldExternalizeStyles(): boolean {\n const effectiveWatchMode = isTest ? testWatchMode : watchMode;\n if (!effectiveWatchMode) return false;\n return !!(shouldEnableLiveReload() || pluginOptions.hasTailwindCss);\n }\n\n function resolveTsConfigPath() {\n const tsconfigValue = pluginOptions.tsconfigGetter();\n return getTsConfigPath(\n tsConfigResolutionContext!.root,\n tsconfigValue,\n tsConfigResolutionContext!.isProd,\n isTest,\n tsConfigResolutionContext!.isLib,\n );\n }\n\n function resolveCompilationApiTsConfigPath(\n resolvedTsConfigPath: string,\n config: ResolvedConfig,\n ): string {\n const includedFiles = tsconfigResolver.ensureIncludeCache();\n const cached = tsconfigResolver.getCachedTsconfigOptions(\n resolvedTsConfigPath,\n config,\n );\n const expandedGraphRoots = tsconfigResolver.collectExpandedTsconfigRoots(\n resolvedTsConfigPath,\n config,\n );\n const mergedRootNames = union(\n cached.rootNames,\n expandedGraphRoots,\n includedFiles,\n ).map((file) => normalizePath(file));\n\n if (mergedRootNames.length === cached.rootNames.length) {\n return resolvedTsConfigPath;\n }\n\n const resolvedCacheDir = isAbsolute(config.cacheDir)\n ? config.cacheDir\n : resolve(config.root, config.cacheDir);\n const wrapperDir = join(\n resolvedCacheDir,\n 'analog-angular',\n 'compilation-api',\n );\n const rawTsconfig = (ts.readConfigFile(\n resolvedTsConfigPath,\n ts.sys.readFile,\n ).config ?? {}) as { references?: unknown[] };\n const wrapperPayload = {\n extends: normalizePath(resolvedTsConfigPath),\n files: [...mergedRootNames].sort(),\n ...(rawTsconfig.references ? { references: rawTsconfig.references } : {}),\n };\n const wrapperHash = createHash('sha1')\n .update(JSON.stringify(wrapperPayload))\n .digest('hex')\n .slice(0, 12);\n const wrapperPath = join(\n wrapperDir,\n `tsconfig.includes.${wrapperHash}.json`,\n );\n\n mkdirSync(wrapperDir, { recursive: true });\n if (!existsSync(wrapperPath)) {\n writeFileSync(\n wrapperPath,\n `${JSON.stringify(wrapperPayload, null, 2)}\\n`,\n 'utf-8',\n );\n }\n\n debugCompilationApi('generated include wrapper tsconfig', {\n originalTsconfig: resolvedTsConfigPath,\n wrapperTsconfig: wrapperPath,\n includeCount: includedFiles.length,\n rootNameCount: mergedRootNames.length,\n });\n\n return wrapperPath;\n }\n\n const normalizeEmitterLookupId = (file: string) => {\n const normalizedFile = normalizePath(file);\n if (!normalizedFile.startsWith('/@fs/')) return normalizedFile;\n const fsPath = normalizedFile\n .slice('/@fs'.length)\n .replace(/^\\/([A-Za-z]:\\/)/, '$1');\n return normalizePath(fsPath);\n };\n\n let outputFile: ((file: string) => void) | undefined;\n const fileEmitter = (file: string) => {\n const normalizedFile = normalizeEmitterLookupId(file);\n outputFile?.(normalizedFile);\n return outputFiles.get(normalizedFile);\n };\n\n async function performAngularCompilation(\n config: ResolvedConfig,\n ids?: string[],\n ) {\n const compilation = (angularCompilation ??= await (\n createAngularCompilation as typeof createAngularCompilationType\n )(!!pluginOptions.jit, false));\n const modifiedFiles = ids?.length\n ? new Set(ids.map((file) => normalizePath(file)))\n : undefined;\n if (modifiedFiles?.size) {\n sourceFileCache.invalidate(modifiedFiles);\n }\n if (modifiedFiles?.size && compilation.update) {\n debugCompilationApi('incremental update', {\n files: [...modifiedFiles],\n });\n await compilation.update(modifiedFiles);\n }\n\n const resolvedTsConfigPath = resolveTsConfigPath();\n const compilationApiTsConfigPath = resolveCompilationApiTsConfigPath(\n resolvedTsConfigPath,\n config,\n );\n debugEmit('compilation initialize', {\n resolvedTsConfigPath,\n compilationApiTsConfigPath,\n modifiedFileCount: modifiedFiles?.size ?? 0,\n });\n const compilationResult = await compilation.initialize(\n compilationApiTsConfigPath,\n {\n fileReplacements: toAngularCompilationFileReplacements(\n pluginOptions.fileReplacements,\n pluginOptions.workspaceRoot,\n ),\n modifiedFiles,\n async transformStylesheet(\n data: string,\n containingFile: string,\n resourceFile: string | null,\n order: number,\n className: string | null,\n ) {\n const filename =\n resourceFile ??\n containingFile.replace(\n '.ts',\n `.${pluginOptions.inlineStylesExtension}`,\n );\n\n const preprocessed = preprocessStylesheetResult(\n data,\n filename,\n pluginOptions.stylePreprocessor,\n {\n filename,\n containingFile,\n resourceFile,\n className,\n order,\n inline: !resourceFile,\n },\n );\n\n if (shouldEnableLiveReload() && className && containingFile) {\n classNames.set(normalizePath(containingFile), className as string);\n }\n\n if (shouldExternalizeStyles()) {\n const stylesheetId = registerStylesheetContent(\n stylesheetRegistry!,\n {\n code: preprocessed.code,\n dependencies: normalizeStylesheetDependencies(\n preprocessed.dependencies,\n ),\n diagnostics: preprocessed.diagnostics,\n tags: preprocessed.tags,\n containingFile,\n className: className as string | undefined,\n order,\n inlineStylesExtension: pluginOptions.inlineStylesExtension,\n resourceFile: resourceFile ?? undefined,\n },\n );\n\n debugStyles('stylesheet deferred to Vite pipeline', {\n stylesheetId,\n resourceFile: resourceFile ?? '(inline)',\n });\n\n return stylesheetId;\n }\n\n debugStyles('stylesheet processed inline via preprocessCSS', {\n filename,\n resourceFile: resourceFile ?? '(inline)',\n dataLength: preprocessed.code.length,\n });\n\n let stylesheetResult;\n try {\n stylesheetResult = await preprocessCSS(\n preprocessed.code,\n `${filename}?direct`,\n resolvedConfig,\n );\n } catch (e) {\n if (isTailwindReferenceError(e)) {\n throw e;\n }\n debugStyles('preprocessCSS error', {\n filename,\n resourceFile: resourceFile ?? '(inline)',\n error: String(e),\n });\n }\n\n return stylesheetResult?.code || '';\n },\n processWebWorker(_workerFile: string, _containingFile: string) {\n return '';\n },\n },\n (tsCompilerOptions: Record<string, unknown>) => {\n if (shouldExternalizeStyles()) {\n tsCompilerOptions['externalRuntimeStyles'] = true;\n }\n\n if (shouldEnableLiveReload()) {\n tsCompilerOptions['_enableHmr'] = true;\n tsCompilerOptions['supportTestBed'] = true;\n }\n\n debugCompiler('tsCompilerOptions (compilation API)', {\n liveReload: pluginOptions.liveReload,\n viteHmr: hasViteHmrTransport(),\n hasTailwindCss: pluginOptions.hasTailwindCss,\n watchMode,\n shouldExternalize: shouldExternalizeStyles(),\n externalRuntimeStyles: !!tsCompilerOptions['externalRuntimeStyles'],\n hmrEnabled: !!tsCompilerOptions['_enableHmr'],\n });\n\n if (tsCompilerOptions['compilationMode'] === 'partial') {\n tsCompilerOptions['supportTestBed'] = true;\n tsCompilerOptions['supportJitMode'] = true;\n }\n\n if (!isTest && resolvedConfig.build?.lib) {\n tsCompilerOptions['declaration'] = true;\n tsCompilerOptions['declarationMap'] = watchMode;\n tsCompilerOptions['inlineSources'] = true;\n }\n\n if (isTest) {\n tsCompilerOptions['supportTestBed'] = true;\n }\n\n return tsCompilerOptions;\n },\n );\n\n // Preprocess external stylesheets for Tailwind CSS @reference\n debugStyles('external stylesheets from compilation API', {\n count: compilationResult.externalStylesheets?.size ?? 0,\n hasPreprocessor: !!pluginOptions.stylePreprocessor,\n hasInlineMap: !!stylesheetRegistry,\n });\n const preprocessStats = { total: 0, injected: 0, skipped: 0, errors: 0 };\n for (const [key, value] of compilationResult.externalStylesheets ?? []) {\n preprocessStats.total++;\n const angularHash = `${value}.css`;\n stylesheetRegistry?.registerExternalRequest(angularHash, key);\n\n if (\n stylesheetRegistry &&\n pluginOptions.stylePreprocessor &&\n existsSync(key)\n ) {\n try {\n const rawCss = readFileSync(key, 'utf-8');\n const preprocessed = preprocessStylesheetResult(\n rawCss,\n key,\n pluginOptions.stylePreprocessor,\n );\n const servedCss = rewriteRelativeCssImports(preprocessed.code, key);\n stylesheetRegistry.registerServedStylesheet(\n {\n publicId: angularHash,\n sourcePath: key,\n originalCode: rawCss,\n normalizedCode: servedCss,\n dependencies: normalizeStylesheetDependencies(\n preprocessed.dependencies,\n ),\n diagnostics: preprocessed.diagnostics,\n tags: preprocessed.tags,\n },\n [key, normalizePath(key), basename(key), key.replace(/^\\//, '')],\n );\n\n if (servedCss && servedCss !== rawCss) {\n preprocessStats.injected++;\n } else {\n preprocessStats.skipped++;\n }\n } catch (e) {\n preprocessStats.errors++;\n console.warn(\n `[@analogjs/vite-plugin-angular] failed to preprocess external stylesheet: ${key}: ${e}`,\n );\n }\n } else {\n preprocessStats.skipped++;\n }\n }\n debugStyles('external stylesheet preprocessing complete', preprocessStats);\n\n const diagnostics = await compilation.diagnoseFiles(\n pluginOptions.disableTypeChecking\n ? DiagnosticModes.All & ~DiagnosticModes.Semantic\n : DiagnosticModes.All,\n );\n\n const errors = diagnostics.errors?.length ? diagnostics.errors : [];\n const warnings = diagnostics.warnings?.length ? diagnostics.warnings : [];\n\n const templateUpdates = mapTemplateUpdatesToFiles(\n compilationResult.templateUpdates,\n );\n if (templateUpdates.size > 0) {\n debugHmr('compilation API template updates', {\n count: templateUpdates.size,\n files: [...templateUpdates.keys()],\n });\n }\n\n const affectedFiles = await compilation.emitAffectedFiles();\n debugEmit('emitAffectedFiles summary', {\n count: affectedFiles.length,\n templateUpdateCount: templateUpdates.size,\n knownOutputCountBefore: outputFiles.size,\n });\n\n for (const file of affectedFiles) {\n const normalizedFilename = normalizePath(file.filename);\n const templateUpdate = templateUpdates.get(normalizedFilename);\n\n if (templateUpdate) {\n classNames.set(normalizedFilename, templateUpdate.className);\n }\n\n outputFiles.set(normalizedFilename, {\n content: file.contents,\n dependencies: [],\n errors: errors.map((error: { text?: string }) => error.text || ''),\n warnings: warnings.map(\n (warning: { text?: string }) => warning.text || '',\n ),\n hmrUpdateCode: templateUpdate?.code,\n hmrEligible: !!templateUpdate?.code,\n });\n }\n }\n\n async function performCompilation(config: ResolvedConfig, ids?: string[]) {\n let resolve: (() => unknown) | undefined;\n const previousLock = compilationLock;\n compilationLock = new Promise<void>((r) => {\n resolve = r;\n });\n try {\n await previousLock;\n await performAngularCompilation(config, ids);\n } finally {\n resolve!();\n }\n }\n\n function isComponentStyleSheet(id: string): boolean {\n return id.includes('ngcomp=');\n }\n\n function getFilenameFromPath(id: string): string {\n try {\n return new URL(id, 'http://localhost').pathname.replace(/^\\//, '');\n } catch {\n const queryIndex = id.indexOf('?');\n const pathname = queryIndex >= 0 ? id.slice(0, queryIndex) : id;\n return pathname.replace(/^\\//, '');\n }\n }\n\n function sendHMRComponentUpdate(server: ViteDevServer, id: string) {\n debugHmrV('ws send: angular component update', {\n id,\n timestamp: Date.now(),\n });\n server.ws.send('angular:component-update', {\n id: encodeURIComponent(id),\n timestamp: Date.now(),\n });\n classNames.delete(id);\n }\n\n return {\n name: '@analogjs/vite-plugin-angular-compilation-api',\n enforce: 'pre' as const,\n async config(config, { command }) {\n activateDeferredDebug(command);\n watchMode = command === 'serve';\n const isProd =\n config.mode === 'production' ||\n process.env['NODE_ENV'] === 'production';\n\n tsConfigResolutionContext = {\n root: config.root || '.',\n isProd,\n isLib: !!config?.build?.lib,\n };\n\n if (angularFullVersion < 200100) {\n console.warn(\n '[@analogjs/vite-plugin-angular]: The Angular Compilation API is only available with Angular v20.1 and later',\n );\n } else {\n debugCompilationApi('enabled (Angular %s)', angularFullVersion);\n }\n\n // Angular Compilation API handles TypeScript transforms — disable\n // esbuild/oxc so they don't compete.\n debugCompilationApi('esbuild/oxc disabled, Angular handles transforms');\n\n return {\n esbuild: undefined,\n oxc: undefined,\n optimizeDeps: {\n include: ['rxjs/operators', 'rxjs', 'tslib'],\n exclude: ['@angular/platform-server'],\n },\n resolve: {\n conditions: ['style', ...(config.resolve?.conditions ?? [])],\n },\n };\n },\n configResolved(config) {\n resolvedConfig = config;\n\n stylesheetRegistry = new AnalogStylesheetRegistry();\n configureStylePipelineRegistry(\n pluginOptions.stylePipeline,\n stylesheetRegistry,\n { workspaceRoot: pluginOptions.workspaceRoot },\n );\n debugStyles('stylesheet registry initialized (Angular Compilation API)');\n\n if (isTest) {\n testWatchMode =\n !(config.server.watch === null) ||\n (config as any).test?.watch === true ||\n testWatchMode;\n }\n },\n configureServer(server) {\n viteServer = server;\n\n const invalidateCompilation = async () => {\n tsconfigResolver.invalidateAll();\n await performCompilation(resolvedConfig);\n };\n server.watcher.on('add', invalidateCompilation);\n server.watcher.on('unlink', invalidateCompilation);\n server.watcher.on('change', (file) => {\n if (file.includes('tsconfig')) {\n tsconfigResolver.invalidateTsconfigCaches();\n }\n });\n },\n async buildStart() {\n if (!isVitestVscode) {\n await performCompilation(resolvedConfig);\n pendingCompilation = null;\n initialCompilation = true;\n }\n },\n async handleHotUpdate(ctx) {\n if (isIgnoredHmrFile(ctx.file)) {\n debugHmr('ignored file change', { file: ctx.file });\n return [];\n }\n\n if (TS_EXT_REGEX.test(ctx.file)) {\n const [fileId] = ctx.file.split('?');\n debugHmr('TS file changed', { file: ctx.file, fileId });\n\n pendingCompilation = performCompilation(resolvedConfig, [fileId]);\n\n let result;\n\n if (shouldEnableLiveReload()) {\n await pendingCompilation;\n pendingCompilation = null;\n result = fileEmitter(fileId);\n debugHmr('TS file emitted', {\n fileId,\n hmrEligible: !!result?.hmrEligible,\n hasClassName: !!classNames.get(fileId),\n });\n }\n\n if (\n shouldEnableLiveReload() &&\n result?.hmrEligible &&\n classNames.get(fileId)\n ) {\n const relativeFileId = `${normalizePath(\n relative(process.cwd(), fileId),\n )}@${classNames.get(fileId)}`;\n\n debugHmr('sending component update', { relativeFileId });\n sendHMRComponentUpdate(ctx.server, relativeFileId);\n\n return ctx.modules.map((mod) => {\n if (mod.id === ctx.file) {\n mod.isSelfAccepting = true;\n }\n return mod;\n });\n }\n }\n\n if (/\\.(html|htm)$/.test(ctx.file)) {\n debugHmr('template file changed', { file: ctx.file });\n // Recompile to pick up template changes\n pendingCompilation = performCompilation(resolvedConfig);\n }\n\n if (/\\.(css|less|sass|scss)$/.test(ctx.file)) {\n debugHmr('stylesheet file changed', { file: ctx.file });\n refreshStylesheetRegistryForFile(\n ctx.file,\n stylesheetRegistry,\n pluginOptions.stylePreprocessor,\n );\n }\n\n return ctx.modules;\n },\n resolveId(id) {\n // Map angular component stylesheets\n if (isComponentStyleSheet(id)) {\n const filename = getFilenameFromPath(id);\n\n if (stylesheetRegistry?.hasServed(filename)) {\n return id;\n }\n\n const componentStyles =\n stylesheetRegistry?.resolveExternalSource(filename);\n if (componentStyles) {\n return componentStyles + new URL(id, 'http://localhost').search;\n }\n }\n\n return undefined;\n },\n async load(id) {\n // Virtual raw ids back JIT-emitted templateUrl/styleUrl imports.\n // virtual-modules-plugin resolves them; this plugin is the active\n // compilation plugin in compilation-API mode, so load must read the\n // backing file (jit=true is the test-mode default).\n const rawModule = await loadVirtualRawModule(this, id);\n if (rawModule !== undefined) return rawModule;\n\n // Serve component stylesheets from registry\n if (isComponentStyleSheet(id)) {\n const filename = getFilenameFromPath(id);\n const componentStyles = stylesheetRegistry?.getServedContent(filename);\n if (componentStyles) {\n stylesheetRegistry?.registerActiveRequest(id);\n return componentStyles;\n }\n }\n\n return;\n },\n transform: {\n filter: {\n id: {\n include: [TS_EXT_REGEX],\n exclude: [/node_modules/, 'type=script', '@ng/component'],\n },\n },\n async handler(code, id) {\n if (\n pluginOptions.transformFilter &&\n !(pluginOptions.transformFilter(code, id) ?? true)\n ) {\n return;\n }\n\n // Skip non-Angular files — in compilation API mode, Angular\n // compiles TypeScript before this hook, so only Angular files\n // need processing.\n const isAngular =\n /(Component|Directive|Pipe|Injectable|NgModule)\\(/.test(code);\n if (!isAngular) {\n debugCompilationApi('transform skip (non-Angular file)', { id });\n return;\n }\n\n if (id.includes('?') && id.includes('analog-content-')) {\n return;\n }\n\n if (id.includes('.ts?')) {\n id = id.replace(/\\?(.*)/, '');\n }\n\n if (isTest) {\n if (isVitestVscode && !initialCompilation) {\n pendingCompilation = performCompilation(resolvedConfig);\n initialCompilation = true;\n }\n\n const tsMod = viteServer?.moduleGraph.getModuleById(id);\n if (tsMod) {\n const invalidated = tsMod.lastInvalidationTimestamp;\n if (testWatchMode && invalidated) {\n pendingCompilation = performCompilation(resolvedConfig, [id]);\n }\n }\n }\n\n if (pendingCompilation) {\n await pendingCompilation;\n pendingCompilation = null;\n }\n\n const typescriptResult = fileEmitter(id);\n if (!typescriptResult) {\n debugCompilationApi('transform skip (file not emitted)', { id });\n if (isAngular) {\n this.warn(\n `[@analogjs/vite-plugin-angular]: \"${id}\" contains Angular decorators but is not in the TypeScript program. ` +\n `Ensure it is included in your tsconfig.`,\n );\n }\n return;\n }\n\n if (typescriptResult.warnings && typescriptResult.warnings.length > 0) {\n this.warn(`${typescriptResult.warnings.join('\\n')}`);\n }\n\n if (typescriptResult.errors && typescriptResult.errors.length > 0) {\n this.error(`${typescriptResult.errors.join('\\n')}`);\n }\n\n let data = typescriptResult.content ?? '';\n\n // Re-inject @vite-ignore for Angular HMR dynamic imports\n if (data.includes('HmrLoad')) {\n const hasMetaUrl = data.includes('getReplaceMetadataURL');\n if (hasMetaUrl) {\n data = injectViteIgnoreForHmrMetadata(data);\n }\n }\n\n return {\n code: data,\n map: null,\n };\n },\n },\n closeBundle() {\n angularCompilation?.close?.();\n angularCompilation = undefined;\n },\n };\n}\n"],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export { compilationAPIPlugin, type CompilationAPIPluginOptions } from "./compilation-api-plugin.js";
@@ -0,0 +1 @@
1
+ import "./compilation-api-plugin.js";
@@ -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;