@analogjs/vite-plugin-angular 3.0.0-alpha.42 → 3.0.0-alpha.44

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/package.json +1 -1
  2. package/src/lib/angular-jit-plugin.js +1 -1
  3. package/src/lib/angular-vite-plugin.d.ts +3 -77
  4. package/src/lib/angular-vite-plugin.js +77 -1012
  5. package/src/lib/angular-vite-plugin.js.map +1 -1
  6. package/src/lib/compilation-api/compilation-api-plugin.d.ts +29 -0
  7. package/src/lib/compilation-api/compilation-api-plugin.js +468 -0
  8. package/src/lib/compilation-api/compilation-api-plugin.js.map +1 -0
  9. package/src/lib/compilation-api/index.d.ts +1 -0
  10. package/src/lib/compilation-api/index.js +1 -0
  11. package/src/lib/compiler/compile.js +2 -2
  12. package/src/lib/compiler/defer.js +1 -1
  13. package/src/lib/compiler/js-emitter.js +1 -1
  14. package/src/lib/encapsulation-plugin.d.ts +13 -0
  15. package/src/lib/encapsulation-plugin.js +48 -0
  16. package/src/lib/encapsulation-plugin.js.map +1 -0
  17. package/src/lib/fast-compile-plugin.js +2 -28
  18. package/src/lib/fast-compile-plugin.js.map +1 -1
  19. package/src/lib/host.js +1 -1
  20. package/src/lib/stylesheet-registry.js +1 -1
  21. package/src/lib/tailwind-plugin.d.ts +34 -0
  22. package/src/lib/tailwind-plugin.js +116 -0
  23. package/src/lib/tailwind-plugin.js.map +1 -0
  24. package/src/lib/template-class-binding-guard-plugin.d.ts +30 -0
  25. package/src/lib/template-class-binding-guard-plugin.js +237 -0
  26. package/src/lib/template-class-binding-guard-plugin.js.map +1 -0
  27. package/src/lib/utils/compilation-shared.d.ts +58 -0
  28. package/src/lib/utils/compilation-shared.js +133 -0
  29. package/src/lib/utils/compilation-shared.js.map +1 -0
  30. package/src/lib/utils/tsconfig-resolver.d.ts +28 -0
  31. package/src/lib/utils/tsconfig-resolver.js +191 -0
  32. package/src/lib/utils/tsconfig-resolver.js.map +1 -0
  33. package/src/lib/utils/virtual-resources.js +4 -31
  34. package/src/lib/utils/virtual-resources.js.map +1 -1
  35. package/src/lib/virtual-modules-plugin.d.ts +5 -0
  36. package/src/lib/virtual-modules-plugin.js +50 -0
  37. package/src/lib/virtual-modules-plugin.js.map +1 -0
