@analogjs/vite-plugin-angular 3.0.0-alpha.35 → 3.0.0-alpha.37

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 (72) hide show
  1. package/README.md +22 -0
  2. package/package.json +3 -4
  3. package/src/lib/angular-jit-plugin.js +3 -0
  4. package/src/lib/angular-jit-plugin.js.map +1 -1
  5. package/src/lib/angular-vite-plugin.d.ts +12 -7
  6. package/src/lib/angular-vite-plugin.js +229 -43
  7. package/src/lib/angular-vite-plugin.js.map +1 -1
  8. package/src/lib/compiler/angular-version.d.ts +19 -0
  9. package/src/lib/compiler/angular-version.js +16 -0
  10. package/src/lib/compiler/angular-version.js.map +1 -0
  11. package/src/lib/compiler/class-field-lowering.d.ts +23 -0
  12. package/src/lib/compiler/class-field-lowering.js +131 -0
  13. package/src/lib/compiler/class-field-lowering.js.map +1 -0
  14. package/src/lib/compiler/compile.d.ts +44 -0
  15. package/src/lib/compiler/compile.js +731 -0
  16. package/src/lib/compiler/compile.js.map +1 -0
  17. package/src/lib/compiler/constants.d.ts +18 -0
  18. package/src/lib/compiler/constants.js +52 -0
  19. package/src/lib/compiler/constants.js.map +1 -0
  20. package/src/lib/compiler/debug.d.ts +22 -0
  21. package/src/lib/compiler/debug.js +20 -0
  22. package/src/lib/compiler/debug.js.map +1 -0
  23. package/src/lib/compiler/defer.d.ts +47 -0
  24. package/src/lib/compiler/defer.js +138 -0
  25. package/src/lib/compiler/defer.js.map +1 -0
  26. package/src/lib/compiler/dts-reader.d.ts +35 -0
  27. package/src/lib/compiler/dts-reader.js +365 -0
  28. package/src/lib/compiler/dts-reader.js.map +1 -0
  29. package/src/lib/compiler/hmr.d.ts +16 -0
  30. package/src/lib/compiler/hmr.js +69 -0
  31. package/src/lib/compiler/hmr.js.map +1 -0
  32. package/src/lib/compiler/index.d.ts +7 -0
  33. package/src/lib/compiler/index.js +7 -0
  34. package/src/lib/compiler/jit-metadata.d.ts +14 -0
  35. package/src/lib/compiler/jit-metadata.js +146 -0
  36. package/src/lib/compiler/jit-metadata.js.map +1 -0
  37. package/src/lib/compiler/jit-transform.d.ts +24 -0
  38. package/src/lib/compiler/jit-transform.js +200 -0
  39. package/src/lib/compiler/jit-transform.js.map +1 -0
  40. package/src/lib/compiler/js-emitter.d.ts +10 -0
  41. package/src/lib/compiler/js-emitter.js +420 -0
  42. package/src/lib/compiler/js-emitter.js.map +1 -0
  43. package/src/lib/compiler/metadata.d.ts +45 -0
  44. package/src/lib/compiler/metadata.js +633 -0
  45. package/src/lib/compiler/metadata.js.map +1 -0
  46. package/src/lib/compiler/registry.d.ts +49 -0
  47. package/src/lib/compiler/registry.js +164 -0
  48. package/src/lib/compiler/registry.js.map +1 -0
  49. package/src/lib/compiler/resource-inliner.d.ts +21 -0
  50. package/src/lib/compiler/resource-inliner.js +152 -0
  51. package/src/lib/compiler/resource-inliner.js.map +1 -0
  52. package/src/lib/compiler/style-ast.d.ts +8 -0
  53. package/src/lib/compiler/style-ast.js +54 -0
  54. package/src/lib/compiler/style-ast.js.map +1 -0
  55. package/src/lib/compiler/styles.d.ts +13 -0
  56. package/src/lib/compiler/test-helpers.d.ts +7 -0
  57. package/src/lib/compiler/type-elision.d.ts +26 -0
  58. package/src/lib/compiler/type-elision.js +211 -0
  59. package/src/lib/compiler/type-elision.js.map +1 -0
  60. package/src/lib/compiler/utils.d.ts +10 -0
  61. package/src/lib/compiler/utils.js +35 -0
  62. package/src/lib/compiler/utils.js.map +1 -0
  63. package/src/lib/{analog-compiler-plugin.d.ts → fast-compile-plugin.d.ts} +3 -3
  64. package/src/lib/{analog-compiler-plugin.js → fast-compile-plugin.js} +46 -33
  65. package/src/lib/fast-compile-plugin.js.map +1 -0
  66. package/src/lib/utils/debug.d.ts +3 -1
  67. package/src/lib/utils/debug.js +6 -2
  68. package/src/lib/utils/debug.js.map +1 -1
  69. package/src/lib/utils/virtual-resources.d.ts +16 -0
  70. package/src/lib/utils/virtual-resources.js +31 -2
  71. package/src/lib/utils/virtual-resources.js.map +1 -1
  72. package/src/lib/analog-compiler-plugin.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fast-compile-plugin.js","names":[],"sources":["../../../src/lib/fast-compile-plugin.ts"],"sourcesContent":["import { promises as fsPromises } from 'node:fs';\nimport { dirname, resolve } from 'node:path';\nimport * as vite from 'vite';\n\nimport * as compilerCli from '@angular/compiler-cli';\nimport {\n defaultClientConditions,\n normalizePath,\n Plugin,\n preprocessCSS,\n ResolvedConfig,\n} from 'vite';\n\nimport {\n compile,\n scanFile,\n scanPackageDts,\n collectImportedPackages,\n collectRelativeReExports,\n jitTransform,\n inlineResourceUrls,\n extractInlineStyles,\n generateHmrCode,\n debugCompile,\n debugRegistry,\n type ComponentRegistry,\n} from './compiler/index.js';\n\nimport {\n TS_EXT_REGEX,\n getTsConfigPath,\n createDepOptimizerConfig,\n type TsConfigResolutionContext,\n} from './utils/plugin-config.js';\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 rewriteHtmlRawImport,\n rewriteInlineStyleImport,\n shouldPreprocessTestCss,\n} from './utils/virtual-resources.js';\n\nexport interface FastCompilePluginOptions {\n tsconfigGetter: () => string;\n workspaceRoot: string;\n inlineStylesExtension: string;\n jit: boolean;\n liveReload: boolean;\n supportedBrowsers: string[];\n transformFilter?: (code: string, id: string) => boolean;\n isTest: boolean;\n isAstroIntegration: boolean;\n fastCompileMode?: 'full' | 'partial';\n}\n\nexport function fastCompilePlugin(\n pluginOptions: FastCompilePluginOptions,\n): Plugin {\n let resolvedConfig: ResolvedConfig;\n let tsConfigResolutionContext: TsConfigResolutionContext | null = null;\n let watchMode = false;\n\n // fast-compile plugin state\n const registry: ComponentRegistry = new Map();\n const resourceToSource = new Map<string, string>();\n const scannedDtsPackages = new Set<string>();\n let projectRoot = '';\n let useDefineForClassFields = true;\n\n /**\n * Scan a file into the registry, then recursively walk its relative\n * `export *` / `export { … } from './x'` chain so any underlying\n * directive classes also land in the registry. Used both at\n * `buildStart` (for tsconfig path entries) and at dev time (file\n * `add` and `handleHotUpdate`) so newly added barrels stay in sync\n * without requiring a server restart.\n *\n * The `visited` set prevents infinite recursion within a single\n * top-level call. Each fresh scan should pass an empty set (so HMR\n * re-scans aren't blocked by buildStart's earlier visits).\n */\n async function scanBarrelExports(\n file: string,\n visited: Set<string> = new Set(),\n overwrite = false,\n ): Promise<void> {\n if (visited.has(file)) return;\n visited.add(file);\n let code: string;\n try {\n code = await fsPromises.readFile(file, 'utf-8');\n } catch (e) {\n if (debugRegistry.enabled) {\n debugRegistry(\n 'scanBarrelExports: failed to read %s: %s',\n file,\n (e as Error)?.message,\n );\n }\n return;\n }\n const entries = scanFile(code, file);\n for (const entry of entries) {\n // At buildStart we want stable registry entries (don't overwrite\n // an earlier scan with a barrel re-scan); HMR explicitly asks\n // for overwrite so updated metadata replaces stale entries.\n if (overwrite || !registry.has(entry.className)) {\n registry.set(entry.className, entry);\n }\n }\n // Collect every relative re-export specifier via OXC AST so\n // recursive scans can't trip over each other (a shared `/g` regex\n // would have its `lastIndex` reset by each recursive call and\n // silently skip half of an outer barrel's re-exports, which\n // previously left directives like `HlmRadioGroup` unregistered).\n const dir = dirname(file);\n for (const rel of collectRelativeReExports(code, file)) {\n // NodeNext-style libraries write `export * from './foo.js'`\n // even though the source is `./foo.ts`. Strip the ESM\n // extension before probing or the candidates would be\n // `foo.js.ts` / `foo.js/index.ts`, which never exist.\n const normalizedRel = rel.replace(/\\.(?:js|mjs)$/u, '');\n const reExportCandidates = [\n resolve(dir, normalizedRel + '.ts'),\n resolve(dir, normalizedRel, 'index.ts'),\n ];\n let resolved = false;\n for (const candidate of reExportCandidates) {\n try {\n await fsPromises.access(candidate);\n await scanBarrelExports(candidate, visited, overwrite);\n resolved = true;\n break;\n } catch {\n // try next candidate\n }\n }\n if (!resolved && debugRegistry.enabled) {\n debugRegistry(\n 'scanBarrelExports: %s re-export %s did not resolve to %o',\n file,\n rel,\n reExportCandidates,\n );\n }\n }\n }\n\n async function initFastCompile() {\n if (pluginOptions.jit) return; // JIT: no registry scan needed\n\n // Scan all source files to build the registry\n registry.clear();\n scannedDtsPackages.clear();\n const resolvedTsConfigPath = resolveTsConfigPath();\n projectRoot = dirname(resolvedTsConfigPath);\n const config = compilerCli.readConfiguration(resolvedTsConfigPath);\n useDefineForClassFields = config.options?.useDefineForClassFields ?? true;\n\n // Collect candidate files: tsconfig rootNames PLUS the entry points\n // named in `compilerOptions.paths`. App tsconfigs typically only\n // include the app's own sources, so workspace library entry barrels\n // (e.g. `HlmSelectImports = [HlmSelect, HlmSelectContent, ...] as\n // const`) live outside `rootNames` and would otherwise miss the\n // initial scan. The compiler then can't see that `HlmSelectImports`\n // is a tuple barrel and emits the bare identifier into the parent\n // component's `dependencies()` list, where Angular's runtime\n // silently drops it because arrays don't have a directive def.\n const candidates = new Set<string>(config.rootNames);\n const tsPaths = config.options?.paths;\n const baseUrl = (config.options?.baseUrl ?? projectRoot) as string;\n if (tsPaths) {\n for (const targets of Object.values(tsPaths)) {\n for (const target of targets as string[]) {\n // Skip wildcard patterns — entry barrels are normally exact\n // file paths like \"libs/helm/select/src/index.ts\".\n if (target.includes('*')) continue;\n candidates.add(resolve(baseUrl, target));\n }\n }\n }\n const results = await Promise.all(\n Array.from(candidates).map(async (file) => {\n try {\n const code = await fsPromises.readFile(file, 'utf-8');\n return scanFile(code, file);\n } catch (e) {\n if (debugRegistry.enabled) {\n debugRegistry(\n 'initFastCompile: skipping unreadable %s: %s',\n file,\n (e as Error)?.message,\n );\n }\n return []; // Skip unreadable files\n }\n }),\n );\n\n for (const entries of results) {\n for (const entry of entries) {\n registry.set(entry.className, entry);\n }\n }\n\n // Library barrels typically `export * from './lib/...'` rather than\n // declaring directives directly, so the entry file alone gives us\n // the tuple consts but not the directive classes they reference.\n // Walk the relative `export *` chain so the underlying classes also\n // land in the registry. Use a SHARED visited set across all\n // barrels so recursive walks don't double-scan a file that's\n // re-exported from multiple entry points.\n const buildStartVisited = new Set<string>();\n if (tsPaths) {\n const barrelCandidates: string[] = [];\n for (const targets of Object.values(tsPaths)) {\n for (const target of targets as string[]) {\n if (target.includes('*')) continue;\n barrelCandidates.push(resolve(baseUrl, target));\n }\n }\n await Promise.all(\n barrelCandidates.map((c) => scanBarrelExports(c, buildStartVisited)),\n );\n }\n debugRegistry(\n 'initFastCompile done: %d entries from %d candidate files',\n registry.size,\n candidates.size,\n );\n }\n\n function ensureDtsRegistryForSource(code: string, id: string) {\n for (const pkg of collectImportedPackages(code, id)) {\n if (scannedDtsPackages.has(pkg)) continue;\n scannedDtsPackages.add(pkg);\n\n try {\n const dtsEntries = scanPackageDts(pkg, projectRoot);\n for (const entry of dtsEntries) {\n if (!registry.has(entry.className)) {\n registry.set(entry.className, entry);\n }\n }\n } catch {\n // Package may not have .d.ts files or may not be Angular\n }\n }\n }\n\n async function handleFastCompileTransform(\n code: string,\n id: string,\n ): Promise<{ code: string; map: any } | undefined> {\n if (!/(Component|Directive|Pipe|Injectable|NgModule)\\(/.test(code)) {\n // Non-Angular file — leave it alone so a downstream plugin (or\n // Vite's built-in TS handler) can process it.\n return undefined;\n }\n\n // JIT mode\n if (pluginOptions.jit) {\n const result = jitTransform(code, id);\n return { code: result.code, map: result.map };\n }\n\n // Inline external templateUrl/styleUrl(s) into the source before compilation\n code = inlineResourceUrls(code, id);\n\n // Pre-resolve inline styles that need preprocessing (SCSS/Sass/Less)\n let resolvedStyles: Map<string, string> | undefined;\n let resolvedInlineStyles: Map<number, string> | undefined;\n\n if (pluginOptions.inlineStylesExtension !== 'css') {\n const styleStrings = extractInlineStyles(code, id);\n\n if (styleStrings.length > 0) {\n resolvedInlineStyles = new Map();\n for (let i = 0; i < styleStrings.length; i++) {\n try {\n const fakePath = id.replace(\n /\\.ts$/,\n `.inline-${i}.${pluginOptions.inlineStylesExtension}`,\n );\n // In tests, mirror Vitest's `test.css` rules — defaults to no\n // preprocessing (matches Vite's CSS pipeline behavior). (#2297)\n if (!shouldPreprocessTestCss(resolvedConfig, fakePath)) {\n resolvedInlineStyles.set(i, styleStrings[i]);\n continue;\n }\n const processed = await preprocessCSS(\n styleStrings[i],\n fakePath,\n resolvedConfig,\n );\n resolvedInlineStyles.set(i, processed.code);\n } catch (e) {\n if (debugCompile.enabled) {\n debugCompile(\n 'inline style #%d preprocessing failed in %s: %s',\n i,\n id,\n (e as Error)?.message,\n );\n }\n // Skip styles that can't be preprocessed\n }\n }\n if (resolvedInlineStyles.size === 0) resolvedInlineStyles = undefined;\n }\n }\n\n ensureDtsRegistryForSource(code, id);\n\n const result = compile(code, id, {\n registry,\n resolvedStyles,\n resolvedInlineStyles,\n useDefineForClassFields,\n compilationMode: pluginOptions.fastCompileMode,\n });\n\n // Track resource dependencies for HMR\n for (const dep of result.resourceDependencies) {\n resourceToSource.set(dep, id);\n }\n\n // Strip TypeScript-only syntax\n const stripped = vite.transformWithOxc\n ? await vite.transformWithOxc(result.code, id, {\n lang: 'ts',\n sourcemap: false,\n decorator: { legacy: false, emitDecoratorMetadata: false },\n })\n : await vite.transformWithEsbuild(result.code, id, {\n loader: 'ts',\n sourcemap: false,\n });\n let outputCode = stripped.code;\n\n // Append HMR code in dev mode\n if (watchMode && pluginOptions.liveReload) {\n const fileDeclarations = [...registry.values()].filter(\n (e) => e.fileName === id,\n );\n if (fileDeclarations.length > 0) {\n const localDepClassNames = fileDeclarations.map((e) => e.className);\n outputCode += generateHmrCode(fileDeclarations, localDepClassNames);\n }\n }\n\n return { code: outputCode, map: result.map };\n }\n\n function resolveTsConfigPath() {\n const { root, isProd, isLib } = tsConfigResolutionContext!;\n return getTsConfigPath(\n root,\n pluginOptions.tsconfigGetter(),\n isProd,\n pluginOptions.isTest,\n isLib,\n );\n }\n\n return {\n name: '@analogjs/vite-plugin-angular-fast-compile',\n enforce: 'pre' as const,\n async config(config, { command }) {\n watchMode = command === 'serve';\n const isProd =\n config.mode === 'production' ||\n process.env['NODE_ENV'] === 'production';\n\n tsConfigResolutionContext = {\n root: config.root || '.',\n isProd,\n isLib: !!config?.build?.lib,\n };\n\n const preliminaryTsConfigPath = resolveTsConfigPath();\n\n const depOptimizer = createDepOptimizerConfig({\n tsconfig: preliminaryTsConfigPath,\n isProd,\n jit: pluginOptions.jit,\n watchMode,\n isTest: pluginOptions.isTest,\n isAstroIntegration: pluginOptions.isAstroIntegration,\n });\n\n return {\n ...(vite.rolldownVersion ? { oxc: {} as any } : { esbuild: false }),\n ...depOptimizer,\n resolve: {\n conditions: [\n ...depOptimizer.resolve.conditions,\n ...(config.resolve?.conditions || defaultClientConditions),\n ],\n },\n };\n },\n configResolved(config) {\n resolvedConfig = config;\n },\n configureServer(server) {\n // Watch for new .ts files and scan them into the registry. Use\n // the barrel-aware scanner so a newly added re-export entry\n // (`export * from './x'`) also expands its underlying directive\n // classes — otherwise the registry stays stale until restart.\n server.watcher.on('add', async (filePath) => {\n if (\n filePath.endsWith('.ts') &&\n !filePath.endsWith('.spec.ts') &&\n !filePath.endsWith('.d.ts')\n ) {\n await scanBarrelExports(filePath, new Set(), true);\n }\n });\n },\n async buildStart() {\n await initFastCompile();\n },\n async handleHotUpdate(ctx) {\n // Resource file changes → invalidate parent .ts module\n if (resourceToSource.has(ctx.file)) {\n const parentSource = resourceToSource.get(ctx.file)!;\n const parentModule = ctx.server.moduleGraph.getModuleById(parentSource);\n if (parentModule) {\n return [parentModule];\n }\n }\n\n if (TS_EXT_REGEX.test(ctx.file)) {\n const [fileId] = ctx.file.split('?');\n\n // Remove old entries from this file\n const oldEntries = [...registry.entries()]\n .filter(([_, v]) => v.fileName === fileId)\n .map(([k]) => k);\n for (const key of oldEntries) {\n registry.delete(key);\n }\n\n // Rescan the changed file via the barrel-aware scanner so an\n // edited barrel re-export picks up newly-referenced files.\n // Pass overwrite=true so updated metadata replaces stale\n // entries from the previous scan.\n await scanBarrelExports(fileId, new Set(), true);\n }\n\n // Let Vite handle the rest — the transform hook will recompile\n return ctx.modules;\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 const rawRewrite = rewriteHtmlRawImport(id, importer);\n if (rawRewrite) return rawRewrite;\n\n const inlineRewrite = rewriteInlineStyleImport(id, importer);\n if (inlineRewrite) return inlineRewrite;\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 bypass: module-runner skips resolveId, so the bare `?inline`\n // query reaches load unchanged.\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 // In tests, mirror Vitest's `test.css` rules — defaults to no\n // preprocessing (matches Vite's CSS pipeline behavior). (#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\n return;\n },\n transform: {\n filter: {\n id: {\n include: [TS_EXT_REGEX],\n exclude: [/node_modules/, 'type=script', '@ng/component'],\n },\n },\n async handler(code, id) {\n if (\n pluginOptions.transformFilter &&\n !(pluginOptions.transformFilter(code, id) ?? true)\n ) {\n return;\n }\n\n if (id.includes('.ts?')) {\n id = id.replace(/\\?(.*)/, '');\n }\n return handleFastCompileTransform(code, id);\n },\n },\n };\n}\n"],"mappings":"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"}
@@ -3,12 +3,14 @@ export declare const debugHmr: unknown;
3
3
  export declare const debugStyles: unknown;
4
4
  export declare const debugCompiler: unknown;
5
5
  export declare const debugCompilationApi: unknown;
6
+ export declare const debugEmit: unknown;
6
7
  export declare const debugStylePipeline: unknown;
7
8
  export declare const debugTailwindV: unknown;
8
9
  export declare const debugHmrV: unknown;
9
10
  export declare const debugStylesV: unknown;
10
11
  export declare const debugCompilerV: unknown;
11
- export type DebugScope = "analog:angular:*" | "analog:angular:hmr" | "analog:angular:hmr:v" | "analog:angular:styles" | "analog:angular:styles:v" | "analog:angular:compiler" | "analog:angular:compiler:v" | "analog:angular:compilation-api" | "analog:angular:style-pipeline" | "analog:angular:tailwind" | "analog:angular:tailwind:v" | (string & {});
12
+ export declare const debugEmitV: unknown;
13
+ export type DebugScope = "analog:angular:*" | "analog:angular:hmr" | "analog:angular:hmr:v" | "analog:angular:styles" | "analog:angular:styles:v" | "analog:angular:compiler" | "analog:angular:compiler:v" | "analog:angular:compilation-api" | "analog:angular:emit" | "analog:angular:emit:v" | "analog:angular:style-pipeline" | "analog:angular:tailwind" | "analog:angular:tailwind:v" | (string & {});
12
14
  export type DebugMode = "build" | "dev";
13
15
  export interface DebugModeOptions {
14
16
  scopes?: boolean | DebugScope[];
@@ -6,11 +6,13 @@ var debugHmr = createDebug("analog:angular:hmr");
6
6
  var debugStyles = createDebug("analog:angular:styles");
7
7
  var debugCompiler = createDebug("analog:angular:compiler");
8
8
  var debugCompilationApi = createDebug("analog:angular:compilation-api");
9
+ var debugEmit = createDebug("analog:angular:emit");
9
10
  var debugStylePipeline = createDebug("analog:angular:style-pipeline");
10
11
  var debugTailwindV = createDebug("analog:angular:tailwind:v");
11
12
  var debugHmrV = createDebug("analog:angular:hmr:v");
12
13
  var debugStylesV = createDebug("analog:angular:styles:v");
13
14
  var debugCompilerV = createDebug("analog:angular:compiler:v");
15
+ var debugEmitV = createDebug("analog:angular:emit:v");
14
16
  var harness = createDebugHarness({
15
17
  fallbackNamespace: "analog:angular:*",
16
18
  instanceGroups: [[
@@ -19,17 +21,19 @@ var harness = createDebugHarness({
19
21
  debugStyles,
20
22
  debugCompiler,
21
23
  debugCompilationApi,
24
+ debugEmit,
22
25
  debugStylePipeline,
23
26
  debugTailwindV,
24
27
  debugHmrV,
25
28
  debugStylesV,
26
- debugCompilerV
29
+ debugCompilerV,
30
+ debugEmitV
27
31
  ]]
28
32
  });
29
33
  var applyDebugOption = harness.applyDebugOption;
30
34
  var activateDeferredDebug = harness.activateDeferredDebug;
31
35
  harness._resetDeferredDebug;
32
36
  //#endregion
33
- export { activateDeferredDebug, applyDebugOption, debugCompilationApi, debugCompiler, debugCompilerV, debugHmr, debugHmrV, debugStylePipeline, debugStyles, debugStylesV, debugTailwind, debugTailwindV };
37
+ export { activateDeferredDebug, applyDebugOption, debugCompilationApi, debugCompiler, debugCompilerV, debugEmit, debugEmitV, debugHmr, debugHmrV, debugStylePipeline, debugStyles, debugStylesV, debugTailwind, debugTailwindV };
34
38
 
35
39
  //# sourceMappingURL=debug.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"debug.js","names":[],"sources":["../../../../src/lib/utils/debug.ts"],"sourcesContent":["import { createDebug } from 'obug';\nimport { createDebugHarness } from './debug-harness.js';\n\n// Normal — key decisions, once per startup or per component\nexport const debugTailwind = createDebug('analog:angular:tailwind');\nexport const debugHmr = createDebug('analog:angular:hmr');\nexport const debugStyles = createDebug('analog:angular:styles');\nexport const debugCompiler = createDebug('analog:angular:compiler');\nexport const debugCompilationApi = createDebug(\n 'analog:angular:compilation-api',\n);\nexport const debugStylePipeline = createDebug('analog:angular:style-pipeline');\n\n// Verbose — per-file detail, enable with :v suffix or parent:*\nexport const debugTailwindV = createDebug('analog:angular:tailwind:v');\nexport const debugHmrV = createDebug('analog:angular:hmr:v');\nexport const debugStylesV = createDebug('analog:angular:styles:v');\nexport const debugCompilerV = createDebug('analog:angular:compiler:v');\n\nconst angularDebugInstances = [\n debugTailwind,\n debugHmr,\n debugStyles,\n debugCompiler,\n debugCompilationApi,\n debugStylePipeline,\n debugTailwindV,\n debugHmrV,\n debugStylesV,\n debugCompilerV,\n];\n\nexport type DebugScope =\n | 'analog:angular:*'\n | 'analog:angular:hmr'\n | 'analog:angular:hmr:v'\n | 'analog:angular:styles'\n | 'analog:angular:styles:v'\n | 'analog:angular:compiler'\n | 'analog:angular:compiler:v'\n | 'analog:angular:compilation-api'\n | 'analog:angular:style-pipeline'\n | 'analog:angular:tailwind'\n | 'analog:angular:tailwind:v'\n | (string & {});\n\nexport type DebugMode = 'build' | 'dev';\n\nexport interface DebugModeOptions {\n scopes?: boolean | DebugScope[];\n mode?: DebugMode;\n /**\n * Write debug output to log files under `tmp/debug/` in the workspace root.\n * - `true` or `'single'` — all output to `tmp/debug/analog.log`\n * - `'scoped'` — one file per scope, e.g. `tmp/debug/analog.angular.hmr.log`\n */\n logFile?: boolean | 'single' | 'scoped';\n}\n\nexport type DebugOption =\n | boolean\n | DebugScope[]\n | DebugModeOptions\n | DebugModeOptions[];\n\nconst harness = createDebugHarness({\n fallbackNamespace: 'analog:angular:*',\n instanceGroups: [angularDebugInstances],\n});\n\nexport const applyDebugOption: (\n debug: DebugOption | undefined,\n workspaceRoot?: string,\n) => void = harness.applyDebugOption;\nexport const activateDeferredDebug: (command: 'build' | 'serve') => void =\n harness.activateDeferredDebug;\nexport const _resetDeferredDebug: () => void = harness._resetDeferredDebug;\n"],"mappings":";;;AAIA,IAAa,gBAAgB,YAAY,0BAA0B;AACnE,IAAa,WAAW,YAAY,qBAAqB;AACzD,IAAa,cAAc,YAAY,wBAAwB;AAC/D,IAAa,gBAAgB,YAAY,0BAA0B;AACnE,IAAa,sBAAsB,YACjC,iCACD;AACD,IAAa,qBAAqB,YAAY,gCAAgC;AAG9E,IAAa,iBAAiB,YAAY,4BAA4B;AACtE,IAAa,YAAY,YAAY,uBAAuB;AAC5D,IAAa,eAAe,YAAY,0BAA0B;AAClE,IAAa,iBAAiB,YAAY,4BAA4B;AAgDtE,IAAM,UAAU,mBAAmB;CACjC,mBAAmB;CACnB,gBAAgB,CAhDY;EAC5B;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAqCwC;CACxC,CAAC;AAEF,IAAa,mBAGD,QAAQ;AACpB,IAAa,wBACX,QAAQ;AACqC,QAAQ"}
1
+ {"version":3,"file":"debug.js","names":[],"sources":["../../../../src/lib/utils/debug.ts"],"sourcesContent":["import { createDebug } from 'obug';\nimport { createDebugHarness } from './debug-harness.js';\n\n// Normal — key decisions, once per startup or per component\nexport const debugTailwind = createDebug('analog:angular:tailwind');\nexport const debugHmr = createDebug('analog:angular:hmr');\nexport const debugStyles = createDebug('analog:angular:styles');\nexport const debugCompiler = createDebug('analog:angular:compiler');\nexport const debugCompilationApi = createDebug(\n 'analog:angular:compilation-api',\n);\nexport const debugEmit = createDebug('analog:angular:emit');\nexport const debugStylePipeline = createDebug('analog:angular:style-pipeline');\n\n// Verbose — per-file detail, enable with :v suffix or parent:*\nexport const debugTailwindV = createDebug('analog:angular:tailwind:v');\nexport const debugHmrV = createDebug('analog:angular:hmr:v');\nexport const debugStylesV = createDebug('analog:angular:styles:v');\nexport const debugCompilerV = createDebug('analog:angular:compiler:v');\nexport const debugEmitV = createDebug('analog:angular:emit:v');\n\nconst angularDebugInstances = [\n debugTailwind,\n debugHmr,\n debugStyles,\n debugCompiler,\n debugCompilationApi,\n debugEmit,\n debugStylePipeline,\n debugTailwindV,\n debugHmrV,\n debugStylesV,\n debugCompilerV,\n debugEmitV,\n];\n\nexport type DebugScope =\n | 'analog:angular:*'\n | 'analog:angular:hmr'\n | 'analog:angular:hmr:v'\n | 'analog:angular:styles'\n | 'analog:angular:styles:v'\n | 'analog:angular:compiler'\n | 'analog:angular:compiler:v'\n | 'analog:angular:compilation-api'\n | 'analog:angular:emit'\n | 'analog:angular:emit:v'\n | 'analog:angular:style-pipeline'\n | 'analog:angular:tailwind'\n | 'analog:angular:tailwind:v'\n | (string & {});\n\nexport type DebugMode = 'build' | 'dev';\n\nexport interface DebugModeOptions {\n scopes?: boolean | DebugScope[];\n mode?: DebugMode;\n /**\n * Write debug output to log files under `tmp/debug/` in the workspace root.\n * - `true` or `'single'` — all output to `tmp/debug/analog.log`\n * - `'scoped'` — one file per scope, e.g. `tmp/debug/analog.angular.hmr.log`\n */\n logFile?: boolean | 'single' | 'scoped';\n}\n\nexport type DebugOption =\n | boolean\n | DebugScope[]\n | DebugModeOptions\n | DebugModeOptions[];\n\nconst harness = createDebugHarness({\n fallbackNamespace: 'analog:angular:*',\n instanceGroups: [angularDebugInstances],\n});\n\nexport const applyDebugOption: (\n debug: DebugOption | undefined,\n workspaceRoot?: string,\n) => void = harness.applyDebugOption;\nexport const activateDeferredDebug: (command: 'build' | 'serve') => void =\n harness.activateDeferredDebug;\nexport const _resetDeferredDebug: () => void = harness._resetDeferredDebug;\n"],"mappings":";;;AAIA,IAAa,gBAAgB,YAAY,0BAA0B;AACnE,IAAa,WAAW,YAAY,qBAAqB;AACzD,IAAa,cAAc,YAAY,wBAAwB;AAC/D,IAAa,gBAAgB,YAAY,0BAA0B;AACnE,IAAa,sBAAsB,YACjC,iCACD;AACD,IAAa,YAAY,YAAY,sBAAsB;AAC3D,IAAa,qBAAqB,YAAY,gCAAgC;AAG9E,IAAa,iBAAiB,YAAY,4BAA4B;AACtE,IAAa,YAAY,YAAY,uBAAuB;AAC5D,IAAa,eAAe,YAAY,0BAA0B;AAClE,IAAa,iBAAiB,YAAY,4BAA4B;AACtE,IAAa,aAAa,YAAY,wBAAwB;AAoD9D,IAAM,UAAU,mBAAmB;CACjC,mBAAmB;CACnB,gBAAgB,CApDY;EAC5B;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAuCwC;CACxC,CAAC;AAEF,IAAa,mBAGD,QAAQ;AACpB,IAAa,wBACX,QAAQ;AACqC,QAAQ"}
@@ -3,6 +3,22 @@ interface PluginContextLike {
3
3
  addWatchFile(path: string): void;
4
4
  }
5
5
  /**
6
+ * True when the given stylesheet should be run through Vite's `preprocessCSS`,
7
+ * given Vitest's `test.css` semantics:
8
+ *
9
+ * - non-test contexts → always preprocess
10
+ * - `test.css: true` → always preprocess
11
+ * - `test.css: false` → never preprocess
12
+ * - `test.css: { include }` → preprocess only when `filePath` matches an
13
+ * include pattern and isn't excluded
14
+ * - `test.css` unset → Vitest defaults to `include: []`, so nothing
15
+ * matches and we don't preprocess
16
+ *
17
+ * Used to gate `preprocessCSS` calls in test mode so we don't surface SCSS
18
+ * deprecation noise or pay preprocessing cost the user didn't ask for. (#2297)
19
+ */
20
+ export declare function shouldPreprocessTestCss(config: ResolvedConfig | undefined, filePath?: string): boolean;
21
+ /**
6
22
  * Rewrite a user `.html?raw` import to a virtual raw id. Returns undefined
7
23
  * when the id doesn't match, so callers can fall through to the next check.
8
24
  *
@@ -4,6 +4,33 @@ import { dirname, isAbsolute, resolve } from "node:path";
4
4
  import { normalizePath, preprocessCSS } from "vite";
5
5
  //#region packages/vite-plugin-angular/src/lib/utils/virtual-resources.ts
6
6
  var INLINE_STYLE_QUERY_RE = /\.(css|scss|sass|less)\?inline$/;
7
+ /**
8
+ * True when the given stylesheet should be run through Vite's `preprocessCSS`,
9
+ * given Vitest's `test.css` semantics:
10
+ *
11
+ * - non-test contexts → always preprocess
12
+ * - `test.css: true` → always preprocess
13
+ * - `test.css: false` → never preprocess
14
+ * - `test.css: { include }` → preprocess only when `filePath` matches an
15
+ * include pattern and isn't excluded
16
+ * - `test.css` unset → Vitest defaults to `include: []`, so nothing
17
+ * matches and we don't preprocess
18
+ *
19
+ * Used to gate `preprocessCSS` calls in test mode so we don't surface SCSS
20
+ * deprecation noise or pay preprocessing cost the user didn't ask for. (#2297)
21
+ */
22
+ function shouldPreprocessTestCss(config, filePath) {
23
+ if (!(process.env.NODE_ENV === "test" || !!process.env["VITEST"])) return true;
24
+ const cssOpt = config?.test?.css;
25
+ if (cssOpt === true) return true;
26
+ if (cssOpt === false || cssOpt == null) return false;
27
+ const toArray = (value) => value == null ? [] : Array.isArray(value) ? value : [value];
28
+ const include = toArray(cssOpt.include);
29
+ const exclude = toArray(cssOpt.exclude);
30
+ if (!filePath || include.length === 0) return false;
31
+ const matches = (patterns) => patterns.some((p) => typeof p === "string" ? filePath.includes(p) : p.test(filePath));
32
+ return matches(include) && !matches(exclude);
33
+ }
7
34
  function resolveImportPath(id, importer) {
8
35
  const filePath = id.split("?")[0];
9
36
  return isAbsolute(filePath) ? normalizePath(filePath) : importer ? normalizePath(resolve(dirname(importer), filePath)) : void 0;
@@ -51,10 +78,12 @@ async function loadVirtualStyleModule(ctx, id, resolvedConfig) {
51
78
  if (!isVirtualStyleId(id)) return void 0;
52
79
  const filePath = fromVirtualStyleId(id);
53
80
  ctx.addWatchFile(filePath);
54
- const result = await preprocessCSS(await promises.readFile(filePath, "utf-8"), filePath, resolvedConfig);
81
+ const code = await promises.readFile(filePath, "utf-8");
82
+ if (!shouldPreprocessTestCss(resolvedConfig, filePath)) return `export default ${JSON.stringify(code)}`;
83
+ const result = await preprocessCSS(code, filePath, resolvedConfig);
55
84
  return `export default ${JSON.stringify(result.code)}`;
56
85
  }
57
86
  //#endregion
58
- export { loadVirtualRawModule, loadVirtualStyleModule, rewriteHtmlRawImport, rewriteInlineStyleImport };
87
+ export { loadVirtualRawModule, loadVirtualStyleModule, rewriteHtmlRawImport, rewriteInlineStyleImport, shouldPreprocessTestCss };
59
88
 
60
89
  //# 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// analog-compiler-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\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 const result = await preprocessCSS(code, filePath, resolvedConfig);\n return `export default ${JSON.stringify(result.code)}`;\n}\n"],"mappings":";;;;;AAkBA,IAAM,wBAAwB;AAM9B,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;CAE1B,MAAM,SAAS,MAAM,cADR,MAAM,SAAW,SAAS,UAAU,QAAQ,EAChB,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":";;;;;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 +0,0 @@
1
- {"version":3,"file":"analog-compiler-plugin.js","names":[],"sources":["../../../src/lib/analog-compiler-plugin.ts"],"sourcesContent":["import { promises as fsPromises } from 'node:fs';\nimport { dirname, resolve } from 'node:path';\nimport * as vite from 'vite';\n\nimport * as compilerCli from '@angular/compiler-cli';\nimport {\n defaultClientConditions,\n normalizePath,\n Plugin,\n preprocessCSS,\n ResolvedConfig,\n} from 'vite';\n\nimport {\n compile,\n scanFile,\n scanPackageDts,\n collectImportedPackages,\n collectRelativeReExports,\n jitTransform,\n inlineResourceUrls,\n extractInlineStyles,\n generateHmrCode,\n debugCompile,\n debugRegistry,\n type ComponentRegistry,\n} from '@analogjs/angular-compiler';\n\nimport {\n TS_EXT_REGEX,\n getTsConfigPath,\n createDepOptimizerConfig,\n type TsConfigResolutionContext,\n} from './utils/plugin-config.js';\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 rewriteHtmlRawImport,\n rewriteInlineStyleImport,\n} from './utils/virtual-resources.js';\n\nexport interface AnalogCompilerPluginOptions {\n tsconfigGetter: () => string;\n workspaceRoot: string;\n inlineStylesExtension: string;\n jit: boolean;\n liveReload: boolean;\n supportedBrowsers: string[];\n transformFilter?: (code: string, id: string) => boolean;\n isTest: boolean;\n isAstroIntegration: boolean;\n analogCompilationMode?: 'full' | 'partial';\n}\n\nexport function analogCompilerPlugin(\n pluginOptions: AnalogCompilerPluginOptions,\n): Plugin {\n let resolvedConfig: ResolvedConfig;\n let tsConfigResolutionContext: TsConfigResolutionContext | null = null;\n let watchMode = false;\n\n // Analog compiler state\n const analogRegistry: ComponentRegistry = new Map();\n const analogResourceToSource = new Map<string, string>();\n const scannedDtsPackages = new Set<string>();\n let analogProjectRoot = '';\n let useDefineForClassFields = true;\n\n /**\n * Scan a file into the registry, then recursively walk its relative\n * `export *` / `export { … } from './x'` chain so any underlying\n * directive classes also land in the registry. Used both at\n * `buildStart` (for tsconfig path entries) and at dev time (file\n * `add` and `handleHotUpdate`) so newly added barrels stay in sync\n * without requiring a server restart.\n *\n * The `visited` set prevents infinite recursion within a single\n * top-level call. Each fresh scan should pass an empty set (so HMR\n * re-scans aren't blocked by buildStart's earlier visits).\n */\n async function scanBarrelExports(\n file: string,\n visited: Set<string> = new Set(),\n overwrite = false,\n ): Promise<void> {\n if (visited.has(file)) return;\n visited.add(file);\n let code: string;\n try {\n code = await fsPromises.readFile(file, 'utf-8');\n } catch (e) {\n if (debugRegistry.enabled) {\n debugRegistry(\n 'scanBarrelExports: failed to read %s: %s',\n file,\n (e as Error)?.message,\n );\n }\n return;\n }\n const entries = scanFile(code, file);\n for (const entry of entries) {\n // At buildStart we want stable registry entries (don't overwrite\n // an earlier scan with a barrel re-scan); HMR explicitly asks\n // for overwrite so updated metadata replaces stale entries.\n if (overwrite || !analogRegistry.has(entry.className)) {\n analogRegistry.set(entry.className, entry);\n }\n }\n // Collect every relative re-export specifier via OXC AST so\n // recursive scans can't trip over each other (a shared `/g` regex\n // would have its `lastIndex` reset by each recursive call and\n // silently skip half of an outer barrel's re-exports, which\n // previously left directives like `HlmRadioGroup` unregistered).\n const dir = dirname(file);\n for (const rel of collectRelativeReExports(code, file)) {\n // NodeNext-style libraries write `export * from './foo.js'`\n // even though the source is `./foo.ts`. Strip the ESM\n // extension before probing or the candidates would be\n // `foo.js.ts` / `foo.js/index.ts`, which never exist.\n const normalizedRel = rel.replace(/\\.(?:js|mjs)$/u, '');\n const reExportCandidates = [\n resolve(dir, normalizedRel + '.ts'),\n resolve(dir, normalizedRel, 'index.ts'),\n ];\n let resolved = false;\n for (const candidate of reExportCandidates) {\n try {\n await fsPromises.access(candidate);\n await scanBarrelExports(candidate, visited, overwrite);\n resolved = true;\n break;\n } catch {\n // try next candidate\n }\n }\n if (!resolved && debugRegistry.enabled) {\n debugRegistry(\n 'scanBarrelExports: %s re-export %s did not resolve to %o',\n file,\n rel,\n reExportCandidates,\n );\n }\n }\n }\n\n async function initAnalogCompiler() {\n if (pluginOptions.jit) return; // JIT: no registry scan needed\n\n // Scan all source files to build the registry\n analogRegistry.clear();\n scannedDtsPackages.clear();\n const resolvedTsConfigPath = resolveTsConfigPath();\n analogProjectRoot = dirname(resolvedTsConfigPath);\n const config = compilerCli.readConfiguration(resolvedTsConfigPath);\n useDefineForClassFields = config.options?.useDefineForClassFields ?? true;\n\n // Collect candidate files: tsconfig rootNames PLUS the entry points\n // named in `compilerOptions.paths`. App tsconfigs typically only\n // include the app's own sources, so workspace library entry barrels\n // (e.g. `HlmSelectImports = [HlmSelect, HlmSelectContent, ...] as\n // const`) live outside `rootNames` and would otherwise miss the\n // initial scan. The compiler then can't see that `HlmSelectImports`\n // is a tuple barrel and emits the bare identifier into the parent\n // component's `dependencies()` list, where Angular's runtime\n // silently drops it because arrays don't have a directive def.\n const candidates = new Set<string>(config.rootNames);\n const tsPaths = config.options?.paths;\n const baseUrl = (config.options?.baseUrl ?? analogProjectRoot) as string;\n if (tsPaths) {\n for (const targets of Object.values(tsPaths)) {\n for (const target of targets as string[]) {\n // Skip wildcard patterns — entry barrels are normally exact\n // file paths like \"libs/helm/select/src/index.ts\".\n if (target.includes('*')) continue;\n candidates.add(resolve(baseUrl, target));\n }\n }\n }\n const results = await Promise.all(\n Array.from(candidates).map(async (file) => {\n try {\n const code = await fsPromises.readFile(file, 'utf-8');\n return scanFile(code, file);\n } catch (e) {\n if (debugRegistry.enabled) {\n debugRegistry(\n 'initAnalogCompiler: skipping unreadable %s: %s',\n file,\n (e as Error)?.message,\n );\n }\n return []; // Skip unreadable files\n }\n }),\n );\n\n for (const entries of results) {\n for (const entry of entries) {\n analogRegistry.set(entry.className, entry);\n }\n }\n\n // Library barrels typically `export * from './lib/...'` rather than\n // declaring directives directly, so the entry file alone gives us\n // the tuple consts but not the directive classes they reference.\n // Walk the relative `export *` chain so the underlying classes also\n // land in the registry. Use a SHARED visited set across all\n // barrels so recursive walks don't double-scan a file that's\n // re-exported from multiple entry points.\n const buildStartVisited = new Set<string>();\n if (tsPaths) {\n const barrelCandidates: string[] = [];\n for (const targets of Object.values(tsPaths)) {\n for (const target of targets as string[]) {\n if (target.includes('*')) continue;\n barrelCandidates.push(resolve(baseUrl, target));\n }\n }\n await Promise.all(\n barrelCandidates.map((c) => scanBarrelExports(c, buildStartVisited)),\n );\n }\n debugRegistry(\n 'initAnalogCompiler done: %d entries from %d candidate files',\n analogRegistry.size,\n candidates.size,\n );\n }\n\n function ensureDtsRegistryForSource(code: string, id: string) {\n for (const pkg of collectImportedPackages(code, id)) {\n if (scannedDtsPackages.has(pkg)) continue;\n scannedDtsPackages.add(pkg);\n\n try {\n const dtsEntries = scanPackageDts(pkg, analogProjectRoot);\n for (const entry of dtsEntries) {\n if (!analogRegistry.has(entry.className)) {\n analogRegistry.set(entry.className, entry);\n }\n }\n } catch {\n // Package may not have .d.ts files or may not be Angular\n }\n }\n }\n\n async function handleAnalogCompilerTransform(\n code: string,\n id: string,\n ): Promise<{ code: string; map: any } | undefined> {\n if (!/(Component|Directive|Pipe|Injectable|NgModule)\\(/.test(code)) {\n // Non-Angular file — leave it alone so a downstream plugin (or\n // Vite's built-in TS handler) can process it.\n return undefined;\n }\n\n // JIT mode\n if (pluginOptions.jit) {\n const result = jitTransform(code, id);\n return { code: result.code, map: result.map };\n }\n\n // Inline external templateUrl/styleUrl(s) into the source before compilation\n code = inlineResourceUrls(code, id);\n\n // Pre-resolve inline styles that need preprocessing (SCSS/Sass/Less)\n let resolvedStyles: Map<string, string> | undefined;\n let resolvedInlineStyles: Map<number, string> | undefined;\n\n if (pluginOptions.inlineStylesExtension !== 'css') {\n const styleStrings = extractInlineStyles(code, id);\n\n if (styleStrings.length > 0) {\n resolvedInlineStyles = new Map();\n for (let i = 0; i < styleStrings.length; i++) {\n try {\n const fakePath = id.replace(\n /\\.ts$/,\n `.inline-${i}.${pluginOptions.inlineStylesExtension}`,\n );\n const processed = await preprocessCSS(\n styleStrings[i],\n fakePath,\n resolvedConfig,\n );\n resolvedInlineStyles.set(i, processed.code);\n } catch (e) {\n if (debugCompile.enabled) {\n debugCompile(\n 'inline style #%d preprocessing failed in %s: %s',\n i,\n id,\n (e as Error)?.message,\n );\n }\n // Skip styles that can't be preprocessed\n }\n }\n if (resolvedInlineStyles.size === 0) resolvedInlineStyles = undefined;\n }\n }\n\n ensureDtsRegistryForSource(code, id);\n\n const result = compile(code, id, {\n registry: analogRegistry,\n resolvedStyles,\n resolvedInlineStyles,\n useDefineForClassFields,\n compilationMode: pluginOptions.analogCompilationMode,\n });\n\n // Track resource dependencies for HMR\n for (const dep of result.resourceDependencies) {\n analogResourceToSource.set(dep, id);\n }\n\n // Strip TypeScript-only syntax\n const stripped = vite.transformWithOxc\n ? await vite.transformWithOxc(result.code, id, {\n lang: 'ts',\n sourcemap: false,\n decorator: { legacy: false, emitDecoratorMetadata: false },\n })\n : await vite.transformWithEsbuild(result.code, id, {\n loader: 'ts',\n sourcemap: false,\n });\n let outputCode = stripped.code;\n\n // Append HMR code in dev mode\n if (watchMode && pluginOptions.liveReload) {\n const fileDeclarations = [...analogRegistry.values()].filter(\n (e) => e.fileName === id,\n );\n if (fileDeclarations.length > 0) {\n const localDepClassNames = fileDeclarations.map((e) => e.className);\n outputCode += generateHmrCode(fileDeclarations, localDepClassNames);\n }\n }\n\n return { code: outputCode, map: result.map };\n }\n\n function resolveTsConfigPath() {\n const { root, isProd, isLib } = tsConfigResolutionContext!;\n return getTsConfigPath(\n root,\n pluginOptions.tsconfigGetter(),\n isProd,\n pluginOptions.isTest,\n isLib,\n );\n }\n\n return {\n name: '@analogjs/vite-plugin-angular-compiler',\n enforce: 'pre' as const,\n async config(config, { command }) {\n watchMode = command === 'serve';\n const isProd =\n config.mode === 'production' ||\n process.env['NODE_ENV'] === 'production';\n\n tsConfigResolutionContext = {\n root: config.root || '.',\n isProd,\n isLib: !!config?.build?.lib,\n };\n\n const preliminaryTsConfigPath = resolveTsConfigPath();\n\n const depOptimizer = createDepOptimizerConfig({\n tsconfig: preliminaryTsConfigPath,\n isProd,\n jit: pluginOptions.jit,\n watchMode,\n isTest: pluginOptions.isTest,\n isAstroIntegration: pluginOptions.isAstroIntegration,\n });\n\n return {\n ...(vite.rolldownVersion ? { oxc: {} as any } : { esbuild: false }),\n ...depOptimizer,\n resolve: {\n conditions: [\n ...depOptimizer.resolve.conditions,\n ...(config.resolve?.conditions || defaultClientConditions),\n ],\n },\n };\n },\n configResolved(config) {\n resolvedConfig = config;\n },\n configureServer(server) {\n // Watch for new .ts files and scan them into the registry. Use\n // the barrel-aware scanner so a newly added re-export entry\n // (`export * from './x'`) also expands its underlying directive\n // classes — otherwise the registry stays stale until restart.\n server.watcher.on('add', async (filePath) => {\n if (\n filePath.endsWith('.ts') &&\n !filePath.endsWith('.spec.ts') &&\n !filePath.endsWith('.d.ts')\n ) {\n await scanBarrelExports(filePath, new Set(), true);\n }\n });\n },\n async buildStart() {\n await initAnalogCompiler();\n },\n async handleHotUpdate(ctx) {\n // Resource file changes → invalidate parent .ts module\n if (analogResourceToSource.has(ctx.file)) {\n const parentSource = analogResourceToSource.get(ctx.file)!;\n const parentModule = ctx.server.moduleGraph.getModuleById(parentSource);\n if (parentModule) {\n return [parentModule];\n }\n }\n\n if (TS_EXT_REGEX.test(ctx.file)) {\n const [fileId] = ctx.file.split('?');\n\n // Remove old entries from this file\n const oldEntries = [...analogRegistry.entries()]\n .filter(([_, v]) => v.fileName === fileId)\n .map(([k]) => k);\n for (const key of oldEntries) {\n analogRegistry.delete(key);\n }\n\n // Rescan the changed file via the barrel-aware scanner so an\n // edited barrel re-export picks up newly-referenced files.\n // Pass overwrite=true so updated metadata replaces stale\n // entries from the previous scan.\n await scanBarrelExports(fileId, new Set(), true);\n }\n\n // Let Vite handle the rest — the transform hook will recompile\n return ctx.modules;\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 const rawRewrite = rewriteHtmlRawImport(id, importer);\n if (rawRewrite) return rawRewrite;\n\n const inlineRewrite = rewriteInlineStyleImport(id, importer);\n if (inlineRewrite) return inlineRewrite;\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 bypass: module-runner skips resolveId, so the bare `?inline`\n // query reaches load unchanged.\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 const result = await preprocessCSS(code, filePath, resolvedConfig);\n return `export default ${JSON.stringify(result.code)}`;\n }\n\n return;\n },\n transform: {\n filter: {\n id: {\n include: [TS_EXT_REGEX],\n exclude: [/node_modules/, 'type=script', '@ng/component'],\n },\n },\n async handler(code, id) {\n if (\n pluginOptions.transformFilter &&\n !(pluginOptions.transformFilter(code, id) ?? true)\n ) {\n return;\n }\n\n if (id.includes('.ts?')) {\n id = id.replace(/\\?(.*)/, '');\n }\n return handleAnalogCompilerTransform(code, id);\n },\n },\n };\n}\n"],"mappings":"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"}