@analogjs/vite-plugin-angular 3.0.0-alpha.16 → 3.0.0-alpha.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@analogjs/vite-plugin-angular",
3
- "version": "3.0.0-alpha.16",
3
+ "version": "3.0.0-alpha.18",
4
4
  "description": "Vite Plugin for Angular",
5
5
  "type": "module",
6
6
  "keywords": [
@@ -1 +1 @@
1
- {"version":3,"file":"setup-vitest.js","names":[],"sources":["../../../packages/vite-plugin-angular/setup-vitest.ts"],"sourcesContent":["import 'zone.js';\nimport 'zone.js/plugins/sync-test';\nimport 'zone.js/plugins/proxy';\nimport 'zone.js/testing';\n\n/**\n * Patch Vitest's describe/test/beforeEach/afterEach functions so test code\n * always runs in a testZone (ProxyZone).\n */\n/* global Zone */\nconst { Zone } = globalThis as any;\n\nif (Zone === undefined) {\n throw new Error('Missing: Zone (zone.js)');\n}\n\nif ((globalThis as any)['__vitest_zone_patch__'] === true) {\n throw new Error(\"'vitest' has already been patched with 'Zone'.\");\n}\n\n(globalThis as any)['__vitest_zone_patch__'] = true;\nconst { SyncTestZoneSpec } = Zone;\nconst { ProxyZoneSpec } = Zone;\n\nif (SyncTestZoneSpec === undefined) {\n throw new Error('Missing: SyncTestZoneSpec (zone.js/plugins/sync-test)');\n}\nif (ProxyZoneSpec === undefined) {\n throw new Error('Missing: ProxyZoneSpec (zone.js/plugins/proxy.js)');\n}\n\nconst env = globalThis as any;\nconst ambientZone = Zone.current;\n\n// Create a synchronous-only zone in which to run `describe` blocks in order to\n// Raise an error if any asynchronous operations are attempted\n// Inside of a `describe` but outside of a `beforeEach` or `it`.\nconst syncZone = ambientZone.fork(new SyncTestZoneSpec('vitest.describe'));\nfunction wrapDescribeInZone(describeBody: any) {\n return function (...args: any) {\n return syncZone.run(describeBody, null, args);\n };\n}\n\n// Create a proxy zone in which to run `test` blocks so that the tests function\n// Can retroactively install different zones.\nconst testProxyZone = ambientZone.fork(new ProxyZoneSpec());\nfunction wrapTestInZone(testBody: string | any[] | undefined) {\n if (testBody === undefined) {\n return;\n }\n\n const wrappedFunc = function wrappedFunc(...args: any[]) {\n return testProxyZone.run(testBody, null, args);\n };\n try {\n Object.defineProperty(wrappedFunc, 'length', {\n configurable: true,\n enumerable: false,\n writable: true,\n });\n wrappedFunc.length = testBody.length;\n } catch (e) {\n return testBody.length === 0\n ? () => testProxyZone.run(testBody, null)\n : (done: any) => testProxyZone.run(testBody, null, [done]);\n }\n\n return wrappedFunc;\n}\n\n/**\n * Allows Vitest to handle Angular test fixtures\n *\n * Vitest Snapshot guide ==> https://vitest.dev/guide/snapshot.html\n *\n * @returns customSnapshotSerializer for Angular Fixture Component\n */\nconst customSnapshotSerializer = () => {\n function serialize(\n val: any,\n config: any,\n indentation: any,\n depth: any,\n refs: any,\n printer: any,\n ): string {\n // `printer` is a function that serializes a value using existing plugins.\n return `${printer(\n fixtureVitestSerializer(val),\n config,\n indentation,\n depth,\n refs,\n )}`;\n }\n function test(val: any): boolean {\n // * If it's a ComponentFixture we apply the transformation rules\n return val && isAngularFixture(val);\n }\n return {\n serialize,\n test,\n };\n};\n\n/**\n * Check if is an Angular fixture\n *\n * @param val Angular fixture\n * @returns boolean who check if is an angular fixture\n */\nfunction isAngularFixture(val: any): boolean {\n if (typeof val !== 'object') {\n return false;\n }\n\n if (val['componentRef'] || val['componentInstance']) {\n return true;\n }\n\n if (val['componentType']) {\n return true;\n }\n\n // * Angular fixture keys in Fixture component Object\n const fixtureKeys = [\n 'componentRef',\n 'ngZone',\n 'effectRunner',\n '_autoDetect',\n '_isStable',\n '_isDestroyed',\n '_resolve',\n '_promise',\n '_onUnstableSubscription',\n '_onStableSubscription',\n '_onMicrotaskEmptySubscription',\n '_onErrorSubscription',\n 'changeDetectorRef',\n 'elementRef',\n 'debugElement',\n 'componentInstance',\n 'nativeElement',\n ];\n\n // * Angular fixture keys in Fixture componentRef Object\n const fixtureComponentRefKeys = [\n 'location',\n '_rootLView',\n '_tNode',\n 'previousInputValues',\n 'instance',\n 'changeDetectorRef',\n 'hostView',\n 'componentType',\n ];\n\n return (\n JSON.stringify(Object.keys(val)) === JSON.stringify(fixtureKeys) ||\n JSON.stringify(Object.keys(val)) === JSON.stringify(fixtureComponentRefKeys)\n );\n}\n\n/**\n * Serialize Angular fixture for Vitest\n *\n * @param fixture Angular Fixture Component\n * @returns HTML Child Node\n */\nfunction fixtureVitestSerializer(fixture: any) {\n // * Get Component meta data\n const componentType = (\n fixture && fixture.componentType\n ? fixture.componentType\n : fixture.componentRef.componentType\n ) as any;\n\n let inputsData = '';\n\n const selector = Reflect.getOwnPropertyDescriptor(\n componentType,\n '__annotations__',\n )?.value[0].selector;\n\n if (componentType && componentType.propDecorators) {\n inputsData = Object.entries(componentType.propDecorators)\n .map(([key, value]) => `${key}=\"${value}\"`)\n .join('');\n }\n\n // * Get DOM Elements\n const divElement =\n fixture && fixture.nativeElement\n ? fixture.nativeElement\n : fixture.location.nativeElement;\n\n // * Convert string data to HTML data\n const doc = new DOMParser().parseFromString(\n `<${selector} ${inputsData}>${divElement.innerHTML}</${selector}>`,\n 'text/html',\n );\n\n return doc.body.childNodes[0];\n}\n\n/**\n * Bind describe method to wrap describe.each function\n */\nconst bindDescribe = (\n self: any,\n originalVitestFn: {\n apply: (\n arg0: any,\n arg1: any[],\n ) => {\n (): any;\n new (): any;\n apply: { (arg0: any, arg1: any[]): any; new (): any };\n };\n },\n) =>\n function bindDescribe(...eachArgs: any) {\n return function bindDescribe(...args: any[]) {\n args[1] = wrapDescribeInZone(args[1]);\n\n return originalVitestFn.apply(self, eachArgs).apply(self, args);\n };\n };\n\n/**\n * Bind test method to wrap test.each function\n */\nconst bindTest = (\n self: any,\n originalVitestFn: {\n apply: (\n arg0: any,\n arg1: any[],\n ) => {\n (): any;\n new (): any;\n apply: { (arg0: any, arg1: any[]): any; new (): any };\n };\n },\n) =>\n function bindTest(...eachArgs: any) {\n return function bindTest(...args: any[]) {\n args[1] = wrapTestInZone(args[1]);\n\n return originalVitestFn.apply(self, eachArgs).apply(self, args);\n };\n };\n\n['describe'].forEach((methodName) => {\n const originalvitestFn = env[methodName];\n env[methodName] = function (...args: any[]) {\n args[1] = wrapDescribeInZone(args[1]);\n\n return originalvitestFn.apply(this, args);\n };\n env[methodName].each = bindDescribe(originalvitestFn, originalvitestFn.each);\n if (methodName === 'describe') {\n env[methodName].only = bindDescribe(\n originalvitestFn,\n originalvitestFn.only,\n );\n env[methodName].skip = bindDescribe(\n originalvitestFn,\n originalvitestFn.skip,\n );\n }\n});\n\n['test', 'it'].forEach((methodName) => {\n const originalvitestFn = env[methodName];\n env[methodName] = function (...args: any[]) {\n args[1] = wrapTestInZone(args[1]);\n\n return originalvitestFn.apply(this, args);\n };\n env[methodName].each = bindTest(originalvitestFn, originalvitestFn.each);\n env[methodName].only = bindTest(originalvitestFn, originalvitestFn.only);\n env[methodName].skip = bindTest(originalvitestFn, originalvitestFn.skip);\n\n if (methodName === 'test' || methodName === 'it') {\n env[methodName].todo = function todo(...args: any) {\n return originalvitestFn.todo.apply(this, args);\n };\n }\n});\n\n['beforeEach', 'afterEach', 'beforeAll', 'afterAll'].forEach((methodName) => {\n const originalvitestFn = env[methodName];\n\n env[methodName] = function (...args: any[]) {\n args[0] = wrapTestInZone(args[0]);\n\n return originalvitestFn.apply(this, args);\n };\n});\n\n['expect'].forEach((methodName) => {\n const originalvitestFn = env[methodName];\n return originalvitestFn.addSnapshotSerializer(customSnapshotSerializer());\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"setup-vitest.js","names":[],"sources":["../setup-vitest.ts"],"sourcesContent":["import 'zone.js';\nimport 'zone.js/plugins/sync-test';\nimport 'zone.js/plugins/proxy';\nimport 'zone.js/testing';\n\n/**\n * Patch Vitest's describe/test/beforeEach/afterEach functions so test code\n * always runs in a testZone (ProxyZone).\n */\n/* global Zone */\nconst { Zone } = globalThis as any;\n\nif (Zone === undefined) {\n throw new Error('Missing: Zone (zone.js)');\n}\n\nif ((globalThis as any)['__vitest_zone_patch__'] === true) {\n throw new Error(\"'vitest' has already been patched with 'Zone'.\");\n}\n\n(globalThis as any)['__vitest_zone_patch__'] = true;\nconst { SyncTestZoneSpec } = Zone;\nconst { ProxyZoneSpec } = Zone;\n\nif (SyncTestZoneSpec === undefined) {\n throw new Error('Missing: SyncTestZoneSpec (zone.js/plugins/sync-test)');\n}\nif (ProxyZoneSpec === undefined) {\n throw new Error('Missing: ProxyZoneSpec (zone.js/plugins/proxy.js)');\n}\n\nconst env = globalThis as any;\nconst ambientZone = Zone.current;\n\n// Create a synchronous-only zone in which to run `describe` blocks in order to\n// Raise an error if any asynchronous operations are attempted\n// Inside of a `describe` but outside of a `beforeEach` or `it`.\nconst syncZone = ambientZone.fork(new SyncTestZoneSpec('vitest.describe'));\nfunction wrapDescribeInZone(describeBody: any) {\n return function (...args: any) {\n return syncZone.run(describeBody, null, args);\n };\n}\n\n// Create a proxy zone in which to run `test` blocks so that the tests function\n// Can retroactively install different zones.\nconst testProxyZone = ambientZone.fork(new ProxyZoneSpec());\nfunction wrapTestInZone(testBody: string | any[] | undefined) {\n if (testBody === undefined) {\n return;\n }\n\n const wrappedFunc = function wrappedFunc(...args: any[]) {\n return testProxyZone.run(testBody, null, args);\n };\n try {\n Object.defineProperty(wrappedFunc, 'length', {\n configurable: true,\n enumerable: false,\n writable: true,\n });\n wrappedFunc.length = testBody.length;\n } catch (e) {\n return testBody.length === 0\n ? () => testProxyZone.run(testBody, null)\n : (done: any) => testProxyZone.run(testBody, null, [done]);\n }\n\n return wrappedFunc;\n}\n\n/**\n * Allows Vitest to handle Angular test fixtures\n *\n * Vitest Snapshot guide ==> https://vitest.dev/guide/snapshot.html\n *\n * @returns customSnapshotSerializer for Angular Fixture Component\n */\nconst customSnapshotSerializer = () => {\n function serialize(\n val: any,\n config: any,\n indentation: any,\n depth: any,\n refs: any,\n printer: any,\n ): string {\n // `printer` is a function that serializes a value using existing plugins.\n return `${printer(\n fixtureVitestSerializer(val),\n config,\n indentation,\n depth,\n refs,\n )}`;\n }\n function test(val: any): boolean {\n // * If it's a ComponentFixture we apply the transformation rules\n return val && isAngularFixture(val);\n }\n return {\n serialize,\n test,\n };\n};\n\n/**\n * Check if is an Angular fixture\n *\n * @param val Angular fixture\n * @returns boolean who check if is an angular fixture\n */\nfunction isAngularFixture(val: any): boolean {\n if (typeof val !== 'object') {\n return false;\n }\n\n if (val['componentRef'] || val['componentInstance']) {\n return true;\n }\n\n if (val['componentType']) {\n return true;\n }\n\n // * Angular fixture keys in Fixture component Object\n const fixtureKeys = [\n 'componentRef',\n 'ngZone',\n 'effectRunner',\n '_autoDetect',\n '_isStable',\n '_isDestroyed',\n '_resolve',\n '_promise',\n '_onUnstableSubscription',\n '_onStableSubscription',\n '_onMicrotaskEmptySubscription',\n '_onErrorSubscription',\n 'changeDetectorRef',\n 'elementRef',\n 'debugElement',\n 'componentInstance',\n 'nativeElement',\n ];\n\n // * Angular fixture keys in Fixture componentRef Object\n const fixtureComponentRefKeys = [\n 'location',\n '_rootLView',\n '_tNode',\n 'previousInputValues',\n 'instance',\n 'changeDetectorRef',\n 'hostView',\n 'componentType',\n ];\n\n return (\n JSON.stringify(Object.keys(val)) === JSON.stringify(fixtureKeys) ||\n JSON.stringify(Object.keys(val)) === JSON.stringify(fixtureComponentRefKeys)\n );\n}\n\n/**\n * Serialize Angular fixture for Vitest\n *\n * @param fixture Angular Fixture Component\n * @returns HTML Child Node\n */\nfunction fixtureVitestSerializer(fixture: any) {\n // * Get Component meta data\n const componentType = (\n fixture && fixture.componentType\n ? fixture.componentType\n : fixture.componentRef.componentType\n ) as any;\n\n let inputsData = '';\n\n const selector = Reflect.getOwnPropertyDescriptor(\n componentType,\n '__annotations__',\n )?.value[0].selector;\n\n if (componentType && componentType.propDecorators) {\n inputsData = Object.entries(componentType.propDecorators)\n .map(([key, value]) => `${key}=\"${value}\"`)\n .join('');\n }\n\n // * Get DOM Elements\n const divElement =\n fixture && fixture.nativeElement\n ? fixture.nativeElement\n : fixture.location.nativeElement;\n\n // * Convert string data to HTML data\n const doc = new DOMParser().parseFromString(\n `<${selector} ${inputsData}>${divElement.innerHTML}</${selector}>`,\n 'text/html',\n );\n\n return doc.body.childNodes[0];\n}\n\n/**\n * Bind describe method to wrap describe.each function\n */\nconst bindDescribe = (\n self: any,\n originalVitestFn: {\n apply: (\n arg0: any,\n arg1: any[],\n ) => {\n (): any;\n new (): any;\n apply: { (arg0: any, arg1: any[]): any; new (): any };\n };\n },\n) =>\n function bindDescribe(...eachArgs: any) {\n return function bindDescribe(...args: any[]) {\n args[1] = wrapDescribeInZone(args[1]);\n\n return originalVitestFn.apply(self, eachArgs).apply(self, args);\n };\n };\n\n/**\n * Bind test method to wrap test.each function\n */\nconst bindTest = (\n self: any,\n originalVitestFn: {\n apply: (\n arg0: any,\n arg1: any[],\n ) => {\n (): any;\n new (): any;\n apply: { (arg0: any, arg1: any[]): any; new (): any };\n };\n },\n) =>\n function bindTest(...eachArgs: any) {\n return function bindTest(...args: any[]) {\n args[1] = wrapTestInZone(args[1]);\n\n return originalVitestFn.apply(self, eachArgs).apply(self, args);\n };\n };\n\n['describe'].forEach((methodName) => {\n const originalvitestFn = env[methodName];\n env[methodName] = function (...args: any[]) {\n args[1] = wrapDescribeInZone(args[1]);\n\n return originalvitestFn.apply(this, args);\n };\n env[methodName].each = bindDescribe(originalvitestFn, originalvitestFn.each);\n if (methodName === 'describe') {\n env[methodName].only = bindDescribe(\n originalvitestFn,\n originalvitestFn.only,\n );\n env[methodName].skip = bindDescribe(\n originalvitestFn,\n originalvitestFn.skip,\n );\n }\n});\n\n['test', 'it'].forEach((methodName) => {\n const originalvitestFn = env[methodName];\n env[methodName] = function (...args: any[]) {\n args[1] = wrapTestInZone(args[1]);\n\n return originalvitestFn.apply(this, args);\n };\n env[methodName].each = bindTest(originalvitestFn, originalvitestFn.each);\n env[methodName].only = bindTest(originalvitestFn, originalvitestFn.only);\n env[methodName].skip = bindTest(originalvitestFn, originalvitestFn.skip);\n\n if (methodName === 'test' || methodName === 'it') {\n env[methodName].todo = function todo(...args: any) {\n return originalvitestFn.todo.apply(this, args);\n };\n }\n});\n\n['beforeEach', 'afterEach', 'beforeAll', 'afterAll'].forEach((methodName) => {\n const originalvitestFn = env[methodName];\n\n env[methodName] = function (...args: any[]) {\n args[0] = wrapTestInZone(args[0]);\n\n return originalvitestFn.apply(this, args);\n };\n});\n\n['expect'].forEach((methodName) => {\n const originalvitestFn = env[methodName];\n return originalvitestFn.addSnapshotSerializer(customSnapshotSerializer());\n});\n"],"mappings":"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"}
package/src/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  import { angular } from "./lib/angular-vite-plugin.js";
2
2
  export type { PluginOptions } from "./lib/angular-vite-plugin.js";
3
+ export type { StylePreprocessor } from "./lib/style-preprocessor.js";
3
4
  export default angular;
package/src/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../../packages/vite-plugin-angular/src/index.ts"],"sourcesContent":["import { angular } from './lib/angular-vite-plugin.js';\nexport type { PluginOptions } from './lib/angular-vite-plugin.js';\n\nexport default angular;\n"],"mappings":";;AAGA,IAAA,cAAe"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/index.ts"],"sourcesContent":["import { angular } from './lib/angular-vite-plugin.js';\nexport type { PluginOptions } from './lib/angular-vite-plugin.js';\nexport type { StylePreprocessor } from './lib/style-preprocessor.js';\n\nexport default angular;\n"],"mappings":";;AAIA,IAAA,cAAe"}
@@ -1 +1 @@
1
- {"version":3,"file":"angular-build-optimizer-plugin.js","names":[],"sources":["../../../../../packages/vite-plugin-angular/src/lib/angular-build-optimizer-plugin.ts"],"sourcesContent":["import type { Plugin, UserConfig } from 'vite';\nimport { JavaScriptTransformer } from './utils/devkit.js';\nimport { getJsTransformConfigKey } from './utils/rolldown.js';\n\nexport function buildOptimizerPlugin({\n jit,\n}: {\n supportedBrowsers: string[];\n jit: boolean;\n}): Plugin {\n const javascriptTransformer = new JavaScriptTransformer(\n {\n sourcemap: false,\n thirdPartySourcemaps: false,\n advancedOptimizations: true,\n jit: true,\n },\n 1,\n );\n let isProd = false;\n\n return {\n name: '@analogjs/vite-plugin-angular-optimizer',\n apply: 'build',\n config(userConfig) {\n isProd =\n userConfig.mode === 'production' ||\n process.env['NODE_ENV'] === 'production';\n const jsTransformConfigKey = getJsTransformConfigKey();\n\n return {\n define: isProd\n ? {\n ngJitMode: 'false',\n ngI18nClosureMode: 'false',\n ngDevMode: 'false',\n ngServerMode: `${!!userConfig.build?.ssr}`,\n }\n : {},\n [jsTransformConfigKey]: {\n define: isProd\n ? {\n ngDevMode: 'false',\n ngJitMode: 'false',\n ngI18nClosureMode: 'false',\n ngServerMode: `${!!userConfig.build?.ssr}`,\n }\n : undefined,\n },\n } as UserConfig;\n },\n transform: {\n filter: {\n id: /\\.[cm]?js$/,\n },\n async handler(code, id) {\n const angularPackage = /fesm20/.test(id);\n\n if (!angularPackage) {\n return {\n code: isProd\n ? code.replace(/^\\/\\/# sourceMappingURL=[^\\r\\n]*/gm, '')\n : code,\n map: {\n mappings: '',\n },\n };\n }\n\n const sideEffects =\n jit && id.includes('@angular/compiler') ? true : false;\n const result: Uint8Array = await javascriptTransformer.transformData(\n id,\n code,\n false,\n sideEffects,\n );\n\n return {\n code: Buffer.from(result).toString(),\n };\n },\n },\n };\n}\n"],"mappings":";;;AAIA,SAAgB,qBAAqB,EACnC,OAIS;CACT,MAAM,wBAAwB,IAAI,GAChC;EACE,WAAW;EACX,sBAAsB;EACtB,uBAAuB;EACvB,KAAK;EACN,EACD,EACD;CACD,IAAI,SAAS;AAEb,QAAO;EACL,MAAM;EACN,OAAO;EACP,OAAO,YAAY;AACjB,YACE,WAAW,SAAS,gBAAA,QAAA,IAAA,aACQ;GAC9B,MAAM,uBAAuB,yBAAyB;AAEtD,UAAO;IACL,QAAQ,SACJ;KACE,WAAW;KACX,mBAAmB;KACnB,WAAW;KACX,cAAc,GAAG,CAAC,CAAC,WAAW,OAAO;KACtC,GACD,EAAE;KACL,uBAAuB,EACtB,QAAQ,SACJ;KACE,WAAW;KACX,WAAW;KACX,mBAAmB;KACnB,cAAc,GAAG,CAAC,CAAC,WAAW,OAAO;KACtC,GACD,KAAA,GACL;IACF;;EAEH,WAAW;GACT,QAAQ,EACN,IAAI,cACL;GACD,MAAM,QAAQ,MAAM,IAAI;AAGtB,QAAI,CAFmB,SAAS,KAAK,GAAG,CAGtC,QAAO;KACL,MAAM,SACF,KAAK,QAAQ,sCAAsC,GAAG,GACtD;KACJ,KAAK,EACH,UAAU,IACX;KACF;IAGH,MAAM,cACJ,OAAO,GAAG,SAAS,oBAAoB,GAAG,OAAO;IACnD,MAAM,SAAqB,MAAM,sBAAsB,cACrD,IACA,MACA,OACA,YACD;AAED,WAAO,EACL,MAAM,OAAO,KAAK,OAAO,CAAC,UAAU,EACrC;;GAEJ;EACF"}
1
+ {"version":3,"file":"angular-build-optimizer-plugin.js","names":[],"sources":["../../../src/lib/angular-build-optimizer-plugin.ts"],"sourcesContent":["import type { Plugin, UserConfig } from 'vite';\nimport { JavaScriptTransformer } from './utils/devkit.js';\nimport { getJsTransformConfigKey } from './utils/rolldown.js';\n\nexport function buildOptimizerPlugin({\n jit,\n}: {\n supportedBrowsers: string[];\n jit: boolean;\n}): Plugin {\n const javascriptTransformer = new JavaScriptTransformer(\n {\n sourcemap: false,\n thirdPartySourcemaps: false,\n advancedOptimizations: true,\n jit: true,\n },\n 1,\n );\n let isProd = false;\n\n return {\n name: '@analogjs/vite-plugin-angular-optimizer',\n apply: 'build',\n config(userConfig) {\n isProd =\n userConfig.mode === 'production' ||\n process.env['NODE_ENV'] === 'production';\n const jsTransformConfigKey = getJsTransformConfigKey();\n\n return {\n define: isProd\n ? {\n ngJitMode: 'false',\n ngI18nClosureMode: 'false',\n ngDevMode: 'false',\n ngServerMode: `${!!userConfig.build?.ssr}`,\n }\n : {},\n [jsTransformConfigKey]: {\n define: isProd\n ? {\n ngDevMode: 'false',\n ngJitMode: 'false',\n ngI18nClosureMode: 'false',\n ngServerMode: `${!!userConfig.build?.ssr}`,\n }\n : undefined,\n },\n } as UserConfig;\n },\n transform: {\n filter: {\n id: /\\.[cm]?js$/,\n },\n async handler(code, id) {\n const angularPackage = /fesm20/.test(id);\n\n if (!angularPackage) {\n return {\n code: isProd\n ? code.replace(/^\\/\\/# sourceMappingURL=[^\\r\\n]*/gm, '')\n : code,\n map: {\n mappings: '',\n },\n };\n }\n\n const sideEffects =\n jit && id.includes('@angular/compiler') ? true : false;\n const result: Uint8Array = await javascriptTransformer.transformData(\n id,\n code,\n false,\n sideEffects,\n );\n\n return {\n code: Buffer.from(result).toString(),\n };\n },\n },\n };\n}\n"],"mappings":";;;AAIA,SAAgB,qBAAqB,EACnC,OAIS;CACT,MAAM,wBAAwB,IAAI,GAChC;EACE,WAAW;EACX,sBAAsB;EACtB,uBAAuB;EACvB,KAAK;EACN,EACD,EACD;CACD,IAAI,SAAS;AAEb,QAAO;EACL,MAAM;EACN,OAAO;EACP,OAAO,YAAY;AACjB,YACE,WAAW,SAAS,gBAAA,QAAA,IAAA,aACQ;GAC9B,MAAM,uBAAuB,yBAAyB;AAEtD,UAAO;IACL,QAAQ,SACJ;KACE,WAAW;KACX,mBAAmB;KACnB,WAAW;KACX,cAAc,GAAG,CAAC,CAAC,WAAW,OAAO;KACtC,GACD,EAAE;KACL,uBAAuB,EACtB,QAAQ,SACJ;KACE,WAAW;KACX,WAAW;KACX,mBAAmB;KACnB,cAAc,GAAG,CAAC,CAAC,WAAW,OAAO;KACtC,GACD,KAAA,GACL;IACF;;EAEH,WAAW;GACT,QAAQ,EACN,IAAI,cACL;GACD,MAAM,QAAQ,MAAM,IAAI;AAGtB,QAAI,CAFmB,SAAS,KAAK,GAAG,CAGtC,QAAO;KACL,MAAM,SACF,KAAK,QAAQ,sCAAsC,GAAG,GACtD;KACJ,KAAK,EACH,UAAU,IACX;KACF;IAGH,MAAM,cACJ,OAAO,GAAG,SAAS,oBAAoB,GAAG,OAAO;IACnD,MAAM,SAAqB,MAAM,sBAAsB,cACrD,IACA,MACA,OACA,YACD;AAED,WAAO,EACL,MAAM,OAAO,KAAK,OAAO,CAAC,UAAU,EACrC;;GAEJ;EACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"angular-jit-plugin.js","names":[],"sources":["../../../../../packages/vite-plugin-angular/src/lib/angular-jit-plugin.ts"],"sourcesContent":["import { createHash } from 'node:crypto';\nimport { Plugin, ResolvedConfig, preprocessCSS } from 'vite';\n\nexport function jitPlugin({\n inlineStylesExtension,\n}: {\n inlineStylesExtension: string;\n}): Plugin {\n let config: ResolvedConfig;\n\n return {\n name: '@analogjs/vite-plugin-angular-jit',\n configResolved(_config) {\n config = _config;\n },\n resolveId(id: string) {\n if (id.startsWith('virtual:angular')) {\n return `\\0${id}`;\n }\n\n return;\n },\n async load(id: string) {\n if (id.includes('virtual:angular:jit:style:inline;')) {\n const styleId = id.split('style:inline;')[1];\n // styleId may exceed 255 bytes of base64-encoded content, limit to 16\n const styleIdHash = createHash('sha256')\n .update(styleId)\n .digest('hex')\n .slice(0, 16);\n\n const decodedStyles = Buffer.from(\n decodeURIComponent(styleId),\n 'base64',\n ).toString();\n\n let styles: string | undefined = '';\n\n try {\n const compiled = await preprocessCSS(\n decodedStyles,\n `${styleIdHash}.${inlineStylesExtension}?direct`,\n config,\n );\n styles = compiled?.code;\n } catch (e) {\n console.error(`${e}`);\n }\n\n return `export default \\`${styles}\\``;\n }\n\n return;\n },\n };\n}\n"],"mappings":";;;AAGA,SAAgB,UAAU,EACxB,yBAGS;CACT,IAAI;AAEJ,QAAO;EACL,MAAM;EACN,eAAe,SAAS;AACtB,YAAS;;EAEX,UAAU,IAAY;AACpB,OAAI,GAAG,WAAW,kBAAkB,CAClC,QAAO,KAAK;;EAKhB,MAAM,KAAK,IAAY;AACrB,OAAI,GAAG,SAAS,oCAAoC,EAAE;IACpD,MAAM,UAAU,GAAG,MAAM,gBAAgB,CAAC;IAE1C,MAAM,cAAc,WAAW,SAAS,CACrC,OAAO,QAAQ,CACf,OAAO,MAAM,CACb,MAAM,GAAG,GAAG;IAEf,MAAM,gBAAgB,OAAO,KAC3B,mBAAmB,QAAQ,EAC3B,SACD,CAAC,UAAU;IAEZ,IAAI,SAA6B;AAEjC,QAAI;AAMF,eALiB,MAAM,cACrB,eACA,GAAG,YAAY,GAAG,sBAAsB,UACxC,OACD,GACkB;aACZ,GAAG;AACV,aAAQ,MAAM,GAAG,IAAI;;AAGvB,WAAO,oBAAoB,OAAO;;;EAKvC"}
1
+ {"version":3,"file":"angular-jit-plugin.js","names":[],"sources":["../../../src/lib/angular-jit-plugin.ts"],"sourcesContent":["import { createHash } from 'node:crypto';\nimport { Plugin, ResolvedConfig, preprocessCSS } from 'vite';\n\nexport function jitPlugin({\n inlineStylesExtension,\n}: {\n inlineStylesExtension: string;\n}): Plugin {\n let config: ResolvedConfig;\n\n return {\n name: '@analogjs/vite-plugin-angular-jit',\n configResolved(_config) {\n config = _config;\n },\n resolveId(id: string) {\n if (id.startsWith('virtual:angular')) {\n return `\\0${id}`;\n }\n\n return;\n },\n async load(id: string) {\n if (id.includes('virtual:angular:jit:style:inline;')) {\n const styleId = id.split('style:inline;')[1];\n // styleId may exceed 255 bytes of base64-encoded content, limit to 16\n const styleIdHash = createHash('sha256')\n .update(styleId)\n .digest('hex')\n .slice(0, 16);\n\n const decodedStyles = Buffer.from(\n decodeURIComponent(styleId),\n 'base64',\n ).toString();\n\n let styles: string | undefined = '';\n\n try {\n const compiled = await preprocessCSS(\n decodedStyles,\n `${styleIdHash}.${inlineStylesExtension}?direct`,\n config,\n );\n styles = compiled?.code;\n } catch (e) {\n console.error(`${e}`);\n }\n\n return `export default \\`${styles}\\``;\n }\n\n return;\n },\n };\n}\n"],"mappings":";;;AAGA,SAAgB,UAAU,EACxB,yBAGS;CACT,IAAI;AAEJ,QAAO;EACL,MAAM;EACN,eAAe,SAAS;AACtB,YAAS;;EAEX,UAAU,IAAY;AACpB,OAAI,GAAG,WAAW,kBAAkB,CAClC,QAAO,KAAK;;EAKhB,MAAM,KAAK,IAAY;AACrB,OAAI,GAAG,SAAS,oCAAoC,EAAE;IACpD,MAAM,UAAU,GAAG,MAAM,gBAAgB,CAAC;IAE1C,MAAM,cAAc,WAAW,SAAS,CACrC,OAAO,QAAQ,CACf,OAAO,MAAM,CACb,MAAM,GAAG,GAAG;IAEf,MAAM,gBAAgB,OAAO,KAC3B,mBAAmB,QAAQ,EAC3B,SACD,CAAC,UAAU;IAEZ,IAAI,SAA6B;AAEjC,QAAI;AAMF,eALiB,MAAM,cACrB,eACA,GAAG,YAAY,GAAG,sBAAsB,UACxC,OACD,GACkB;aACZ,GAAG;AACV,aAAQ,MAAM,GAAG,IAAI;;AAGvB,WAAO,oBAAoB,OAAO;;;EAKvC"}
@@ -1 +1 @@
1
- {"version":3,"file":"angular-pending-tasks.plugin.js","names":[],"sources":["../../../../../packages/vite-plugin-angular/src/lib/angular-pending-tasks.plugin.ts"],"sourcesContent":["import { Plugin } from 'vite';\n\nimport { angularFullVersion } from './utils/devkit.js';\n\n/**\n * This plugin is a workaround for the ɵPendingTasks symbol being renamed\n * to ɵPendingTasksInternal in Angular v19.0.4. The symbol is renamed to support previous versions of\n * Angular with Analog that used the ɵPendingTasks symbol.\n *\n * Commmit: https://github.com/angular/angular/commit/24e317cb157bf1ef159ed8554f1b79cb3443edf4\n */\nexport function pendingTasksPlugin(): Plugin {\n return {\n name: 'analogjs-pending-tasks-plugin',\n transform(code, id) {\n if (id.includes('analogjs-content.mjs')) {\n return {\n code: code.replace('ɵPendingTasksInternal', 'ɵPendingTasks'),\n };\n }\n return;\n },\n };\n}\n"],"mappings":";;;;;;;;AAWA,SAAgB,qBAA6B;AAC3C,QAAO;EACL,MAAM;EACN,UAAU,MAAM,IAAI;AAClB,OAAI,GAAG,SAAS,uBAAuB,CACrC,QAAO,EACL,MAAM,KAAK,QAAQ,yBAAyB,gBAAgB,EAC7D;;EAIN"}
1
+ {"version":3,"file":"angular-pending-tasks.plugin.js","names":[],"sources":["../../../src/lib/angular-pending-tasks.plugin.ts"],"sourcesContent":["import { Plugin } from 'vite';\n\nimport { angularFullVersion } from './utils/devkit.js';\n\n/**\n * This plugin is a workaround for the ɵPendingTasks symbol being renamed\n * to ɵPendingTasksInternal in Angular v19.0.4. The symbol is renamed to support previous versions of\n * Angular with Analog that used the ɵPendingTasks symbol.\n *\n * Commmit: https://github.com/angular/angular/commit/24e317cb157bf1ef159ed8554f1b79cb3443edf4\n */\nexport function pendingTasksPlugin(): Plugin {\n return {\n name: 'analogjs-pending-tasks-plugin',\n transform(code, id) {\n if (id.includes('analogjs-content.mjs')) {\n return {\n code: code.replace('ɵPendingTasksInternal', 'ɵPendingTasks'),\n };\n }\n return;\n },\n };\n}\n"],"mappings":";;;;;;;;AAWA,SAAgB,qBAA6B;AAC3C,QAAO;EACL,MAAM;EACN,UAAU,MAAM,IAAI;AAClB,OAAI,GAAG,SAAS,uBAAuB,CACrC,QAAO,EACL,MAAM,KAAK,QAAQ,yBAAyB,gBAAgB,EAC7D;;EAIN"}
@@ -1,6 +1,7 @@
1
1
  import { NgtscProgram } from "@angular/compiler-cli";
2
2
  import * as ts from "typescript";
3
3
  import { Plugin } from "vite";
4
+ import type { StylePreprocessor } from "./style-preprocessor.js";
4
5
  import { FileReplacement } from "./plugins/file-replacements.plugin.js";
5
6
  export declare enum DiagnosticModes {
6
7
  None = 0,
@@ -33,6 +34,82 @@ export interface PluginOptions {
33
34
  experimental?: {
34
35
  useAngularCompilationAPI?: boolean;
35
36
  };
37
+ /**
38
+ * Optional preprocessor that transforms component CSS before it enters Vite's
39
+ * preprocessCSS pipeline. Runs on every component stylesheet (both external
40
+ * `.component.css` files and inline `styles: [...]` blocks).
41
+ *
42
+ * @param code - Raw CSS content of the component stylesheet
43
+ * @param filename - Resolved file path of the stylesheet (or containing .ts file for inline styles)
44
+ * @returns Transformed CSS string, or the original code if no transformation is needed
45
+ */
46
+ stylePreprocessor?: StylePreprocessor;
47
+ /**
48
+ * First-class Tailwind CSS v4 integration for Angular component styles.
49
+ *
50
+ * Angular's compiler processes component CSS through Vite's `preprocessCSS()`,
51
+ * which runs `@tailwindcss/vite` — but each component stylesheet is processed
52
+ * in isolation without access to the root Tailwind configuration (prefix, @theme,
53
+ * @custom-variant, @plugin definitions). This causes errors like:
54
+ *
55
+ * "Cannot apply utility class `sa:grid` because the `sa` variant does not exist"
56
+ *
57
+ * The `tailwindCss` option solves this by auto-injecting a `@reference` directive
58
+ * into every component CSS file that uses Tailwind utilities, pointing it to the
59
+ * root Tailwind stylesheet so `@tailwindcss/vite` can resolve the full configuration.
60
+ *
61
+ * @example Basic usage — reference a root Tailwind CSS file:
62
+ * ```ts
63
+ * import { resolve } from 'node:path';
64
+ *
65
+ * angular({
66
+ * tailwindCss: {
67
+ * rootStylesheet: resolve(__dirname, 'src/styles/tailwind.css'),
68
+ * },
69
+ * })
70
+ * ```
71
+ *
72
+ * @example With prefix detection — only inject for files using specific prefixes:
73
+ * ```ts
74
+ * angular({
75
+ * tailwindCss: {
76
+ * rootStylesheet: resolve(__dirname, 'src/styles/tailwind.css'),
77
+ * // Only inject @reference into files that use these prefixed classes
78
+ * prefixes: ['sa:', 'tw:'],
79
+ * },
80
+ * })
81
+ * ```
82
+ *
83
+ * @example AnalogJS platform — passed through the `vite` option:
84
+ * ```ts
85
+ * analog({
86
+ * vite: {
87
+ * tailwindCss: {
88
+ * rootStylesheet: resolve(__dirname, '../../../libs/meritos/tailwind.config.css'),
89
+ * },
90
+ * },
91
+ * })
92
+ * ```
93
+ */
94
+ tailwindCss?: {
95
+ /**
96
+ * Absolute path to the root Tailwind CSS file that contains `@import "tailwindcss"`,
97
+ * `@theme`, `@custom-variant`, and `@plugin` definitions.
98
+ *
99
+ * A `@reference` directive pointing to this file will be auto-injected into
100
+ * component CSS files that use Tailwind utilities.
101
+ */
102
+ rootStylesheet: string;
103
+ /**
104
+ * Optional list of class prefixes to detect (e.g. `['sa:', 'tw:']`).
105
+ * When provided, `@reference` is only injected into component CSS files that
106
+ * contain at least one of these prefixes. When omitted, `@reference` is injected
107
+ * into all component CSS files that contain `@apply` or `@` directives.
108
+ *
109
+ * @default undefined — inject into all component CSS files with `@apply`
110
+ */
111
+ prefixes?: string[];
112
+ };
36
113
  }
37
114
  export declare function angular(options?: PluginOptions): Plugin[];
38
115
  export declare function createFsWatcherCacheInvalidator(invalidateFsCaches: () => void, invalidateTsconfigCaches: () => void, performCompilation: () => Promise<void>): () => Promise<void>;
@@ -36,6 +36,30 @@ var DiagnosticModes = /* @__PURE__ */ function(DiagnosticModes) {
36
36
  */
37
37
  var TS_EXT_REGEX = /\.[cm]?(ts)[^x]?\??/;
38
38
  var classNames = /* @__PURE__ */ new Map();
39
+ /**
40
+ * Builds a resolved stylePreprocessor function from plugin options.
41
+ * If `tailwindCss` is provided, creates an auto-reference injector.
42
+ * If `stylePreprocessor` is also provided, chains them (tailwind first, then user).
43
+ */
44
+ function buildStylePreprocessor(options) {
45
+ const userPreprocessor = options?.stylePreprocessor;
46
+ const tw = options?.tailwindCss;
47
+ if (!tw && !userPreprocessor) return;
48
+ let tailwindPreprocessor;
49
+ if (tw) {
50
+ const rootStylesheet = tw.rootStylesheet;
51
+ const prefixes = tw.prefixes;
52
+ tailwindPreprocessor = (code, filename) => {
53
+ if (code.includes("@reference") || code.includes("@import \"tailwindcss\"") || code.includes("@import 'tailwindcss'")) return code;
54
+ if (!(prefixes ? prefixes.some((prefix) => code.includes(prefix)) : code.includes("@apply"))) return code;
55
+ return `@reference "${relative(dirname(filename), rootStylesheet)}";\n${code}`;
56
+ };
57
+ }
58
+ if (tailwindPreprocessor && userPreprocessor) return (code, filename) => {
59
+ return userPreprocessor(tailwindPreprocessor(code, filename), filename);
60
+ };
61
+ return tailwindPreprocessor ?? userPreprocessor;
62
+ }
39
63
  function angular(options) {
40
64
  /**
41
65
  * Normalize plugin options so defaults
@@ -57,7 +81,8 @@ function angular(options) {
57
81
  liveReload: options?.liveReload ?? false,
58
82
  disableTypeChecking: options?.disableTypeChecking ?? true,
59
83
  fileReplacements: options?.fileReplacements ?? [],
60
- useAngularCompilationAPI: options?.experimental?.useAngularCompilationAPI ?? false
84
+ useAngularCompilationAPI: options?.experimental?.useAngularCompilationAPI ?? false,
85
+ stylePreprocessor: buildStylePreprocessor(options)
61
86
  };
62
87
  let resolvedConfig;
63
88
  let tsConfigResolutionContext = null;
@@ -439,15 +464,16 @@ function angular(options) {
439
464
  fileReplacements: toAngularCompilationFileReplacements(pluginOptions.fileReplacements, pluginOptions.workspaceRoot),
440
465
  modifiedFiles,
441
466
  async transformStylesheet(data, containingFile, resourceFile, order, className) {
442
- if (pluginOptions.liveReload) {
443
- const filename = createHash("sha256").update(containingFile).update(className).update(String(order)).update(data).digest("hex") + "." + pluginOptions.inlineStylesExtension;
444
- inlineComponentStyles.set(filename, data);
445
- return filename;
467
+ const filename = resourceFile ?? containingFile.replace(".ts", `.${pluginOptions.inlineStylesExtension}`);
468
+ const preprocessedData = pluginOptions.stylePreprocessor ? pluginOptions.stylePreprocessor(data, filename) ?? data : data;
469
+ if (pluginOptions.liveReload && watchMode) {
470
+ const stylesheetId = createHash("sha256").update(containingFile).update(className).update(String(order)).update(preprocessedData).digest("hex") + "." + pluginOptions.inlineStylesExtension;
471
+ inlineComponentStyles.set(stylesheetId, preprocessedData);
472
+ return stylesheetId;
446
473
  }
447
- const filename = resourceFile ?? containingFile.replace(".ts", `.${options?.inlineStylesExtension}`);
448
474
  let stylesheetResult;
449
475
  try {
450
- stylesheetResult = await preprocessCSS(data, `${filename}?direct`, resolvedConfig);
476
+ stylesheetResult = await preprocessCSS(preprocessedData, `${filename}?direct`, resolvedConfig);
451
477
  } catch (e) {
452
478
  console.error(`${e}`);
453
479
  }
@@ -602,7 +628,8 @@ function angular(options) {
602
628
  isProd,
603
629
  inlineComponentStyles,
604
630
  externalComponentStyles,
605
- sourceFileCache: sourceFileCache$1
631
+ sourceFileCache: sourceFileCache$1,
632
+ stylePreprocessor: pluginOptions.stylePreprocessor
606
633
  });
607
634
  }
608
635
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"angular-vite-plugin.js","names":[],"sources":["../../../../../packages/vite-plugin-angular/src/lib/angular-vite-plugin.ts"],"sourcesContent":["import { NgtscProgram } from '@angular/compiler-cli';\nimport { existsSync, mkdirSync, writeFileSync } from 'node:fs';\nimport {\n basename,\n dirname,\n isAbsolute,\n join,\n relative,\n resolve,\n} from 'node:path';\nimport * as vite from 'vite';\n\nimport * as compilerCli from '@angular/compiler-cli';\nimport { createRequire } from 'node:module';\nimport * as ts from 'typescript';\nimport { type createAngularCompilation as createAngularCompilationType } from '@angular/build/private';\n\nimport * as ngCompiler from '@angular/compiler';\nimport { globSync } from 'tinyglobby';\nimport {\n defaultClientConditions,\n ModuleNode,\n normalizePath,\n Plugin,\n preprocessCSS,\n ResolvedConfig,\n ViteDevServer,\n} from 'vite';\nimport { buildOptimizerPlugin } from './angular-build-optimizer-plugin.js';\nimport { jitPlugin } from './angular-jit-plugin.js';\nimport {\n createCompilerPlugin,\n createRolldownCompilerPlugin,\n} from './compiler-plugin.js';\nimport {\n StyleUrlsResolver,\n TemplateUrlsResolver,\n} from './component-resolvers.js';\nimport {\n augmentHostWithCaching,\n augmentHostWithResources,\n augmentProgramWithVersioning,\n mergeTransformers,\n} from './host.js';\n\nimport { angularVitestPlugins } from './angular-vitest-plugin.js';\nimport {\n createAngularCompilation,\n createJitResourceTransformer,\n SourceFileCache,\n angularFullVersion,\n} from './utils/devkit.js';\nimport { getJsTransformConfigKey, isRolldown } from './utils/rolldown.js';\nimport { type SourceFileCache as SourceFileCacheType } from './utils/source-file-cache.js';\n\nconst require = createRequire(import.meta.url);\n\nimport { pendingTasksPlugin } from './angular-pending-tasks.plugin.js';\nimport { liveReloadPlugin } from './live-reload-plugin.js';\nimport { EmitFileResult } from './models.js';\nimport { nxFolderPlugin } from './nx-folder-plugin.js';\nimport {\n FileReplacement,\n FileReplacementSSR,\n FileReplacementWith,\n replaceFiles,\n} from './plugins/file-replacements.plugin.js';\nimport { routerPlugin } from './router-plugin.js';\nimport { createHash } from 'node:crypto';\n\nexport enum DiagnosticModes {\n None = 0,\n Option = 1 << 0,\n Syntactic = 1 << 1,\n Semantic = 1 << 2,\n All = Option | Syntactic | Semantic,\n}\n\nexport interface PluginOptions {\n tsconfig?: string | (() => string);\n workspaceRoot?: string;\n inlineStylesExtension?: string;\n jit?: boolean;\n advanced?: {\n /**\n * Custom TypeScript transformers that are run before Angular compilation\n */\n tsTransformers?: ts.CustomTransformers;\n };\n supportedBrowsers?: string[];\n transformFilter?: (code: string, id: string) => boolean;\n /**\n * Additional files to include in compilation\n */\n include?: string[];\n additionalContentDirs?: string[];\n liveReload?: boolean;\n disableTypeChecking?: boolean;\n fileReplacements?: FileReplacement[];\n experimental?: {\n useAngularCompilationAPI?: boolean;\n };\n}\n\n/**\n * TypeScript file extension regex\n * Match .(c or m)ts, .ts extensions with an optional ? for query params\n * Ignore .tsx extensions\n */\nconst TS_EXT_REGEX = /\\.[cm]?(ts)[^x]?\\??/;\nconst classNames = new Map();\n\ninterface DeclarationFile {\n declarationFileDir: string;\n declarationPath: string;\n data: string;\n}\n\nexport function angular(options?: PluginOptions): Plugin[] {\n /**\n * Normalize plugin options so defaults\n * are used for values not provided.\n */\n const pluginOptions = {\n tsconfigGetter: createTsConfigGetter(options?.tsconfig),\n workspaceRoot: options?.workspaceRoot ?? process.cwd(),\n inlineStylesExtension: options?.inlineStylesExtension ?? 'css',\n advanced: {\n tsTransformers: {\n before: options?.advanced?.tsTransformers?.before ?? [],\n after: options?.advanced?.tsTransformers?.after ?? [],\n afterDeclarations:\n options?.advanced?.tsTransformers?.afterDeclarations ?? [],\n },\n },\n supportedBrowsers: options?.supportedBrowsers ?? ['safari 15'],\n jit: options?.jit,\n include: options?.include ?? [],\n additionalContentDirs: options?.additionalContentDirs ?? [],\n liveReload: options?.liveReload ?? false,\n disableTypeChecking: options?.disableTypeChecking ?? true,\n fileReplacements: options?.fileReplacements ?? [],\n useAngularCompilationAPI:\n options?.experimental?.useAngularCompilationAPI ?? false,\n };\n\n let resolvedConfig: ResolvedConfig;\n // Store config context needed for getTsConfigPath resolution\n let tsConfigResolutionContext: {\n root: string;\n isProd: boolean;\n isLib: boolean;\n } | null = null;\n\n const ts = require('typescript');\n let builder: ts.BuilderProgram | ts.EmitAndSemanticDiagnosticsBuilderProgram;\n let nextProgram: NgtscProgram | undefined;\n // Caches (always rebuild Angular program per user request)\n const tsconfigOptionsCache = new Map<\n string,\n { options: ts.CompilerOptions; rootNames: string[] }\n >();\n let cachedHost: ts.CompilerHost | undefined;\n let cachedHostKey: string | undefined;\n let includeCache: string[] = [];\n function invalidateFsCaches() {\n includeCache = [];\n }\n function invalidateTsconfigCaches() {\n // `readConfiguration` caches the root file list, so hot-added pages can be\n // missing from Angular's compilation program until we clear this state.\n tsconfigOptionsCache.clear();\n cachedHost = undefined;\n cachedHostKey = undefined;\n }\n let watchMode = false;\n let testWatchMode = isTestWatchMode();\n let inlineComponentStyles: Map<string, string> | undefined;\n let externalComponentStyles: Map<string, string> | undefined;\n const sourceFileCache: SourceFileCacheType = new SourceFileCache();\n const isTest = process.env['NODE_ENV'] === 'test' || !!process.env['VITEST'];\n const isVitestVscode = !!process.env['VITEST_VSCODE'];\n const isStackBlitz = !!process.versions['webcontainer'];\n const isAstroIntegration = process.env['ANALOG_ASTRO'] === 'true';\n\n const jit =\n typeof pluginOptions?.jit !== 'undefined' ? pluginOptions.jit : isTest;\n let viteServer: ViteDevServer | undefined;\n\n const styleUrlsResolver = new StyleUrlsResolver();\n const templateUrlsResolver = new TemplateUrlsResolver();\n let outputFile: ((file: string) => void) | undefined;\n const outputFiles = new Map<string, EmitFileResult>();\n const fileEmitter = (file: string) => {\n outputFile?.(file);\n return outputFiles.get(normalizePath(file));\n };\n let initialCompilation = false;\n const declarationFiles: DeclarationFile[] = [];\n const fileTransformMap = new Map<string, string>();\n let styleTransform: (\n code: string,\n filename: string,\n ) => Promise<vite.PreprocessCSSResult>;\n let pendingCompilation: Promise<void> | null;\n let compilationLock = Promise.resolve();\n // Persistent Angular Compilation API instance. Kept alive across rebuilds so\n // Angular can diff previous state and emit `templateUpdates` for HMR.\n // Previously the compilation was recreated on every pass, which meant Angular\n // never had prior state and could never produce HMR payloads.\n let angularCompilation:\n | Awaited<ReturnType<typeof createAngularCompilationType>>\n | undefined;\n\n function angularPlugin(): Plugin {\n let isProd = false;\n\n if (angularFullVersion < 190000 || isTest) {\n pluginOptions.liveReload = false;\n }\n\n // liveReload and fileReplacements guards were previously here and forced\n // both options off when useAngularCompilationAPI was enabled. Those guards\n // have been removed because:\n // - liveReload: the persistent compilation instance (above) now gives\n // Angular the prior state it needs to emit `templateUpdates` for HMR\n // - fileReplacements: Angular's AngularHostOptions already accepts a\n // `fileReplacements` record — we now convert and pass it through in\n // `performAngularCompilation` via `toAngularCompilationFileReplacements`\n if (pluginOptions.useAngularCompilationAPI) {\n if (angularFullVersion < 200100) {\n pluginOptions.useAngularCompilationAPI = false;\n console.warn(\n '[@analogjs/vite-plugin-angular]: The Angular Compilation API is only available with Angular v20.1 and later',\n );\n }\n }\n\n return {\n name: '@analogjs/vite-plugin-angular',\n async config(config, { command }) {\n watchMode = command === 'serve';\n isProd =\n config.mode === 'production' ||\n process.env['NODE_ENV'] === 'production';\n\n // Store the config context for later resolution in configResolved\n tsConfigResolutionContext = {\n root: config.root || '.',\n isProd,\n isLib: !!config?.build?.lib,\n };\n\n // Do a preliminary resolution for esbuild plugin (before configResolved)\n const preliminaryTsConfigPath = resolveTsConfigPath();\n\n const esbuild = pluginOptions.useAngularCompilationAPI\n ? undefined\n : (config.esbuild ?? false);\n const oxc = pluginOptions.useAngularCompilationAPI\n ? undefined\n : (config.oxc ?? false);\n\n const defineOptions = {\n ngJitMode: 'false',\n ngI18nClosureMode: 'false',\n ...(watchMode ? {} : { ngDevMode: 'false' }),\n };\n const useRolldown = isRolldown();\n const jsTransformConfigKey = getJsTransformConfigKey();\n const jsTransformConfigValue =\n jsTransformConfigKey === 'oxc' ? oxc : esbuild;\n\n const rolldownOptions: vite.DepOptimizationOptions['rolldownOptions'] =\n {\n plugins: [\n createRolldownCompilerPlugin(\n {\n tsconfig: preliminaryTsConfigPath,\n sourcemap: !isProd,\n advancedOptimizations: isProd,\n jit,\n incremental: watchMode,\n },\n // Astro manages the transformer lifecycle externally.\n !isAstroIntegration,\n ),\n ],\n };\n\n const esbuildOptions: vite.DepOptimizationOptions['esbuildOptions'] = {\n plugins: [\n createCompilerPlugin(\n {\n tsconfig: preliminaryTsConfigPath,\n sourcemap: !isProd,\n advancedOptimizations: isProd,\n jit,\n incremental: watchMode,\n },\n isTest,\n !isAstroIntegration,\n ),\n ],\n define: defineOptions,\n };\n\n return {\n [jsTransformConfigKey]: jsTransformConfigValue,\n optimizeDeps: {\n include: ['rxjs/operators', 'rxjs'],\n exclude: ['@angular/platform-server'],\n ...(useRolldown ? { rolldownOptions } : { esbuildOptions }),\n },\n resolve: {\n conditions: [\n 'style',\n ...(config.resolve?.conditions || defaultClientConditions),\n ],\n },\n };\n },\n configResolved(config) {\n resolvedConfig = config;\n\n if (pluginOptions.useAngularCompilationAPI) {\n externalComponentStyles = new Map();\n inlineComponentStyles = new Map();\n }\n\n if (!jit) {\n styleTransform = (code: string, filename: string) =>\n preprocessCSS(code, filename, config);\n }\n\n if (isTest) {\n // set test watch mode\n // - vite override from vitest-angular\n // - @nx/vite executor set server.watch explicitly to undefined (watch)/null (watch=false)\n // - vite config for test.watch variable\n // - vitest watch mode detected from the command line\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 // Add/unlink changes the TypeScript program shape, not just file\n // contents, so we need to invalidate both include discovery and the\n // cached tsconfig root names before recompiling.\n const invalidateCompilationOnFsChange = createFsWatcherCacheInvalidator(\n invalidateFsCaches,\n invalidateTsconfigCaches,\n () => performCompilation(resolvedConfig),\n );\n server.watcher.on('add', invalidateCompilationOnFsChange);\n server.watcher.on('unlink', invalidateCompilationOnFsChange);\n server.watcher.on('change', (file) => {\n if (file.includes('tsconfig')) {\n invalidateTsconfigCaches();\n }\n });\n },\n async buildStart() {\n // Defer the first compilation in test mode\n if (!isVitestVscode) {\n await performCompilation(resolvedConfig);\n pendingCompilation = null;\n\n initialCompilation = true;\n }\n },\n async handleHotUpdate(ctx) {\n if (TS_EXT_REGEX.test(ctx.file)) {\n const [fileId] = ctx.file.split('?');\n\n pendingCompilation = performCompilation(resolvedConfig, [fileId]);\n\n let result;\n\n if (pluginOptions.liveReload) {\n await pendingCompilation;\n pendingCompilation = null;\n result = fileEmitter(fileId);\n }\n\n if (\n pluginOptions.liveReload &&\n result?.hmrEligible &&\n classNames.get(fileId)\n ) {\n const relativeFileId = `${normalizePath(\n relative(process.cwd(), fileId),\n )}@${classNames.get(fileId)}`;\n\n sendHMRComponentUpdate(ctx.server, relativeFileId);\n\n return ctx.modules.map((mod) => {\n if (mod.id === ctx.file) {\n return markModuleSelfAccepting(mod);\n }\n\n return mod;\n });\n }\n }\n\n if (/\\.(html|htm|css|less|sass|scss)$/.test(ctx.file)) {\n fileTransformMap.delete(ctx.file.split('?')[0]);\n /**\n * Check to see if this was a direct request\n * for an external resource (styles, html).\n */\n const isDirect = ctx.modules.find(\n (mod) => ctx.file === mod.file && mod.id?.includes('?direct'),\n );\n const isInline = ctx.modules.find(\n (mod) => ctx.file === mod.file && mod.id?.includes('?inline'),\n );\n\n if (isDirect || isInline) {\n if (pluginOptions.liveReload && isDirect?.id && isDirect.file) {\n const isComponentStyle =\n isDirect.type === 'css' && isComponentStyleSheet(isDirect.id);\n if (isComponentStyle) {\n const { encapsulation } = getComponentStyleSheetMeta(\n isDirect.id,\n );\n\n // Track if the component uses ShadowDOM encapsulation\n // Shadow DOM components currently require a full reload.\n // Vite's CSS hot replacement does not support shadow root searching.\n if (encapsulation !== 'shadow') {\n ctx.server.ws.send({\n type: 'update',\n updates: [\n {\n type: 'css-update',\n timestamp: Date.now(),\n path: isDirect.url,\n acceptedPath: isDirect.file,\n },\n ],\n });\n\n return ctx.modules\n .filter((mod) => {\n // Component stylesheets will have 2 modules (*.component.scss and *.component.scss?direct&ngcomp=xyz&e=x)\n // We remove the module with the query params to prevent vite double logging the stylesheet name \"hmr update *.component.scss, *.component.scss?direct&ngcomp=xyz&e=x\"\n return mod.file !== ctx.file || mod.id !== isDirect.id;\n })\n .map((mod) => {\n if (mod.file === ctx.file) {\n return markModuleSelfAccepting(mod);\n }\n return mod;\n }) as ModuleNode[];\n }\n }\n }\n return ctx.modules;\n }\n\n const mods: ModuleNode[] = [];\n const updates: string[] = [];\n ctx.modules.forEach((mod) => {\n mod.importers.forEach((imp) => {\n ctx.server.moduleGraph.invalidateModule(imp);\n\n if (pluginOptions.liveReload && classNames.get(imp.id)) {\n updates.push(imp.id as string);\n } else {\n mods.push(imp);\n }\n });\n });\n\n pendingCompilation = performCompilation(resolvedConfig, [\n ...mods.map((mod) => mod.id as string),\n ...updates,\n ]);\n\n if (updates.length > 0) {\n await pendingCompilation;\n pendingCompilation = null;\n\n updates.forEach((updateId) => {\n const impRelativeFileId = `${normalizePath(\n relative(process.cwd(), updateId),\n )}@${classNames.get(updateId)}`;\n\n sendHMRComponentUpdate(ctx.server, impRelativeFileId);\n });\n\n return ctx.modules.map((mod) => {\n if (mod.id === ctx.file) {\n return markModuleSelfAccepting(mod);\n }\n\n return mod;\n });\n }\n\n return mods;\n }\n\n // clear HMR updates with a full reload\n classNames.clear();\n return ctx.modules;\n },\n resolveId(id, importer) {\n if (jit && id.startsWith('angular:jit:')) {\n const path = id.split(';')[1];\n return `${normalizePath(\n resolve(dirname(importer as string), path),\n )}?${id.includes(':style') ? 'inline' : 'raw'}`;\n }\n\n // Map angular external styleUrls to the source file\n if (isComponentStyleSheet(id)) {\n const componentStyles = externalComponentStyles?.get(\n getFilenameFromPath(id),\n );\n if (componentStyles) {\n return componentStyles + new URL(id, 'http://localhost').search;\n }\n }\n\n return undefined;\n },\n async load(id) {\n // Map angular inline styles to the source text\n if (isComponentStyleSheet(id)) {\n const componentStyles = inlineComponentStyles?.get(\n getFilenameFromPath(id),\n );\n if (componentStyles) {\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 /**\n * Check for options.transformFilter\n */\n if (\n options?.transformFilter &&\n !(options?.transformFilter(code, id) ?? true)\n ) {\n return;\n }\n\n if (pluginOptions.useAngularCompilationAPI) {\n const isAngular =\n /(Component|Directive|Pipe|Injectable|NgModule)\\(/.test(code);\n\n if (!isAngular) {\n return;\n }\n }\n\n /**\n * Skip transforming content files\n */\n if (id.includes('?') && id.includes('analog-content-')) {\n return;\n }\n\n /**\n * Encapsulate component stylesheets that use emulated encapsulation\n */\n if (pluginOptions.liveReload && isComponentStyleSheet(id)) {\n const { encapsulation, componentId } =\n getComponentStyleSheetMeta(id);\n if (encapsulation === 'emulated' && componentId) {\n const encapsulated = ngCompiler.encapsulateStyle(\n code,\n componentId,\n );\n return {\n code: encapsulated,\n map: null,\n };\n }\n }\n\n if (id.includes('.ts?')) {\n // Strip the query string off the ID\n // in case of a dynamically loaded file\n id = id.replace(/\\?(.*)/, '');\n }\n\n fileTransformMap.set(id, code);\n\n /**\n * Re-analyze on each transform\n * for test(Vitest)\n */\n if (isTest) {\n if (isVitestVscode && !initialCompilation) {\n // Do full initial compilation\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\n if (testWatchMode && invalidated) {\n pendingCompilation = performCompilation(resolvedConfig, [id]);\n }\n }\n }\n\n const hasComponent = code.includes('@Component');\n const templateUrls = hasComponent\n ? templateUrlsResolver.resolve(code, id)\n : [];\n const styleUrls = hasComponent\n ? styleUrlsResolver.resolve(code, id)\n : [];\n\n if (hasComponent && watchMode) {\n for (const urlSet of [...templateUrls, ...styleUrls]) {\n // `urlSet` is a string where a relative path is joined with an\n // absolute path using the `|` symbol.\n // For example: `./app.component.html|/home/projects/analog/src/app/app.component.html`.\n const [, absoluteFileUrl] = urlSet.split('|');\n this.addWatchFile(absoluteFileUrl);\n }\n }\n\n if (pendingCompilation) {\n await pendingCompilation;\n pendingCompilation = null;\n }\n\n const typescriptResult = fileEmitter(id);\n\n if (\n typescriptResult?.warnings &&\n typescriptResult?.warnings.length > 0\n ) {\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 // return fileEmitter\n let data = typescriptResult?.content ?? '';\n\n if (jit && data.includes('angular:jit:')) {\n data = data.replace(\n /angular:jit:style:inline;/g,\n 'virtual:angular:jit:style:inline;',\n );\n\n templateUrls.forEach((templateUrlSet) => {\n const [templateFile, resolvedTemplateUrl] =\n templateUrlSet.split('|');\n data = data.replace(\n `angular:jit:template:file;${templateFile}`,\n `${resolvedTemplateUrl}?raw`,\n );\n });\n\n styleUrls.forEach((styleUrlSet) => {\n const [styleFile, resolvedStyleUrl] = styleUrlSet.split('|');\n data = data.replace(\n `angular:jit:style:file;${styleFile}`,\n `${resolvedStyleUrl}?inline`,\n );\n });\n }\n\n return {\n code: data,\n map: null,\n };\n },\n },\n closeBundle() {\n declarationFiles.forEach(\n ({ declarationFileDir, declarationPath, data }) => {\n mkdirSync(declarationFileDir, { recursive: true });\n writeFileSync(declarationPath, data, 'utf-8');\n },\n );\n // Tear down the persistent compilation instance at end of build so it\n // does not leak memory across unrelated Vite invocations.\n angularCompilation?.close?.();\n angularCompilation = undefined;\n },\n };\n }\n\n return [\n replaceFiles(pluginOptions.fileReplacements, pluginOptions.workspaceRoot),\n angularPlugin(),\n pluginOptions.liveReload && liveReloadPlugin({ classNames, fileEmitter }),\n ...(isTest && !isStackBlitz ? angularVitestPlugins() : []),\n (jit &&\n jitPlugin({\n inlineStylesExtension: pluginOptions.inlineStylesExtension,\n })) as Plugin,\n buildOptimizerPlugin({\n supportedBrowsers: pluginOptions.supportedBrowsers,\n jit,\n }),\n routerPlugin(),\n angularFullVersion < 190004 && pendingTasksPlugin(),\n nxFolderPlugin(),\n ].filter(Boolean) as Plugin[];\n\n function findIncludes() {\n const workspaceRoot = normalizePath(resolve(pluginOptions.workspaceRoot));\n\n // Map include patterns to absolute workspace paths\n const globs = [\n ...pluginOptions.include.map((glob) => `${workspaceRoot}${glob}`),\n ];\n\n // Discover TypeScript files using tinyglobby\n return globSync(globs, {\n dot: true,\n absolute: true,\n });\n }\n\n function createTsConfigGetter(tsconfigOrGetter?: string | (() => string)) {\n if (typeof tsconfigOrGetter === 'function') {\n return tsconfigOrGetter;\n }\n\n return () => tsconfigOrGetter || '';\n }\n\n function getTsConfigPath(\n root: string,\n tsconfig: string,\n isProd: boolean,\n isTest: boolean,\n isLib: boolean,\n ) {\n if (tsconfig && isAbsolute(tsconfig)) {\n if (!existsSync(tsconfig)) {\n console.error(\n `[@analogjs/vite-plugin-angular]: Unable to resolve tsconfig at ${tsconfig}. This causes compilation issues. Check the path or set the \"tsconfig\" property with an absolute path.`,\n );\n }\n\n return tsconfig;\n }\n\n let tsconfigFilePath = './tsconfig.app.json';\n\n if (isLib) {\n tsconfigFilePath = isProd\n ? './tsconfig.lib.prod.json'\n : './tsconfig.lib.json';\n }\n\n if (isTest) {\n tsconfigFilePath = './tsconfig.spec.json';\n }\n\n if (tsconfig) {\n tsconfigFilePath = tsconfig;\n }\n\n const resolvedPath = resolve(root, tsconfigFilePath);\n\n if (!existsSync(resolvedPath)) {\n console.error(\n `[@analogjs/vite-plugin-angular]: Unable to resolve tsconfig at ${resolvedPath}. This causes compilation issues. Check the path or set the \"tsconfig\" property with an absolute path.`,\n );\n }\n\n return resolvedPath;\n }\n\n function resolveTsConfigPath() {\n const tsconfigValue = pluginOptions.tsconfigGetter();\n\n return getTsConfigPath(\n tsConfigResolutionContext!.root,\n tsconfigValue,\n tsConfigResolutionContext!.isProd,\n isTest,\n tsConfigResolutionContext!.isLib,\n );\n }\n\n /**\n * Perform compilation using Angular's private Compilation API.\n *\n * Key differences from the standard `performCompilation` path:\n * 1. The compilation instance is reused across rebuilds (nullish-coalescing\n * assignment below) so Angular retains prior state and can diff it to\n * produce `templateUpdates` for HMR.\n * 2. `ids` (modified files) are forwarded to both the source-file cache and\n * `angularCompilation.update()` so that incremental re-analysis is\n * scoped to what actually changed.\n * 3. `fileReplacements` are converted and passed into Angular's host via\n * `toAngularCompilationFileReplacements`.\n * 4. `templateUpdates` from the compilation result are mapped back to\n * file-level HMR metadata (`hmrUpdateCode`, `hmrEligible`, `classNames`).\n */\n async function performAngularCompilation(\n config: ResolvedConfig,\n ids?: string[],\n ) {\n // Reuse the existing instance so Angular can diff against prior state.\n 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 // Notify Angular of modified files before re-initialization so it can\n // scope its incremental analysis.\n if (modifiedFiles?.size && angularCompilation.update) {\n await angularCompilation.update(modifiedFiles);\n }\n\n const resolvedTsConfigPath = resolveTsConfigPath();\n const compilationResult = await angularCompilation.initialize(\n resolvedTsConfigPath,\n {\n // Convert Analog's browser-style `{ replace, with }` entries into the\n // `Record<string, string>` shape that Angular's AngularHostOptions\n // expects. SSR-only replacements (`{ replace, ssr }`) are intentionally\n // excluded — they stay on the Vite runtime side.\n fileReplacements: toAngularCompilationFileReplacements(\n pluginOptions.fileReplacements,\n pluginOptions.workspaceRoot,\n ),\n modifiedFiles,\n async transformStylesheet(\n data,\n containingFile,\n resourceFile,\n order,\n className,\n ) {\n if (pluginOptions.liveReload) {\n const id = createHash('sha256')\n .update(containingFile)\n .update(className as string)\n .update(String(order))\n .update(data)\n .digest('hex');\n const filename = id + '.' + pluginOptions.inlineStylesExtension;\n inlineComponentStyles!.set(filename, data);\n return filename;\n }\n\n const filename =\n resourceFile ??\n containingFile.replace('.ts', `.${options?.inlineStylesExtension}`);\n\n let stylesheetResult;\n\n try {\n stylesheetResult = await preprocessCSS(\n data,\n `${filename}?direct`,\n resolvedConfig,\n );\n } catch (e) {\n console.error(`${e}`);\n }\n\n return stylesheetResult?.code || '';\n },\n processWebWorker(workerFile, containingFile) {\n return '';\n },\n },\n (tsCompilerOptions) => {\n if (pluginOptions.liveReload && watchMode) {\n tsCompilerOptions['_enableHmr'] = true;\n tsCompilerOptions['externalRuntimeStyles'] = true;\n // Workaround for https://github.com/angular/angular/issues/59310\n // Force extra instructions to be generated for HMR w/defer\n tsCompilerOptions['supportTestBed'] = true;\n }\n\n if (tsCompilerOptions.compilationMode === 'partial') {\n // These options can't be false in partial mode\n tsCompilerOptions['supportTestBed'] = true;\n tsCompilerOptions['supportJitMode'] = true;\n }\n\n if (!isTest && config.build?.lib) {\n tsCompilerOptions['declaration'] = true;\n tsCompilerOptions['declarationMap'] = watchMode;\n tsCompilerOptions['inlineSources'] = true;\n }\n\n if (isTest) {\n // Allow `TestBed.overrideXXX()` APIs.\n tsCompilerOptions['supportTestBed'] = true;\n }\n\n return tsCompilerOptions;\n },\n );\n\n compilationResult.externalStylesheets?.forEach((value, key) => {\n externalComponentStyles?.set(`${value}.css`, key);\n });\n\n const diagnostics = await angularCompilation.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 // Angular encodes template updates as `encodedFilePath@ClassName` keys.\n // `mapTemplateUpdatesToFiles` decodes them back to absolute file paths so\n // we can attach HMR metadata to the correct `EmitFileResult` below.\n const templateUpdates = mapTemplateUpdatesToFiles(\n compilationResult.templateUpdates,\n );\n\n for (const file of await angularCompilation.emitAffectedFiles()) {\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 // Surface Angular's HMR payloads into Analog's existing live-reload\n // flow via the `hmrUpdateCode` / `hmrEligible` fields.\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 _doPerformCompilation(config, ids);\n } finally {\n resolve!();\n }\n }\n\n /**\n * This method share mutable state and performs the actual compilation work.\n * It should not be called concurrently. Use `performCompilation` which wraps this method in a lock to ensure only one compilation runs at a time.\n */\n async function _doPerformCompilation(config: ResolvedConfig, ids?: string[]) {\n // Forward `ids` (modified files) so the Compilation API path can do\n // incremental re-analysis instead of a full recompile on every change.\n if (pluginOptions.useAngularCompilationAPI) {\n await performAngularCompilation(config, ids);\n return;\n }\n\n const isProd = config.mode === 'production';\n const modifiedFiles = new Set<string>(ids ?? []);\n sourceFileCache.invalidate(modifiedFiles);\n\n if (ids?.length) {\n for (const id of ids || []) {\n fileTransformMap.delete(id);\n }\n }\n\n // Cached include discovery (invalidated only on FS events)\n if (pluginOptions.include.length > 0 && includeCache.length === 0) {\n includeCache = findIncludes();\n }\n\n const resolvedTsConfigPath = resolveTsConfigPath();\n const tsconfigKey = [\n resolvedTsConfigPath,\n isProd ? 'prod' : 'dev',\n isTest ? 'test' : 'app',\n config.build?.lib ? 'lib' : 'nolib',\n ].join('|');\n let cached = tsconfigOptionsCache.get(tsconfigKey);\n\n if (!cached) {\n const read = compilerCli.readConfiguration(resolvedTsConfigPath, {\n suppressOutputPathCheck: true,\n outDir: undefined,\n sourceMap: false,\n inlineSourceMap: !isProd,\n inlineSources: !isProd,\n declaration: false,\n declarationMap: false,\n allowEmptyCodegenFiles: false,\n annotationsAs: 'decorators',\n enableResourceInlining: false,\n noEmitOnError: false,\n mapRoot: undefined,\n sourceRoot: undefined,\n supportTestBed: false,\n supportJitMode: false,\n });\n cached = { options: read.options, rootNames: read.rootNames };\n tsconfigOptionsCache.set(tsconfigKey, cached);\n }\n\n // Clone options before mutation (preserve cache purity)\n const tsCompilerOptions = { ...cached.options };\n let rootNames = [...cached.rootNames];\n\n if (pluginOptions.liveReload && watchMode) {\n tsCompilerOptions['_enableHmr'] = true;\n tsCompilerOptions['externalRuntimeStyles'] = true;\n // Workaround for https://github.com/angular/angular/issues/59310\n // Force extra instructions to be generated for HMR w/defer\n tsCompilerOptions['supportTestBed'] = true;\n }\n\n if (tsCompilerOptions['compilationMode'] === 'partial') {\n // These options can't be false in partial mode\n tsCompilerOptions['supportTestBed'] = true;\n tsCompilerOptions['supportJitMode'] = true;\n }\n\n if (!isTest && config.build?.lib) {\n tsCompilerOptions['declaration'] = true;\n tsCompilerOptions['declarationMap'] = watchMode;\n tsCompilerOptions['inlineSources'] = true;\n }\n\n if (isTest) {\n // Allow `TestBed.overrideXXX()` APIs.\n tsCompilerOptions['supportTestBed'] = true;\n }\n\n const replacements = pluginOptions.fileReplacements.map((rp) =>\n join(\n pluginOptions.workspaceRoot,\n (rp as FileReplacementSSR).ssr || (rp as FileReplacementWith).with,\n ),\n );\n // Merge + dedupe root names\n rootNames = [...new Set([...rootNames, ...includeCache, ...replacements])];\n const hostKey = JSON.stringify(tsCompilerOptions);\n let host: ts.CompilerHost;\n\n if (cachedHost && cachedHostKey === hostKey) {\n host = cachedHost;\n } else {\n host = ts.createIncrementalCompilerHost(tsCompilerOptions, {\n ...ts.sys,\n readFile(path: string, encoding: string) {\n if (fileTransformMap.has(path)) {\n return fileTransformMap.get(path);\n }\n\n const file = ts.sys.readFile.call(null, path, encoding);\n\n if (file) {\n fileTransformMap.set(path, file);\n }\n\n return file;\n },\n });\n cachedHost = host;\n cachedHostKey = hostKey;\n\n // Only store cache if in watch mode\n if (watchMode) {\n augmentHostWithCaching(host, sourceFileCache);\n }\n }\n\n if (!jit) {\n inlineComponentStyles = tsCompilerOptions['externalRuntimeStyles']\n ? new Map()\n : undefined;\n externalComponentStyles = tsCompilerOptions['externalRuntimeStyles']\n ? new Map()\n : undefined;\n augmentHostWithResources(host, styleTransform, {\n inlineStylesExtension: pluginOptions.inlineStylesExtension,\n isProd,\n inlineComponentStyles,\n externalComponentStyles,\n sourceFileCache,\n });\n }\n\n /**\n * Creates a new NgtscProgram to analyze/re-analyze\n * the source files and create a file emitter.\n * This is shared between an initial build and a hot update.\n */\n let typeScriptProgram: ts.Program;\n let angularCompiler: NgtscProgram['compiler'];\n const oldBuilder =\n builder ?? ts.readBuilderProgram(tsCompilerOptions, host);\n\n if (!jit) {\n // Create the Angular specific program that contains the Angular compiler\n const angularProgram: NgtscProgram = new compilerCli.NgtscProgram(\n rootNames,\n tsCompilerOptions,\n host,\n nextProgram,\n );\n angularCompiler = angularProgram.compiler;\n typeScriptProgram = angularProgram.compiler.getCurrentProgram();\n augmentProgramWithVersioning(typeScriptProgram);\n\n builder = ts.createEmitAndSemanticDiagnosticsBuilderProgram(\n typeScriptProgram,\n host,\n oldBuilder as ts.EmitAndSemanticDiagnosticsBuilderProgram,\n );\n\n nextProgram = angularProgram;\n } else {\n builder = ts.createEmitAndSemanticDiagnosticsBuilderProgram(\n rootNames,\n tsCompilerOptions,\n host,\n oldBuilder as ts.EmitAndSemanticDiagnosticsBuilderProgram,\n );\n\n typeScriptProgram = builder.getProgram();\n }\n\n if (!watchMode) {\n // When not in watch mode, the startup cost of the incremental analysis can be avoided by\n // using an abstract builder that only wraps a TypeScript program.\n builder = ts.createAbstractBuilder(typeScriptProgram, host, oldBuilder);\n }\n\n if (angularCompiler!) {\n await angularCompiler.analyzeAsync();\n }\n\n const beforeTransformers = jit\n ? [\n compilerCli.constructorParametersDownlevelTransform(\n builder.getProgram(),\n ),\n createJitResourceTransformer(() =>\n builder.getProgram().getTypeChecker(),\n ),\n ]\n : [];\n\n const transformers = mergeTransformers(\n { before: beforeTransformers },\n jit ? {} : angularCompiler!.prepareEmit().transformers,\n );\n\n const fileMetadata = getFileMetadata(\n builder,\n angularCompiler!,\n pluginOptions.liveReload,\n pluginOptions.disableTypeChecking,\n );\n\n const writeFileCallback: ts.WriteFileCallback = (\n _filename,\n content,\n _a,\n _b,\n sourceFiles,\n ) => {\n if (!sourceFiles?.length) {\n return;\n }\n\n const filename = normalizePath(sourceFiles[0].fileName);\n\n if (filename.includes('ngtypecheck.ts') || filename.includes('.d.')) {\n return;\n }\n\n const metadata = watchMode ? fileMetadata(filename) : {};\n\n outputFiles.set(filename, {\n content,\n dependencies: [],\n errors: metadata.errors,\n warnings: metadata.warnings,\n hmrUpdateCode: metadata.hmrUpdateCode,\n hmrEligible: metadata.hmrEligible,\n });\n };\n\n const writeOutputFile = (id: string) => {\n const sourceFile = builder.getSourceFile(id);\n if (!sourceFile) {\n return;\n }\n\n let content = '';\n builder.emit(\n sourceFile,\n (filename, data) => {\n if (/\\.[cm]?js$/.test(filename)) {\n content = data;\n }\n\n if (\n !watchMode &&\n !isTest &&\n /\\.d\\.ts/.test(filename) &&\n !filename.includes('.ngtypecheck.')\n ) {\n // output to library root instead /src\n const declarationPath = resolve(\n config.root,\n config.build.outDir,\n relative(config.root, filename),\n ).replace('/src/', '/');\n\n const declarationFileDir = declarationPath\n .replace(basename(filename), '')\n .replace('/src/', '/');\n\n declarationFiles.push({\n declarationFileDir,\n declarationPath,\n data,\n });\n }\n },\n undefined /* cancellationToken */,\n undefined /* emitOnlyDtsFiles */,\n transformers,\n );\n\n writeFileCallback(id, content, false, undefined, [sourceFile]);\n\n if (angularCompiler) {\n angularCompiler.incrementalCompilation.recordSuccessfulEmit(sourceFile);\n }\n };\n\n if (watchMode) {\n if (ids && ids.length > 0) {\n ids.forEach((id) => writeOutputFile(id));\n } else {\n /**\n * Only block the server from starting up\n * during testing.\n */\n if (isTest) {\n // TypeScript will loop until there are no more affected files in the program\n while (\n (\n builder as ts.EmitAndSemanticDiagnosticsBuilderProgram\n ).emitNextAffectedFile(\n writeFileCallback,\n undefined,\n undefined,\n transformers,\n )\n ) {\n /* empty */\n }\n }\n }\n }\n\n if (!isTest) {\n /**\n * Perf: Output files on demand so the dev server\n * isn't blocked when emitting files.\n */\n outputFile = writeOutputFile;\n }\n }\n}\n\nexport function createFsWatcherCacheInvalidator(\n invalidateFsCaches: () => void,\n invalidateTsconfigCaches: () => void,\n performCompilation: () => Promise<void>,\n): () => Promise<void> {\n return async (): Promise<void> => {\n invalidateFsCaches();\n invalidateTsconfigCaches();\n await performCompilation();\n };\n}\n\n/**\n * Convert Analog/Angular CLI-style file replacements into the flat record\n * expected by `AngularHostOptions.fileReplacements`.\n *\n * Only browser replacements (`{ replace, with }`) are converted. SSR-only\n * replacements (`{ replace, ssr }`) are left for the Vite runtime plugin to\n * handle — they should not be baked into the Angular compilation host because\n * that would apply them to both browser and server builds.\n *\n * Relative paths are resolved against `workspaceRoot` so that the host\n * receives the same absolute paths it would get from the Angular CLI.\n */\nexport function toAngularCompilationFileReplacements(\n replacements: FileReplacement[],\n workspaceRoot: string,\n): Record<string, string> | undefined {\n const mappedReplacements = replacements.flatMap((replacement) => {\n // Skip SSR-only entries — they use `ssr` instead of `with`.\n if (!('with' in replacement)) {\n return [];\n }\n\n return [\n [\n isAbsolute(replacement.replace)\n ? replacement.replace\n : resolve(workspaceRoot, replacement.replace),\n isAbsolute(replacement.with)\n ? replacement.with\n : resolve(workspaceRoot, replacement.with),\n ] as const,\n ];\n });\n\n return mappedReplacements.length\n ? Object.fromEntries(mappedReplacements)\n : undefined;\n}\n\n/**\n * Map Angular's `templateUpdates` (keyed by `encodedFilePath@ClassName`)\n * back to absolute file paths with their associated HMR code and component\n * class name.\n *\n * Angular's private Compilation API emits template update keys in the form\n * `encodeURIComponent(relativePath + '@' + className)`. We decode and resolve\n * them so the caller can look up updates by the same normalized absolute path\n * used elsewhere in the plugin (`outputFiles`, `classNames`, etc.).\n */\nexport function mapTemplateUpdatesToFiles(\n templateUpdates: ReadonlyMap<string, string> | undefined,\n): Map<\n string,\n {\n className: string;\n code: string;\n }\n> {\n const updatesByFile = new Map<string, { className: string; code: string }>();\n\n templateUpdates?.forEach((code, encodedUpdateId) => {\n const [file, className = ''] =\n decodeURIComponent(encodedUpdateId).split('@');\n const resolvedFile = normalizePath(resolve(process.cwd(), file));\n\n updatesByFile.set(resolvedFile, {\n className,\n code,\n });\n });\n\n return updatesByFile;\n}\n\nfunction sendHMRComponentUpdate(server: ViteDevServer, id: string) {\n server.ws.send('angular:component-update', {\n id: encodeURIComponent(id),\n timestamp: Date.now(),\n });\n\n classNames.delete(id);\n}\n\nexport function getFileMetadata(\n program: ts.BuilderProgram,\n angularCompiler?: NgtscProgram['compiler'],\n liveReload?: boolean,\n disableTypeChecking?: boolean,\n) {\n const ts = require('typescript');\n return (\n file: string,\n ): {\n errors?: string[];\n warnings?: (string | ts.DiagnosticMessageChain)[];\n hmrUpdateCode?: string | null;\n hmrEligible?: boolean;\n } => {\n const sourceFile = program.getSourceFile(file);\n if (!sourceFile) {\n return {};\n }\n\n const diagnostics = getDiagnosticsForSourceFile(\n sourceFile,\n !!disableTypeChecking,\n program,\n angularCompiler,\n );\n\n const errors = diagnostics\n .filter((d) => d.category === ts.DiagnosticCategory?.Error)\n .map((d) =>\n typeof d.messageText === 'object'\n ? d.messageText.messageText\n : d.messageText,\n );\n\n const warnings = diagnostics\n .filter((d) => d.category === ts.DiagnosticCategory?.Warning)\n .map((d) => d.messageText);\n\n let hmrUpdateCode: string | null | undefined = undefined;\n\n let hmrEligible = false;\n if (liveReload) {\n for (const node of sourceFile.statements) {\n if (ts.isClassDeclaration(node) && (node as any).name != null) {\n hmrUpdateCode = angularCompiler?.emitHmrUpdateModule(node as any);\n if (hmrUpdateCode) {\n classNames.set(file, (node as any).name.getText());\n hmrEligible = true;\n }\n }\n }\n }\n\n return { errors, warnings, hmrUpdateCode, hmrEligible };\n };\n}\n\nfunction getDiagnosticsForSourceFile(\n sourceFile: ts.SourceFile,\n disableTypeChecking: boolean,\n program: ts.BuilderProgram,\n angularCompiler?: NgtscProgram['compiler'],\n) {\n const syntacticDiagnostics = program.getSyntacticDiagnostics(sourceFile);\n\n if (disableTypeChecking) {\n // Syntax errors are cheap to compute and the app will not run if there are any\n // So always show these types of errors regardless if type checking is disabled\n return syntacticDiagnostics;\n }\n\n const semanticDiagnostics = program.getSemanticDiagnostics(sourceFile);\n const angularDiagnostics = angularCompiler\n ? angularCompiler.getDiagnosticsForFile(sourceFile, 1)\n : [];\n return [\n ...syntacticDiagnostics,\n ...semanticDiagnostics,\n ...angularDiagnostics,\n ];\n}\n\nfunction markModuleSelfAccepting(mod: ModuleNode): ModuleNode {\n // support Vite 6\n if ('_clientModule' in mod) {\n (mod as any)['_clientModule'].isSelfAccepting = true;\n }\n\n return {\n ...mod,\n isSelfAccepting: true,\n } as ModuleNode;\n}\n\nfunction isComponentStyleSheet(id: string): boolean {\n return id.includes('ngcomp=');\n}\n\nfunction getComponentStyleSheetMeta(id: string): {\n componentId: string;\n encapsulation: 'emulated' | 'shadow' | 'none';\n} {\n const params = new URL(id, 'http://localhost').searchParams;\n const encapsulationMapping = {\n '0': 'emulated',\n '2': 'none',\n '3': 'shadow',\n };\n return {\n componentId: params.get('ngcomp')!,\n encapsulation: encapsulationMapping[\n params.get('e') as keyof typeof encapsulationMapping\n ] as 'emulated' | 'shadow' | 'none',\n };\n}\n\n/**\n * Removes leading / and query string from a url path\n * e.g. /foo.scss?direct&ngcomp=ng-c3153525609&e=0 returns foo.scss\n * @param id\n */\nfunction getFilenameFromPath(id: string): string {\n return new URL(id, 'http://localhost').pathname.replace(/^\\//, '');\n}\n\n/**\n * Checks for vitest run from the command line\n * @returns boolean\n */\nexport function isTestWatchMode(args: string[] = process.argv): boolean {\n // vitest --run\n const hasRun = args.find((arg) => arg.includes('--run'));\n if (hasRun) {\n return false;\n }\n\n // vitest --no-run\n const hasNoRun = args.find((arg) => arg.includes('--no-run'));\n if (hasNoRun) {\n return true;\n }\n\n // check for --watch=false or --no-watch\n const hasWatch = args.find((arg) => arg.includes('watch'));\n if (hasWatch && ['false', 'no'].some((neg) => hasWatch.includes(neg))) {\n return false;\n }\n\n // check for --watch false\n const watchIndex = args.findIndex((arg) => arg.includes('watch'));\n const watchArg = args[watchIndex + 1];\n if (watchArg && watchArg === 'false') {\n return false;\n }\n\n return true;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"angular-vite-plugin.js","names":[],"sources":["../../../src/lib/angular-vite-plugin.ts"],"sourcesContent":["import { NgtscProgram } from '@angular/compiler-cli';\nimport { existsSync, mkdirSync, writeFileSync } from 'node:fs';\nimport {\n basename,\n dirname,\n isAbsolute,\n join,\n relative,\n resolve,\n} from 'node:path';\nimport * as vite from 'vite';\n\nimport * as compilerCli from '@angular/compiler-cli';\nimport { createRequire } from 'node:module';\nimport * as ts from 'typescript';\nimport { type createAngularCompilation as createAngularCompilationType } from '@angular/build/private';\n\nimport * as ngCompiler from '@angular/compiler';\nimport { globSync } from 'tinyglobby';\nimport {\n defaultClientConditions,\n ModuleNode,\n normalizePath,\n Plugin,\n preprocessCSS,\n ResolvedConfig,\n ViteDevServer,\n} from 'vite';\nimport { buildOptimizerPlugin } from './angular-build-optimizer-plugin.js';\nimport { jitPlugin } from './angular-jit-plugin.js';\nimport {\n createCompilerPlugin,\n createRolldownCompilerPlugin,\n} from './compiler-plugin.js';\nimport {\n StyleUrlsResolver,\n TemplateUrlsResolver,\n} from './component-resolvers.js';\nimport {\n augmentHostWithCaching,\n augmentHostWithResources,\n augmentProgramWithVersioning,\n mergeTransformers,\n} from './host.js';\nimport type { StylePreprocessor } from './style-preprocessor.js';\n\nimport { angularVitestPlugins } from './angular-vitest-plugin.js';\nimport {\n createAngularCompilation,\n createJitResourceTransformer,\n SourceFileCache,\n angularFullVersion,\n} from './utils/devkit.js';\nimport { getJsTransformConfigKey, isRolldown } from './utils/rolldown.js';\nimport { type SourceFileCache as SourceFileCacheType } from './utils/source-file-cache.js';\n\nconst require = createRequire(import.meta.url);\n\nimport { pendingTasksPlugin } from './angular-pending-tasks.plugin.js';\nimport { liveReloadPlugin } from './live-reload-plugin.js';\nimport { EmitFileResult } from './models.js';\nimport { nxFolderPlugin } from './nx-folder-plugin.js';\nimport {\n FileReplacement,\n FileReplacementSSR,\n FileReplacementWith,\n replaceFiles,\n} from './plugins/file-replacements.plugin.js';\nimport { routerPlugin } from './router-plugin.js';\nimport { createHash } from 'node:crypto';\n\nexport enum DiagnosticModes {\n None = 0,\n Option = 1 << 0,\n Syntactic = 1 << 1,\n Semantic = 1 << 2,\n All = Option | Syntactic | Semantic,\n}\n\nexport interface PluginOptions {\n tsconfig?: string | (() => string);\n workspaceRoot?: string;\n inlineStylesExtension?: string;\n jit?: boolean;\n advanced?: {\n /**\n * Custom TypeScript transformers that are run before Angular compilation\n */\n tsTransformers?: ts.CustomTransformers;\n };\n supportedBrowsers?: string[];\n transformFilter?: (code: string, id: string) => boolean;\n /**\n * Additional files to include in compilation\n */\n include?: string[];\n additionalContentDirs?: string[];\n liveReload?: boolean;\n disableTypeChecking?: boolean;\n fileReplacements?: FileReplacement[];\n experimental?: {\n useAngularCompilationAPI?: boolean;\n };\n /**\n * Optional preprocessor that transforms component CSS before it enters Vite's\n * preprocessCSS pipeline. Runs on every component stylesheet (both external\n * `.component.css` files and inline `styles: [...]` blocks).\n *\n * @param code - Raw CSS content of the component stylesheet\n * @param filename - Resolved file path of the stylesheet (or containing .ts file for inline styles)\n * @returns Transformed CSS string, or the original code if no transformation is needed\n */\n stylePreprocessor?: StylePreprocessor;\n /**\n * First-class Tailwind CSS v4 integration for Angular component styles.\n *\n * Angular's compiler processes component CSS through Vite's `preprocessCSS()`,\n * which runs `@tailwindcss/vite` — but each component stylesheet is processed\n * in isolation without access to the root Tailwind configuration (prefix, @theme,\n * @custom-variant, @plugin definitions). This causes errors like:\n *\n * \"Cannot apply utility class `sa:grid` because the `sa` variant does not exist\"\n *\n * The `tailwindCss` option solves this by auto-injecting a `@reference` directive\n * into every component CSS file that uses Tailwind utilities, pointing it to the\n * root Tailwind stylesheet so `@tailwindcss/vite` can resolve the full configuration.\n *\n * @example Basic usage — reference a root Tailwind CSS file:\n * ```ts\n * import { resolve } from 'node:path';\n *\n * angular({\n * tailwindCss: {\n * rootStylesheet: resolve(__dirname, 'src/styles/tailwind.css'),\n * },\n * })\n * ```\n *\n * @example With prefix detection — only inject for files using specific prefixes:\n * ```ts\n * angular({\n * tailwindCss: {\n * rootStylesheet: resolve(__dirname, 'src/styles/tailwind.css'),\n * // Only inject @reference into files that use these prefixed classes\n * prefixes: ['sa:', 'tw:'],\n * },\n * })\n * ```\n *\n * @example AnalogJS platform — passed through the `vite` option:\n * ```ts\n * analog({\n * vite: {\n * tailwindCss: {\n * rootStylesheet: resolve(__dirname, '../../../libs/meritos/tailwind.config.css'),\n * },\n * },\n * })\n * ```\n */\n tailwindCss?: {\n /**\n * Absolute path to the root Tailwind CSS file that contains `@import \"tailwindcss\"`,\n * `@theme`, `@custom-variant`, and `@plugin` definitions.\n *\n * A `@reference` directive pointing to this file will be auto-injected into\n * component CSS files that use Tailwind utilities.\n */\n rootStylesheet: string;\n /**\n * Optional list of class prefixes to detect (e.g. `['sa:', 'tw:']`).\n * When provided, `@reference` is only injected into component CSS files that\n * contain at least one of these prefixes. When omitted, `@reference` is injected\n * into all component CSS files that contain `@apply` or `@` directives.\n *\n * @default undefined — inject into all component CSS files with `@apply`\n */\n prefixes?: string[];\n };\n}\n\n/**\n * TypeScript file extension regex\n * Match .(c or m)ts, .ts extensions with an optional ? for query params\n * Ignore .tsx extensions\n */\nconst TS_EXT_REGEX = /\\.[cm]?(ts)[^x]?\\??/;\nconst classNames = new Map();\n\ninterface DeclarationFile {\n declarationFileDir: string;\n declarationPath: string;\n data: string;\n}\n\n/**\n * Builds a resolved stylePreprocessor function from plugin options.\n * If `tailwindCss` is provided, creates an auto-reference injector.\n * If `stylePreprocessor` is also provided, chains them (tailwind first, then user).\n */\nfunction buildStylePreprocessor(\n options?: PluginOptions,\n): ((code: string, filename: string) => string) | undefined {\n const userPreprocessor = options?.stylePreprocessor;\n const tw = options?.tailwindCss;\n\n if (!tw && !userPreprocessor) {\n return undefined;\n }\n\n // Build the Tailwind @reference injector\n let tailwindPreprocessor:\n | ((code: string, filename: string) => string)\n | undefined;\n\n if (tw) {\n const rootStylesheet = tw.rootStylesheet;\n const prefixes = tw.prefixes;\n\n tailwindPreprocessor = (code: string, filename: string): string => {\n // Skip if already has @reference or is a root Tailwind file\n if (\n code.includes('@reference') ||\n code.includes('@import \"tailwindcss\"') ||\n code.includes(\"@import 'tailwindcss'\")\n ) {\n return code;\n }\n\n // Check if the file uses Tailwind utilities\n const needsReference = prefixes\n ? prefixes.some((prefix) => code.includes(prefix))\n : code.includes('@apply');\n\n if (!needsReference) {\n return code;\n }\n\n const refPath = relative(dirname(filename), rootStylesheet);\n return `@reference \"${refPath}\";\\n${code}`;\n };\n }\n\n // Chain: tailwind preprocessor first, then user preprocessor\n if (tailwindPreprocessor && userPreprocessor) {\n return (code: string, filename: string) => {\n const intermediate = tailwindPreprocessor!(code, filename);\n return userPreprocessor(intermediate, filename);\n };\n }\n\n return tailwindPreprocessor ?? userPreprocessor;\n}\n\nexport function angular(options?: PluginOptions): Plugin[] {\n /**\n * Normalize plugin options so defaults\n * are used for values not provided.\n */\n const pluginOptions = {\n tsconfigGetter: createTsConfigGetter(options?.tsconfig),\n workspaceRoot: options?.workspaceRoot ?? process.cwd(),\n inlineStylesExtension: options?.inlineStylesExtension ?? 'css',\n advanced: {\n tsTransformers: {\n before: options?.advanced?.tsTransformers?.before ?? [],\n after: options?.advanced?.tsTransformers?.after ?? [],\n afterDeclarations:\n options?.advanced?.tsTransformers?.afterDeclarations ?? [],\n },\n },\n supportedBrowsers: options?.supportedBrowsers ?? ['safari 15'],\n jit: options?.jit,\n include: options?.include ?? [],\n additionalContentDirs: options?.additionalContentDirs ?? [],\n liveReload: options?.liveReload ?? false,\n disableTypeChecking: options?.disableTypeChecking ?? true,\n fileReplacements: options?.fileReplacements ?? [],\n useAngularCompilationAPI:\n options?.experimental?.useAngularCompilationAPI ?? false,\n stylePreprocessor: buildStylePreprocessor(options),\n };\n\n let resolvedConfig: ResolvedConfig;\n // Store config context needed for getTsConfigPath resolution\n let tsConfigResolutionContext: {\n root: string;\n isProd: boolean;\n isLib: boolean;\n } | null = null;\n\n const ts = require('typescript');\n let builder: ts.BuilderProgram | ts.EmitAndSemanticDiagnosticsBuilderProgram;\n let nextProgram: NgtscProgram | undefined;\n // Caches (always rebuild Angular program per user request)\n const tsconfigOptionsCache = new Map<\n string,\n { options: ts.CompilerOptions; rootNames: string[] }\n >();\n let cachedHost: ts.CompilerHost | undefined;\n let cachedHostKey: string | undefined;\n let includeCache: string[] = [];\n function invalidateFsCaches() {\n includeCache = [];\n }\n function invalidateTsconfigCaches() {\n // `readConfiguration` caches the root file list, so hot-added pages can be\n // missing from Angular's compilation program until we clear this state.\n tsconfigOptionsCache.clear();\n cachedHost = undefined;\n cachedHostKey = undefined;\n }\n let watchMode = false;\n let testWatchMode = isTestWatchMode();\n let inlineComponentStyles: Map<string, string> | undefined;\n let externalComponentStyles: Map<string, string> | undefined;\n const sourceFileCache: SourceFileCacheType = new SourceFileCache();\n const isTest = process.env['NODE_ENV'] === 'test' || !!process.env['VITEST'];\n const isVitestVscode = !!process.env['VITEST_VSCODE'];\n const isStackBlitz = !!process.versions['webcontainer'];\n const isAstroIntegration = process.env['ANALOG_ASTRO'] === 'true';\n\n const jit =\n typeof pluginOptions?.jit !== 'undefined' ? pluginOptions.jit : isTest;\n let viteServer: ViteDevServer | undefined;\n\n const styleUrlsResolver = new StyleUrlsResolver();\n const templateUrlsResolver = new TemplateUrlsResolver();\n let outputFile: ((file: string) => void) | undefined;\n const outputFiles = new Map<string, EmitFileResult>();\n const fileEmitter = (file: string) => {\n outputFile?.(file);\n return outputFiles.get(normalizePath(file));\n };\n let initialCompilation = false;\n const declarationFiles: DeclarationFile[] = [];\n const fileTransformMap = new Map<string, string>();\n let styleTransform: (\n code: string,\n filename: string,\n ) => Promise<vite.PreprocessCSSResult>;\n let pendingCompilation: Promise<void> | null;\n let compilationLock = Promise.resolve();\n // Persistent Angular Compilation API instance. Kept alive across rebuilds so\n // Angular can diff previous state and emit `templateUpdates` for HMR.\n // Previously the compilation was recreated on every pass, which meant Angular\n // never had prior state and could never produce HMR payloads.\n let angularCompilation:\n | Awaited<ReturnType<typeof createAngularCompilationType>>\n | undefined;\n\n function angularPlugin(): Plugin {\n let isProd = false;\n\n if (angularFullVersion < 190000 || isTest) {\n pluginOptions.liveReload = false;\n }\n\n // liveReload and fileReplacements guards were previously here and forced\n // both options off when useAngularCompilationAPI was enabled. Those guards\n // have been removed because:\n // - liveReload: the persistent compilation instance (above) now gives\n // Angular the prior state it needs to emit `templateUpdates` for HMR\n // - fileReplacements: Angular's AngularHostOptions already accepts a\n // `fileReplacements` record — we now convert and pass it through in\n // `performAngularCompilation` via `toAngularCompilationFileReplacements`\n if (pluginOptions.useAngularCompilationAPI) {\n if (angularFullVersion < 200100) {\n pluginOptions.useAngularCompilationAPI = false;\n console.warn(\n '[@analogjs/vite-plugin-angular]: The Angular Compilation API is only available with Angular v20.1 and later',\n );\n }\n }\n\n return {\n name: '@analogjs/vite-plugin-angular',\n async config(config, { command }) {\n watchMode = command === 'serve';\n isProd =\n config.mode === 'production' ||\n process.env['NODE_ENV'] === 'production';\n\n // Store the config context for later resolution in configResolved\n tsConfigResolutionContext = {\n root: config.root || '.',\n isProd,\n isLib: !!config?.build?.lib,\n };\n\n // Do a preliminary resolution for esbuild plugin (before configResolved)\n const preliminaryTsConfigPath = resolveTsConfigPath();\n\n const esbuild = pluginOptions.useAngularCompilationAPI\n ? undefined\n : (config.esbuild ?? false);\n const oxc = pluginOptions.useAngularCompilationAPI\n ? undefined\n : (config.oxc ?? false);\n\n const defineOptions = {\n ngJitMode: 'false',\n ngI18nClosureMode: 'false',\n ...(watchMode ? {} : { ngDevMode: 'false' }),\n };\n const useRolldown = isRolldown();\n const jsTransformConfigKey = getJsTransformConfigKey();\n const jsTransformConfigValue =\n jsTransformConfigKey === 'oxc' ? oxc : esbuild;\n\n const rolldownOptions: vite.DepOptimizationOptions['rolldownOptions'] =\n {\n plugins: [\n createRolldownCompilerPlugin(\n {\n tsconfig: preliminaryTsConfigPath,\n sourcemap: !isProd,\n advancedOptimizations: isProd,\n jit,\n incremental: watchMode,\n },\n // Astro manages the transformer lifecycle externally.\n !isAstroIntegration,\n ),\n ],\n };\n\n const esbuildOptions: vite.DepOptimizationOptions['esbuildOptions'] = {\n plugins: [\n createCompilerPlugin(\n {\n tsconfig: preliminaryTsConfigPath,\n sourcemap: !isProd,\n advancedOptimizations: isProd,\n jit,\n incremental: watchMode,\n },\n isTest,\n !isAstroIntegration,\n ),\n ],\n define: defineOptions,\n };\n\n return {\n [jsTransformConfigKey]: jsTransformConfigValue,\n optimizeDeps: {\n include: ['rxjs/operators', 'rxjs'],\n exclude: ['@angular/platform-server'],\n ...(useRolldown ? { rolldownOptions } : { esbuildOptions }),\n },\n resolve: {\n conditions: [\n 'style',\n ...(config.resolve?.conditions || defaultClientConditions),\n ],\n },\n };\n },\n configResolved(config) {\n resolvedConfig = config;\n\n if (pluginOptions.useAngularCompilationAPI) {\n externalComponentStyles = new Map();\n inlineComponentStyles = new Map();\n }\n\n if (!jit) {\n styleTransform = (code: string, filename: string) =>\n preprocessCSS(code, filename, config);\n }\n\n if (isTest) {\n // set test watch mode\n // - vite override from vitest-angular\n // - @nx/vite executor set server.watch explicitly to undefined (watch)/null (watch=false)\n // - vite config for test.watch variable\n // - vitest watch mode detected from the command line\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 // Add/unlink changes the TypeScript program shape, not just file\n // contents, so we need to invalidate both include discovery and the\n // cached tsconfig root names before recompiling.\n const invalidateCompilationOnFsChange = createFsWatcherCacheInvalidator(\n invalidateFsCaches,\n invalidateTsconfigCaches,\n () => performCompilation(resolvedConfig),\n );\n server.watcher.on('add', invalidateCompilationOnFsChange);\n server.watcher.on('unlink', invalidateCompilationOnFsChange);\n server.watcher.on('change', (file) => {\n if (file.includes('tsconfig')) {\n invalidateTsconfigCaches();\n }\n });\n },\n async buildStart() {\n // Defer the first compilation in test mode\n if (!isVitestVscode) {\n await performCompilation(resolvedConfig);\n pendingCompilation = null;\n\n initialCompilation = true;\n }\n },\n async handleHotUpdate(ctx) {\n if (TS_EXT_REGEX.test(ctx.file)) {\n const [fileId] = ctx.file.split('?');\n\n pendingCompilation = performCompilation(resolvedConfig, [fileId]);\n\n let result;\n\n if (pluginOptions.liveReload) {\n await pendingCompilation;\n pendingCompilation = null;\n result = fileEmitter(fileId);\n }\n\n if (\n pluginOptions.liveReload &&\n result?.hmrEligible &&\n classNames.get(fileId)\n ) {\n const relativeFileId = `${normalizePath(\n relative(process.cwd(), fileId),\n )}@${classNames.get(fileId)}`;\n\n sendHMRComponentUpdate(ctx.server, relativeFileId);\n\n return ctx.modules.map((mod) => {\n if (mod.id === ctx.file) {\n return markModuleSelfAccepting(mod);\n }\n\n return mod;\n });\n }\n }\n\n if (/\\.(html|htm|css|less|sass|scss)$/.test(ctx.file)) {\n fileTransformMap.delete(ctx.file.split('?')[0]);\n /**\n * Check to see if this was a direct request\n * for an external resource (styles, html).\n */\n const isDirect = ctx.modules.find(\n (mod) => ctx.file === mod.file && mod.id?.includes('?direct'),\n );\n const isInline = ctx.modules.find(\n (mod) => ctx.file === mod.file && mod.id?.includes('?inline'),\n );\n\n if (isDirect || isInline) {\n if (pluginOptions.liveReload && isDirect?.id && isDirect.file) {\n const isComponentStyle =\n isDirect.type === 'css' && isComponentStyleSheet(isDirect.id);\n if (isComponentStyle) {\n const { encapsulation } = getComponentStyleSheetMeta(\n isDirect.id,\n );\n\n // Track if the component uses ShadowDOM encapsulation\n // Shadow DOM components currently require a full reload.\n // Vite's CSS hot replacement does not support shadow root searching.\n if (encapsulation !== 'shadow') {\n ctx.server.ws.send({\n type: 'update',\n updates: [\n {\n type: 'css-update',\n timestamp: Date.now(),\n path: isDirect.url,\n acceptedPath: isDirect.file,\n },\n ],\n });\n\n return ctx.modules\n .filter((mod) => {\n // Component stylesheets will have 2 modules (*.component.scss and *.component.scss?direct&ngcomp=xyz&e=x)\n // We remove the module with the query params to prevent vite double logging the stylesheet name \"hmr update *.component.scss, *.component.scss?direct&ngcomp=xyz&e=x\"\n return mod.file !== ctx.file || mod.id !== isDirect.id;\n })\n .map((mod) => {\n if (mod.file === ctx.file) {\n return markModuleSelfAccepting(mod);\n }\n return mod;\n }) as ModuleNode[];\n }\n }\n }\n return ctx.modules;\n }\n\n const mods: ModuleNode[] = [];\n const updates: string[] = [];\n ctx.modules.forEach((mod) => {\n mod.importers.forEach((imp) => {\n ctx.server.moduleGraph.invalidateModule(imp);\n\n if (pluginOptions.liveReload && classNames.get(imp.id)) {\n updates.push(imp.id as string);\n } else {\n mods.push(imp);\n }\n });\n });\n\n pendingCompilation = performCompilation(resolvedConfig, [\n ...mods.map((mod) => mod.id as string),\n ...updates,\n ]);\n\n if (updates.length > 0) {\n await pendingCompilation;\n pendingCompilation = null;\n\n updates.forEach((updateId) => {\n const impRelativeFileId = `${normalizePath(\n relative(process.cwd(), updateId),\n )}@${classNames.get(updateId)}`;\n\n sendHMRComponentUpdate(ctx.server, impRelativeFileId);\n });\n\n return ctx.modules.map((mod) => {\n if (mod.id === ctx.file) {\n return markModuleSelfAccepting(mod);\n }\n\n return mod;\n });\n }\n\n return mods;\n }\n\n // clear HMR updates with a full reload\n classNames.clear();\n return ctx.modules;\n },\n resolveId(id, importer) {\n if (jit && id.startsWith('angular:jit:')) {\n const path = id.split(';')[1];\n return `${normalizePath(\n resolve(dirname(importer as string), path),\n )}?${id.includes(':style') ? 'inline' : 'raw'}`;\n }\n\n // Map angular external styleUrls to the source file\n if (isComponentStyleSheet(id)) {\n const componentStyles = externalComponentStyles?.get(\n getFilenameFromPath(id),\n );\n if (componentStyles) {\n return componentStyles + new URL(id, 'http://localhost').search;\n }\n }\n\n return undefined;\n },\n async load(id) {\n // Map angular inline styles to the source text\n if (isComponentStyleSheet(id)) {\n const componentStyles = inlineComponentStyles?.get(\n getFilenameFromPath(id),\n );\n if (componentStyles) {\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 /**\n * Check for options.transformFilter\n */\n if (\n options?.transformFilter &&\n !(options?.transformFilter(code, id) ?? true)\n ) {\n return;\n }\n\n if (pluginOptions.useAngularCompilationAPI) {\n const isAngular =\n /(Component|Directive|Pipe|Injectable|NgModule)\\(/.test(code);\n\n if (!isAngular) {\n return;\n }\n }\n\n /**\n * Skip transforming content files\n */\n if (id.includes('?') && id.includes('analog-content-')) {\n return;\n }\n\n /**\n * Encapsulate component stylesheets that use emulated encapsulation\n */\n if (pluginOptions.liveReload && isComponentStyleSheet(id)) {\n const { encapsulation, componentId } =\n getComponentStyleSheetMeta(id);\n if (encapsulation === 'emulated' && componentId) {\n const encapsulated = ngCompiler.encapsulateStyle(\n code,\n componentId,\n );\n return {\n code: encapsulated,\n map: null,\n };\n }\n }\n\n if (id.includes('.ts?')) {\n // Strip the query string off the ID\n // in case of a dynamically loaded file\n id = id.replace(/\\?(.*)/, '');\n }\n\n fileTransformMap.set(id, code);\n\n /**\n * Re-analyze on each transform\n * for test(Vitest)\n */\n if (isTest) {\n if (isVitestVscode && !initialCompilation) {\n // Do full initial compilation\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\n if (testWatchMode && invalidated) {\n pendingCompilation = performCompilation(resolvedConfig, [id]);\n }\n }\n }\n\n const hasComponent = code.includes('@Component');\n const templateUrls = hasComponent\n ? templateUrlsResolver.resolve(code, id)\n : [];\n const styleUrls = hasComponent\n ? styleUrlsResolver.resolve(code, id)\n : [];\n\n if (hasComponent && watchMode) {\n for (const urlSet of [...templateUrls, ...styleUrls]) {\n // `urlSet` is a string where a relative path is joined with an\n // absolute path using the `|` symbol.\n // For example: `./app.component.html|/home/projects/analog/src/app/app.component.html`.\n const [, absoluteFileUrl] = urlSet.split('|');\n this.addWatchFile(absoluteFileUrl);\n }\n }\n\n if (pendingCompilation) {\n await pendingCompilation;\n pendingCompilation = null;\n }\n\n const typescriptResult = fileEmitter(id);\n\n if (\n typescriptResult?.warnings &&\n typescriptResult?.warnings.length > 0\n ) {\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 // return fileEmitter\n let data = typescriptResult?.content ?? '';\n\n if (jit && data.includes('angular:jit:')) {\n data = data.replace(\n /angular:jit:style:inline;/g,\n 'virtual:angular:jit:style:inline;',\n );\n\n templateUrls.forEach((templateUrlSet) => {\n const [templateFile, resolvedTemplateUrl] =\n templateUrlSet.split('|');\n data = data.replace(\n `angular:jit:template:file;${templateFile}`,\n `${resolvedTemplateUrl}?raw`,\n );\n });\n\n styleUrls.forEach((styleUrlSet) => {\n const [styleFile, resolvedStyleUrl] = styleUrlSet.split('|');\n data = data.replace(\n `angular:jit:style:file;${styleFile}`,\n `${resolvedStyleUrl}?inline`,\n );\n });\n }\n\n return {\n code: data,\n map: null,\n };\n },\n },\n closeBundle() {\n declarationFiles.forEach(\n ({ declarationFileDir, declarationPath, data }) => {\n mkdirSync(declarationFileDir, { recursive: true });\n writeFileSync(declarationPath, data, 'utf-8');\n },\n );\n // Tear down the persistent compilation instance at end of build so it\n // does not leak memory across unrelated Vite invocations.\n angularCompilation?.close?.();\n angularCompilation = undefined;\n },\n };\n }\n\n return [\n replaceFiles(pluginOptions.fileReplacements, pluginOptions.workspaceRoot),\n angularPlugin(),\n pluginOptions.liveReload && liveReloadPlugin({ classNames, fileEmitter }),\n ...(isTest && !isStackBlitz ? angularVitestPlugins() : []),\n (jit &&\n jitPlugin({\n inlineStylesExtension: pluginOptions.inlineStylesExtension,\n })) as Plugin,\n buildOptimizerPlugin({\n supportedBrowsers: pluginOptions.supportedBrowsers,\n jit,\n }),\n routerPlugin(),\n angularFullVersion < 190004 && pendingTasksPlugin(),\n nxFolderPlugin(),\n ].filter(Boolean) as Plugin[];\n\n function findIncludes() {\n const workspaceRoot = normalizePath(resolve(pluginOptions.workspaceRoot));\n\n // Map include patterns to absolute workspace paths\n const globs = [\n ...pluginOptions.include.map((glob) => `${workspaceRoot}${glob}`),\n ];\n\n // Discover TypeScript files using tinyglobby\n return globSync(globs, {\n dot: true,\n absolute: true,\n });\n }\n\n function createTsConfigGetter(tsconfigOrGetter?: string | (() => string)) {\n if (typeof tsconfigOrGetter === 'function') {\n return tsconfigOrGetter;\n }\n\n return () => tsconfigOrGetter || '';\n }\n\n function getTsConfigPath(\n root: string,\n tsconfig: string,\n isProd: boolean,\n isTest: boolean,\n isLib: boolean,\n ) {\n if (tsconfig && isAbsolute(tsconfig)) {\n if (!existsSync(tsconfig)) {\n console.error(\n `[@analogjs/vite-plugin-angular]: Unable to resolve tsconfig at ${tsconfig}. This causes compilation issues. Check the path or set the \"tsconfig\" property with an absolute path.`,\n );\n }\n\n return tsconfig;\n }\n\n let tsconfigFilePath = './tsconfig.app.json';\n\n if (isLib) {\n tsconfigFilePath = isProd\n ? './tsconfig.lib.prod.json'\n : './tsconfig.lib.json';\n }\n\n if (isTest) {\n tsconfigFilePath = './tsconfig.spec.json';\n }\n\n if (tsconfig) {\n tsconfigFilePath = tsconfig;\n }\n\n const resolvedPath = resolve(root, tsconfigFilePath);\n\n if (!existsSync(resolvedPath)) {\n console.error(\n `[@analogjs/vite-plugin-angular]: Unable to resolve tsconfig at ${resolvedPath}. This causes compilation issues. Check the path or set the \"tsconfig\" property with an absolute path.`,\n );\n }\n\n return resolvedPath;\n }\n\n function resolveTsConfigPath() {\n const tsconfigValue = pluginOptions.tsconfigGetter();\n\n return getTsConfigPath(\n tsConfigResolutionContext!.root,\n tsconfigValue,\n tsConfigResolutionContext!.isProd,\n isTest,\n tsConfigResolutionContext!.isLib,\n );\n }\n\n /**\n * Perform compilation using Angular's private Compilation API.\n *\n * Key differences from the standard `performCompilation` path:\n * 1. The compilation instance is reused across rebuilds (nullish-coalescing\n * assignment below) so Angular retains prior state and can diff it to\n * produce `templateUpdates` for HMR.\n * 2. `ids` (modified files) are forwarded to both the source-file cache and\n * `angularCompilation.update()` so that incremental re-analysis is\n * scoped to what actually changed.\n * 3. `fileReplacements` are converted and passed into Angular's host via\n * `toAngularCompilationFileReplacements`.\n * 4. `templateUpdates` from the compilation result are mapped back to\n * file-level HMR metadata (`hmrUpdateCode`, `hmrEligible`, `classNames`).\n */\n async function performAngularCompilation(\n config: ResolvedConfig,\n ids?: string[],\n ) {\n // Reuse the existing instance so Angular can diff against prior state.\n 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 // Notify Angular of modified files before re-initialization so it can\n // scope its incremental analysis.\n if (modifiedFiles?.size && angularCompilation.update) {\n await angularCompilation.update(modifiedFiles);\n }\n\n const resolvedTsConfigPath = resolveTsConfigPath();\n const compilationResult = await angularCompilation.initialize(\n resolvedTsConfigPath,\n {\n // Convert Analog's browser-style `{ replace, with }` entries into the\n // `Record<string, string>` shape that Angular's AngularHostOptions\n // expects. SSR-only replacements (`{ replace, ssr }`) are intentionally\n // excluded — they stay on the Vite runtime side.\n fileReplacements: toAngularCompilationFileReplacements(\n pluginOptions.fileReplacements,\n pluginOptions.workspaceRoot,\n ),\n modifiedFiles,\n async transformStylesheet(\n data,\n containingFile,\n resourceFile,\n order,\n className,\n ) {\n const filename =\n resourceFile ??\n containingFile.replace(\n '.ts',\n `.${pluginOptions.inlineStylesExtension}`,\n );\n\n // Apply any user-defined stylesheet preprocessing before Vite transforms it.\n const preprocessedData = pluginOptions.stylePreprocessor\n ? (pluginOptions.stylePreprocessor(data, filename) ?? data)\n : data;\n\n if (pluginOptions.liveReload && watchMode) {\n // Store the preprocessed (but not yet CSS-transformed) data so that\n // Vite's serve-time pipeline handles PostCSS / Tailwind processing\n // exactly once when the load hook returns this CSS. Running\n // preprocessCSS() here would strip directives like @reference before\n // the CSS re-enters the transform pipeline, causing plugins such as\n // @tailwindcss/vite to fail on the second pass.\n // Guard must match the externalRuntimeStyles condition (line ~927)\n // because the Angular compiler only emits external style references\n // when externalRuntimeStyles is enabled.\n const id = createHash('sha256')\n .update(containingFile)\n .update(className as string)\n .update(String(order))\n .update(preprocessedData)\n .digest('hex');\n const stylesheetId = id + '.' + pluginOptions.inlineStylesExtension;\n inlineComponentStyles!.set(stylesheetId, preprocessedData);\n return stylesheetId;\n }\n\n // Non-liveReload: the CSS is returned directly to the Angular\n // compiler and never re-enters Vite's pipeline, so we must run\n // preprocessCSS() eagerly here.\n let stylesheetResult;\n\n try {\n stylesheetResult = await preprocessCSS(\n preprocessedData,\n `${filename}?direct`,\n resolvedConfig,\n );\n } catch (e) {\n console.error(`${e}`);\n }\n\n return stylesheetResult?.code || '';\n },\n processWebWorker(workerFile, containingFile) {\n return '';\n },\n },\n (tsCompilerOptions) => {\n if (pluginOptions.liveReload && watchMode) {\n tsCompilerOptions['_enableHmr'] = true;\n tsCompilerOptions['externalRuntimeStyles'] = true;\n // Workaround for https://github.com/angular/angular/issues/59310\n // Force extra instructions to be generated for HMR w/defer\n tsCompilerOptions['supportTestBed'] = true;\n }\n\n if (tsCompilerOptions.compilationMode === 'partial') {\n // These options can't be false in partial mode\n tsCompilerOptions['supportTestBed'] = true;\n tsCompilerOptions['supportJitMode'] = true;\n }\n\n if (!isTest && config.build?.lib) {\n tsCompilerOptions['declaration'] = true;\n tsCompilerOptions['declarationMap'] = watchMode;\n tsCompilerOptions['inlineSources'] = true;\n }\n\n if (isTest) {\n // Allow `TestBed.overrideXXX()` APIs.\n tsCompilerOptions['supportTestBed'] = true;\n }\n\n return tsCompilerOptions;\n },\n );\n\n compilationResult.externalStylesheets?.forEach((value, key) => {\n externalComponentStyles?.set(`${value}.css`, key);\n });\n\n const diagnostics = await angularCompilation.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 // Angular encodes template updates as `encodedFilePath@ClassName` keys.\n // `mapTemplateUpdatesToFiles` decodes them back to absolute file paths so\n // we can attach HMR metadata to the correct `EmitFileResult` below.\n const templateUpdates = mapTemplateUpdatesToFiles(\n compilationResult.templateUpdates,\n );\n\n for (const file of await angularCompilation.emitAffectedFiles()) {\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 // Surface Angular's HMR payloads into Analog's existing live-reload\n // flow via the `hmrUpdateCode` / `hmrEligible` fields.\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 _doPerformCompilation(config, ids);\n } finally {\n resolve!();\n }\n }\n\n /**\n * This method share mutable state and performs the actual compilation work.\n * It should not be called concurrently. Use `performCompilation` which wraps this method in a lock to ensure only one compilation runs at a time.\n */\n async function _doPerformCompilation(config: ResolvedConfig, ids?: string[]) {\n // Forward `ids` (modified files) so the Compilation API path can do\n // incremental re-analysis instead of a full recompile on every change.\n if (pluginOptions.useAngularCompilationAPI) {\n await performAngularCompilation(config, ids);\n return;\n }\n\n const isProd = config.mode === 'production';\n const modifiedFiles = new Set<string>(ids ?? []);\n sourceFileCache.invalidate(modifiedFiles);\n\n if (ids?.length) {\n for (const id of ids || []) {\n fileTransformMap.delete(id);\n }\n }\n\n // Cached include discovery (invalidated only on FS events)\n if (pluginOptions.include.length > 0 && includeCache.length === 0) {\n includeCache = findIncludes();\n }\n\n const resolvedTsConfigPath = resolveTsConfigPath();\n const tsconfigKey = [\n resolvedTsConfigPath,\n isProd ? 'prod' : 'dev',\n isTest ? 'test' : 'app',\n config.build?.lib ? 'lib' : 'nolib',\n ].join('|');\n let cached = tsconfigOptionsCache.get(tsconfigKey);\n\n if (!cached) {\n const read = compilerCli.readConfiguration(resolvedTsConfigPath, {\n suppressOutputPathCheck: true,\n outDir: undefined,\n sourceMap: false,\n inlineSourceMap: !isProd,\n inlineSources: !isProd,\n declaration: false,\n declarationMap: false,\n allowEmptyCodegenFiles: false,\n annotationsAs: 'decorators',\n enableResourceInlining: false,\n noEmitOnError: false,\n mapRoot: undefined,\n sourceRoot: undefined,\n supportTestBed: false,\n supportJitMode: false,\n });\n cached = { options: read.options, rootNames: read.rootNames };\n tsconfigOptionsCache.set(tsconfigKey, cached);\n }\n\n // Clone options before mutation (preserve cache purity)\n const tsCompilerOptions = { ...cached.options };\n let rootNames = [...cached.rootNames];\n\n if (pluginOptions.liveReload && watchMode) {\n tsCompilerOptions['_enableHmr'] = true;\n tsCompilerOptions['externalRuntimeStyles'] = true;\n // Workaround for https://github.com/angular/angular/issues/59310\n // Force extra instructions to be generated for HMR w/defer\n tsCompilerOptions['supportTestBed'] = true;\n }\n\n if (tsCompilerOptions['compilationMode'] === 'partial') {\n // These options can't be false in partial mode\n tsCompilerOptions['supportTestBed'] = true;\n tsCompilerOptions['supportJitMode'] = true;\n }\n\n if (!isTest && config.build?.lib) {\n tsCompilerOptions['declaration'] = true;\n tsCompilerOptions['declarationMap'] = watchMode;\n tsCompilerOptions['inlineSources'] = true;\n }\n\n if (isTest) {\n // Allow `TestBed.overrideXXX()` APIs.\n tsCompilerOptions['supportTestBed'] = true;\n }\n\n const replacements = pluginOptions.fileReplacements.map((rp) =>\n join(\n pluginOptions.workspaceRoot,\n (rp as FileReplacementSSR).ssr || (rp as FileReplacementWith).with,\n ),\n );\n // Merge + dedupe root names\n rootNames = [...new Set([...rootNames, ...includeCache, ...replacements])];\n const hostKey = JSON.stringify(tsCompilerOptions);\n let host: ts.CompilerHost;\n\n if (cachedHost && cachedHostKey === hostKey) {\n host = cachedHost;\n } else {\n host = ts.createIncrementalCompilerHost(tsCompilerOptions, {\n ...ts.sys,\n readFile(path: string, encoding: string) {\n if (fileTransformMap.has(path)) {\n return fileTransformMap.get(path);\n }\n\n const file = ts.sys.readFile.call(null, path, encoding);\n\n if (file) {\n fileTransformMap.set(path, file);\n }\n\n return file;\n },\n });\n cachedHost = host;\n cachedHostKey = hostKey;\n\n // Only store cache if in watch mode\n if (watchMode) {\n augmentHostWithCaching(host, sourceFileCache);\n }\n }\n\n if (!jit) {\n inlineComponentStyles = tsCompilerOptions['externalRuntimeStyles']\n ? new Map()\n : undefined;\n externalComponentStyles = tsCompilerOptions['externalRuntimeStyles']\n ? new Map()\n : undefined;\n augmentHostWithResources(host, styleTransform, {\n inlineStylesExtension: pluginOptions.inlineStylesExtension,\n isProd,\n inlineComponentStyles,\n externalComponentStyles,\n sourceFileCache,\n stylePreprocessor: pluginOptions.stylePreprocessor,\n });\n }\n\n /**\n * Creates a new NgtscProgram to analyze/re-analyze\n * the source files and create a file emitter.\n * This is shared between an initial build and a hot update.\n */\n let typeScriptProgram: ts.Program;\n let angularCompiler: NgtscProgram['compiler'];\n const oldBuilder =\n builder ?? ts.readBuilderProgram(tsCompilerOptions, host);\n\n if (!jit) {\n // Create the Angular specific program that contains the Angular compiler\n const angularProgram: NgtscProgram = new compilerCli.NgtscProgram(\n rootNames,\n tsCompilerOptions,\n host,\n nextProgram,\n );\n angularCompiler = angularProgram.compiler;\n typeScriptProgram = angularProgram.compiler.getCurrentProgram();\n augmentProgramWithVersioning(typeScriptProgram);\n\n builder = ts.createEmitAndSemanticDiagnosticsBuilderProgram(\n typeScriptProgram,\n host,\n oldBuilder as ts.EmitAndSemanticDiagnosticsBuilderProgram,\n );\n\n nextProgram = angularProgram;\n } else {\n builder = ts.createEmitAndSemanticDiagnosticsBuilderProgram(\n rootNames,\n tsCompilerOptions,\n host,\n oldBuilder as ts.EmitAndSemanticDiagnosticsBuilderProgram,\n );\n\n typeScriptProgram = builder.getProgram();\n }\n\n if (!watchMode) {\n // When not in watch mode, the startup cost of the incremental analysis can be avoided by\n // using an abstract builder that only wraps a TypeScript program.\n builder = ts.createAbstractBuilder(typeScriptProgram, host, oldBuilder);\n }\n\n if (angularCompiler!) {\n await angularCompiler.analyzeAsync();\n }\n\n const beforeTransformers = jit\n ? [\n compilerCli.constructorParametersDownlevelTransform(\n builder.getProgram(),\n ),\n createJitResourceTransformer(() =>\n builder.getProgram().getTypeChecker(),\n ),\n ]\n : [];\n\n const transformers = mergeTransformers(\n { before: beforeTransformers },\n jit ? {} : angularCompiler!.prepareEmit().transformers,\n );\n\n const fileMetadata = getFileMetadata(\n builder,\n angularCompiler!,\n pluginOptions.liveReload,\n pluginOptions.disableTypeChecking,\n );\n\n const writeFileCallback: ts.WriteFileCallback = (\n _filename,\n content,\n _a,\n _b,\n sourceFiles,\n ) => {\n if (!sourceFiles?.length) {\n return;\n }\n\n const filename = normalizePath(sourceFiles[0].fileName);\n\n if (filename.includes('ngtypecheck.ts') || filename.includes('.d.')) {\n return;\n }\n\n const metadata = watchMode ? fileMetadata(filename) : {};\n\n outputFiles.set(filename, {\n content,\n dependencies: [],\n errors: metadata.errors,\n warnings: metadata.warnings,\n hmrUpdateCode: metadata.hmrUpdateCode,\n hmrEligible: metadata.hmrEligible,\n });\n };\n\n const writeOutputFile = (id: string) => {\n const sourceFile = builder.getSourceFile(id);\n if (!sourceFile) {\n return;\n }\n\n let content = '';\n builder.emit(\n sourceFile,\n (filename, data) => {\n if (/\\.[cm]?js$/.test(filename)) {\n content = data;\n }\n\n if (\n !watchMode &&\n !isTest &&\n /\\.d\\.ts/.test(filename) &&\n !filename.includes('.ngtypecheck.')\n ) {\n // output to library root instead /src\n const declarationPath = resolve(\n config.root,\n config.build.outDir,\n relative(config.root, filename),\n ).replace('/src/', '/');\n\n const declarationFileDir = declarationPath\n .replace(basename(filename), '')\n .replace('/src/', '/');\n\n declarationFiles.push({\n declarationFileDir,\n declarationPath,\n data,\n });\n }\n },\n undefined /* cancellationToken */,\n undefined /* emitOnlyDtsFiles */,\n transformers,\n );\n\n writeFileCallback(id, content, false, undefined, [sourceFile]);\n\n if (angularCompiler) {\n angularCompiler.incrementalCompilation.recordSuccessfulEmit(sourceFile);\n }\n };\n\n if (watchMode) {\n if (ids && ids.length > 0) {\n ids.forEach((id) => writeOutputFile(id));\n } else {\n /**\n * Only block the server from starting up\n * during testing.\n */\n if (isTest) {\n // TypeScript will loop until there are no more affected files in the program\n while (\n (\n builder as ts.EmitAndSemanticDiagnosticsBuilderProgram\n ).emitNextAffectedFile(\n writeFileCallback,\n undefined,\n undefined,\n transformers,\n )\n ) {\n /* empty */\n }\n }\n }\n }\n\n if (!isTest) {\n /**\n * Perf: Output files on demand so the dev server\n * isn't blocked when emitting files.\n */\n outputFile = writeOutputFile;\n }\n }\n}\n\nexport function createFsWatcherCacheInvalidator(\n invalidateFsCaches: () => void,\n invalidateTsconfigCaches: () => void,\n performCompilation: () => Promise<void>,\n): () => Promise<void> {\n return async (): Promise<void> => {\n invalidateFsCaches();\n invalidateTsconfigCaches();\n await performCompilation();\n };\n}\n\n/**\n * Convert Analog/Angular CLI-style file replacements into the flat record\n * expected by `AngularHostOptions.fileReplacements`.\n *\n * Only browser replacements (`{ replace, with }`) are converted. SSR-only\n * replacements (`{ replace, ssr }`) are left for the Vite runtime plugin to\n * handle — they should not be baked into the Angular compilation host because\n * that would apply them to both browser and server builds.\n *\n * Relative paths are resolved against `workspaceRoot` so that the host\n * receives the same absolute paths it would get from the Angular CLI.\n */\nexport function toAngularCompilationFileReplacements(\n replacements: FileReplacement[],\n workspaceRoot: string,\n): Record<string, string> | undefined {\n const mappedReplacements = replacements.flatMap((replacement) => {\n // Skip SSR-only entries — they use `ssr` instead of `with`.\n if (!('with' in replacement)) {\n return [];\n }\n\n return [\n [\n isAbsolute(replacement.replace)\n ? replacement.replace\n : resolve(workspaceRoot, replacement.replace),\n isAbsolute(replacement.with)\n ? replacement.with\n : resolve(workspaceRoot, replacement.with),\n ] as const,\n ];\n });\n\n return mappedReplacements.length\n ? Object.fromEntries(mappedReplacements)\n : undefined;\n}\n\n/**\n * Map Angular's `templateUpdates` (keyed by `encodedFilePath@ClassName`)\n * back to absolute file paths with their associated HMR code and component\n * class name.\n *\n * Angular's private Compilation API emits template update keys in the form\n * `encodeURIComponent(relativePath + '@' + className)`. We decode and resolve\n * them so the caller can look up updates by the same normalized absolute path\n * used elsewhere in the plugin (`outputFiles`, `classNames`, etc.).\n */\nexport function mapTemplateUpdatesToFiles(\n templateUpdates: ReadonlyMap<string, string> | undefined,\n): Map<\n string,\n {\n className: string;\n code: string;\n }\n> {\n const updatesByFile = new Map<string, { className: string; code: string }>();\n\n templateUpdates?.forEach((code, encodedUpdateId) => {\n const [file, className = ''] =\n decodeURIComponent(encodedUpdateId).split('@');\n const resolvedFile = normalizePath(resolve(process.cwd(), file));\n\n updatesByFile.set(resolvedFile, {\n className,\n code,\n });\n });\n\n return updatesByFile;\n}\n\nfunction sendHMRComponentUpdate(server: ViteDevServer, id: string) {\n server.ws.send('angular:component-update', {\n id: encodeURIComponent(id),\n timestamp: Date.now(),\n });\n\n classNames.delete(id);\n}\n\nexport function getFileMetadata(\n program: ts.BuilderProgram,\n angularCompiler?: NgtscProgram['compiler'],\n liveReload?: boolean,\n disableTypeChecking?: boolean,\n) {\n const ts = require('typescript');\n return (\n file: string,\n ): {\n errors?: string[];\n warnings?: (string | ts.DiagnosticMessageChain)[];\n hmrUpdateCode?: string | null;\n hmrEligible?: boolean;\n } => {\n const sourceFile = program.getSourceFile(file);\n if (!sourceFile) {\n return {};\n }\n\n const diagnostics = getDiagnosticsForSourceFile(\n sourceFile,\n !!disableTypeChecking,\n program,\n angularCompiler,\n );\n\n const errors = diagnostics\n .filter((d) => d.category === ts.DiagnosticCategory?.Error)\n .map((d) =>\n typeof d.messageText === 'object'\n ? d.messageText.messageText\n : d.messageText,\n );\n\n const warnings = diagnostics\n .filter((d) => d.category === ts.DiagnosticCategory?.Warning)\n .map((d) => d.messageText);\n\n let hmrUpdateCode: string | null | undefined = undefined;\n\n let hmrEligible = false;\n if (liveReload) {\n for (const node of sourceFile.statements) {\n if (ts.isClassDeclaration(node) && (node as any).name != null) {\n hmrUpdateCode = angularCompiler?.emitHmrUpdateModule(node as any);\n if (hmrUpdateCode) {\n classNames.set(file, (node as any).name.getText());\n hmrEligible = true;\n }\n }\n }\n }\n\n return { errors, warnings, hmrUpdateCode, hmrEligible };\n };\n}\n\nfunction getDiagnosticsForSourceFile(\n sourceFile: ts.SourceFile,\n disableTypeChecking: boolean,\n program: ts.BuilderProgram,\n angularCompiler?: NgtscProgram['compiler'],\n) {\n const syntacticDiagnostics = program.getSyntacticDiagnostics(sourceFile);\n\n if (disableTypeChecking) {\n // Syntax errors are cheap to compute and the app will not run if there are any\n // So always show these types of errors regardless if type checking is disabled\n return syntacticDiagnostics;\n }\n\n const semanticDiagnostics = program.getSemanticDiagnostics(sourceFile);\n const angularDiagnostics = angularCompiler\n ? angularCompiler.getDiagnosticsForFile(sourceFile, 1)\n : [];\n return [\n ...syntacticDiagnostics,\n ...semanticDiagnostics,\n ...angularDiagnostics,\n ];\n}\n\nfunction markModuleSelfAccepting(mod: ModuleNode): ModuleNode {\n // support Vite 6\n if ('_clientModule' in mod) {\n (mod as any)['_clientModule'].isSelfAccepting = true;\n }\n\n return {\n ...mod,\n isSelfAccepting: true,\n } as ModuleNode;\n}\n\nfunction isComponentStyleSheet(id: string): boolean {\n return id.includes('ngcomp=');\n}\n\nfunction getComponentStyleSheetMeta(id: string): {\n componentId: string;\n encapsulation: 'emulated' | 'shadow' | 'none';\n} {\n const params = new URL(id, 'http://localhost').searchParams;\n const encapsulationMapping = {\n '0': 'emulated',\n '2': 'none',\n '3': 'shadow',\n };\n return {\n componentId: params.get('ngcomp')!,\n encapsulation: encapsulationMapping[\n params.get('e') as keyof typeof encapsulationMapping\n ] as 'emulated' | 'shadow' | 'none',\n };\n}\n\n/**\n * Removes leading / and query string from a url path\n * e.g. /foo.scss?direct&ngcomp=ng-c3153525609&e=0 returns foo.scss\n * @param id\n */\nfunction getFilenameFromPath(id: string): string {\n return new URL(id, 'http://localhost').pathname.replace(/^\\//, '');\n}\n\n/**\n * Checks for vitest run from the command line\n * @returns boolean\n */\nexport function isTestWatchMode(args: string[] = process.argv): boolean {\n // vitest --run\n const hasRun = args.find((arg) => arg.includes('--run'));\n if (hasRun) {\n return false;\n }\n\n // vitest --no-run\n const hasNoRun = args.find((arg) => arg.includes('--no-run'));\n if (hasNoRun) {\n return true;\n }\n\n // check for --watch=false or --no-watch\n const hasWatch = args.find((arg) => arg.includes('watch'));\n if (hasWatch && ['false', 'no'].some((neg) => hasWatch.includes(neg))) {\n return false;\n }\n\n // check for --watch false\n const watchIndex = args.findIndex((arg) => arg.includes('watch'));\n const watchArg = args[watchIndex + 1];\n if (watchArg && watchArg === 'false') {\n return false;\n }\n\n return true;\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"angular-vitest-plugin.js","names":[],"sources":["../../../../../packages/vite-plugin-angular/src/lib/angular-vitest-plugin.ts"],"sourcesContent":["import type { Plugin, TransformResult, UserConfig } from 'vite';\n// Use the namespace import so these runtime helpers still resolve on Vite 6,\n// which does not expose them as named exports.\nimport * as vite from 'vite';\nimport { getJsTransformConfigKey, isRolldown } from './utils/rolldown.js';\n\n/**\n * Sets up test config for Vitest and downlevels Angular FESM bundles and\n * `@angular/cdk` from modern async/await to ES2016 so that Zone.js can\n * intercept promises during `fakeAsync` tests.\n *\n * Under Vite 8+ (Rolldown) the OXC transformer is used.\n * Under Vite ≤7, esbuild handles the downlevel.\n */\nexport function angularVitestPlugin(): Plugin {\n return {\n name: '@analogjs/vitest-angular-esm-plugin',\n apply: 'serve',\n enforce: 'post',\n config(userConfig) {\n return {\n optimizeDeps: {\n include: ['tslib'],\n },\n ssr: {\n noExternal: [\n '@analogjs/vitest-angular/setup-testbed',\n /fesm2022(.*?)testing/,\n /fesm2015/,\n ],\n },\n test: {\n pool: (userConfig as any).test?.pool ?? 'vmThreads',\n },\n };\n },\n // Filter by module ID so only Angular FESM2022 bundles and CDK enter\n // the handler. The inner guards add a secondary code-content check\n // (`async` keyword) for fesm2022 to avoid needless transforms.\n transform: {\n filter: {\n id: /fesm2022|@angular\\/cdk/,\n },\n async handler(_code, id) {\n if (\n (/fesm2022/.test(id) && _code.includes('async ')) ||\n _code.includes('@angular/cdk')\n ) {\n if (isRolldown()) {\n // OXC does not expose a `format` option like esbuild; ESM output\n // is the default when the source contains import/export statements.\n const { code, map } = await vite.transformWithOxc(_code, id, {\n lang: 'js',\n target: 'es2016',\n sourceType: 'module',\n sourcemap: true,\n });\n\n return {\n code,\n map,\n };\n } else {\n const { code, map } = await vite.transformWithEsbuild(_code, id, {\n loader: 'js',\n format: 'esm',\n target: 'es2016',\n sourcemap: true,\n sourcefile: id,\n });\n\n return {\n code,\n map,\n };\n }\n }\n\n return undefined;\n },\n },\n };\n}\n\n/**\n * Eagerly disables the built-in JS transformer (esbuild on Vite ≤7, OXC on\n * Vite 8+) so Vitest's internal plugin doesn't race with the Angular\n * compiler. Must run at `enforce: 'pre'` to take effect before Vitest\n * reads the resolved config.\n */\nexport function angularVitestEsbuildPlugin(): Plugin {\n return {\n name: '@analogjs/vitest-angular-esbuild-oxc-plugin',\n enforce: 'pre',\n config(userConfig: UserConfig) {\n const jsTransformConfigKey = getJsTransformConfigKey();\n\n return {\n [jsTransformConfigKey]:\n jsTransformConfigKey === 'oxc'\n ? (userConfig.oxc ?? false)\n : (userConfig.esbuild ?? false),\n };\n },\n };\n}\n\n/**\n * Post-processes `.ts` files with the JS transformer (esbuild / OXC) to\n * re-align sourcemaps so breakpoints and coverage reports work correctly.\n *\n * Inline style/template virtual modules (`?inline`) are excluded because\n * they are already handled by the Angular compiler.\n */\nexport function angularVitestSourcemapPlugin(): Plugin {\n return {\n name: '@analogjs/vitest-angular-sourcemap-plugin',\n transform: {\n filter: {\n // Match `.ts` at the end of the path OR before a `?` query string.\n // Vite/Vitest appends query params for virtual modules (e.g.\n // `component.ts?inline`), so a plain `$` anchor would reject them\n // and leave sourcemaps misaligned — causing Angular TestBed teardown\n // crashes (`_doc` undefined in `removeAllRootElements`).\n // The negative lookahead `(?!x)` prevents matching `.tsx` or `.d.ts`.\n id: /\\.ts(?:\\?|$)/,\n },\n async handler(code: string, id: string) {\n const [, query] = id.split('?');\n\n if (query && query.includes('inline')) {\n return;\n }\n\n if (isRolldown()) {\n // lang must be 'ts' (not 'js') so OXC parses TypeScript syntax;\n // using 'js' would cause parse errors on type annotations.\n const result = await vite.transformWithOxc(code, id, {\n lang: 'ts',\n });\n\n return result as unknown as TransformResult;\n } else {\n const result = await vite.transformWithEsbuild(code, id, {\n loader: 'ts',\n });\n\n return result;\n }\n },\n },\n };\n}\n\nexport function angularVitestPlugins(): Plugin[] {\n return [\n angularVitestPlugin(),\n angularVitestEsbuildPlugin(),\n angularVitestSourcemapPlugin(),\n ];\n}\n"],"mappings":";;;;;;;;;;;AAcA,SAAgB,sBAA8B;AAC5C,QAAO;EACL,MAAM;EACN,OAAO;EACP,SAAS;EACT,OAAO,YAAY;AACjB,UAAO;IACL,cAAc,EACZ,SAAS,CAAC,QAAQ,EACnB;IACD,KAAK,EACH,YAAY;KACV;KACA;KACA;KACD,EACF;IACD,MAAM,EACJ,MAAO,WAAmB,MAAM,QAAQ,aACzC;IACF;;EAKH,WAAW;GACT,QAAQ,EACN,IAAI,0BACL;GACD,MAAM,QAAQ,OAAO,IAAI;AACvB,QACG,WAAW,KAAK,GAAG,IAAI,MAAM,SAAS,SAAS,IAChD,MAAM,SAAS,eAAe,CAE9B,KAAI,YAAY,EAAE;KAGhB,MAAM,EAAE,MAAM,QAAQ,MAAM,KAAK,iBAAiB,OAAO,IAAI;MAC3D,MAAM;MACN,QAAQ;MACR,YAAY;MACZ,WAAW;MACZ,CAAC;AAEF,YAAO;MACL;MACA;MACD;WACI;KACL,MAAM,EAAE,MAAM,QAAQ,MAAM,KAAK,qBAAqB,OAAO,IAAI;MAC/D,QAAQ;MACR,QAAQ;MACR,QAAQ;MACR,WAAW;MACX,YAAY;MACb,CAAC;AAEF,YAAO;MACL;MACA;MACD;;;GAMR;EACF;;;;;;;;AASH,SAAgB,6BAAqC;AACnD,QAAO;EACL,MAAM;EACN,SAAS;EACT,OAAO,YAAwB;GAC7B,MAAM,uBAAuB,yBAAyB;AAEtD,UAAO,GACJ,uBACC,yBAAyB,QACpB,WAAW,OAAO,QAClB,WAAW,WAAW,OAC9B;;EAEJ;;;;;;;;;AAUH,SAAgB,+BAAuC;AACrD,QAAO;EACL,MAAM;EACN,WAAW;GACT,QAAQ,EAON,IAAI,gBACL;GACD,MAAM,QAAQ,MAAc,IAAY;IACtC,MAAM,GAAG,SAAS,GAAG,MAAM,IAAI;AAE/B,QAAI,SAAS,MAAM,SAAS,SAAS,CACnC;AAGF,QAAI,YAAY,CAOd,QAJe,MAAM,KAAK,iBAAiB,MAAM,IAAI,EACnD,MAAM,MACP,CAAC;QAQF,QAJe,MAAM,KAAK,qBAAqB,MAAM,IAAI,EACvD,QAAQ,MACT,CAAC;;GAKP;EACF;;AAGH,SAAgB,uBAAiC;AAC/C,QAAO;EACL,qBAAqB;EACrB,4BAA4B;EAC5B,8BAA8B;EAC/B"}
1
+ {"version":3,"file":"angular-vitest-plugin.js","names":[],"sources":["../../../src/lib/angular-vitest-plugin.ts"],"sourcesContent":["import type { Plugin, TransformResult, UserConfig } from 'vite';\n// Use the namespace import so these runtime helpers still resolve on Vite 6,\n// which does not expose them as named exports.\nimport * as vite from 'vite';\nimport { getJsTransformConfigKey, isRolldown } from './utils/rolldown.js';\n\n/**\n * Sets up test config for Vitest and downlevels Angular FESM bundles and\n * `@angular/cdk` from modern async/await to ES2016 so that Zone.js can\n * intercept promises during `fakeAsync` tests.\n *\n * Under Vite 8+ (Rolldown) the OXC transformer is used.\n * Under Vite ≤7, esbuild handles the downlevel.\n */\nexport function angularVitestPlugin(): Plugin {\n return {\n name: '@analogjs/vitest-angular-esm-plugin',\n apply: 'serve',\n enforce: 'post',\n config(userConfig) {\n return {\n optimizeDeps: {\n include: ['tslib'],\n },\n ssr: {\n noExternal: [\n '@analogjs/vitest-angular/setup-testbed',\n /fesm2022(.*?)testing/,\n /fesm2015/,\n ],\n },\n test: {\n pool: (userConfig as any).test?.pool ?? 'vmThreads',\n },\n };\n },\n // Filter by module ID so only Angular FESM2022 bundles and CDK enter\n // the handler. The inner guards add a secondary code-content check\n // (`async` keyword) for fesm2022 to avoid needless transforms.\n transform: {\n filter: {\n id: /fesm2022|@angular\\/cdk/,\n },\n async handler(_code, id) {\n if (\n (/fesm2022/.test(id) && _code.includes('async ')) ||\n _code.includes('@angular/cdk')\n ) {\n if (isRolldown()) {\n // OXC does not expose a `format` option like esbuild; ESM output\n // is the default when the source contains import/export statements.\n const { code, map } = await vite.transformWithOxc(_code, id, {\n lang: 'js',\n target: 'es2016',\n sourceType: 'module',\n sourcemap: true,\n });\n\n return {\n code,\n map,\n };\n } else {\n const { code, map } = await vite.transformWithEsbuild(_code, id, {\n loader: 'js',\n format: 'esm',\n target: 'es2016',\n sourcemap: true,\n sourcefile: id,\n });\n\n return {\n code,\n map,\n };\n }\n }\n\n return undefined;\n },\n },\n };\n}\n\n/**\n * Eagerly disables the built-in JS transformer (esbuild on Vite ≤7, OXC on\n * Vite 8+) so Vitest's internal plugin doesn't race with the Angular\n * compiler. Must run at `enforce: 'pre'` to take effect before Vitest\n * reads the resolved config.\n */\nexport function angularVitestEsbuildPlugin(): Plugin {\n return {\n name: '@analogjs/vitest-angular-esbuild-oxc-plugin',\n enforce: 'pre',\n config(userConfig: UserConfig) {\n const jsTransformConfigKey = getJsTransformConfigKey();\n\n return {\n [jsTransformConfigKey]:\n jsTransformConfigKey === 'oxc'\n ? (userConfig.oxc ?? false)\n : (userConfig.esbuild ?? false),\n };\n },\n };\n}\n\n/**\n * Post-processes `.ts` files with the JS transformer (esbuild / OXC) to\n * re-align sourcemaps so breakpoints and coverage reports work correctly.\n *\n * Inline style/template virtual modules (`?inline`) are excluded because\n * they are already handled by the Angular compiler.\n */\nexport function angularVitestSourcemapPlugin(): Plugin {\n return {\n name: '@analogjs/vitest-angular-sourcemap-plugin',\n transform: {\n filter: {\n // Match `.ts` at the end of the path OR before a `?` query string.\n // Vite/Vitest appends query params for virtual modules (e.g.\n // `component.ts?inline`), so a plain `$` anchor would reject them\n // and leave sourcemaps misaligned — causing Angular TestBed teardown\n // crashes (`_doc` undefined in `removeAllRootElements`).\n // The negative lookahead `(?!x)` prevents matching `.tsx` or `.d.ts`.\n id: /\\.ts(?:\\?|$)/,\n },\n async handler(code: string, id: string) {\n const [, query] = id.split('?');\n\n if (query && query.includes('inline')) {\n return;\n }\n\n if (isRolldown()) {\n // lang must be 'ts' (not 'js') so OXC parses TypeScript syntax;\n // using 'js' would cause parse errors on type annotations.\n const result = await vite.transformWithOxc(code, id, {\n lang: 'ts',\n });\n\n return result as unknown as TransformResult;\n } else {\n const result = await vite.transformWithEsbuild(code, id, {\n loader: 'ts',\n });\n\n return result;\n }\n },\n },\n };\n}\n\nexport function angularVitestPlugins(): Plugin[] {\n return [\n angularVitestPlugin(),\n angularVitestEsbuildPlugin(),\n angularVitestSourcemapPlugin(),\n ];\n}\n"],"mappings":";;;;;;;;;;;AAcA,SAAgB,sBAA8B;AAC5C,QAAO;EACL,MAAM;EACN,OAAO;EACP,SAAS;EACT,OAAO,YAAY;AACjB,UAAO;IACL,cAAc,EACZ,SAAS,CAAC,QAAQ,EACnB;IACD,KAAK,EACH,YAAY;KACV;KACA;KACA;KACD,EACF;IACD,MAAM,EACJ,MAAO,WAAmB,MAAM,QAAQ,aACzC;IACF;;EAKH,WAAW;GACT,QAAQ,EACN,IAAI,0BACL;GACD,MAAM,QAAQ,OAAO,IAAI;AACvB,QACG,WAAW,KAAK,GAAG,IAAI,MAAM,SAAS,SAAS,IAChD,MAAM,SAAS,eAAe,CAE9B,KAAI,YAAY,EAAE;KAGhB,MAAM,EAAE,MAAM,QAAQ,MAAM,KAAK,iBAAiB,OAAO,IAAI;MAC3D,MAAM;MACN,QAAQ;MACR,YAAY;MACZ,WAAW;MACZ,CAAC;AAEF,YAAO;MACL;MACA;MACD;WACI;KACL,MAAM,EAAE,MAAM,QAAQ,MAAM,KAAK,qBAAqB,OAAO,IAAI;MAC/D,QAAQ;MACR,QAAQ;MACR,QAAQ;MACR,WAAW;MACX,YAAY;MACb,CAAC;AAEF,YAAO;MACL;MACA;MACD;;;GAMR;EACF;;;;;;;;AASH,SAAgB,6BAAqC;AACnD,QAAO;EACL,MAAM;EACN,SAAS;EACT,OAAO,YAAwB;GAC7B,MAAM,uBAAuB,yBAAyB;AAEtD,UAAO,GACJ,uBACC,yBAAyB,QACpB,WAAW,OAAO,QAClB,WAAW,WAAW,OAC9B;;EAEJ;;;;;;;;;AAUH,SAAgB,+BAAuC;AACrD,QAAO;EACL,MAAM;EACN,WAAW;GACT,QAAQ,EAON,IAAI,gBACL;GACD,MAAM,QAAQ,MAAc,IAAY;IACtC,MAAM,GAAG,SAAS,GAAG,MAAM,IAAI;AAE/B,QAAI,SAAS,MAAM,SAAS,SAAS,CACnC;AAGF,QAAI,YAAY,CAOd,QAJe,MAAM,KAAK,iBAAiB,MAAM,IAAI,EACnD,MAAM,MACP,CAAC;QAQF,QAJe,MAAM,KAAK,qBAAqB,MAAM,IAAI,EACvD,QAAQ,MACT,CAAC;;GAKP;EACF;;AAGH,SAAgB,uBAAiC;AAC/C,QAAO;EACL,qBAAqB;EACrB,4BAA4B;EAC5B,8BAA8B;EAC/B"}
@@ -1 +1 @@
1
- {"version":3,"file":"compiler-plugin.js","names":[],"sources":["../../../../../packages/vite-plugin-angular/src/lib/compiler-plugin.ts"],"sourcesContent":["/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\nimport type { DepOptimizationConfig, Rolldown } from 'vite';\nimport type { PluginBuild } from 'esbuild';\n\nimport {\n CompilerPluginOptions,\n JavaScriptTransformer,\n} from './utils/devkit.js';\n\ntype EsbuildOptions = NonNullable<DepOptimizationConfig['esbuildOptions']>;\ntype EsbuildPlugin = NonNullable<EsbuildOptions['plugins']>[number];\n\nexport function createCompilerPlugin(\n pluginOptions: CompilerPluginOptions,\n isTest: boolean,\n closeTransformer: boolean,\n): EsbuildPlugin {\n const javascriptTransformer = new JavaScriptTransformer(\n { ...pluginOptions, jit: true },\n 1,\n );\n\n return {\n name: 'analogjs-angular-esbuild-deps-optimizer-plugin',\n async setup(build: PluginBuild) {\n if (!isTest) {\n build.onLoad({ filter: /\\.[cm]?js$/ }, async (args) => {\n const contents = await javascriptTransformer.transformFile(args.path);\n\n return {\n contents,\n loader: 'js',\n };\n });\n }\n\n if (closeTransformer) {\n build.onEnd(() => javascriptTransformer.close());\n }\n },\n };\n}\n\nexport function createRolldownCompilerPlugin(\n pluginOptions: CompilerPluginOptions,\n closeTransformer: boolean,\n): Rolldown.Plugin {\n const javascriptTransformer = new JavaScriptTransformer(\n { ...pluginOptions, jit: true },\n 1,\n );\n return {\n name: 'analogjs-rolldown-deps-optimizer-plugin',\n load: {\n filter: {\n id: /\\.[cm]?js$/,\n },\n async handler(id) {\n const contents = await javascriptTransformer.transformFile(id);\n\n return {\n code: Buffer.from(contents).toString('utf-8'),\n loader: 'js',\n } as any;\n },\n },\n // Close the JavaScriptTransformer worker pool when Rolldown finishes to\n // prevent leaked handles. Skipped for Astro, which owns the lifecycle.\n buildEnd() {\n if (closeTransformer) {\n javascriptTransformer.close();\n }\n },\n };\n}\n"],"mappings":";;AAmBA,SAAgB,qBACd,eACA,QACA,kBACe;CACf,MAAM,wBAAwB,IAAI,GAChC;EAAE,GAAG;EAAe,KAAK;EAAM,EAC/B,EACD;AAED,QAAO;EACL,MAAM;EACN,MAAM,MAAM,OAAoB;AAC9B,OAAI,CAAC,OACH,OAAM,OAAO,EAAE,QAAQ,cAAc,EAAE,OAAO,SAAS;AAGrD,WAAO;KACL,UAHe,MAAM,sBAAsB,cAAc,KAAK,KAAK;KAInE,QAAQ;KACT;KACD;AAGJ,OAAI,iBACF,OAAM,YAAY,sBAAsB,OAAO,CAAC;;EAGrD;;AAGH,SAAgB,6BACd,eACA,kBACiB;CACjB,MAAM,wBAAwB,IAAI,GAChC;EAAE,GAAG;EAAe,KAAK;EAAM,EAC/B,EACD;AACD,QAAO;EACL,MAAM;EACN,MAAM;GACJ,QAAQ,EACN,IAAI,cACL;GACD,MAAM,QAAQ,IAAI;IAChB,MAAM,WAAW,MAAM,sBAAsB,cAAc,GAAG;AAE9D,WAAO;KACL,MAAM,OAAO,KAAK,SAAS,CAAC,SAAS,QAAQ;KAC7C,QAAQ;KACT;;GAEJ;EAGD,WAAW;AACT,OAAI,iBACF,uBAAsB,OAAO;;EAGlC"}
1
+ {"version":3,"file":"compiler-plugin.js","names":[],"sources":["../../../src/lib/compiler-plugin.ts"],"sourcesContent":["/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\nimport type { DepOptimizationConfig, Rolldown } from 'vite';\nimport type { PluginBuild } from 'esbuild';\n\nimport {\n CompilerPluginOptions,\n JavaScriptTransformer,\n} from './utils/devkit.js';\n\ntype EsbuildOptions = NonNullable<DepOptimizationConfig['esbuildOptions']>;\ntype EsbuildPlugin = NonNullable<EsbuildOptions['plugins']>[number];\n\nexport function createCompilerPlugin(\n pluginOptions: CompilerPluginOptions,\n isTest: boolean,\n closeTransformer: boolean,\n): EsbuildPlugin {\n const javascriptTransformer = new JavaScriptTransformer(\n { ...pluginOptions, jit: true },\n 1,\n );\n\n return {\n name: 'analogjs-angular-esbuild-deps-optimizer-plugin',\n async setup(build: PluginBuild) {\n if (!isTest) {\n build.onLoad({ filter: /\\.[cm]?js$/ }, async (args) => {\n const contents = await javascriptTransformer.transformFile(args.path);\n\n return {\n contents,\n loader: 'js',\n };\n });\n }\n\n if (closeTransformer) {\n build.onEnd(() => javascriptTransformer.close());\n }\n },\n };\n}\n\nexport function createRolldownCompilerPlugin(\n pluginOptions: CompilerPluginOptions,\n closeTransformer: boolean,\n): Rolldown.Plugin {\n const javascriptTransformer = new JavaScriptTransformer(\n { ...pluginOptions, jit: true },\n 1,\n );\n return {\n name: 'analogjs-rolldown-deps-optimizer-plugin',\n load: {\n filter: {\n id: /\\.[cm]?js$/,\n },\n async handler(id) {\n const contents = await javascriptTransformer.transformFile(id);\n\n return {\n code: Buffer.from(contents).toString('utf-8'),\n loader: 'js',\n } as any;\n },\n },\n // Close the JavaScriptTransformer worker pool when Rolldown finishes to\n // prevent leaked handles. Skipped for Astro, which owns the lifecycle.\n buildEnd() {\n if (closeTransformer) {\n javascriptTransformer.close();\n }\n },\n };\n}\n"],"mappings":";;AAmBA,SAAgB,qBACd,eACA,QACA,kBACe;CACf,MAAM,wBAAwB,IAAI,GAChC;EAAE,GAAG;EAAe,KAAK;EAAM,EAC/B,EACD;AAED,QAAO;EACL,MAAM;EACN,MAAM,MAAM,OAAoB;AAC9B,OAAI,CAAC,OACH,OAAM,OAAO,EAAE,QAAQ,cAAc,EAAE,OAAO,SAAS;AAGrD,WAAO;KACL,UAHe,MAAM,sBAAsB,cAAc,KAAK,KAAK;KAInE,QAAQ;KACT;KACD;AAGJ,OAAI,iBACF,OAAM,YAAY,sBAAsB,OAAO,CAAC;;EAGrD;;AAGH,SAAgB,6BACd,eACA,kBACiB;CACjB,MAAM,wBAAwB,IAAI,GAChC;EAAE,GAAG;EAAe,KAAK;EAAM,EAC/B,EACD;AACD,QAAO;EACL,MAAM;EACN,MAAM;GACJ,QAAQ,EACN,IAAI,cACL;GACD,MAAM,QAAQ,IAAI;IAChB,MAAM,WAAW,MAAM,sBAAsB,cAAc,GAAG;AAE9D,WAAO;KACL,MAAM,OAAO,KAAK,SAAS,CAAC,SAAS,QAAQ;KAC7C,QAAQ;KACT;;GAEJ;EAGD,WAAW;AACT,OAAI,iBACF,uBAAsB,OAAO;;EAGlC"}
@@ -1 +1 @@
1
- {"version":3,"file":"component-resolvers.js","names":[],"sources":["../../../../../packages/vite-plugin-angular/src/lib/component-resolvers.ts"],"sourcesContent":["import { dirname, resolve } from 'node:path';\n// OXC parser (native Rust, NAPI-RS) replaces ts-morph for AST extraction.\n// It is ~10-50x faster for the narrow task of pulling property values from\n// Angular component decorators. The Visitor helper from Rolldown walks the\n// ESTree-compatible AST that OXC produces.\nimport { parseSync } from 'oxc-parser';\nimport { Visitor } from 'rolldown/utils';\nimport { normalizePath } from 'vite';\n\n// ---------------------------------------------------------------------------\n// AST helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Extracts a string value from an ESTree AST node.\n *\n * Handles three forms that Angular decorators may use:\n * - `Literal` with a string value → `'./foo.css'` / `\"./foo.css\"`\n * - `StringLiteral` (OXC-specific) → same representation\n * - `TemplateLiteral` with zero expressions → `` `./foo.css` ``\n *\n * Uses `any` because OXC's AST mixes standard ESTree nodes with\n * OXC-specific variants (e.g. `StringLiteral`), and the project's\n * tsconfig enforces `noPropertyAccessFromIndexSignature`.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction getStringValue(node: any): string | undefined {\n if (!node) return undefined;\n // Standard ESTree Literal (string value)\n if (node.type === 'Literal' && typeof node.value === 'string') {\n return node.value;\n }\n // OXC-specific StringLiteral node\n if (node.type === 'StringLiteral') {\n return node.value;\n }\n // Template literal with no interpolation (e.g., `./foo.css`)\n if (\n node.type === 'TemplateLiteral' &&\n node.expressions.length === 0 &&\n node.quasis.length === 1\n ) {\n return node.quasis[0].value.cooked ?? node.quasis[0].value.raw;\n }\n return undefined;\n}\n\n/**\n * Parses TypeScript/JS source with OXC and collects `styleUrl`, `styleUrls`,\n * and `templateUrl` property values from Angular `@Component()` decorators\n * in a single AST pass.\n *\n * This replaces the previous ts-morph implementation — OXC parses natively\n * via Rust NAPI bindings, avoiding the overhead of spinning up a full\n * TypeScript `Project` for each file.\n */\nfunction collectComponentUrls(code: string): {\n styleUrls: string[];\n templateUrls: string[];\n} {\n const { program } = parseSync('cmp.ts', code);\n const styleUrls: string[] = [];\n const templateUrls: string[] = [];\n\n const visitor = new Visitor({\n // The Visitor callback receives raw ESTree nodes. We use `any`\n // because OXC's AST includes non-standard node variants and the\n // project tsconfig enforces `noPropertyAccessFromIndexSignature`.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n Property(node: any) {\n if (node.key?.type !== 'Identifier') return;\n const name: string = node.key.name;\n\n if (name === 'styleUrls' && node.value?.type === 'ArrayExpression') {\n for (const el of node.value.elements) {\n const val = getStringValue(el);\n if (val !== undefined) styleUrls.push(val);\n }\n }\n\n if (name === 'styleUrl') {\n const val = getStringValue(node.value);\n if (val !== undefined) styleUrls.push(val);\n }\n\n if (name === 'templateUrl') {\n const val = getStringValue(node.value);\n if (val !== undefined) templateUrls.push(val);\n }\n },\n });\n visitor.visit(program);\n\n return { styleUrls, templateUrls };\n}\n\n/** Extract all `styleUrl` / `styleUrls` values from Angular component source. */\nexport function getStyleUrls(code: string): string[] {\n return collectComponentUrls(code).styleUrls;\n}\n\n/** Extract all `templateUrl` values from Angular component source. */\nexport function getTemplateUrls(code: string): string[] {\n return collectComponentUrls(code).templateUrls;\n}\n\n// ---------------------------------------------------------------------------\n// Resolver caches\n// ---------------------------------------------------------------------------\n\ninterface StyleUrlsCacheEntry {\n matchedStyleUrls: string[];\n styleUrls: string[];\n}\n\nexport class StyleUrlsResolver {\n // These resolvers may be called multiple times during the same\n // compilation for the same files. Caching is required because these\n // resolvers use synchronous system calls to the filesystem, which can\n // degrade performance when running compilations for multiple files.\n private readonly styleUrlsCache = new Map<string, StyleUrlsCacheEntry>();\n\n resolve(code: string, id: string): string[] {\n const matchedStyleUrls = getStyleUrls(code);\n const entry = this.styleUrlsCache.get(id);\n // We're using `matchedStyleUrls` as a key because the code may be changing continuously,\n // resulting in the resolver being called multiple times. While the code changes, the\n // `styleUrls` may remain constant, which means we should always return the previously\n // resolved style URLs.\n if (entry && entry.matchedStyleUrls === matchedStyleUrls) {\n return entry.styleUrls;\n }\n\n const styleUrls = matchedStyleUrls.map((styleUrlPath) => {\n return `${styleUrlPath}|${normalizePath(\n resolve(dirname(id), styleUrlPath),\n )}`;\n });\n\n this.styleUrlsCache.set(id, { styleUrls, matchedStyleUrls });\n return styleUrls;\n }\n}\n\ninterface TemplateUrlsCacheEntry {\n code: string;\n templateUrlPaths: string[];\n}\n\nexport class TemplateUrlsResolver {\n private readonly templateUrlsCache = new Map<\n string,\n TemplateUrlsCacheEntry\n >();\n\n resolve(code: string, id: string): string[] {\n const entry = this.templateUrlsCache.get(id);\n if (entry?.code === code) {\n return entry.templateUrlPaths;\n }\n\n const templateUrlPaths = getTemplateUrls(code).map(\n (url) => `${url}|${normalizePath(resolve(dirname(id), url))}`,\n );\n\n this.templateUrlsCache.set(id, { code, templateUrlPaths });\n return templateUrlPaths;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AA0BA,SAAS,eAAe,MAA+B;AACrD,KAAI,CAAC,KAAM,QAAO,KAAA;AAElB,KAAI,KAAK,SAAS,aAAa,OAAO,KAAK,UAAU,SACnD,QAAO,KAAK;AAGd,KAAI,KAAK,SAAS,gBAChB,QAAO,KAAK;AAGd,KACE,KAAK,SAAS,qBACd,KAAK,YAAY,WAAW,KAC5B,KAAK,OAAO,WAAW,EAEvB,QAAO,KAAK,OAAO,GAAG,MAAM,UAAU,KAAK,OAAO,GAAG,MAAM;;;;;;;;;;;AAc/D,SAAS,qBAAqB,MAG5B;CACA,MAAM,EAAE,YAAY,UAAU,UAAU,KAAK;CAC7C,MAAM,YAAsB,EAAE;CAC9B,MAAM,eAAyB,EAAE;AAEjB,KAAI,QAAQ,EAK1B,SAAS,MAAW;AAClB,MAAI,KAAK,KAAK,SAAS,aAAc;EACrC,MAAM,OAAe,KAAK,IAAI;AAE9B,MAAI,SAAS,eAAe,KAAK,OAAO,SAAS,kBAC/C,MAAK,MAAM,MAAM,KAAK,MAAM,UAAU;GACpC,MAAM,MAAM,eAAe,GAAG;AAC9B,OAAI,QAAQ,KAAA,EAAW,WAAU,KAAK,IAAI;;AAI9C,MAAI,SAAS,YAAY;GACvB,MAAM,MAAM,eAAe,KAAK,MAAM;AACtC,OAAI,QAAQ,KAAA,EAAW,WAAU,KAAK,IAAI;;AAG5C,MAAI,SAAS,eAAe;GAC1B,MAAM,MAAM,eAAe,KAAK,MAAM;AACtC,OAAI,QAAQ,KAAA,EAAW,cAAa,KAAK,IAAI;;IAGlD,CAAC,CACM,MAAM,QAAQ;AAEtB,QAAO;EAAE;EAAW;EAAc;;;AAIpC,SAAgB,aAAa,MAAwB;AACnD,QAAO,qBAAqB,KAAK,CAAC;;;AAIpC,SAAgB,gBAAgB,MAAwB;AACtD,QAAO,qBAAqB,KAAK,CAAC;;AAYpC,IAAa,oBAAb,MAA+B;CAK7B,iCAAkC,IAAI,KAAkC;CAExE,QAAQ,MAAc,IAAsB;EAC1C,MAAM,mBAAmB,aAAa,KAAK;EAC3C,MAAM,QAAQ,KAAK,eAAe,IAAI,GAAG;AAKzC,MAAI,SAAS,MAAM,qBAAqB,iBACtC,QAAO,MAAM;EAGf,MAAM,YAAY,iBAAiB,KAAK,iBAAiB;AACvD,UAAO,GAAG,aAAa,GAAG,cACxB,QAAQ,QAAQ,GAAG,EAAE,aAAa,CACnC;IACD;AAEF,OAAK,eAAe,IAAI,IAAI;GAAE;GAAW;GAAkB,CAAC;AAC5D,SAAO;;;AASX,IAAa,uBAAb,MAAkC;CAChC,oCAAqC,IAAI,KAGtC;CAEH,QAAQ,MAAc,IAAsB;EAC1C,MAAM,QAAQ,KAAK,kBAAkB,IAAI,GAAG;AAC5C,MAAI,OAAO,SAAS,KAClB,QAAO,MAAM;EAGf,MAAM,mBAAmB,gBAAgB,KAAK,CAAC,KAC5C,QAAQ,GAAG,IAAI,GAAG,cAAc,QAAQ,QAAQ,GAAG,EAAE,IAAI,CAAC,GAC5D;AAED,OAAK,kBAAkB,IAAI,IAAI;GAAE;GAAM;GAAkB,CAAC;AAC1D,SAAO"}
1
+ {"version":3,"file":"component-resolvers.js","names":[],"sources":["../../../src/lib/component-resolvers.ts"],"sourcesContent":["import { dirname, resolve } from 'node:path';\n// OXC parser (native Rust, NAPI-RS) replaces ts-morph for AST extraction.\n// It is ~10-50x faster for the narrow task of pulling property values from\n// Angular component decorators. The Visitor helper from Rolldown walks the\n// ESTree-compatible AST that OXC produces.\nimport { parseSync } from 'oxc-parser';\nimport { Visitor } from 'rolldown/utils';\nimport { normalizePath } from 'vite';\n\n// ---------------------------------------------------------------------------\n// AST helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Extracts a string value from an ESTree AST node.\n *\n * Handles three forms that Angular decorators may use:\n * - `Literal` with a string value → `'./foo.css'` / `\"./foo.css\"`\n * - `StringLiteral` (OXC-specific) → same representation\n * - `TemplateLiteral` with zero expressions → `` `./foo.css` ``\n *\n * Uses `any` because OXC's AST mixes standard ESTree nodes with\n * OXC-specific variants (e.g. `StringLiteral`), and the project's\n * tsconfig enforces `noPropertyAccessFromIndexSignature`.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction getStringValue(node: any): string | undefined {\n if (!node) return undefined;\n // Standard ESTree Literal (string value)\n if (node.type === 'Literal' && typeof node.value === 'string') {\n return node.value;\n }\n // OXC-specific StringLiteral node\n if (node.type === 'StringLiteral') {\n return node.value;\n }\n // Template literal with no interpolation (e.g., `./foo.css`)\n if (\n node.type === 'TemplateLiteral' &&\n node.expressions.length === 0 &&\n node.quasis.length === 1\n ) {\n return node.quasis[0].value.cooked ?? node.quasis[0].value.raw;\n }\n return undefined;\n}\n\n/**\n * Parses TypeScript/JS source with OXC and collects `styleUrl`, `styleUrls`,\n * and `templateUrl` property values from Angular `@Component()` decorators\n * in a single AST pass.\n *\n * This replaces the previous ts-morph implementation — OXC parses natively\n * via Rust NAPI bindings, avoiding the overhead of spinning up a full\n * TypeScript `Project` for each file.\n */\nfunction collectComponentUrls(code: string): {\n styleUrls: string[];\n templateUrls: string[];\n} {\n const { program } = parseSync('cmp.ts', code);\n const styleUrls: string[] = [];\n const templateUrls: string[] = [];\n\n const visitor = new Visitor({\n // The Visitor callback receives raw ESTree nodes. We use `any`\n // because OXC's AST includes non-standard node variants and the\n // project tsconfig enforces `noPropertyAccessFromIndexSignature`.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n Property(node: any) {\n if (node.key?.type !== 'Identifier') return;\n const name: string = node.key.name;\n\n if (name === 'styleUrls' && node.value?.type === 'ArrayExpression') {\n for (const el of node.value.elements) {\n const val = getStringValue(el);\n if (val !== undefined) styleUrls.push(val);\n }\n }\n\n if (name === 'styleUrl') {\n const val = getStringValue(node.value);\n if (val !== undefined) styleUrls.push(val);\n }\n\n if (name === 'templateUrl') {\n const val = getStringValue(node.value);\n if (val !== undefined) templateUrls.push(val);\n }\n },\n });\n visitor.visit(program);\n\n return { styleUrls, templateUrls };\n}\n\n/** Extract all `styleUrl` / `styleUrls` values from Angular component source. */\nexport function getStyleUrls(code: string): string[] {\n return collectComponentUrls(code).styleUrls;\n}\n\n/** Extract all `templateUrl` values from Angular component source. */\nexport function getTemplateUrls(code: string): string[] {\n return collectComponentUrls(code).templateUrls;\n}\n\n// ---------------------------------------------------------------------------\n// Resolver caches\n// ---------------------------------------------------------------------------\n\ninterface StyleUrlsCacheEntry {\n matchedStyleUrls: string[];\n styleUrls: string[];\n}\n\nexport class StyleUrlsResolver {\n // These resolvers may be called multiple times during the same\n // compilation for the same files. Caching is required because these\n // resolvers use synchronous system calls to the filesystem, which can\n // degrade performance when running compilations for multiple files.\n private readonly styleUrlsCache = new Map<string, StyleUrlsCacheEntry>();\n\n resolve(code: string, id: string): string[] {\n const matchedStyleUrls = getStyleUrls(code);\n const entry = this.styleUrlsCache.get(id);\n // We're using `matchedStyleUrls` as a key because the code may be changing continuously,\n // resulting in the resolver being called multiple times. While the code changes, the\n // `styleUrls` may remain constant, which means we should always return the previously\n // resolved style URLs.\n if (entry && entry.matchedStyleUrls === matchedStyleUrls) {\n return entry.styleUrls;\n }\n\n const styleUrls = matchedStyleUrls.map((styleUrlPath) => {\n return `${styleUrlPath}|${normalizePath(\n resolve(dirname(id), styleUrlPath),\n )}`;\n });\n\n this.styleUrlsCache.set(id, { styleUrls, matchedStyleUrls });\n return styleUrls;\n }\n}\n\ninterface TemplateUrlsCacheEntry {\n code: string;\n templateUrlPaths: string[];\n}\n\nexport class TemplateUrlsResolver {\n private readonly templateUrlsCache = new Map<\n string,\n TemplateUrlsCacheEntry\n >();\n\n resolve(code: string, id: string): string[] {\n const entry = this.templateUrlsCache.get(id);\n if (entry?.code === code) {\n return entry.templateUrlPaths;\n }\n\n const templateUrlPaths = getTemplateUrls(code).map(\n (url) => `${url}|${normalizePath(resolve(dirname(id), url))}`,\n );\n\n this.templateUrlsCache.set(id, { code, templateUrlPaths });\n return templateUrlPaths;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AA0BA,SAAS,eAAe,MAA+B;AACrD,KAAI,CAAC,KAAM,QAAO,KAAA;AAElB,KAAI,KAAK,SAAS,aAAa,OAAO,KAAK,UAAU,SACnD,QAAO,KAAK;AAGd,KAAI,KAAK,SAAS,gBAChB,QAAO,KAAK;AAGd,KACE,KAAK,SAAS,qBACd,KAAK,YAAY,WAAW,KAC5B,KAAK,OAAO,WAAW,EAEvB,QAAO,KAAK,OAAO,GAAG,MAAM,UAAU,KAAK,OAAO,GAAG,MAAM;;;;;;;;;;;AAc/D,SAAS,qBAAqB,MAG5B;CACA,MAAM,EAAE,YAAY,UAAU,UAAU,KAAK;CAC7C,MAAM,YAAsB,EAAE;CAC9B,MAAM,eAAyB,EAAE;AAEjB,KAAI,QAAQ,EAK1B,SAAS,MAAW;AAClB,MAAI,KAAK,KAAK,SAAS,aAAc;EACrC,MAAM,OAAe,KAAK,IAAI;AAE9B,MAAI,SAAS,eAAe,KAAK,OAAO,SAAS,kBAC/C,MAAK,MAAM,MAAM,KAAK,MAAM,UAAU;GACpC,MAAM,MAAM,eAAe,GAAG;AAC9B,OAAI,QAAQ,KAAA,EAAW,WAAU,KAAK,IAAI;;AAI9C,MAAI,SAAS,YAAY;GACvB,MAAM,MAAM,eAAe,KAAK,MAAM;AACtC,OAAI,QAAQ,KAAA,EAAW,WAAU,KAAK,IAAI;;AAG5C,MAAI,SAAS,eAAe;GAC1B,MAAM,MAAM,eAAe,KAAK,MAAM;AACtC,OAAI,QAAQ,KAAA,EAAW,cAAa,KAAK,IAAI;;IAGlD,CAAC,CACM,MAAM,QAAQ;AAEtB,QAAO;EAAE;EAAW;EAAc;;;AAIpC,SAAgB,aAAa,MAAwB;AACnD,QAAO,qBAAqB,KAAK,CAAC;;;AAIpC,SAAgB,gBAAgB,MAAwB;AACtD,QAAO,qBAAqB,KAAK,CAAC;;AAYpC,IAAa,oBAAb,MAA+B;CAK7B,iCAAkC,IAAI,KAAkC;CAExE,QAAQ,MAAc,IAAsB;EAC1C,MAAM,mBAAmB,aAAa,KAAK;EAC3C,MAAM,QAAQ,KAAK,eAAe,IAAI,GAAG;AAKzC,MAAI,SAAS,MAAM,qBAAqB,iBACtC,QAAO,MAAM;EAGf,MAAM,YAAY,iBAAiB,KAAK,iBAAiB;AACvD,UAAO,GAAG,aAAa,GAAG,cACxB,QAAQ,QAAQ,GAAG,EAAE,aAAa,CACnC;IACD;AAEF,OAAK,eAAe,IAAI,IAAI;GAAE;GAAW;GAAkB,CAAC;AAC5D,SAAO;;;AASX,IAAa,uBAAb,MAAkC;CAChC,oCAAqC,IAAI,KAGtC;CAEH,QAAQ,MAAc,IAAsB;EAC1C,MAAM,QAAQ,KAAK,kBAAkB,IAAI,GAAG;AAC5C,MAAI,OAAO,SAAS,KAClB,QAAO,MAAM;EAGf,MAAM,mBAAmB,gBAAgB,KAAK,CAAC,KAC5C,QAAQ,GAAG,IAAI,GAAG,cAAc,QAAQ,QAAQ,GAAG,EAAE,IAAI,CAAC,GAC5D;AAED,OAAK,kBAAkB,IAAI,IAAI;GAAE;GAAM;GAAkB,CAAC;AAC1D,SAAO"}
package/src/lib/host.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import * as ts from "typescript";
2
+ import type { StylePreprocessor } from "./style-preprocessor.js";
2
3
  import type { SourceFileCache } from "./utils/source-file-cache.js";
3
4
  export declare function augmentHostWithResources(host: ts.CompilerHost, transform: (code: string, id: string, options?: {
4
5
  ssr?: boolean;
@@ -8,6 +9,7 @@ export declare function augmentHostWithResources(host: ts.CompilerHost, transfor
8
9
  inlineComponentStyles?: Map<string, string>;
9
10
  externalComponentStyles?: Map<string, string>;
10
11
  sourceFileCache?: SourceFileCache;
12
+ stylePreprocessor?: StylePreprocessor;
11
13
  }): void;
12
14
  export declare function augmentProgramWithVersioning(program: ts.Program): void;
13
15
  export declare function augmentHostWithCaching(host: ts.CompilerHost, cache: Map<string, ts.SourceFile>): void;
package/src/lib/host.js CHANGED
@@ -15,15 +15,16 @@ function augmentHostWithResources(host, transform, options) {
15
15
  };
16
16
  resourceHost.transformResource = async function(data, context) {
17
17
  if (context.type !== "style") return null;
18
+ const filename = context.resourceFile ?? context.containingFile.replace(".ts", `.${options?.inlineStylesExtension}`);
19
+ const preprocessedData = options.stylePreprocessor ? options.stylePreprocessor(data, filename) ?? data : data;
18
20
  if (options.inlineComponentStyles) {
19
- const filename = createHash("sha256").update(context.containingFile).update(context.className).update(String(context.order)).update(data).digest("hex") + "." + options.inlineStylesExtension;
20
- options.inlineComponentStyles.set(filename, data);
21
- return { content: filename };
21
+ const stylesheetId = createHash("sha256").update(context.containingFile).update(context.className).update(String(context.order)).update(preprocessedData).digest("hex") + "." + options.inlineStylesExtension;
22
+ options.inlineComponentStyles.set(stylesheetId, preprocessedData);
23
+ return { content: stylesheetId };
22
24
  }
23
- const filename = context.resourceFile ?? context.containingFile.replace(".ts", `.${options?.inlineStylesExtension}`);
24
25
  let stylesheetResult;
25
26
  try {
26
- stylesheetResult = await transform(data, `${filename}?direct`);
27
+ stylesheetResult = await transform(preprocessedData, `${filename}?direct`);
27
28
  } catch (e) {
28
29
  console.error(`${e}`);
29
30
  }
@@ -1 +1 @@
1
- {"version":3,"file":"host.js","names":[],"sources":["../../../../../packages/vite-plugin-angular/src/lib/host.ts"],"sourcesContent":["import type { CompilerHost } from '@angular/compiler-cli';\nimport { normalizePath } from 'vite';\n\nimport * as ts from 'typescript';\n\nimport { createHash } from 'node:crypto';\nimport path from 'node:path';\nimport type { SourceFileCache } from './utils/source-file-cache.js';\n\nexport function augmentHostWithResources(\n host: ts.CompilerHost,\n transform: (\n code: string,\n id: string,\n options?: { ssr?: boolean },\n ) => ReturnType<any> | null,\n options: {\n inlineStylesExtension: string;\n isProd?: boolean;\n inlineComponentStyles?: Map<string, string>;\n externalComponentStyles?: Map<string, string>;\n sourceFileCache?: SourceFileCache;\n },\n): void {\n const resourceHost = host as CompilerHost;\n\n resourceHost.readResource = async function (fileName: string) {\n const filePath = normalizePath(fileName);\n\n const content = (this as any).readFile(filePath);\n\n if (content === undefined) {\n throw new Error('Unable to locate component resource: ' + fileName);\n }\n\n return content;\n };\n\n resourceHost.getModifiedResourceFiles = function () {\n return options?.sourceFileCache?.modifiedFiles;\n };\n\n resourceHost.transformResource = async function (data, context) {\n // Only style resources are supported currently\n if (context.type !== 'style') {\n return null;\n }\n\n if (options.inlineComponentStyles) {\n const id = createHash('sha256')\n .update(context.containingFile)\n .update(context.className)\n .update(String(context.order))\n .update(data)\n .digest('hex');\n const filename = id + '.' + options.inlineStylesExtension;\n options.inlineComponentStyles.set(filename, data);\n return { content: filename };\n }\n\n // Resource file only exists for external stylesheets\n const filename =\n context.resourceFile ??\n context.containingFile.replace(\n '.ts',\n `.${options?.inlineStylesExtension}`,\n );\n\n let stylesheetResult;\n\n try {\n stylesheetResult = await transform(data, `${filename}?direct`);\n } catch (e) {\n console.error(`${e}`);\n }\n\n return { content: stylesheetResult?.code || '' };\n };\n\n resourceHost.resourceNameToFileName = function (\n resourceName,\n containingFile,\n ) {\n const resolvedPath = path.join(path.dirname(containingFile), resourceName);\n\n // All resource names that have template file extensions are assumed to be templates\n if (!options.externalComponentStyles || !hasStyleExtension(resolvedPath)) {\n return resolvedPath;\n }\n\n // For external stylesheets, create a unique identifier and store the mapping\n let externalId = options.externalComponentStyles.get(resolvedPath);\n externalId ??= createHash('sha256').update(resolvedPath).digest('hex');\n\n const filename = externalId + path.extname(resolvedPath);\n\n options.externalComponentStyles.set(filename, resolvedPath);\n\n return filename;\n };\n}\n\nexport function augmentProgramWithVersioning(program: ts.Program): void {\n const baseGetSourceFiles = program.getSourceFiles;\n program.getSourceFiles = function (...parameters) {\n const files: readonly (ts.SourceFile & { version?: string })[] =\n baseGetSourceFiles(...parameters);\n\n for (const file of files) {\n file.version ??= createHash('sha256').update(file.text).digest('hex');\n }\n\n return files;\n };\n}\n\nexport function augmentHostWithCaching(\n host: ts.CompilerHost,\n cache: Map<string, ts.SourceFile>,\n): void {\n const baseGetSourceFile = host.getSourceFile;\n host.getSourceFile = function (\n fileName,\n languageVersion,\n onError,\n shouldCreateNewSourceFile,\n ...parameters\n ) {\n if (!shouldCreateNewSourceFile && cache.has(fileName)) {\n return cache.get(fileName);\n }\n\n const file = baseGetSourceFile.call(\n host,\n fileName,\n languageVersion,\n onError,\n true,\n ...parameters,\n );\n\n if (file) {\n cache.set(fileName, file);\n }\n\n return file;\n };\n}\n\nexport function mergeTransformers(\n first: ts.CustomTransformers,\n second: ts.CustomTransformers,\n): ts.CustomTransformers {\n const result: ts.CustomTransformers = {};\n\n if (first.before || second.before) {\n result.before = [...(first.before || []), ...(second.before || [])];\n }\n\n if (first.after || second.after) {\n result.after = [...(first.after || []), ...(second.after || [])];\n }\n\n if (first.afterDeclarations || second.afterDeclarations) {\n result.afterDeclarations = [\n ...(first.afterDeclarations || []),\n ...(second.afterDeclarations || []),\n ];\n }\n\n return result;\n}\n\nfunction hasStyleExtension(file: string): boolean {\n const extension = path.extname(file).toLowerCase();\n\n switch (extension) {\n case '.css':\n case '.scss':\n return true;\n default:\n return false;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"host.js","names":[],"sources":["../../../src/lib/host.ts"],"sourcesContent":["import type { CompilerHost } from '@angular/compiler-cli';\nimport { normalizePath } from 'vite';\n\nimport * as ts from 'typescript';\n\nimport { createHash } from 'node:crypto';\nimport path from 'node:path';\nimport type { StylePreprocessor } from './style-preprocessor.js';\nimport type { SourceFileCache } from './utils/source-file-cache.js';\n\nexport function augmentHostWithResources(\n host: ts.CompilerHost,\n transform: (\n code: string,\n id: string,\n options?: { ssr?: boolean },\n ) => ReturnType<any> | null,\n options: {\n inlineStylesExtension: string;\n isProd?: boolean;\n inlineComponentStyles?: Map<string, string>;\n externalComponentStyles?: Map<string, string>;\n sourceFileCache?: SourceFileCache;\n stylePreprocessor?: StylePreprocessor;\n },\n): void {\n const resourceHost = host as CompilerHost;\n\n resourceHost.readResource = async function (fileName: string) {\n const filePath = normalizePath(fileName);\n\n const content = (this as any).readFile(filePath);\n\n if (content === undefined) {\n throw new Error('Unable to locate component resource: ' + fileName);\n }\n\n return content;\n };\n\n resourceHost.getModifiedResourceFiles = function () {\n return options?.sourceFileCache?.modifiedFiles;\n };\n\n resourceHost.transformResource = async function (data, context) {\n // Only style resources are supported currently\n if (context.type !== 'style') {\n return null;\n }\n\n const filename =\n context.resourceFile ??\n context.containingFile.replace(\n '.ts',\n `.${options?.inlineStylesExtension}`,\n );\n const preprocessedData = options.stylePreprocessor\n ? (options.stylePreprocessor(data, filename) ?? data)\n : data;\n\n // liveReload path: store preprocessed CSS for Vite's serve-time pipeline.\n // CSS must NOT be transformed here — the load hook returns it into\n // Vite's transform pipeline where PostCSS / Tailwind process it once.\n if (options.inlineComponentStyles) {\n const id = createHash('sha256')\n .update(context.containingFile)\n .update(context.className)\n .update(String(context.order))\n .update(preprocessedData)\n .digest('hex');\n const stylesheetId = id + '.' + options.inlineStylesExtension;\n options.inlineComponentStyles.set(stylesheetId, preprocessedData);\n return { content: stylesheetId };\n }\n\n // Non-liveReload: CSS is returned directly to the Angular compiler\n // and never re-enters Vite's pipeline, so transform eagerly.\n let stylesheetResult;\n\n try {\n stylesheetResult = await transform(\n preprocessedData,\n `${filename}?direct`,\n );\n } catch (e) {\n console.error(`${e}`);\n }\n\n return { content: stylesheetResult?.code || '' };\n };\n\n resourceHost.resourceNameToFileName = function (\n resourceName,\n containingFile,\n ) {\n const resolvedPath = path.join(path.dirname(containingFile), resourceName);\n\n // All resource names that have template file extensions are assumed to be templates\n if (!options.externalComponentStyles || !hasStyleExtension(resolvedPath)) {\n return resolvedPath;\n }\n\n // For external stylesheets, create a unique identifier and store the mapping\n let externalId = options.externalComponentStyles.get(resolvedPath);\n externalId ??= createHash('sha256').update(resolvedPath).digest('hex');\n\n const filename = externalId + path.extname(resolvedPath);\n\n options.externalComponentStyles.set(filename, resolvedPath);\n\n return filename;\n };\n}\n\nexport function augmentProgramWithVersioning(program: ts.Program): void {\n const baseGetSourceFiles = program.getSourceFiles;\n program.getSourceFiles = function (...parameters) {\n const files: readonly (ts.SourceFile & { version?: string })[] =\n baseGetSourceFiles(...parameters);\n\n for (const file of files) {\n file.version ??= createHash('sha256').update(file.text).digest('hex');\n }\n\n return files;\n };\n}\n\nexport function augmentHostWithCaching(\n host: ts.CompilerHost,\n cache: Map<string, ts.SourceFile>,\n): void {\n const baseGetSourceFile = host.getSourceFile;\n host.getSourceFile = function (\n fileName,\n languageVersion,\n onError,\n shouldCreateNewSourceFile,\n ...parameters\n ) {\n if (!shouldCreateNewSourceFile && cache.has(fileName)) {\n return cache.get(fileName);\n }\n\n const file = baseGetSourceFile.call(\n host,\n fileName,\n languageVersion,\n onError,\n true,\n ...parameters,\n );\n\n if (file) {\n cache.set(fileName, file);\n }\n\n return file;\n };\n}\n\nexport function mergeTransformers(\n first: ts.CustomTransformers,\n second: ts.CustomTransformers,\n): ts.CustomTransformers {\n const result: ts.CustomTransformers = {};\n\n if (first.before || second.before) {\n result.before = [...(first.before || []), ...(second.before || [])];\n }\n\n if (first.after || second.after) {\n result.after = [...(first.after || []), ...(second.after || [])];\n }\n\n if (first.afterDeclarations || second.afterDeclarations) {\n result.afterDeclarations = [\n ...(first.afterDeclarations || []),\n ...(second.afterDeclarations || []),\n ];\n }\n\n return result;\n}\n\nfunction hasStyleExtension(file: string): boolean {\n const extension = path.extname(file).toLowerCase();\n\n switch (extension) {\n case '.css':\n case '.scss':\n return true;\n default:\n return false;\n }\n}\n"],"mappings":";;;;AAUA,SAAgB,yBACd,MACA,WAKA,SAQM;CACN,MAAM,eAAe;AAErB,cAAa,eAAe,eAAgB,UAAkB;EAC5D,MAAM,WAAW,cAAc,SAAS;EAExC,MAAM,UAAW,KAAa,SAAS,SAAS;AAEhD,MAAI,YAAY,KAAA,EACd,OAAM,IAAI,MAAM,0CAA0C,SAAS;AAGrE,SAAO;;AAGT,cAAa,2BAA2B,WAAY;AAClD,SAAO,SAAS,iBAAiB;;AAGnC,cAAa,oBAAoB,eAAgB,MAAM,SAAS;AAE9D,MAAI,QAAQ,SAAS,QACnB,QAAO;EAGT,MAAM,WACJ,QAAQ,gBACR,QAAQ,eAAe,QACrB,OACA,IAAI,SAAS,wBACd;EACH,MAAM,mBAAmB,QAAQ,oBAC5B,QAAQ,kBAAkB,MAAM,SAAS,IAAI,OAC9C;AAKJ,MAAI,QAAQ,uBAAuB;GAOjC,MAAM,eANK,WAAW,SAAS,CAC5B,OAAO,QAAQ,eAAe,CAC9B,OAAO,QAAQ,UAAU,CACzB,OAAO,OAAO,QAAQ,MAAM,CAAC,CAC7B,OAAO,iBAAiB,CACxB,OAAO,MAAM,GACU,MAAM,QAAQ;AACxC,WAAQ,sBAAsB,IAAI,cAAc,iBAAiB;AACjE,UAAO,EAAE,SAAS,cAAc;;EAKlC,IAAI;AAEJ,MAAI;AACF,sBAAmB,MAAM,UACvB,kBACA,GAAG,SAAS,SACb;WACM,GAAG;AACV,WAAQ,MAAM,GAAG,IAAI;;AAGvB,SAAO,EAAE,SAAS,kBAAkB,QAAQ,IAAI;;AAGlD,cAAa,yBAAyB,SACpC,cACA,gBACA;EACA,MAAM,eAAe,KAAK,KAAK,KAAK,QAAQ,eAAe,EAAE,aAAa;AAG1E,MAAI,CAAC,QAAQ,2BAA2B,CAAC,kBAAkB,aAAa,CACtE,QAAO;EAIT,IAAI,aAAa,QAAQ,wBAAwB,IAAI,aAAa;AAClE,iBAAe,WAAW,SAAS,CAAC,OAAO,aAAa,CAAC,OAAO,MAAM;EAEtE,MAAM,WAAW,aAAa,KAAK,QAAQ,aAAa;AAExD,UAAQ,wBAAwB,IAAI,UAAU,aAAa;AAE3D,SAAO;;;AAIX,SAAgB,6BAA6B,SAA2B;CACtE,MAAM,qBAAqB,QAAQ;AACnC,SAAQ,iBAAiB,SAAU,GAAG,YAAY;EAChD,MAAM,QACJ,mBAAmB,GAAG,WAAW;AAEnC,OAAK,MAAM,QAAQ,MACjB,MAAK,YAAY,WAAW,SAAS,CAAC,OAAO,KAAK,KAAK,CAAC,OAAO,MAAM;AAGvE,SAAO;;;AAIX,SAAgB,uBACd,MACA,OACM;CACN,MAAM,oBAAoB,KAAK;AAC/B,MAAK,gBAAgB,SACnB,UACA,iBACA,SACA,2BACA,GAAG,YACH;AACA,MAAI,CAAC,6BAA6B,MAAM,IAAI,SAAS,CACnD,QAAO,MAAM,IAAI,SAAS;EAG5B,MAAM,OAAO,kBAAkB,KAC7B,MACA,UACA,iBACA,SACA,MACA,GAAG,WACJ;AAED,MAAI,KACF,OAAM,IAAI,UAAU,KAAK;AAG3B,SAAO;;;AAIX,SAAgB,kBACd,OACA,QACuB;CACvB,MAAM,SAAgC,EAAE;AAExC,KAAI,MAAM,UAAU,OAAO,OACzB,QAAO,SAAS,CAAC,GAAI,MAAM,UAAU,EAAE,EAAG,GAAI,OAAO,UAAU,EAAE,CAAE;AAGrE,KAAI,MAAM,SAAS,OAAO,MACxB,QAAO,QAAQ,CAAC,GAAI,MAAM,SAAS,EAAE,EAAG,GAAI,OAAO,SAAS,EAAE,CAAE;AAGlE,KAAI,MAAM,qBAAqB,OAAO,kBACpC,QAAO,oBAAoB,CACzB,GAAI,MAAM,qBAAqB,EAAE,EACjC,GAAI,OAAO,qBAAqB,EAAE,CACnC;AAGH,QAAO;;AAGT,SAAS,kBAAkB,MAAuB;AAGhD,SAFkB,KAAK,QAAQ,KAAK,CAAC,aAAa,EAElD;EACE,KAAK;EACL,KAAK,QACH,QAAO;EACT,QACE,QAAO"}
@@ -1 +1 @@
1
- {"version":3,"file":"live-reload-plugin.js","names":[],"sources":["../../../../../packages/vite-plugin-angular/src/lib/live-reload-plugin.ts"],"sourcesContent":["import { resolve } from 'node:path';\nimport { ServerResponse } from 'node:http';\nimport { Connect, normalizePath, Plugin, ViteDevServer } from 'vite';\n\nimport { EmitFileResult } from './models.js';\n\nconst ANGULAR_COMPONENT_PREFIX = '/@ng/component';\nconst FILE_PREFIX = 'file:';\n\nexport function liveReloadPlugin({\n classNames,\n fileEmitter,\n}: {\n classNames: Map<string, string>;\n fileEmitter: (file: string) => EmitFileResult | undefined;\n}): Plugin {\n return {\n name: 'analogjs-live-reload-plugin',\n apply: 'serve',\n configureServer(server: ViteDevServer) {\n const angularComponentMiddleware: Connect.HandleFunction = async (\n req: Connect.IncomingMessage,\n res: ServerResponse<Connect.IncomingMessage>,\n next: Connect.NextFunction,\n ) => {\n if (req.url === undefined || res.writableEnded) {\n return;\n }\n\n if (!req.url.includes(ANGULAR_COMPONENT_PREFIX)) {\n next();\n\n return;\n }\n\n const requestUrl = new URL(req.url, 'http://localhost');\n const componentId = requestUrl.searchParams.get('c');\n\n if (!componentId) {\n res.statusCode = 400;\n res.end();\n\n return;\n }\n\n const [fileId] = decodeURIComponent(componentId).split('@');\n const resolvedId = normalizePath(resolve(process.cwd(), fileId));\n const invalidated =\n !!server.moduleGraph.getModuleById(resolvedId)\n ?.lastInvalidationTimestamp && classNames.get(resolvedId);\n\n // don't send an HMR update until the file has been invalidated\n if (!invalidated) {\n res.setHeader('Content-Type', 'text/javascript');\n res.setHeader('Cache-Control', 'no-cache');\n res.end('');\n return;\n }\n\n const result = fileEmitter(resolvedId);\n res.setHeader('Content-Type', 'text/javascript');\n res.setHeader('Cache-Control', 'no-cache');\n res.end(`${result?.hmrUpdateCode || ''}`);\n };\n\n server.middlewares.use(angularComponentMiddleware);\n },\n resolveId(id, _importer, options) {\n if (\n options?.ssr &&\n id.startsWith(FILE_PREFIX) &&\n id.includes(ANGULAR_COMPONENT_PREFIX)\n ) {\n return `\\0${id}`;\n }\n\n return undefined;\n },\n load(id, options) {\n if (options?.ssr && id.includes(ANGULAR_COMPONENT_PREFIX)) {\n const requestUrl = new URL(id.slice(1), 'http://localhost');\n const componentId = requestUrl.searchParams.get('c');\n\n if (!componentId) {\n return;\n }\n\n const result = fileEmitter(\n normalizePath(\n resolve(\n process.cwd(),\n decodeURIComponent(componentId).split('@')[0],\n ),\n ),\n );\n\n return result?.hmrUpdateCode || '';\n }\n\n return;\n },\n };\n}\n"],"mappings":";;;AAMA,IAAM,2BAA2B;AACjC,IAAM,cAAc;AAEpB,SAAgB,iBAAiB,EAC/B,YACA,eAIS;AACT,QAAO;EACL,MAAM;EACN,OAAO;EACP,gBAAgB,QAAuB;GACrC,MAAM,6BAAqD,OACzD,KACA,KACA,SACG;AACH,QAAI,IAAI,QAAQ,KAAA,KAAa,IAAI,cAC/B;AAGF,QAAI,CAAC,IAAI,IAAI,SAAS,yBAAyB,EAAE;AAC/C,WAAM;AAEN;;IAIF,MAAM,cADa,IAAI,IAAI,IAAI,KAAK,mBAAmB,CACxB,aAAa,IAAI,IAAI;AAEpD,QAAI,CAAC,aAAa;AAChB,SAAI,aAAa;AACjB,SAAI,KAAK;AAET;;IAGF,MAAM,CAAC,UAAU,mBAAmB,YAAY,CAAC,MAAM,IAAI;IAC3D,MAAM,aAAa,cAAc,QAAQ,QAAQ,KAAK,EAAE,OAAO,CAAC;AAMhE,QAAI,EAJF,CAAC,CAAC,OAAO,YAAY,cAAc,WAAW,EAC1C,6BAA6B,WAAW,IAAI,WAAW,GAG3C;AAChB,SAAI,UAAU,gBAAgB,kBAAkB;AAChD,SAAI,UAAU,iBAAiB,WAAW;AAC1C,SAAI,IAAI,GAAG;AACX;;IAGF,MAAM,SAAS,YAAY,WAAW;AACtC,QAAI,UAAU,gBAAgB,kBAAkB;AAChD,QAAI,UAAU,iBAAiB,WAAW;AAC1C,QAAI,IAAI,GAAG,QAAQ,iBAAiB,KAAK;;AAG3C,UAAO,YAAY,IAAI,2BAA2B;;EAEpD,UAAU,IAAI,WAAW,SAAS;AAChC,OACE,SAAS,OACT,GAAG,WAAW,YAAY,IAC1B,GAAG,SAAS,yBAAyB,CAErC,QAAO,KAAK;;EAKhB,KAAK,IAAI,SAAS;AAChB,OAAI,SAAS,OAAO,GAAG,SAAS,yBAAyB,EAAE;IAEzD,MAAM,cADa,IAAI,IAAI,GAAG,MAAM,EAAE,EAAE,mBAAmB,CAC5B,aAAa,IAAI,IAAI;AAEpD,QAAI,CAAC,YACH;AAYF,WATe,YACb,cACE,QACE,QAAQ,KAAK,EACb,mBAAmB,YAAY,CAAC,MAAM,IAAI,CAAC,GAC5C,CACF,CACF,EAEc,iBAAiB;;;EAKrC"}
1
+ {"version":3,"file":"live-reload-plugin.js","names":[],"sources":["../../../src/lib/live-reload-plugin.ts"],"sourcesContent":["import { resolve } from 'node:path';\nimport { ServerResponse } from 'node:http';\nimport { Connect, normalizePath, Plugin, ViteDevServer } from 'vite';\n\nimport { EmitFileResult } from './models.js';\n\nconst ANGULAR_COMPONENT_PREFIX = '/@ng/component';\nconst FILE_PREFIX = 'file:';\n\nexport function liveReloadPlugin({\n classNames,\n fileEmitter,\n}: {\n classNames: Map<string, string>;\n fileEmitter: (file: string) => EmitFileResult | undefined;\n}): Plugin {\n return {\n name: 'analogjs-live-reload-plugin',\n apply: 'serve',\n configureServer(server: ViteDevServer) {\n const angularComponentMiddleware: Connect.HandleFunction = async (\n req: Connect.IncomingMessage,\n res: ServerResponse<Connect.IncomingMessage>,\n next: Connect.NextFunction,\n ) => {\n if (req.url === undefined || res.writableEnded) {\n return;\n }\n\n if (!req.url.includes(ANGULAR_COMPONENT_PREFIX)) {\n next();\n\n return;\n }\n\n const requestUrl = new URL(req.url, 'http://localhost');\n const componentId = requestUrl.searchParams.get('c');\n\n if (!componentId) {\n res.statusCode = 400;\n res.end();\n\n return;\n }\n\n const [fileId] = decodeURIComponent(componentId).split('@');\n const resolvedId = normalizePath(resolve(process.cwd(), fileId));\n const invalidated =\n !!server.moduleGraph.getModuleById(resolvedId)\n ?.lastInvalidationTimestamp && classNames.get(resolvedId);\n\n // don't send an HMR update until the file has been invalidated\n if (!invalidated) {\n res.setHeader('Content-Type', 'text/javascript');\n res.setHeader('Cache-Control', 'no-cache');\n res.end('');\n return;\n }\n\n const result = fileEmitter(resolvedId);\n res.setHeader('Content-Type', 'text/javascript');\n res.setHeader('Cache-Control', 'no-cache');\n res.end(`${result?.hmrUpdateCode || ''}`);\n };\n\n server.middlewares.use(angularComponentMiddleware);\n },\n resolveId(id, _importer, options) {\n if (\n options?.ssr &&\n id.startsWith(FILE_PREFIX) &&\n id.includes(ANGULAR_COMPONENT_PREFIX)\n ) {\n return `\\0${id}`;\n }\n\n return undefined;\n },\n load(id, options) {\n if (options?.ssr && id.includes(ANGULAR_COMPONENT_PREFIX)) {\n const requestUrl = new URL(id.slice(1), 'http://localhost');\n const componentId = requestUrl.searchParams.get('c');\n\n if (!componentId) {\n return;\n }\n\n const result = fileEmitter(\n normalizePath(\n resolve(\n process.cwd(),\n decodeURIComponent(componentId).split('@')[0],\n ),\n ),\n );\n\n return result?.hmrUpdateCode || '';\n }\n\n return;\n },\n };\n}\n"],"mappings":";;;AAMA,IAAM,2BAA2B;AACjC,IAAM,cAAc;AAEpB,SAAgB,iBAAiB,EAC/B,YACA,eAIS;AACT,QAAO;EACL,MAAM;EACN,OAAO;EACP,gBAAgB,QAAuB;GACrC,MAAM,6BAAqD,OACzD,KACA,KACA,SACG;AACH,QAAI,IAAI,QAAQ,KAAA,KAAa,IAAI,cAC/B;AAGF,QAAI,CAAC,IAAI,IAAI,SAAS,yBAAyB,EAAE;AAC/C,WAAM;AAEN;;IAIF,MAAM,cADa,IAAI,IAAI,IAAI,KAAK,mBAAmB,CACxB,aAAa,IAAI,IAAI;AAEpD,QAAI,CAAC,aAAa;AAChB,SAAI,aAAa;AACjB,SAAI,KAAK;AAET;;IAGF,MAAM,CAAC,UAAU,mBAAmB,YAAY,CAAC,MAAM,IAAI;IAC3D,MAAM,aAAa,cAAc,QAAQ,QAAQ,KAAK,EAAE,OAAO,CAAC;AAMhE,QAAI,EAJF,CAAC,CAAC,OAAO,YAAY,cAAc,WAAW,EAC1C,6BAA6B,WAAW,IAAI,WAAW,GAG3C;AAChB,SAAI,UAAU,gBAAgB,kBAAkB;AAChD,SAAI,UAAU,iBAAiB,WAAW;AAC1C,SAAI,IAAI,GAAG;AACX;;IAGF,MAAM,SAAS,YAAY,WAAW;AACtC,QAAI,UAAU,gBAAgB,kBAAkB;AAChD,QAAI,UAAU,iBAAiB,WAAW;AAC1C,QAAI,IAAI,GAAG,QAAQ,iBAAiB,KAAK;;AAG3C,UAAO,YAAY,IAAI,2BAA2B;;EAEpD,UAAU,IAAI,WAAW,SAAS;AAChC,OACE,SAAS,OACT,GAAG,WAAW,YAAY,IAC1B,GAAG,SAAS,yBAAyB,CAErC,QAAO,KAAK;;EAKhB,KAAK,IAAI,SAAS;AAChB,OAAI,SAAS,OAAO,GAAG,SAAS,yBAAyB,EAAE;IAEzD,MAAM,cADa,IAAI,IAAI,GAAG,MAAM,EAAE,EAAE,mBAAmB,CAC5B,aAAa,IAAI,IAAI;AAEpD,QAAI,CAAC,YACH;AAYF,WATe,YACb,cACE,QACE,QAAQ,KAAK,EACb,mBAAmB,YAAY,CAAC,MAAM,IAAI,CAAC,GAC5C,CACF,CACF,EAEc,iBAAiB;;;EAKrC"}
@@ -1 +1 @@
1
- {"version":3,"file":"nx-folder-plugin.js","names":[],"sources":["../../../../../packages/vite-plugin-angular/src/lib/nx-folder-plugin.ts"],"sourcesContent":["import { normalizePath, Plugin } from 'vite';\n\n/**\n * Ignores anything in the .nx folder from triggering HMR\n *\n * @returns\n */\nexport function nxFolderPlugin(): Plugin {\n return {\n name: 'analogjs-nx-folder-plugin',\n apply: 'serve',\n handleHotUpdate(ctx) {\n if (ctx.file.includes(normalizePath('/.nx/'))) {\n return [];\n }\n\n return ctx.modules;\n },\n };\n}\n"],"mappings":";;;;;;;AAOA,SAAgB,iBAAyB;AACvC,QAAO;EACL,MAAM;EACN,OAAO;EACP,gBAAgB,KAAK;AACnB,OAAI,IAAI,KAAK,SAAS,cAAc,QAAQ,CAAC,CAC3C,QAAO,EAAE;AAGX,UAAO,IAAI;;EAEd"}
1
+ {"version":3,"file":"nx-folder-plugin.js","names":[],"sources":["../../../src/lib/nx-folder-plugin.ts"],"sourcesContent":["import { normalizePath, Plugin } from 'vite';\n\n/**\n * Ignores anything in the .nx folder from triggering HMR\n *\n * @returns\n */\nexport function nxFolderPlugin(): Plugin {\n return {\n name: 'analogjs-nx-folder-plugin',\n apply: 'serve',\n handleHotUpdate(ctx) {\n if (ctx.file.includes(normalizePath('/.nx/'))) {\n return [];\n }\n\n return ctx.modules;\n },\n };\n}\n"],"mappings":";;;;;;;AAOA,SAAgB,iBAAyB;AACvC,QAAO;EACL,MAAM;EACN,OAAO;EACP,gBAAgB,KAAK;AACnB,OAAI,IAAI,KAAK,SAAS,cAAc,QAAQ,CAAC,CAC3C,QAAO,EAAE;AAGX,UAAO,IAAI;;EAEd"}
@@ -1 +1 @@
1
- {"version":3,"file":"file-replacements.plugin.js","names":[],"sources":["../../../../../../packages/vite-plugin-angular/src/lib/plugins/file-replacements.plugin.ts"],"sourcesContent":["// source: https://github.com/Myrmod/vitejs-theming/blob/master/build-plugins/rollup/replace-files.js\nimport { isAbsolute, resolve } from 'node:path';\nimport { Plugin } from 'vite';\n\nexport function replaceFiles(\n replacements: FileReplacement[],\n workspaceRoot: string,\n): Plugin | false {\n if (!replacements?.length) {\n return false;\n }\n\n return {\n name: 'rollup-plugin-replace-files',\n enforce: 'pre',\n async resolveId(source, importer, options) {\n const resolved = await this.resolve(source, importer, {\n ...options,\n skipSelf: true,\n });\n /**\n * The reason we're using endsWith here is because the resolved id\n * will be the absolute path to the file. We want to check if the\n * file ends with the file we're trying to replace, which will be essentially\n * the path from the root of our workspace.\n */\n const mappedReplacements = replacements.map((fr: FileReplacement) => {\n const frSSR = fr as FileReplacementSSR;\n const frWith = fr as FileReplacementWith;\n\n return {\n ...fr,\n ssr: frSSR.ssr\n ? isAbsolute(frSSR.ssr)\n ? frSSR.ssr\n : resolve(workspaceRoot, frSSR.ssr)\n : '',\n with: frWith.with\n ? isAbsolute(frWith.with)\n ? frWith.with\n : resolve(workspaceRoot, frWith.with)\n : '',\n };\n });\n const foundReplace = mappedReplacements.find((replacement) =>\n resolved?.id?.endsWith(replacement.replace),\n );\n if (foundReplace) {\n try {\n if (this.environment.name === 'ssr' && foundReplace.ssr) {\n // return new file id for ssr\n return {\n id: foundReplace.ssr,\n };\n } else if (foundReplace.ssr) {\n return null;\n }\n\n // return new file id\n return {\n id: foundReplace.with,\n };\n } catch (err) {\n console.error(err);\n return null;\n }\n }\n return null;\n },\n };\n}\n\nexport type FileReplacement = FileReplacementWith | FileReplacementSSR;\n\nexport interface FileReplacementBase {\n replace: string;\n}\nexport interface FileReplacementWith extends FileReplacementBase {\n with: string;\n}\n\nexport interface FileReplacementSSR extends FileReplacementBase {\n ssr: string;\n}\n"],"mappings":";;AAIA,SAAgB,aACd,cACA,eACgB;AAChB,KAAI,CAAC,cAAc,OACjB,QAAO;AAGT,QAAO;EACL,MAAM;EACN,SAAS;EACT,MAAM,UAAU,QAAQ,UAAU,SAAS;GACzC,MAAM,WAAW,MAAM,KAAK,QAAQ,QAAQ,UAAU;IACpD,GAAG;IACH,UAAU;IACX,CAAC;GAyBF,MAAM,eAlBqB,aAAa,KAAK,OAAwB;IACnE,MAAM,QAAQ;IACd,MAAM,SAAS;AAEf,WAAO;KACL,GAAG;KACH,KAAK,MAAM,MACP,WAAW,MAAM,IAAI,GACnB,MAAM,MACN,QAAQ,eAAe,MAAM,IAAI,GACnC;KACJ,MAAM,OAAO,OACT,WAAW,OAAO,KAAK,GACrB,OAAO,OACP,QAAQ,eAAe,OAAO,KAAK,GACrC;KACL;KACD,CACsC,MAAM,gBAC5C,UAAU,IAAI,SAAS,YAAY,QAAQ,CAC5C;AACD,OAAI,aACF,KAAI;AACF,QAAI,KAAK,YAAY,SAAS,SAAS,aAAa,IAElD,QAAO,EACL,IAAI,aAAa,KAClB;aACQ,aAAa,IACtB,QAAO;AAIT,WAAO,EACL,IAAI,aAAa,MAClB;YACM,KAAK;AACZ,YAAQ,MAAM,IAAI;AAClB,WAAO;;AAGX,UAAO;;EAEV"}
1
+ {"version":3,"file":"file-replacements.plugin.js","names":[],"sources":["../../../../src/lib/plugins/file-replacements.plugin.ts"],"sourcesContent":["// source: https://github.com/Myrmod/vitejs-theming/blob/master/build-plugins/rollup/replace-files.js\nimport { isAbsolute, resolve } from 'node:path';\nimport { Plugin } from 'vite';\n\nexport function replaceFiles(\n replacements: FileReplacement[],\n workspaceRoot: string,\n): Plugin | false {\n if (!replacements?.length) {\n return false;\n }\n\n return {\n name: 'rollup-plugin-replace-files',\n enforce: 'pre',\n async resolveId(source, importer, options) {\n const resolved = await this.resolve(source, importer, {\n ...options,\n skipSelf: true,\n });\n /**\n * The reason we're using endsWith here is because the resolved id\n * will be the absolute path to the file. We want to check if the\n * file ends with the file we're trying to replace, which will be essentially\n * the path from the root of our workspace.\n */\n const mappedReplacements = replacements.map((fr: FileReplacement) => {\n const frSSR = fr as FileReplacementSSR;\n const frWith = fr as FileReplacementWith;\n\n return {\n ...fr,\n ssr: frSSR.ssr\n ? isAbsolute(frSSR.ssr)\n ? frSSR.ssr\n : resolve(workspaceRoot, frSSR.ssr)\n : '',\n with: frWith.with\n ? isAbsolute(frWith.with)\n ? frWith.with\n : resolve(workspaceRoot, frWith.with)\n : '',\n };\n });\n const foundReplace = mappedReplacements.find((replacement) =>\n resolved?.id?.endsWith(replacement.replace),\n );\n if (foundReplace) {\n try {\n if (this.environment.name === 'ssr' && foundReplace.ssr) {\n // return new file id for ssr\n return {\n id: foundReplace.ssr,\n };\n } else if (foundReplace.ssr) {\n return null;\n }\n\n // return new file id\n return {\n id: foundReplace.with,\n };\n } catch (err) {\n console.error(err);\n return null;\n }\n }\n return null;\n },\n };\n}\n\nexport type FileReplacement = FileReplacementWith | FileReplacementSSR;\n\nexport interface FileReplacementBase {\n replace: string;\n}\nexport interface FileReplacementWith extends FileReplacementBase {\n with: string;\n}\n\nexport interface FileReplacementSSR extends FileReplacementBase {\n ssr: string;\n}\n"],"mappings":";;AAIA,SAAgB,aACd,cACA,eACgB;AAChB,KAAI,CAAC,cAAc,OACjB,QAAO;AAGT,QAAO;EACL,MAAM;EACN,SAAS;EACT,MAAM,UAAU,QAAQ,UAAU,SAAS;GACzC,MAAM,WAAW,MAAM,KAAK,QAAQ,QAAQ,UAAU;IACpD,GAAG;IACH,UAAU;IACX,CAAC;GAyBF,MAAM,eAlBqB,aAAa,KAAK,OAAwB;IACnE,MAAM,QAAQ;IACd,MAAM,SAAS;AAEf,WAAO;KACL,GAAG;KACH,KAAK,MAAM,MACP,WAAW,MAAM,IAAI,GACnB,MAAM,MACN,QAAQ,eAAe,MAAM,IAAI,GACnC;KACJ,MAAM,OAAO,OACT,WAAW,OAAO,KAAK,GACrB,OAAO,OACP,QAAQ,eAAe,OAAO,KAAK,GACrC;KACL;KACD,CACsC,MAAM,gBAC5C,UAAU,IAAI,SAAS,YAAY,QAAQ,CAC5C;AACD,OAAI,aACF,KAAI;AACF,QAAI,KAAK,YAAY,SAAS,SAAS,aAAa,IAElD,QAAO,EACL,IAAI,aAAa,KAClB;aACQ,aAAa,IACtB,QAAO;AAIT,WAAO,EACL,IAAI,aAAa,MAClB;YACM,KAAK;AACZ,YAAQ,MAAM,IAAI;AAClB,WAAO;;AAGX,UAAO;;EAEV"}
@@ -1 +1 @@
1
- {"version":3,"file":"router-plugin.js","names":[],"sources":["../../../../../packages/vite-plugin-angular/src/lib/router-plugin.ts"],"sourcesContent":["import type { Plugin } from 'vite';\nimport { JavaScriptTransformer } from './utils/devkit.js';\n\nexport function routerPlugin(): Plugin {\n const javascriptTransformer = new JavaScriptTransformer({ jit: true }, 1);\n\n /**\n * Transforms Angular packages the didn't get picked up by Vite's pre-optimization.\n */\n return {\n name: 'analogjs-router-optimization',\n enforce: 'pre',\n apply: 'serve',\n transform: {\n filter: {\n id: /fesm(.*?)\\.mjs/,\n },\n async handler(_code: string, id: string) {\n const path = id.split('?')[0];\n const contents = await javascriptTransformer.transformFile(path);\n\n return {\n code: Buffer.from(contents).toString('utf-8'),\n };\n },\n },\n };\n}\n"],"mappings":";;AAGA,SAAgB,eAAuB;CACrC,MAAM,wBAAwB,IAAI,GAAsB,EAAE,KAAK,MAAM,EAAE,EAAE;;;;AAKzE,QAAO;EACL,MAAM;EACN,SAAS;EACT,OAAO;EACP,WAAW;GACT,QAAQ,EACN,IAAI,kBACL;GACD,MAAM,QAAQ,OAAe,IAAY;IACvC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC;IAC3B,MAAM,WAAW,MAAM,sBAAsB,cAAc,KAAK;AAEhE,WAAO,EACL,MAAM,OAAO,KAAK,SAAS,CAAC,SAAS,QAAQ,EAC9C;;GAEJ;EACF"}
1
+ {"version":3,"file":"router-plugin.js","names":[],"sources":["../../../src/lib/router-plugin.ts"],"sourcesContent":["import type { Plugin } from 'vite';\nimport { JavaScriptTransformer } from './utils/devkit.js';\n\nexport function routerPlugin(): Plugin {\n const javascriptTransformer = new JavaScriptTransformer({ jit: true }, 1);\n\n /**\n * Transforms Angular packages the didn't get picked up by Vite's pre-optimization.\n */\n return {\n name: 'analogjs-router-optimization',\n enforce: 'pre',\n apply: 'serve',\n transform: {\n filter: {\n id: /fesm(.*?)\\.mjs/,\n },\n async handler(_code: string, id: string) {\n const path = id.split('?')[0];\n const contents = await javascriptTransformer.transformFile(path);\n\n return {\n code: Buffer.from(contents).toString('utf-8'),\n };\n },\n },\n };\n}\n"],"mappings":";;AAGA,SAAgB,eAAuB;CACrC,MAAM,wBAAwB,IAAI,GAAsB,EAAE,KAAK,MAAM,EAAE,EAAE;;;;AAKzE,QAAO;EACL,MAAM;EACN,SAAS;EACT,OAAO;EACP,WAAW;GACT,QAAQ,EACN,IAAI,kBACL;GACD,MAAM,QAAQ,OAAe,IAAY;IACvC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC;IAC3B,MAAM,WAAW,MAAM,sBAAsB,cAAc,KAAK;AAEhE,WAAO,EACL,MAAM,OAAO,KAAK,SAAS,CAAC,SAAS,QAAQ,EAC9C;;GAEJ;EACF"}
@@ -0,0 +1 @@
1
+ export type StylePreprocessor = (code: string, filename: string) => string;
@@ -1 +1 @@
1
- {"version":3,"file":"vite-build.impl.js","names":[],"sources":["../../../../../../../../../packages/vite-plugin-angular-tools/src/builders/vite/vite-build.impl.ts"],"sourcesContent":["import {\n BuilderContext,\n BuilderOutput,\n createBuilder,\n targetFromTargetString,\n} from '@angular-devkit/architect';\nimport type { InlineConfig } from 'vite';\nimport { ViteBuildSchema } from './schema';\n\nasync function viteBuilder(\n options: ViteBuildSchema,\n context: BuilderContext,\n): Promise<BuilderOutput> {\n const { createBuilder } = await Function('return import(\"vite\")')();\n if (!context.target) {\n throw new Error('Builder must be executed with a target');\n }\n const projectConfig = await context.getProjectMetadata(context.target);\n const projectName = context.target.project;\n const configuration = context.target.configuration || 'production';\n const buildTargetSpecifier = `::${configuration}`;\n const buildTarget = targetFromTargetString(\n buildTargetSpecifier,\n projectName,\n 'build',\n );\n\n const browserBuilderName = await context.getBuilderNameForTarget(buildTarget);\n const rawBuildOptions = await context.getTargetOptions(buildTarget);\n const buildOptions = await context.validateOptions(\n rawBuildOptions,\n browserBuilderName,\n );\n\n const buildConfig: InlineConfig = {\n configFile: options.configFile,\n root: projectConfig.root as string,\n mode: (process.env.NODE_ENV ??\n buildOptions.mode ??\n configuration) as string,\n build: {\n outDir: options.outputPath,\n sourcemap: !!buildOptions.sourcemap,\n },\n };\n\n try {\n const builder = await createBuilder(buildConfig, false);\n await builder.buildApp();\n\n return {\n success: true,\n };\n } catch (e) {\n console.error(e);\n return {\n success: false,\n };\n }\n}\n\nexport default createBuilder(viteBuilder) as any;\n"],"mappings":";;AASA,eAAe,YACb,SACA,SACwB;CACxB,MAAM,EAAE,kBAAkB,MAAM,SAAS,0BAAwB,EAAE;AACnE,KAAI,CAAC,QAAQ,OACX,OAAM,IAAI,MAAM,yCAAyC;CAE3D,MAAM,gBAAgB,MAAM,QAAQ,mBAAmB,QAAQ,OAAO;CACtE,MAAM,cAAc,QAAQ,OAAO;CACnC,MAAM,gBAAgB,QAAQ,OAAO,iBAAiB;CAEtD,MAAM,eAAA,GAAA,0BAAA,wBADuB,KAAK,iBAGhC,aACA,QACD;CAED,MAAM,qBAAqB,MAAM,QAAQ,wBAAwB,YAAY;CAC7E,MAAM,kBAAkB,MAAM,QAAQ,iBAAiB,YAAY;CACnE,MAAM,eAAe,MAAM,QAAQ,gBACjC,iBACA,mBACD;CAED,MAAM,cAA4B;EAChC,YAAY,QAAQ;EACpB,MAAM,cAAc;EACpB,MAAA,QAAA,IAAA,YACE,aAAa,QACb;EACF,OAAO;GACL,QAAQ,QAAQ;GAChB,WAAW,CAAC,CAAC,aAAa;GAC3B;EACF;AAED,KAAI;AAEF,SADgB,MAAM,cAAc,aAAa,MAAM,EACzC,UAAU;AAExB,SAAO,EACL,SAAS,MACV;UACM,GAAG;AACV,UAAQ,MAAM,EAAE;AAChB,SAAO,EACL,SAAS,OACV;;;AAIL,IAAA,2BAAA,GAAA,0BAAA,eAA6B,YAAY"}
1
+ {"version":3,"file":"vite-build.impl.js","names":[],"sources":["../../../../../../../../vite-plugin-angular-tools/src/builders/vite/vite-build.impl.ts"],"sourcesContent":["import {\n BuilderContext,\n BuilderOutput,\n createBuilder,\n targetFromTargetString,\n} from '@angular-devkit/architect';\nimport type { InlineConfig } from 'vite';\nimport { ViteBuildSchema } from './schema';\n\nasync function viteBuilder(\n options: ViteBuildSchema,\n context: BuilderContext,\n): Promise<BuilderOutput> {\n const { createBuilder } = await Function('return import(\"vite\")')();\n if (!context.target) {\n throw new Error('Builder must be executed with a target');\n }\n const projectConfig = await context.getProjectMetadata(context.target);\n const projectName = context.target.project;\n const configuration = context.target.configuration || 'production';\n const buildTargetSpecifier = `::${configuration}`;\n const buildTarget = targetFromTargetString(\n buildTargetSpecifier,\n projectName,\n 'build',\n );\n\n const browserBuilderName = await context.getBuilderNameForTarget(buildTarget);\n const rawBuildOptions = await context.getTargetOptions(buildTarget);\n const buildOptions = await context.validateOptions(\n rawBuildOptions,\n browserBuilderName,\n );\n\n const buildConfig: InlineConfig = {\n configFile: options.configFile,\n root: projectConfig.root as string,\n mode: (process.env.NODE_ENV ??\n buildOptions.mode ??\n configuration) as string,\n build: {\n outDir: options.outputPath,\n sourcemap: !!buildOptions.sourcemap,\n },\n };\n\n try {\n const builder = await createBuilder(buildConfig, false);\n await builder.buildApp();\n\n return {\n success: true,\n };\n } catch (e) {\n console.error(e);\n return {\n success: false,\n };\n }\n}\n\nexport default createBuilder(viteBuilder) as any;\n"],"mappings":";;AASA,eAAe,YACb,SACA,SACwB;CACxB,MAAM,EAAE,kBAAkB,MAAM,SAAS,0BAAwB,EAAE;AACnE,KAAI,CAAC,QAAQ,OACX,OAAM,IAAI,MAAM,yCAAyC;CAE3D,MAAM,gBAAgB,MAAM,QAAQ,mBAAmB,QAAQ,OAAO;CACtE,MAAM,cAAc,QAAQ,OAAO;CACnC,MAAM,gBAAgB,QAAQ,OAAO,iBAAiB;CAEtD,MAAM,eAAA,GAAA,0BAAA,wBADuB,KAAK,iBAGhC,aACA,QACD;CAED,MAAM,qBAAqB,MAAM,QAAQ,wBAAwB,YAAY;CAC7E,MAAM,kBAAkB,MAAM,QAAQ,iBAAiB,YAAY;CACnE,MAAM,eAAe,MAAM,QAAQ,gBACjC,iBACA,mBACD;CAED,MAAM,cAA4B;EAChC,YAAY,QAAQ;EACpB,MAAM,cAAc;EACpB,MAAA,QAAA,IAAA,YACE,aAAa,QACb;EACF,OAAO;GACL,QAAQ,QAAQ;GAChB,WAAW,CAAC,CAAC,aAAa;GAC3B;EACF;AAED,KAAI;AAEF,SADgB,MAAM,cAAc,aAAa,MAAM,EACzC,UAAU;AAExB,SAAO,EACL,SAAS,MACV;UACM,GAAG;AACV,UAAQ,MAAM,EAAE;AAChB,SAAO,EACL,SAAS,OACV;;;AAIL,IAAA,2BAAA,GAAA,0BAAA,eAA6B,YAAY"}
@@ -1 +1 @@
1
- {"version":3,"file":"dev-server.impl.js","names":[],"sources":["../../../../../../../../../packages/vite-plugin-angular-tools/src/builders/vite-dev-server/dev-server.impl.ts"],"sourcesContent":["import {\n BuilderContext,\n BuilderOutput,\n createBuilder,\n targetFromTargetString,\n} from '@angular-devkit/architect';\nimport type { InlineConfig } from 'vite';\nimport { ViteDevServerSchema } from './schema';\n\nasync function viteDevServerBuilder(\n options: ViteDevServerSchema,\n context: BuilderContext,\n): Promise<BuilderOutput> {\n const { createServer } = await Function('return import(\"vite\")')();\n if (!context.target) {\n throw new Error('Builder must be executed with a target');\n }\n const projectConfig = await context.getProjectMetadata(context.target);\n const projectName = context.target.project;\n const buildTargetSpecifier = options.buildTarget ?? `::development`;\n const buildTarget = targetFromTargetString(\n buildTargetSpecifier,\n projectName,\n 'build',\n );\n\n const browserBuilderName = await context.getBuilderNameForTarget(buildTarget);\n const rawBuildOptions = await context.getTargetOptions(buildTarget);\n const buildOptions = await context.validateOptions(\n rawBuildOptions,\n browserBuilderName,\n );\n\n const serverConfig: InlineConfig = {\n configFile: buildOptions.configFile as string,\n root: projectConfig.root as string,\n mode: (process.env.NODE_ENV ??\n buildOptions.mode ??\n 'development') as string,\n build: {\n sourcemap: !!buildOptions.sourcemap,\n },\n server: {\n hmr: options?.hmr,\n port: options?.port,\n },\n };\n\n try {\n const server = await createServer(serverConfig);\n await server.listen();\n server.printUrls();\n\n const resolvedUrls = [\n ...server.resolvedUrls.local,\n ...server.resolvedUrls.network,\n ];\n\n const processOnExit = async () => {\n await server.close();\n };\n\n // Use process.once to avoid listener accumulation when Nx invokes\n // multiple builders in the same process during a large build graph.\n await new Promise<void>((resolve) => {\n const shutdown = () => {\n processOnExit().then(\n () => resolve(),\n () => resolve(),\n );\n };\n process.once('SIGINT', shutdown);\n process.once('SIGTERM', shutdown);\n process.once('exit', shutdown);\n });\n\n return {\n success: true,\n baseUrl: resolvedUrls[0] ?? '',\n };\n } catch (e) {\n console.error(e);\n return {\n success: false,\n baseUrl: '',\n };\n }\n}\n\nexport default createBuilder(viteDevServerBuilder) as any;\n"],"mappings":";;AASA,eAAe,qBACb,SACA,SACwB;CACxB,MAAM,EAAE,iBAAiB,MAAM,SAAS,0BAAwB,EAAE;AAClE,KAAI,CAAC,QAAQ,OACX,OAAM,IAAI,MAAM,yCAAyC;CAE3D,MAAM,gBAAgB,MAAM,QAAQ,mBAAmB,QAAQ,OAAO;CACtE,MAAM,cAAc,QAAQ,OAAO;CAEnC,MAAM,eAAA,GAAA,0BAAA,wBADuB,QAAQ,eAAe,iBAGlD,aACA,QACD;CAED,MAAM,qBAAqB,MAAM,QAAQ,wBAAwB,YAAY;CAC7E,MAAM,kBAAkB,MAAM,QAAQ,iBAAiB,YAAY;CACnE,MAAM,eAAe,MAAM,QAAQ,gBACjC,iBACA,mBACD;CAED,MAAM,eAA6B;EACjC,YAAY,aAAa;EACzB,MAAM,cAAc;EACpB,MAAA,QAAA,IAAA,YACE,aAAa,QACb;EACF,OAAO,EACL,WAAW,CAAC,CAAC,aAAa,WAC3B;EACD,QAAQ;GACN,KAAK,SAAS;GACd,MAAM,SAAS;GAChB;EACF;AAED,KAAI;EACF,MAAM,SAAS,MAAM,aAAa,aAAa;AAC/C,QAAM,OAAO,QAAQ;AACrB,SAAO,WAAW;EAElB,MAAM,eAAe,CACnB,GAAG,OAAO,aAAa,OACvB,GAAG,OAAO,aAAa,QACxB;EAED,MAAM,gBAAgB,YAAY;AAChC,SAAM,OAAO,OAAO;;AAKtB,QAAM,IAAI,SAAe,YAAY;GACnC,MAAM,iBAAiB;AACrB,mBAAe,CAAC,WACR,SAAS,QACT,SAAS,CAChB;;AAEH,WAAQ,KAAK,UAAU,SAAS;AAChC,WAAQ,KAAK,WAAW,SAAS;AACjC,WAAQ,KAAK,QAAQ,SAAS;IAC9B;AAEF,SAAO;GACL,SAAS;GACT,SAAS,aAAa,MAAM;GAC7B;UACM,GAAG;AACV,UAAQ,MAAM,EAAE;AAChB,SAAO;GACL,SAAS;GACT,SAAS;GACV;;;AAIL,IAAA,2BAAA,GAAA,0BAAA,eAA6B,qBAAqB"}
1
+ {"version":3,"file":"dev-server.impl.js","names":[],"sources":["../../../../../../../../vite-plugin-angular-tools/src/builders/vite-dev-server/dev-server.impl.ts"],"sourcesContent":["import {\n BuilderContext,\n BuilderOutput,\n createBuilder,\n targetFromTargetString,\n} from '@angular-devkit/architect';\nimport type { InlineConfig } from 'vite';\nimport { ViteDevServerSchema } from './schema';\n\nasync function viteDevServerBuilder(\n options: ViteDevServerSchema,\n context: BuilderContext,\n): Promise<BuilderOutput> {\n const { createServer } = await Function('return import(\"vite\")')();\n if (!context.target) {\n throw new Error('Builder must be executed with a target');\n }\n const projectConfig = await context.getProjectMetadata(context.target);\n const projectName = context.target.project;\n const buildTargetSpecifier = options.buildTarget ?? `::development`;\n const buildTarget = targetFromTargetString(\n buildTargetSpecifier,\n projectName,\n 'build',\n );\n\n const browserBuilderName = await context.getBuilderNameForTarget(buildTarget);\n const rawBuildOptions = await context.getTargetOptions(buildTarget);\n const buildOptions = await context.validateOptions(\n rawBuildOptions,\n browserBuilderName,\n );\n\n const serverConfig: InlineConfig = {\n configFile: buildOptions.configFile as string,\n root: projectConfig.root as string,\n mode: (process.env.NODE_ENV ??\n buildOptions.mode ??\n 'development') as string,\n build: {\n sourcemap: !!buildOptions.sourcemap,\n },\n server: {\n hmr: options?.hmr,\n port: options?.port,\n },\n };\n\n try {\n const server = await createServer(serverConfig);\n await server.listen();\n server.printUrls();\n\n const resolvedUrls = [\n ...server.resolvedUrls.local,\n ...server.resolvedUrls.network,\n ];\n\n const processOnExit = async () => {\n await server.close();\n };\n\n // Use process.once to avoid listener accumulation when Nx invokes\n // multiple builders in the same process during a large build graph.\n await new Promise<void>((resolve) => {\n const shutdown = () => {\n processOnExit().then(\n () => resolve(),\n () => resolve(),\n );\n };\n process.once('SIGINT', shutdown);\n process.once('SIGTERM', shutdown);\n process.once('exit', shutdown);\n });\n\n return {\n success: true,\n baseUrl: resolvedUrls[0] ?? '',\n };\n } catch (e) {\n console.error(e);\n return {\n success: false,\n baseUrl: '',\n };\n }\n}\n\nexport default createBuilder(viteDevServerBuilder) as any;\n"],"mappings":";;AASA,eAAe,qBACb,SACA,SACwB;CACxB,MAAM,EAAE,iBAAiB,MAAM,SAAS,0BAAwB,EAAE;AAClE,KAAI,CAAC,QAAQ,OACX,OAAM,IAAI,MAAM,yCAAyC;CAE3D,MAAM,gBAAgB,MAAM,QAAQ,mBAAmB,QAAQ,OAAO;CACtE,MAAM,cAAc,QAAQ,OAAO;CAEnC,MAAM,eAAA,GAAA,0BAAA,wBADuB,QAAQ,eAAe,iBAGlD,aACA,QACD;CAED,MAAM,qBAAqB,MAAM,QAAQ,wBAAwB,YAAY;CAC7E,MAAM,kBAAkB,MAAM,QAAQ,iBAAiB,YAAY;CACnE,MAAM,eAAe,MAAM,QAAQ,gBACjC,iBACA,mBACD;CAED,MAAM,eAA6B;EACjC,YAAY,aAAa;EACzB,MAAM,cAAc;EACpB,MAAA,QAAA,IAAA,YACE,aAAa,QACb;EACF,OAAO,EACL,WAAW,CAAC,CAAC,aAAa,WAC3B;EACD,QAAQ;GACN,KAAK,SAAS;GACd,MAAM,SAAS;GAChB;EACF;AAED,KAAI;EACF,MAAM,SAAS,MAAM,aAAa,aAAa;AAC/C,QAAM,OAAO,QAAQ;AACrB,SAAO,WAAW;EAElB,MAAM,eAAe,CACnB,GAAG,OAAO,aAAa,OACvB,GAAG,OAAO,aAAa,QACxB;EAED,MAAM,gBAAgB,YAAY;AAChC,SAAM,OAAO,OAAO;;AAKtB,QAAM,IAAI,SAAe,YAAY;GACnC,MAAM,iBAAiB;AACrB,mBAAe,CAAC,WACR,SAAS,QACT,SAAS,CAChB;;AAEH,WAAQ,KAAK,UAAU,SAAS;AAChC,WAAQ,KAAK,WAAW,SAAS;AACjC,WAAQ,KAAK,QAAQ,SAAS;IAC9B;AAEF,SAAO;GACL,SAAS;GACT,SAAS,aAAa,MAAM;GAC7B;UACM,GAAG;AACV,UAAQ,MAAM,EAAE;AAChB,SAAO;GACL,SAAS;GACT,SAAS;GACV;;;AAIL,IAAA,2BAAA,GAAA,0BAAA,eAA6B,qBAAqB"}
@@ -1 +1 @@
1
- {"version":3,"file":"devkit.js","names":[],"sources":["../../../../../../packages/vite-plugin-angular/src/lib/utils/devkit.ts"],"sourcesContent":["import { VERSION } from '@angular/compiler-cli';\nimport { createRequire } from 'node:module';\nimport type { CompilerPluginOptions } from './compiler-plugin-options.js';\nimport * as sfc from './source-file-cache.js';\n\nconst require = createRequire(import.meta.url);\n\nconst angularMajor: number = Number(VERSION.major);\nconst angularMinor: number = Number(VERSION.minor);\nconst angularPatch: number = Number(VERSION.patch);\nconst padVersion = (version: number) => String(version).padStart(2, '0');\nconst angularFullVersion: number = Number(\n `${angularMajor}${padVersion(angularMinor)}${padVersion(angularPatch)}`,\n);\nlet sourceFileCache: any;\nlet cjt: (...args: any[]) => any;\nlet jt: any;\nlet createAngularCompilation: (...args: any[]) => any;\n\nif (angularMajor < 17) {\n throw new Error('AnalogJS is not compatible with Angular v16 and lower');\n} else if (angularMajor >= 17 && angularMajor < 18) {\n const cp = require('@angular-devkit/build-angular/src/tools/esbuild/angular/compiler-plugin.js');\n const {\n createJitResourceTransformer,\n } = require('@angular-devkit/build-angular/src/tools/esbuild/angular/jit-resource-transformer.js');\n const {\n JavaScriptTransformer,\n } = require('@angular-devkit/build-angular/src/tools/esbuild/javascript-transformer.js');\n\n /**\n * Workaround for compatibility with Angular 17.0+\n */\n if (typeof cp['SourceFileCache'] !== 'undefined') {\n sourceFileCache = cp.SourceFileCache;\n } else {\n sourceFileCache = sfc.SourceFileCache;\n }\n\n cjt = createJitResourceTransformer;\n jt = JavaScriptTransformer;\n} else {\n const {\n createJitResourceTransformer,\n JavaScriptTransformer,\n SourceFileCache,\n createAngularCompilation: createAngularCompilationFn,\n } = require('@angular/build/private');\n\n sourceFileCache = SourceFileCache;\n cjt = createJitResourceTransformer;\n jt = JavaScriptTransformer;\n createAngularCompilation = createAngularCompilationFn;\n}\n\nexport {\n cjt as createJitResourceTransformer,\n jt as JavaScriptTransformer,\n sourceFileCache as SourceFileCache,\n CompilerPluginOptions,\n angularMajor,\n angularMinor,\n angularPatch,\n createAngularCompilation,\n angularFullVersion,\n};\n"],"mappings":";;;;AAKA,IAAM,UAAU,cAAc,OAAO,KAAK,IAAI;AAE9C,IAAM,eAAuB,OAAO,QAAQ,MAAM;AAClD,IAAM,eAAuB,OAAO,QAAQ,MAAM;AAClD,IAAM,eAAuB,OAAO,QAAQ,MAAM;AAClD,IAAM,cAAc,YAAoB,OAAO,QAAQ,CAAC,SAAS,GAAG,IAAI;AACxE,IAAM,qBAA6B,OACjC,GAAG,eAAe,WAAW,aAAa,GAAG,WAAW,aAAa,GACtE;AACD,IAAI;AACJ,IAAI;AACJ,IAAI;AACJ,IAAI;AAEJ,IAAI,eAAe,GACjB,OAAM,IAAI,MAAM,wDAAwD;SAC/D,gBAAgB,MAAM,eAAe,IAAI;CAClD,MAAM,KAAK,QAAQ,6EAA6E;CAChG,MAAM,EACJ,iCACE,QAAQ,sFAAsF;CAClG,MAAM,EACJ,0BACE,QAAQ,4EAA4E;;;;AAKxF,KAAI,OAAO,GAAG,uBAAuB,YACnC,mBAAkB,GAAG;KAErB,mBAAkB;AAGpB,OAAM;AACN,MAAK;OACA;CACL,MAAM,EACJ,8BACA,uBACA,iBACA,0BAA0B,+BACxB,QAAQ,yBAAyB;AAErC,mBAAkB;AAClB,OAAM;AACN,MAAK;AACL,4BAA2B"}
1
+ {"version":3,"file":"devkit.js","names":[],"sources":["../../../../src/lib/utils/devkit.ts"],"sourcesContent":["import { VERSION } from '@angular/compiler-cli';\nimport { createRequire } from 'node:module';\nimport type { CompilerPluginOptions } from './compiler-plugin-options.js';\nimport * as sfc from './source-file-cache.js';\n\nconst require = createRequire(import.meta.url);\n\nconst angularMajor: number = Number(VERSION.major);\nconst angularMinor: number = Number(VERSION.minor);\nconst angularPatch: number = Number(VERSION.patch);\nconst padVersion = (version: number) => String(version).padStart(2, '0');\nconst angularFullVersion: number = Number(\n `${angularMajor}${padVersion(angularMinor)}${padVersion(angularPatch)}`,\n);\nlet sourceFileCache: any;\nlet cjt: (...args: any[]) => any;\nlet jt: any;\nlet createAngularCompilation: (...args: any[]) => any;\n\nif (angularMajor < 17) {\n throw new Error('AnalogJS is not compatible with Angular v16 and lower');\n} else if (angularMajor >= 17 && angularMajor < 18) {\n const cp = require('@angular-devkit/build-angular/src/tools/esbuild/angular/compiler-plugin.js');\n const {\n createJitResourceTransformer,\n } = require('@angular-devkit/build-angular/src/tools/esbuild/angular/jit-resource-transformer.js');\n const {\n JavaScriptTransformer,\n } = require('@angular-devkit/build-angular/src/tools/esbuild/javascript-transformer.js');\n\n /**\n * Workaround for compatibility with Angular 17.0+\n */\n if (typeof cp['SourceFileCache'] !== 'undefined') {\n sourceFileCache = cp.SourceFileCache;\n } else {\n sourceFileCache = sfc.SourceFileCache;\n }\n\n cjt = createJitResourceTransformer;\n jt = JavaScriptTransformer;\n} else {\n const {\n createJitResourceTransformer,\n JavaScriptTransformer,\n SourceFileCache,\n createAngularCompilation: createAngularCompilationFn,\n } = require('@angular/build/private');\n\n sourceFileCache = SourceFileCache;\n cjt = createJitResourceTransformer;\n jt = JavaScriptTransformer;\n createAngularCompilation = createAngularCompilationFn;\n}\n\nexport {\n cjt as createJitResourceTransformer,\n jt as JavaScriptTransformer,\n sourceFileCache as SourceFileCache,\n CompilerPluginOptions,\n angularMajor,\n angularMinor,\n angularPatch,\n createAngularCompilation,\n angularFullVersion,\n};\n"],"mappings":";;;;AAKA,IAAM,UAAU,cAAc,OAAO,KAAK,IAAI;AAE9C,IAAM,eAAuB,OAAO,QAAQ,MAAM;AAClD,IAAM,eAAuB,OAAO,QAAQ,MAAM;AAClD,IAAM,eAAuB,OAAO,QAAQ,MAAM;AAClD,IAAM,cAAc,YAAoB,OAAO,QAAQ,CAAC,SAAS,GAAG,IAAI;AACxE,IAAM,qBAA6B,OACjC,GAAG,eAAe,WAAW,aAAa,GAAG,WAAW,aAAa,GACtE;AACD,IAAI;AACJ,IAAI;AACJ,IAAI;AACJ,IAAI;AAEJ,IAAI,eAAe,GACjB,OAAM,IAAI,MAAM,wDAAwD;SAC/D,gBAAgB,MAAM,eAAe,IAAI;CAClD,MAAM,KAAK,QAAQ,6EAA6E;CAChG,MAAM,EACJ,iCACE,QAAQ,sFAAsF;CAClG,MAAM,EACJ,0BACE,QAAQ,4EAA4E;;;;AAKxF,KAAI,OAAO,GAAG,uBAAuB,YACnC,mBAAkB,GAAG;KAErB,mBAAkB;AAGpB,OAAM;AACN,MAAK;OACA;CACL,MAAM,EACJ,8BACA,uBACA,iBACA,0BAA0B,+BACxB,QAAQ,yBAAyB;AAErC,mBAAkB;AAClB,OAAM;AACN,MAAK;AACL,4BAA2B"}
@@ -1 +1 @@
1
- {"version":3,"file":"rolldown.js","names":[],"sources":["../../../../../../packages/vite-plugin-angular/src/lib/utils/rolldown.ts"],"sourcesContent":["import * as vite from 'vite';\n\nexport function isRolldown(): boolean {\n return !!vite.rolldownVersion;\n}\n\nexport function getJsTransformConfigKey(): 'oxc' | 'esbuild' {\n return isRolldown() ? 'oxc' : 'esbuild';\n}\n"],"mappings":";;AAEA,SAAgB,aAAsB;AACpC,QAAO,CAAC,CAAC,KAAK;;AAGhB,SAAgB,0BAA6C;AAC3D,QAAO,YAAY,GAAG,QAAQ"}
1
+ {"version":3,"file":"rolldown.js","names":[],"sources":["../../../../src/lib/utils/rolldown.ts"],"sourcesContent":["import * as vite from 'vite';\n\nexport function isRolldown(): boolean {\n return !!vite.rolldownVersion;\n}\n\nexport function getJsTransformConfigKey(): 'oxc' | 'esbuild' {\n return isRolldown() ? 'oxc' : 'esbuild';\n}\n"],"mappings":";;AAEA,SAAgB,aAAsB;AACpC,QAAO,CAAC,CAAC,KAAK;;AAGhB,SAAgB,0BAA6C;AAC3D,QAAO,YAAY,GAAG,QAAQ"}
@@ -1 +1 @@
1
- {"version":3,"file":"source-file-cache.js","names":[],"sources":["../../../../../../packages/vite-plugin-angular/src/lib/utils/source-file-cache.ts"],"sourcesContent":["/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport { platform } from 'node:os';\nimport * as path from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport type ts from 'typescript';\n\nconst USING_WINDOWS = platform() === 'win32';\nconst WINDOWS_SEP_REGEXP = new RegExp(`\\\\${path.win32.sep}`, 'g');\n\nexport class SourceFileCache extends Map<string, ts.SourceFile> {\n readonly modifiedFiles: Set<string> = new Set<string>();\n readonly babelFileCache: Map<string, Uint8Array> = new Map<\n string,\n Uint8Array\n >();\n readonly typeScriptFileCache: Map<string, string | Uint8Array> = new Map<\n string,\n string | Uint8Array\n >();\n\n referencedFiles?: readonly string[];\n\n constructor(readonly persistentCachePath?: string) {\n super();\n }\n\n invalidate(files: Iterable<string>): void {\n if (files !== this.modifiedFiles) {\n this.modifiedFiles.clear();\n }\n for (let file of files) {\n this.babelFileCache.delete(file);\n this.typeScriptFileCache.delete(pathToFileURL(file).href);\n\n // Normalize separators to allow matching TypeScript Host paths\n if (USING_WINDOWS) {\n file = file.replace(WINDOWS_SEP_REGEXP, path.posix.sep);\n }\n\n this.delete(file);\n this.modifiedFiles.add(file);\n }\n }\n}\n"],"mappings":";;;;;;;;;;;AAaA,IAAM,gBAAgB,UAAU,KAAK;AACrC,IAAM,qBAAqB,IAAI,OAAO,KAAK,OAAK,MAAM,OAAO,IAAI;AAEjE,IAAa,kBAAb,cAAqC,IAA2B;CAC9D,gCAAsC,IAAI,KAAa;CACvD,iCAAmD,IAAI,KAGpD;CACH,sCAAiE,IAAI,KAGlE;CAEH;CAEA,YAAY,qBAAuC;AACjD,SAAO;AADY,OAAA,sBAAA;;CAIrB,WAAW,OAA+B;AACxC,MAAI,UAAU,KAAK,cACjB,MAAK,cAAc,OAAO;AAE5B,OAAK,IAAI,QAAQ,OAAO;AACtB,QAAK,eAAe,OAAO,KAAK;AAChC,QAAK,oBAAoB,OAAO,cAAc,KAAK,CAAC,KAAK;AAGzD,OAAI,cACF,QAAO,KAAK,QAAQ,oBAAoB,OAAK,MAAM,IAAI;AAGzD,QAAK,OAAO,KAAK;AACjB,QAAK,cAAc,IAAI,KAAK"}
1
+ {"version":3,"file":"source-file-cache.js","names":[],"sources":["../../../../src/lib/utils/source-file-cache.ts"],"sourcesContent":["/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport { platform } from 'node:os';\nimport * as path from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport type ts from 'typescript';\n\nconst USING_WINDOWS = platform() === 'win32';\nconst WINDOWS_SEP_REGEXP = new RegExp(`\\\\${path.win32.sep}`, 'g');\n\nexport class SourceFileCache extends Map<string, ts.SourceFile> {\n readonly modifiedFiles: Set<string> = new Set<string>();\n readonly babelFileCache: Map<string, Uint8Array> = new Map<\n string,\n Uint8Array\n >();\n readonly typeScriptFileCache: Map<string, string | Uint8Array> = new Map<\n string,\n string | Uint8Array\n >();\n\n referencedFiles?: readonly string[];\n\n constructor(readonly persistentCachePath?: string) {\n super();\n }\n\n invalidate(files: Iterable<string>): void {\n if (files !== this.modifiedFiles) {\n this.modifiedFiles.clear();\n }\n for (let file of files) {\n this.babelFileCache.delete(file);\n this.typeScriptFileCache.delete(pathToFileURL(file).href);\n\n // Normalize separators to allow matching TypeScript Host paths\n if (USING_WINDOWS) {\n file = file.replace(WINDOWS_SEP_REGEXP, path.posix.sep);\n }\n\n this.delete(file);\n this.modifiedFiles.add(file);\n }\n }\n}\n"],"mappings":";;;;;;;;;;;AAaA,IAAM,gBAAgB,UAAU,KAAK;AACrC,IAAM,qBAAqB,IAAI,OAAO,KAAK,OAAK,MAAM,OAAO,IAAI;AAEjE,IAAa,kBAAb,cAAqC,IAA2B;CAC9D,gCAAsC,IAAI,KAAa;CACvD,iCAAmD,IAAI,KAGpD;CACH,sCAAiE,IAAI,KAGlE;CAEH;CAEA,YAAY,qBAAuC;AACjD,SAAO;AADY,OAAA,sBAAA;;CAIrB,WAAW,OAA+B;AACxC,MAAI,UAAU,KAAK,cACjB,MAAK,cAAc,OAAO;AAE5B,OAAK,IAAI,QAAQ,OAAO;AACtB,QAAK,eAAe,OAAO,KAAK;AAChC,QAAK,oBAAoB,OAAO,cAAc,KAAK,CAAC,KAAK;AAGzD,OAAI,cACF,QAAO,KAAK,QAAQ,oBAAoB,OAAK,MAAM,IAAI;AAGzD,QAAK,OAAO,KAAK;AACjB,QAAK,cAAc,IAAI,KAAK"}