@@ -0,0 +1,191 @@
1
+ import { debugEmit, debugEmitV } from "./debug.js";
2
+ import { existsSync, statSync } from "node:fs";
3
+ import { dirname, isAbsolute, join, resolve } from "node:path";
4
+ import * as compilerCli from "@angular/compiler-cli";
5
+ import { createRequire } from "node:module";
6
+ import { normalizePath } from "vite";
7
+ import { globSync } from "tinyglobby";
8
+ //#region packages/vite-plugin-angular/src/lib/utils/tsconfig-resolver.ts
9
+ /**
10
+ * Shared tsconfig resolution logic used by both the ngtsc and compilation-api
11
+ * compilation plugins. Encapsulates the caching, include-glob discovery,
12
+ * tsconfig-graph expansion, and path-root resolution that were previously
13
+ * duplicated across angular-vite-plugin.ts and compilation-api-plugin.ts.
14
+ */
15
+ var ts = createRequire(import.meta.url)("typescript");
16
+ var TsconfigResolver = class {
17
+ includeCache = [];
18
+ tsconfigOptionsCache = /* @__PURE__ */ new Map();
19
+ tsconfigGraphRootCache = /* @__PURE__ */ new Map();
20
+ constructor(options) {
21
+ this.options = options;
22
+ }
23
+ invalidateIncludeCache() {
24
+ this.includeCache = [];
25
+ }
26
+ invalidateTsconfigCaches() {
27
+ this.tsconfigOptionsCache.clear();
28
+ this.tsconfigGraphRootCache.clear();
29
+ }
30
+ invalidateAll() {
31
+ this.invalidateIncludeCache();
32
+ this.invalidateTsconfigCaches();
33
+ }
34
+ ensureIncludeCache() {
35
+ if (this.options.include.length > 0 && this.includeCache.length === 0) {
36
+ this.includeCache = this.findIncludes();
37
+ debugEmit("include cache populated", { fileCount: this.includeCache.length });
38
+ }
39
+ return this.includeCache;
40
+ }
41
+ readAngularTsconfigConfiguration(resolvedTsConfigPath, config) {
42
+ const isProd = config.mode === "production";
43
+ return compilerCli.readConfiguration(resolvedTsConfigPath, {
44
+ suppressOutputPathCheck: true,
45
+ outDir: void 0,
46
+ sourceMap: false,
47
+ inlineSourceMap: !isProd,
48
+ inlineSources: !isProd,
49
+ declaration: false,
50
+ declarationMap: false,
51
+ allowEmptyCodegenFiles: false,
52
+ annotationsAs: "decorators",
53
+ enableResourceInlining: false,
54
+ noEmitOnError: false,
55
+ mapRoot: void 0,
56
+ sourceRoot: void 0,
57
+ supportTestBed: false,
58
+ supportJitMode: false
59
+ });
60
+ }
61
+ getCachedTsconfigOptions(resolvedTsConfigPath, config) {
62
+ const tsconfigKey = this.getTsconfigCacheKey(resolvedTsConfigPath, config);
63
+ let cached = this.tsconfigOptionsCache.get(tsconfigKey);
64
+ if (!cached) {
65
+ const read = this.readAngularTsconfigConfiguration(resolvedTsConfigPath, config);
66
+ cached = {
67
+ options: read.options,
68
+ rootNames: read.rootNames
69
+ };
70
+ this.tsconfigOptionsCache.set(tsconfigKey, cached);
71
+ debugEmit("tsconfig root names loaded", {
72
+ resolvedTsConfigPath,
73
+ rootNameCount: read.rootNames.length
74
+ });
75
+ debugEmitV("tsconfig root names", {
76
+ resolvedTsConfigPath,
77
+ rootNames: read.rootNames.map((file) => normalizePath(file))
78
+ });
79
+ }
80
+ return cached;
81
+ }
82
+ collectExpandedTsconfigRoots(resolvedTsConfigPath, config, visited = /* @__PURE__ */ new Set()) {
83
+ const normalizedTsConfigPath = normalizePath(resolvedTsConfigPath);
84
+ if (visited.has(normalizedTsConfigPath)) return [];
85
+ const tsconfigKey = `${this.getTsconfigCacheKey(normalizedTsConfigPath, config)}|graph`;
86
+ const cached = this.tsconfigGraphRootCache.get(tsconfigKey);
87
+ if (cached) return cached;
88
+ visited.add(normalizedTsConfigPath);
89
+ const read = this.readAngularTsconfigConfiguration(normalizedTsConfigPath, config);
90
+ const rawTsconfig = ts.readConfigFile(normalizedTsConfigPath, ts.sys.readFile).config ?? {};
91
+ const expandedRoots = new Set(read.rootNames.map((file) => normalizePath(file)));
92
+ const pathRoots = collectTsconfigPathRoots(normalizedTsConfigPath, read.options, rawTsconfig);
93
+ for (const pathRoot of pathRoots) expandedRoots.add(pathRoot);
94
+ const referenceConfigs = (rawTsconfig.references ?? []).flatMap((reference) => typeof reference.path === "string" ? [resolveReferenceTsconfigPath(reference.path, normalizedTsConfigPath)] : []).filter((reference) => !!reference);
95
+ for (const referenceConfig of referenceConfigs) for (const referenceRoot of this.collectExpandedTsconfigRoots(referenceConfig, config, visited)) expandedRoots.add(referenceRoot);
96
+ const expandedRootList = [...expandedRoots];
97
+ this.tsconfigGraphRootCache.set(tsconfigKey, expandedRootList);
98
+ debugEmit("expanded tsconfig graph roots", {
99
+ resolvedTsConfigPath: normalizedTsConfigPath,
100
+ directRootNameCount: read.rootNames.length,
101
+ pathRootCount: pathRoots.length,
102
+ referenceConfigCount: referenceConfigs.length,
103
+ expandedRootCount: expandedRootList.length
104
+ });
105
+ debugEmitV("expanded tsconfig graph root files", {
106
+ resolvedTsConfigPath: normalizedTsConfigPath,
107
+ pathRoots,
108
+ referenceConfigs,
109
+ rootNames: expandedRootList
110
+ });
111
+ return expandedRootList;
112
+ }
113
+ getTsconfigCacheKey(resolvedTsConfigPath, config) {
114
+ return [
115
+ resolvedTsConfigPath,
116
+ config.mode === "production" ? "prod" : "dev",
117
+ this.options.isTest ? "test" : "app",
118
+ config.build?.lib ? "lib" : "nolib",
119
+ this.options.liveReload ? "live-reload" : "no-live-reload",
120
+ this.options.hasTailwindCss ? "tw" : "notw"
121
+ ].join("|");
122
+ }
123
+ findIncludes() {
124
+ const globs = this.options.include.map((glob) => normalizeIncludeGlob(this.options.workspaceRoot, glob));
125
+ const files = globSync(globs, {
126
+ dot: true,
127
+ absolute: true
128
+ });
129
+ debugEmit("include discovery", {
130
+ patternCount: globs.length,
131
+ fileCount: files.length
132
+ });
133
+ debugEmitV("include discovery files", {
134
+ globs,
135
+ files: files.map((file) => normalizePath(file))
136
+ });
137
+ return files;
138
+ }
139
+ };
140
+ function normalizeIncludeGlob(workspaceRoot, glob) {
141
+ const normalizedWorkspaceRoot = normalizePath(resolve(workspaceRoot));
142
+ const normalizedGlob = normalizePath(glob);
143
+ if (normalizedGlob === normalizedWorkspaceRoot || normalizedGlob.startsWith(`${normalizedWorkspaceRoot}/`)) return normalizedGlob;
144
+ if (normalizedGlob.startsWith("/")) return `${normalizedWorkspaceRoot}${normalizedGlob}`;
145
+ return normalizePath(resolve(normalizedWorkspaceRoot, normalizedGlob));
146
+ }
147
+ function resolveReferenceTsconfigPath(referencePath, ownerTsconfigPath) {
148
+ const ownerDir = dirname(ownerTsconfigPath);
149
+ const resolvedReference = normalizePath(isAbsolute(referencePath) ? referencePath : resolve(ownerDir, referencePath));
150
+ if (existsSync(resolvedReference)) {
151
+ try {
152
+ if (statSync(resolvedReference).isDirectory()) {
153
+ const nestedTsconfig = join(resolvedReference, "tsconfig.json");
154
+ return existsSync(nestedTsconfig) ? normalizePath(nestedTsconfig) : void 0;
155
+ }
156
+ } catch {
157
+ return;
158
+ }
159
+ return resolvedReference;
160
+ }
161
+ if (!resolvedReference.endsWith(".json")) {
162
+ const asJson = `${resolvedReference}.json`;
163
+ if (existsSync(asJson)) return normalizePath(asJson);
164
+ const nestedTsconfig = join(resolvedReference, "tsconfig.json");
165
+ if (existsSync(nestedTsconfig)) return normalizePath(nestedTsconfig);
166
+ }
167
+ }
168
+ function collectTsconfigPathRoots(resolvedTsConfigPath, options, rawTsconfig) {
169
+ const tsPaths = rawTsconfig.compilerOptions?.paths ?? options.paths;
170
+ if (!tsPaths) return [];
171
+ const tsconfigDir = dirname(resolvedTsConfigPath);
172
+ const configuredBaseUrl = typeof options.baseUrl === "string" ? options.baseUrl : typeof rawTsconfig.compilerOptions?.baseUrl === "string" ? rawTsconfig.compilerOptions.baseUrl : void 0;
173
+ const resolvedBaseUrl = configuredBaseUrl ? isAbsolute(configuredBaseUrl) ? configuredBaseUrl : resolve(tsconfigDir, configuredBaseUrl) : tsconfigDir;
174
+ const discoveredRoots = /* @__PURE__ */ new Set();
175
+ for (const targets of Object.values(tsPaths)) for (const target of targets) {
176
+ const resolvedTarget = normalizePath(isAbsolute(target) ? target : resolve(resolvedBaseUrl, target));
177
+ if (target.includes("*")) {
178
+ for (const match of globSync(resolvedTarget, {
179
+ dot: true,
180
+ absolute: true
181
+ })) discoveredRoots.add(normalizePath(match));
182
+ continue;
183
+ }
184
+ if (existsSync(resolvedTarget)) discoveredRoots.add(resolvedTarget);
185
+ }
186
+ return [...discoveredRoots];
187
+ }
188
+ //#endregion
189
+ export { TsconfigResolver };
190
+
191
+ //# sourceMappingURL=tsconfig-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tsconfig-resolver.js","names":[],"sources":["../../../../src/lib/utils/tsconfig-resolver.ts"],"sourcesContent":["/**\n * Shared tsconfig resolution logic used by both the ngtsc and compilation-api\n * compilation plugins. Encapsulates the caching, include-glob discovery,\n * tsconfig-graph expansion, and path-root resolution that were previously\n * duplicated across angular-vite-plugin.ts and compilation-api-plugin.ts.\n */\n\nimport * as compilerCli from '@angular/compiler-cli';\nimport { existsSync, statSync } from 'node:fs';\nimport { dirname, isAbsolute, join, resolve } from 'node:path';\nimport { createRequire } from 'node:module';\nimport { normalizePath, ResolvedConfig } from 'vite';\nimport { globSync } from 'tinyglobby';\nimport { debugEmit, debugEmitV } from './debug.js';\n\nconst require = createRequire(import.meta.url);\nconst ts = require('typescript');\n\nexport interface TsconfigResolverOptions {\n workspaceRoot: string;\n include: string[];\n liveReload: boolean;\n hasTailwindCss: boolean;\n isTest: boolean;\n}\n\nexport class TsconfigResolver {\n private includeCache: string[] = [];\n private tsconfigOptionsCache = new Map<\n string,\n { options: any; rootNames: string[] }\n >();\n private tsconfigGraphRootCache = new Map<string, string[]>();\n\n constructor(private options: TsconfigResolverOptions) {}\n\n invalidateIncludeCache(): void {\n this.includeCache = [];\n }\n\n invalidateTsconfigCaches(): void {\n this.tsconfigOptionsCache.clear();\n this.tsconfigGraphRootCache.clear();\n }\n\n invalidateAll(): void {\n this.invalidateIncludeCache();\n this.invalidateTsconfigCaches();\n }\n\n ensureIncludeCache(): string[] {\n if (this.options.include.length > 0 && this.includeCache.length === 0) {\n this.includeCache = this.findIncludes();\n debugEmit('include cache populated', {\n fileCount: this.includeCache.length,\n });\n }\n return this.includeCache;\n }\n\n readAngularTsconfigConfiguration(\n resolvedTsConfigPath: string,\n config: ResolvedConfig,\n ) {\n const isProd = config.mode === 'production';\n return 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 }\n\n getCachedTsconfigOptions(\n resolvedTsConfigPath: string,\n config: ResolvedConfig,\n ): { options: any; rootNames: string[] } {\n const tsconfigKey = this.getTsconfigCacheKey(resolvedTsConfigPath, config);\n let cached = this.tsconfigOptionsCache.get(tsconfigKey);\n\n if (!cached) {\n const read = this.readAngularTsconfigConfiguration(\n resolvedTsConfigPath,\n config,\n );\n cached = { options: read.options, rootNames: read.rootNames };\n this.tsconfigOptionsCache.set(tsconfigKey, cached);\n debugEmit('tsconfig root names loaded', {\n resolvedTsConfigPath,\n rootNameCount: read.rootNames.length,\n });\n debugEmitV('tsconfig root names', {\n resolvedTsConfigPath,\n rootNames: read.rootNames.map((file: string) => normalizePath(file)),\n });\n }\n\n return cached;\n }\n\n collectExpandedTsconfigRoots(\n resolvedTsConfigPath: string,\n config: ResolvedConfig,\n visited = new Set<string>(),\n ): string[] {\n const normalizedTsConfigPath = normalizePath(resolvedTsConfigPath);\n if (visited.has(normalizedTsConfigPath)) {\n return [];\n }\n\n const tsconfigKey = `${this.getTsconfigCacheKey(normalizedTsConfigPath, config)}|graph`;\n const cached = this.tsconfigGraphRootCache.get(tsconfigKey);\n if (cached) {\n return cached;\n }\n\n visited.add(normalizedTsConfigPath);\n\n const read = this.readAngularTsconfigConfiguration(\n normalizedTsConfigPath,\n config,\n );\n const rawTsconfig = (ts.readConfigFile(\n normalizedTsConfigPath,\n ts.sys.readFile,\n ).config ?? {}) as {\n compilerOptions?: {\n baseUrl?: unknown;\n paths?: Record<string, string[]>;\n };\n references?: Array<{ path?: unknown }>;\n };\n\n const expandedRoots = new Set(\n read.rootNames.map((file: string) => normalizePath(file)),\n );\n const pathRoots = collectTsconfigPathRoots(\n normalizedTsConfigPath,\n read.options,\n rawTsconfig,\n );\n for (const pathRoot of pathRoots) {\n expandedRoots.add(pathRoot);\n }\n\n const referenceConfigs = (rawTsconfig.references ?? [])\n .flatMap((reference) =>\n typeof reference.path === 'string'\n ? [\n resolveReferenceTsconfigPath(\n reference.path,\n normalizedTsConfigPath,\n ),\n ]\n : [],\n )\n .filter((reference): reference is string => !!reference);\n\n for (const referenceConfig of referenceConfigs) {\n for (const referenceRoot of this.collectExpandedTsconfigRoots(\n referenceConfig,\n config,\n visited,\n )) {\n expandedRoots.add(referenceRoot);\n }\n }\n\n const expandedRootList = [...expandedRoots];\n this.tsconfigGraphRootCache.set(tsconfigKey, expandedRootList);\n debugEmit('expanded tsconfig graph roots', {\n resolvedTsConfigPath: normalizedTsConfigPath,\n directRootNameCount: read.rootNames.length,\n pathRootCount: pathRoots.length,\n referenceConfigCount: referenceConfigs.length,\n expandedRootCount: expandedRootList.length,\n });\n debugEmitV('expanded tsconfig graph root files', {\n resolvedTsConfigPath: normalizedTsConfigPath,\n pathRoots,\n referenceConfigs,\n rootNames: expandedRootList,\n });\n\n return expandedRootList;\n }\n\n private getTsconfigCacheKey(\n resolvedTsConfigPath: string,\n config: ResolvedConfig,\n ): string {\n const isProd = config.mode === 'production';\n return [\n resolvedTsConfigPath,\n isProd ? 'prod' : 'dev',\n this.options.isTest ? 'test' : 'app',\n config.build?.lib ? 'lib' : 'nolib',\n this.options.liveReload ? 'live-reload' : 'no-live-reload',\n this.options.hasTailwindCss ? 'tw' : 'notw',\n ].join('|');\n }\n\n private findIncludes(): string[] {\n const globs = this.options.include.map((glob) =>\n normalizeIncludeGlob(this.options.workspaceRoot, glob),\n );\n const files = globSync(globs, { dot: true, absolute: true });\n debugEmit('include discovery', {\n patternCount: globs.length,\n fileCount: files.length,\n });\n debugEmitV('include discovery files', {\n globs,\n files: files.map((file) => normalizePath(file)),\n });\n return files;\n }\n}\n\nexport function normalizeIncludeGlob(\n workspaceRoot: string,\n glob: string,\n): string {\n const normalizedWorkspaceRoot = normalizePath(resolve(workspaceRoot));\n const normalizedGlob = normalizePath(glob);\n\n if (\n normalizedGlob === normalizedWorkspaceRoot ||\n normalizedGlob.startsWith(`${normalizedWorkspaceRoot}/`)\n ) {\n return normalizedGlob;\n }\n\n if (normalizedGlob.startsWith('/')) {\n return `${normalizedWorkspaceRoot}${normalizedGlob}`;\n }\n\n return normalizePath(resolve(normalizedWorkspaceRoot, normalizedGlob));\n}\n\nfunction resolveReferenceTsconfigPath(\n referencePath: string,\n ownerTsconfigPath: string,\n): string | undefined {\n const ownerDir = dirname(ownerTsconfigPath);\n const resolvedReference = normalizePath(\n isAbsolute(referencePath)\n ? referencePath\n : resolve(ownerDir, referencePath),\n );\n\n if (existsSync(resolvedReference)) {\n try {\n if (statSync(resolvedReference).isDirectory()) {\n const nestedTsconfig = join(resolvedReference, 'tsconfig.json');\n return existsSync(nestedTsconfig)\n ? normalizePath(nestedTsconfig)\n : undefined;\n }\n } catch {\n return undefined;\n }\n return resolvedReference;\n }\n\n if (!resolvedReference.endsWith('.json')) {\n const asJson = `${resolvedReference}.json`;\n if (existsSync(asJson)) {\n return normalizePath(asJson);\n }\n const nestedTsconfig = join(resolvedReference, 'tsconfig.json');\n if (existsSync(nestedTsconfig)) {\n return normalizePath(nestedTsconfig);\n }\n }\n\n return undefined;\n}\n\nfunction collectTsconfigPathRoots(\n resolvedTsConfigPath: string,\n options: any,\n rawTsconfig: {\n compilerOptions?: {\n baseUrl?: unknown;\n paths?: Record<string, string[]>;\n };\n },\n): string[] {\n const tsPaths = rawTsconfig.compilerOptions?.paths ?? options.paths;\n if (!tsPaths) {\n return [];\n }\n\n const tsconfigDir = dirname(resolvedTsConfigPath);\n const configuredBaseUrl =\n typeof options.baseUrl === 'string'\n ? options.baseUrl\n : typeof rawTsconfig.compilerOptions?.baseUrl === 'string'\n ? rawTsconfig.compilerOptions.baseUrl\n : undefined;\n const resolvedBaseUrl = configuredBaseUrl\n ? isAbsolute(configuredBaseUrl)\n ? configuredBaseUrl\n : resolve(tsconfigDir, configuredBaseUrl)\n : tsconfigDir;\n const discoveredRoots = new Set<string>();\n\n for (const targets of Object.values(tsPaths)) {\n for (const target of targets as string[]) {\n const resolvedTarget = normalizePath(\n isAbsolute(target) ? target : resolve(resolvedBaseUrl, target),\n );\n\n if (target.includes('*')) {\n for (const match of globSync(resolvedTarget, {\n dot: true,\n absolute: true,\n })) {\n discoveredRoots.add(normalizePath(match));\n }\n continue;\n }\n\n if (existsSync(resolvedTarget)) {\n discoveredRoots.add(resolvedTarget);\n }\n }\n }\n\n return [...discoveredRoots];\n}\n"],"mappings":"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"}
@@ -1,9 +1,8 @@
1
- import { fromVirtualRawId, fromVirtualStyleId, isVirtualRawId, isVirtualStyleId, toVirtualRawId, toVirtualStyleId } from "./virtual-ids.js";
1
+ import { fromVirtualRawId, fromVirtualStyleId, isVirtualRawId, isVirtualStyleId } from "./virtual-ids.js";
2
2
  import { promises } from "node:fs";
3
- import { dirname, isAbsolute, resolve } from "node:path";
4
- import { normalizePath, preprocessCSS } from "vite";
3
+ import "node:path";
4
+ import { preprocessCSS } from "vite";
5
5
  //#region packages/vite-plugin-angular/src/lib/utils/virtual-resources.ts
6
- var INLINE_STYLE_QUERY_RE = /\.(css|scss|sass|less)\?inline$/;
7
6
  /**
8
7
  * True when the given stylesheet should be run through Vite's `preprocessCSS`,
9
8
  * given Vitest's `test.css` semantics:
@@ -31,32 +30,6 @@ function shouldPreprocessTestCss(config, filePath) {
31
30
  const matches = (patterns) => patterns.some((p) => typeof p === "string" ? filePath.includes(p) : p.test(filePath));
32
31
  return matches(include) && !matches(exclude);
33
32
  }
34
- function resolveImportPath(id, importer) {
35
- const filePath = id.split("?")[0];
36
- return isAbsolute(filePath) ? normalizePath(filePath) : importer ? normalizePath(resolve(dirname(importer), filePath)) : void 0;
37
- }
38
- /**
39
- * Rewrite a user `.html?raw` import to a virtual raw id. Returns undefined
40
- * when the id doesn't match, so callers can fall through to the next check.
41
- *
42
- * Routed through a virtual id (rather than `?analog-raw`) so the path Vite
43
- * sees has no file extension — keeps vite:asset / vite:css from re-tagging
44
- * the id before our load hook runs.
45
- */
46
- function rewriteHtmlRawImport(id, importer) {
47
- if (!id.includes(".html?raw")) return void 0;
48
- const resolved = resolveImportPath(id, importer);
49
- return resolved ? toVirtualRawId(resolved) : void 0;
50
- }
51
- /**
52
- * Rewrite a user `.scss?inline` / `.css?inline` / … import to a virtual
53
- * style id. Returns undefined when the id doesn't match.
54
- */
55
- function rewriteInlineStyleImport(id, importer) {
56
- if (!INLINE_STYLE_QUERY_RE.test(id)) return void 0;
57
- const resolved = resolveImportPath(id, importer);
58
- return resolved ? toVirtualStyleId(resolved) : void 0;
59
- }
60
33
  /**
61
34
  * Load a virtual raw module: reads the backing file, registers it for HMR
62
35
  * watching, and returns its content as a default-exported string. Returns
@@ -84,6 +57,6 @@ async function loadVirtualStyleModule(ctx, id, resolvedConfig) {
84
57
  return `export default ${JSON.stringify(result.code)}`;
85
58
  }
86
59
  //#endregion
87
- export { loadVirtualRawModule, loadVirtualStyleModule, rewriteHtmlRawImport, rewriteInlineStyleImport, shouldPreprocessTestCss };
60
+ export { loadVirtualRawModule, loadVirtualStyleModule, shouldPreprocessTestCss };
88
61
 
89
62
  //# sourceMappingURL=virtual-resources.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"virtual-resources.js","names":[],"sources":["../../../../src/lib/utils/virtual-resources.ts"],"sourcesContent":["// Shared Vite plugin helpers for routing component resources (templates,\n// external styles) through virtual module ids. Both angular-vite-plugin and\n// fast-compile-plugin use these so the rewriting + loading behavior stays\n// in sync between them.\n\nimport { promises as fsPromises } from 'node:fs';\nimport { dirname, isAbsolute, resolve } from 'node:path';\nimport { normalizePath, preprocessCSS, type ResolvedConfig } from 'vite';\n\nimport {\n fromVirtualRawId,\n fromVirtualStyleId,\n isVirtualRawId,\n isVirtualStyleId,\n toVirtualRawId,\n toVirtualStyleId,\n} from './virtual-ids.js';\n\nconst INLINE_STYLE_QUERY_RE = /\\.(css|scss|sass|less)\\?inline$/;\n\ninterface PluginContextLike {\n addWatchFile(path: string): void;\n}\n\ntype CssPattern = string | RegExp;\n\ntype VitestCssOption =\n | boolean\n | undefined\n | {\n // Vitest accepts both single patterns and arrays for include/exclude.\n include?: CssPattern | CssPattern[];\n exclude?: CssPattern | CssPattern[];\n };\n\n/**\n * True when the given stylesheet should be run through Vite's `preprocessCSS`,\n * given Vitest's `test.css` semantics:\n *\n * - non-test contexts → always preprocess\n * - `test.css: true` → always preprocess\n * - `test.css: false` → never preprocess\n * - `test.css: { include }` → preprocess only when `filePath` matches an\n * include pattern and isn't excluded\n * - `test.css` unset → Vitest defaults to `include: []`, so nothing\n * matches and we don't preprocess\n *\n * Used to gate `preprocessCSS` calls in test mode so we don't surface SCSS\n * deprecation noise or pay preprocessing cost the user didn't ask for. (#2297)\n */\nexport function shouldPreprocessTestCss(\n config: ResolvedConfig | undefined,\n filePath?: string,\n): boolean {\n const isTest = process.env['NODE_ENV'] === 'test' || !!process.env['VITEST'];\n if (!isTest) return true;\n\n const cssOpt = (\n config as\n | (ResolvedConfig & { test?: { css?: VitestCssOption } })\n | undefined\n )?.test?.css;\n\n if (cssOpt === true) return true;\n if (cssOpt === false || cssOpt == null) return false;\n\n const toArray = <T>(value: T | T[] | undefined): T[] =>\n value == null ? [] : Array.isArray(value) ? value : [value];\n const include = toArray(cssOpt.include);\n const exclude = toArray(cssOpt.exclude);\n if (!filePath || include.length === 0) return false;\n\n const matches = (patterns: CssPattern[]) =>\n patterns.some((p) =>\n typeof p === 'string' ? filePath.includes(p) : p.test(filePath),\n );\n\n return matches(include) && !matches(exclude);\n}\n\nfunction resolveImportPath(\n id: string,\n importer: string | undefined,\n): string | undefined {\n const filePath = id.split('?')[0];\n return isAbsolute(filePath)\n ? normalizePath(filePath)\n : importer\n ? normalizePath(resolve(dirname(importer), filePath))\n : undefined;\n}\n\n/**\n * Rewrite a user `.html?raw` import to a virtual raw id. Returns undefined\n * when the id doesn't match, so callers can fall through to the next check.\n *\n * Routed through a virtual id (rather than `?analog-raw`) so the path Vite\n * sees has no file extension — keeps vite:asset / vite:css from re-tagging\n * the id before our load hook runs.\n */\nexport function rewriteHtmlRawImport(\n id: string,\n importer: string | undefined,\n): string | undefined {\n if (!id.includes('.html?raw')) return undefined;\n const resolved = resolveImportPath(id, importer);\n return resolved ? toVirtualRawId(resolved) : undefined;\n}\n\n/**\n * Rewrite a user `.scss?inline` / `.css?inline` / … import to a virtual\n * style id. Returns undefined when the id doesn't match.\n */\nexport function rewriteInlineStyleImport(\n id: string,\n importer: string | undefined,\n): string | undefined {\n if (!INLINE_STYLE_QUERY_RE.test(id)) return undefined;\n const resolved = resolveImportPath(id, importer);\n return resolved ? toVirtualStyleId(resolved) : undefined;\n}\n\n/**\n * Load a virtual raw module: reads the backing file, registers it for HMR\n * watching, and returns its content as a default-exported string. Returns\n * undefined when the id is not a virtual raw id.\n */\nexport async function loadVirtualRawModule(\n ctx: PluginContextLike,\n id: string,\n): Promise<string | undefined> {\n if (!isVirtualRawId(id)) return undefined;\n const filePath = fromVirtualRawId(id);\n ctx.addWatchFile(filePath);\n const content = await fsPromises.readFile(filePath, 'utf-8');\n return `export default ${JSON.stringify(content)}`;\n}\n\n/**\n * Load a virtual style module: reads the backing stylesheet, runs it through\n * Vite's CSS preprocessor, and returns the result as a default-exported\n * string. Returns undefined when the id is not a virtual style id.\n */\nexport async function loadVirtualStyleModule(\n ctx: PluginContextLike,\n id: string,\n resolvedConfig: ResolvedConfig,\n): Promise<string | undefined> {\n if (!isVirtualStyleId(id)) return undefined;\n const filePath = fromVirtualStyleId(id);\n ctx.addWatchFile(filePath);\n const code = await fsPromises.readFile(filePath, 'utf-8');\n // In tests, mirror Vitest's `test.css` rules — defaults to no preprocessing\n // (matches Vite's CSS pipeline behavior under Vitest). (#2297)\n if (!shouldPreprocessTestCss(resolvedConfig, filePath)) {\n return `export default ${JSON.stringify(code)}`;\n }\n const result = await preprocessCSS(code, filePath, resolvedConfig);\n return `export default ${JSON.stringify(result.code)}`;\n}\n"],"mappings":";;;;;AAkBA,IAAM,wBAAwB;;;;;;;;;;;;;;;;AAgC9B,SAAgB,wBACd,QACA,UACS;AAET,KAAI,EAAA,QAAA,IAAA,aADuC,UAAU,CAAC,CAAC,QAAQ,IAAI,WACtD,QAAO;CAEpB,MAAM,SACJ,QAGC,MAAM;AAET,KAAI,WAAW,KAAM,QAAO;AAC5B,KAAI,WAAW,SAAS,UAAU,KAAM,QAAO;CAE/C,MAAM,WAAc,UAClB,SAAS,OAAO,EAAE,GAAG,MAAM,QAAQ,MAAM,GAAG,QAAQ,CAAC,MAAM;CAC7D,MAAM,UAAU,QAAQ,OAAO,QAAQ;CACvC,MAAM,UAAU,QAAQ,OAAO,QAAQ;AACvC,KAAI,CAAC,YAAY,QAAQ,WAAW,EAAG,QAAO;CAE9C,MAAM,WAAW,aACf,SAAS,MAAM,MACb,OAAO,MAAM,WAAW,SAAS,SAAS,EAAE,GAAG,EAAE,KAAK,SAAS,CAChE;AAEH,QAAO,QAAQ,QAAQ,IAAI,CAAC,QAAQ,QAAQ;;AAG9C,SAAS,kBACP,IACA,UACoB;CACpB,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC;AAC/B,QAAO,WAAW,SAAS,GACvB,cAAc,SAAS,GACvB,WACE,cAAc,QAAQ,QAAQ,SAAS,EAAE,SAAS,CAAC,GACnD,KAAA;;;;;;;;;;AAWR,SAAgB,qBACd,IACA,UACoB;AACpB,KAAI,CAAC,GAAG,SAAS,YAAY,CAAE,QAAO,KAAA;CACtC,MAAM,WAAW,kBAAkB,IAAI,SAAS;AAChD,QAAO,WAAW,eAAe,SAAS,GAAG,KAAA;;;;;;AAO/C,SAAgB,yBACd,IACA,UACoB;AACpB,KAAI,CAAC,sBAAsB,KAAK,GAAG,CAAE,QAAO,KAAA;CAC5C,MAAM,WAAW,kBAAkB,IAAI,SAAS;AAChD,QAAO,WAAW,iBAAiB,SAAS,GAAG,KAAA;;;;;;;AAQjD,eAAsB,qBACpB,KACA,IAC6B;AAC7B,KAAI,CAAC,eAAe,GAAG,CAAE,QAAO,KAAA;CAChC,MAAM,WAAW,iBAAiB,GAAG;AACrC,KAAI,aAAa,SAAS;CAC1B,MAAM,UAAU,MAAM,SAAW,SAAS,UAAU,QAAQ;AAC5D,QAAO,kBAAkB,KAAK,UAAU,QAAQ;;;;;;;AAQlD,eAAsB,uBACpB,KACA,IACA,gBAC6B;AAC7B,KAAI,CAAC,iBAAiB,GAAG,CAAE,QAAO,KAAA;CAClC,MAAM,WAAW,mBAAmB,GAAG;AACvC,KAAI,aAAa,SAAS;CAC1B,MAAM,OAAO,MAAM,SAAW,SAAS,UAAU,QAAQ;AAGzD,KAAI,CAAC,wBAAwB,gBAAgB,SAAS,CACpD,QAAO,kBAAkB,KAAK,UAAU,KAAK;CAE/C,MAAM,SAAS,MAAM,cAAc,MAAM,UAAU,eAAe;AAClE,QAAO,kBAAkB,KAAK,UAAU,OAAO,KAAK"}
1
+ {"version":3,"file":"virtual-resources.js","names":[],"sources":["../../../../src/lib/utils/virtual-resources.ts"],"sourcesContent":["// Shared Vite plugin helpers for routing component resources (templates,\n// external styles) through virtual module ids. Both angular-vite-plugin and\n// fast-compile-plugin use these so the rewriting + loading behavior stays\n// in sync between them.\n\nimport { promises as fsPromises } from 'node:fs';\nimport { dirname, isAbsolute, resolve } from 'node:path';\nimport { normalizePath, preprocessCSS, type ResolvedConfig } from 'vite';\n\nimport {\n fromVirtualRawId,\n fromVirtualStyleId,\n isVirtualRawId,\n isVirtualStyleId,\n toVirtualRawId,\n toVirtualStyleId,\n} from './virtual-ids.js';\n\nconst INLINE_STYLE_QUERY_RE = /\\.(css|scss|sass|less)\\?inline$/;\n\ninterface PluginContextLike {\n addWatchFile(path: string): void;\n}\n\ntype CssPattern = string | RegExp;\n\ntype VitestCssOption =\n | boolean\n | undefined\n | {\n // Vitest accepts both single patterns and arrays for include/exclude.\n include?: CssPattern | CssPattern[];\n exclude?: CssPattern | CssPattern[];\n };\n\n/**\n * True when the given stylesheet should be run through Vite's `preprocessCSS`,\n * given Vitest's `test.css` semantics:\n *\n * - non-test contexts → always preprocess\n * - `test.css: true` → always preprocess\n * - `test.css: false` → never preprocess\n * - `test.css: { include }` → preprocess only when `filePath` matches an\n * include pattern and isn't excluded\n * - `test.css` unset → Vitest defaults to `include: []`, so nothing\n * matches and we don't preprocess\n *\n * Used to gate `preprocessCSS` calls in test mode so we don't surface SCSS\n * deprecation noise or pay preprocessing cost the user didn't ask for. (#2297)\n */\nexport function shouldPreprocessTestCss(\n config: ResolvedConfig | undefined,\n filePath?: string,\n): boolean {\n const isTest = process.env['NODE_ENV'] === 'test' || !!process.env['VITEST'];\n if (!isTest) return true;\n\n const cssOpt = (\n config as\n | (ResolvedConfig & { test?: { css?: VitestCssOption } })\n | undefined\n )?.test?.css;\n\n if (cssOpt === true) return true;\n if (cssOpt === false || cssOpt == null) return false;\n\n const toArray = <T>(value: T | T[] | undefined): T[] =>\n value == null ? [] : Array.isArray(value) ? value : [value];\n const include = toArray(cssOpt.include);\n const exclude = toArray(cssOpt.exclude);\n if (!filePath || include.length === 0) return false;\n\n const matches = (patterns: CssPattern[]) =>\n patterns.some((p) =>\n typeof p === 'string' ? filePath.includes(p) : p.test(filePath),\n );\n\n return matches(include) && !matches(exclude);\n}\n\nfunction resolveImportPath(\n id: string,\n importer: string | undefined,\n): string | undefined {\n const filePath = id.split('?')[0];\n return isAbsolute(filePath)\n ? normalizePath(filePath)\n : importer\n ? normalizePath(resolve(dirname(importer), filePath))\n : undefined;\n}\n\n/**\n * Rewrite a user `.html?raw` import to a virtual raw id. Returns undefined\n * when the id doesn't match, so callers can fall through to the next check.\n *\n * Routed through a virtual id (rather than `?analog-raw`) so the path Vite\n * sees has no file extension — keeps vite:asset / vite:css from re-tagging\n * the id before our load hook runs.\n */\nexport function rewriteHtmlRawImport(\n id: string,\n importer: string | undefined,\n): string | undefined {\n if (!id.includes('.html?raw')) return undefined;\n const resolved = resolveImportPath(id, importer);\n return resolved ? toVirtualRawId(resolved) : undefined;\n}\n\n/**\n * Rewrite a user `.scss?inline` / `.css?inline` / … import to a virtual\n * style id. Returns undefined when the id doesn't match.\n */\nexport function rewriteInlineStyleImport(\n id: string,\n importer: string | undefined,\n): string | undefined {\n if (!INLINE_STYLE_QUERY_RE.test(id)) return undefined;\n const resolved = resolveImportPath(id, importer);\n return resolved ? toVirtualStyleId(resolved) : undefined;\n}\n\n/**\n * Load a virtual raw module: reads the backing file, registers it for HMR\n * watching, and returns its content as a default-exported string. Returns\n * undefined when the id is not a virtual raw id.\n */\nexport async function loadVirtualRawModule(\n ctx: PluginContextLike,\n id: string,\n): Promise<string | undefined> {\n if (!isVirtualRawId(id)) return undefined;\n const filePath = fromVirtualRawId(id);\n ctx.addWatchFile(filePath);\n const content = await fsPromises.readFile(filePath, 'utf-8');\n return `export default ${JSON.stringify(content)}`;\n}\n\n/**\n * Load a virtual style module: reads the backing stylesheet, runs it through\n * Vite's CSS preprocessor, and returns the result as a default-exported\n * string. Returns undefined when the id is not a virtual style id.\n */\nexport async function loadVirtualStyleModule(\n ctx: PluginContextLike,\n id: string,\n resolvedConfig: ResolvedConfig,\n): Promise<string | undefined> {\n if (!isVirtualStyleId(id)) return undefined;\n const filePath = fromVirtualStyleId(id);\n ctx.addWatchFile(filePath);\n const code = await fsPromises.readFile(filePath, 'utf-8');\n // In tests, mirror Vitest's `test.css` rules — defaults to no preprocessing\n // (matches Vite's CSS pipeline behavior under Vitest). (#2297)\n if (!shouldPreprocessTestCss(resolvedConfig, filePath)) {\n return `export default ${JSON.stringify(code)}`;\n }\n const result = await preprocessCSS(code, filePath, resolvedConfig);\n return `export default ${JSON.stringify(result.code)}`;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAkDA,SAAgB,wBACd,QACA,UACS;AAET,KAAI,EAAA,QAAA,IAAA,aADuC,UAAU,CAAC,CAAC,QAAQ,IAAI,WACtD,QAAO;CAEpB,MAAM,SACJ,QAGC,MAAM;AAET,KAAI,WAAW,KAAM,QAAO;AAC5B,KAAI,WAAW,SAAS,UAAU,KAAM,QAAO;CAE/C,MAAM,WAAc,UAClB,SAAS,OAAO,EAAE,GAAG,MAAM,QAAQ,MAAM,GAAG,QAAQ,CAAC,MAAM;CAC7D,MAAM,UAAU,QAAQ,OAAO,QAAQ;CACvC,MAAM,UAAU,QAAQ,OAAO,QAAQ;AACvC,KAAI,CAAC,YAAY,QAAQ,WAAW,EAAG,QAAO;CAE9C,MAAM,WAAW,aACf,SAAS,MAAM,MACb,OAAO,MAAM,WAAW,SAAS,SAAS,EAAE,GAAG,EAAE,KAAK,SAAS,CAChE;AAEH,QAAO,QAAQ,QAAQ,IAAI,CAAC,QAAQ,QAAQ;;;;;;;AAkD9C,eAAsB,qBACpB,KACA,IAC6B;AAC7B,KAAI,CAAC,eAAe,GAAG,CAAE,QAAO,KAAA;CAChC,MAAM,WAAW,iBAAiB,GAAG;AACrC,KAAI,aAAa,SAAS;CAC1B,MAAM,UAAU,MAAM,SAAW,SAAS,UAAU,QAAQ;AAC5D,QAAO,kBAAkB,KAAK,UAAU,QAAQ;;;;;;;AAQlD,eAAsB,uBACpB,KACA,IACA,gBAC6B;AAC7B,KAAI,CAAC,iBAAiB,GAAG,CAAE,QAAO,KAAA;CAClC,MAAM,WAAW,mBAAmB,GAAG;AACvC,KAAI,aAAa,SAAS;CAC1B,MAAM,OAAO,MAAM,SAAW,SAAS,UAAU,QAAQ;AAGzD,KAAI,CAAC,wBAAwB,gBAAgB,SAAS,CACpD,QAAO,kBAAkB,KAAK,UAAU,KAAK;CAE/C,MAAM,SAAS,MAAM,cAAc,MAAM,UAAU,eAAe;AAClE,QAAO,kBAAkB,KAAK,UAAU,OAAO,KAAK"}
@@ -0,0 +1,5 @@
1
+ import { Plugin } from "vite";
2
+ export interface VirtualModulesPluginOptions {
3
+ jit: boolean;
4
+ }
5
+ export declare function virtualModulesPlugin(pluginOptions: VirtualModulesPluginOptions): Plugin;
@@ -0,0 +1,50 @@
1
+ import { toVirtualRawId, toVirtualStyleId } from "./utils/virtual-ids.js";
2
+ import { loadVirtualRawModule, loadVirtualStyleModule, shouldPreprocessTestCss } from "./utils/virtual-resources.js";
3
+ import { promises } from "node:fs";
4
+ import { dirname, isAbsolute, resolve } from "node:path";
5
+ import { normalizePath, preprocessCSS } from "vite";
6
+ //#region packages/vite-plugin-angular/src/lib/virtual-modules-plugin.ts
7
+ function virtualModulesPlugin(pluginOptions) {
8
+ let resolvedConfig;
9
+ return {
10
+ name: "@analogjs/vite-plugin-angular:virtual-modules",
11
+ enforce: "pre",
12
+ configResolved(config) {
13
+ resolvedConfig = config;
14
+ },
15
+ resolveId(id, importer) {
16
+ if (id.startsWith("virtual:@analogjs/vite-plugin-angular:inline-style:") || id.startsWith("virtual:@analogjs/vite-plugin-angular:raw:")) return `\0${id}`;
17
+ if (pluginOptions.jit && id.startsWith("angular:jit:")) {
18
+ const filePath = normalizePath(resolve(dirname(importer), id.split(";")[1]));
19
+ return id.includes(":style") ? toVirtualStyleId(filePath) : toVirtualRawId(filePath);
20
+ }
21
+ if (id.includes(".html?raw")) {
22
+ const filePath = id.split("?")[0];
23
+ const resolved = isAbsolute(filePath) ? normalizePath(filePath) : importer ? normalizePath(resolve(dirname(importer), filePath)) : void 0;
24
+ if (resolved) return toVirtualRawId(resolved);
25
+ }
26
+ if (/\.(css|scss|sass|less)\?inline$/.test(id)) {
27
+ const filePath = id.split("?")[0];
28
+ const resolved = isAbsolute(filePath) ? normalizePath(filePath) : importer ? normalizePath(resolve(dirname(importer), filePath)) : void 0;
29
+ if (resolved) return toVirtualStyleId(resolved);
30
+ }
31
+ },
32
+ async load(id) {
33
+ const styleModule = await loadVirtualStyleModule(this, id, resolvedConfig);
34
+ if (styleModule !== void 0) return styleModule;
35
+ const rawModule = await loadVirtualRawModule(this, id);
36
+ if (rawModule !== void 0) return rawModule;
37
+ if (/\.(css|scss|sass|less)\?inline$/.test(id)) {
38
+ const filePath = id.split("?")[0];
39
+ const code = await promises.readFile(filePath, "utf-8");
40
+ if (!shouldPreprocessTestCss(resolvedConfig, filePath)) return `export default ${JSON.stringify(code)}`;
41
+ const result = await preprocessCSS(code, filePath, resolvedConfig);
42
+ return `export default ${JSON.stringify(result.code)}`;
43
+ }
44
+ }
45
+ };
46
+ }
47
+ //#endregion
48
+ export { virtualModulesPlugin };
49
+
50
+ //# sourceMappingURL=virtual-modules-plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"virtual-modules-plugin.js","names":[],"sources":["../../../src/lib/virtual-modules-plugin.ts"],"sourcesContent":["import { promises as fsPromises } from 'node:fs';\nimport { dirname, isAbsolute, resolve } from 'node:path';\nimport { normalizePath, Plugin, preprocessCSS, ResolvedConfig } from 'vite';\nimport {\n VIRTUAL_RAW_PREFIX,\n VIRTUAL_STYLE_PREFIX,\n toVirtualRawId,\n toVirtualStyleId,\n} from './utils/virtual-ids.js';\nimport {\n loadVirtualRawModule,\n loadVirtualStyleModule,\n shouldPreprocessTestCss,\n} from './utils/virtual-resources.js';\n\nexport interface VirtualModulesPluginOptions {\n jit: boolean;\n}\n\nexport function virtualModulesPlugin(\n pluginOptions: VirtualModulesPluginOptions,\n): Plugin {\n let resolvedConfig: ResolvedConfig;\n\n return {\n name: '@analogjs/vite-plugin-angular:virtual-modules',\n enforce: 'pre',\n configResolved(config) {\n resolvedConfig = config;\n },\n resolveId(id, importer) {\n if (\n id.startsWith(VIRTUAL_STYLE_PREFIX) ||\n id.startsWith(VIRTUAL_RAW_PREFIX)\n ) {\n return `\\0${id}`;\n }\n\n if (pluginOptions.jit && id.startsWith('angular:jit:')) {\n const filePath = normalizePath(\n resolve(dirname(importer as string), id.split(';')[1]),\n );\n return id.includes(':style')\n ? toVirtualStyleId(filePath)\n : toVirtualRawId(filePath);\n }\n\n // Intercept .html?raw imports to bypass Vite server.fs restrictions\n if (id.includes('.html?raw')) {\n const filePath = id.split('?')[0];\n const resolved = isAbsolute(filePath)\n ? normalizePath(filePath)\n : importer\n ? normalizePath(resolve(dirname(importer), filePath))\n : undefined;\n if (resolved) {\n return toVirtualRawId(resolved);\n }\n }\n\n // Intercept style ?inline imports to bypass Vite server.fs restrictions\n if (/\\.(css|scss|sass|less)\\?inline$/.test(id)) {\n const filePath = id.split('?')[0];\n const resolved = isAbsolute(filePath)\n ? normalizePath(filePath)\n : importer\n ? normalizePath(resolve(dirname(importer), filePath))\n : undefined;\n if (resolved) {\n return toVirtualStyleId(resolved);\n }\n }\n\n return undefined;\n },\n async load(id) {\n const styleModule = await loadVirtualStyleModule(\n this,\n id,\n resolvedConfig,\n );\n if (styleModule !== undefined) return styleModule;\n\n const rawModule = await loadVirtualRawModule(this, id);\n if (rawModule !== undefined) return rawModule;\n\n // Vitest fallback: the module-runner calls ensureEntryFromUrl before\n // transformRequest, which skips pluginContainer.resolveId entirely,\n // so a user `import foo from './a.scss?inline'` reaches load as the\n // bare query form. Handle it here so tests still resolve.\n if (/\\.(css|scss|sass|less)\\?inline$/.test(id)) {\n const filePath = id.split('?')[0];\n const code = await fsPromises.readFile(filePath, 'utf-8');\n if (!shouldPreprocessTestCss(resolvedConfig, filePath)) {\n return `export default ${JSON.stringify(code)}`;\n }\n const result = await preprocessCSS(code, filePath, resolvedConfig);\n return `export default ${JSON.stringify(result.code)}`;\n }\n\n return;\n },\n };\n}\n"],"mappings":";;;;;;AAmBA,SAAgB,qBACd,eACQ;CACR,IAAI;AAEJ,QAAO;EACL,MAAM;EACN,SAAS;EACT,eAAe,QAAQ;AACrB,oBAAiB;;EAEnB,UAAU,IAAI,UAAU;AACtB,OACE,GAAG,WAAA,sDAAgC,IACnC,GAAG,WAAA,6CAA8B,CAEjC,QAAO,KAAK;AAGd,OAAI,cAAc,OAAO,GAAG,WAAW,eAAe,EAAE;IACtD,MAAM,WAAW,cACf,QAAQ,QAAQ,SAAmB,EAAE,GAAG,MAAM,IAAI,CAAC,GAAG,CACvD;AACD,WAAO,GAAG,SAAS,SAAS,GACxB,iBAAiB,SAAS,GAC1B,eAAe,SAAS;;AAI9B,OAAI,GAAG,SAAS,YAAY,EAAE;IAC5B,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC;IAC/B,MAAM,WAAW,WAAW,SAAS,GACjC,cAAc,SAAS,GACvB,WACE,cAAc,QAAQ,QAAQ,SAAS,EAAE,SAAS,CAAC,GACnD,KAAA;AACN,QAAI,SACF,QAAO,eAAe,SAAS;;AAKnC,OAAI,kCAAkC,KAAK,GAAG,EAAE;IAC9C,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC;IAC/B,MAAM,WAAW,WAAW,SAAS,GACjC,cAAc,SAAS,GACvB,WACE,cAAc,QAAQ,QAAQ,SAAS,EAAE,SAAS,CAAC,GACnD,KAAA;AACN,QAAI,SACF,QAAO,iBAAiB,SAAS;;;EAMvC,MAAM,KAAK,IAAI;GACb,MAAM,cAAc,MAAM,uBACxB,MACA,IACA,eACD;AACD,OAAI,gBAAgB,KAAA,EAAW,QAAO;GAEtC,MAAM,YAAY,MAAM,qBAAqB,MAAM,GAAG;AACtD,OAAI,cAAc,KAAA,EAAW,QAAO;AAMpC,OAAI,kCAAkC,KAAK,GAAG,EAAE;IAC9C,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC;IAC/B,MAAM,OAAO,MAAM,SAAW,SAAS,UAAU,QAAQ;AACzD,QAAI,CAAC,wBAAwB,gBAAgB,SAAS,CACpD,QAAO,kBAAkB,KAAK,UAAU,KAAK;IAE/C,MAAM,SAAS,MAAM,cAAc,MAAM,UAAU,eAAe;AAClE,WAAO,kBAAkB,KAAK,UAAU,OAAO,KAAK;;;EAKzD"}