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

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.
@@ -1,7 +1,6 @@
1
1
  import { angularFullVersion, createAngularCompilation, sourceFileCache } from "../utils/devkit.js";
2
2
  import { activateDeferredDebug, debugCompilationApi, debugCompiler, debugEmit, debugHmr, debugHmrV, debugStyles } from "../utils/debug.js";
3
3
  import { isTailwindReferenceError } from "../utils/tailwind-reference.js";
4
- import { shouldPreprocessTestCss } from "../utils/virtual-resources.js";
5
4
  import { normalizeStylesheetDependencies } from "../style-preprocessor.js";
6
5
  import { AnalogStylesheetRegistry, preprocessStylesheetResult, registerStylesheetContent, rewriteRelativeCssImports } from "../stylesheet-registry.js";
7
6
  import { TS_EXT_REGEX, getTsConfigPath } from "../utils/plugin-config.js";
@@ -140,7 +139,6 @@ function compilationAPIPlugin(pluginOptions) {
140
139
  resourceFile: resourceFile ?? "(inline)",
141
140
  dataLength: preprocessed.code.length
142
141
  });
143
- if (!shouldPreprocessTestCss(resolvedConfig, filename)) return "";
144
142
  let stylesheetResult;
145
143
  try {
146
144
  stylesheetResult = await preprocessCSS(preprocessed.code, `${filename}?direct`, resolvedConfig);
@@ -1 +1 @@
1
- {"version":3,"file":"compilation-api-plugin.js","names":[],"sources":["../../../../src/lib/compilation-api/compilation-api-plugin.ts"],"sourcesContent":["import { type createAngularCompilation as createAngularCompilationType } from '@angular/build/private';\nimport { union } from 'es-toolkit';\nimport { createHash } from 'node:crypto';\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport {\n basename,\n dirname,\n isAbsolute,\n join,\n relative,\n resolve,\n} from 'node:path';\nimport { createRequire } from 'node:module';\nimport {\n normalizePath,\n Plugin,\n preprocessCSS,\n ResolvedConfig,\n ViteDevServer,\n} from 'vite';\n\nimport {\n createAngularCompilation,\n SourceFileCache,\n angularFullVersion,\n} from '../utils/devkit.js';\nimport {\n activateDeferredDebug,\n debugCompilationApi,\n debugCompiler,\n debugEmit,\n debugHmr,\n debugHmrV,\n debugStyles,\n type DebugOption,\n} from '../utils/debug.js';\nimport {\n getTsConfigPath,\n TS_EXT_REGEX,\n type TsConfigResolutionContext,\n} from '../utils/plugin-config.js';\nimport { TsconfigResolver } from '../utils/tsconfig-resolver.js';\nimport { shouldPreprocessTestCss } from '../utils/virtual-resources.js';\nimport { isTailwindReferenceError } from '../utils/tailwind-reference.js';\nimport {\n AnalogStylesheetRegistry,\n preprocessStylesheetResult,\n registerStylesheetContent,\n rewriteRelativeCssImports,\n} from '../stylesheet-registry.js';\nimport { normalizeStylesheetDependencies } from '../style-preprocessor.js';\nimport type { StylePreprocessor } from '../style-preprocessor.js';\nimport {\n AngularStylePipelineOptions,\n configureStylePipelineRegistry,\n} from '../style-pipeline.js';\nimport { type FileReplacement } from '../plugins/file-replacements.plugin.js';\nimport type { EmitFileResult } from '../models.js';\nimport type { SourceFileCache as SourceFileCacheType } from '../utils/source-file-cache.js';\nimport {\n injectViteIgnoreForHmrMetadata,\n isIgnoredHmrFile,\n toAngularCompilationFileReplacements,\n mapTemplateUpdatesToFiles,\n refreshStylesheetRegistryForFile,\n DiagnosticModes,\n isTestWatchMode,\n} from '../utils/compilation-shared.js';\n\nconst require = createRequire(import.meta.url);\nconst ts = require('typescript');\n\nexport interface CompilationAPIPluginOptions {\n tsconfigGetter: () => string;\n workspaceRoot: string;\n inlineStylesExtension: string;\n jit: boolean;\n liveReload: boolean;\n disableTypeChecking: boolean;\n supportedBrowsers: string[];\n transformFilter?: (code: string, id: string) => boolean;\n fileReplacements: FileReplacement[];\n stylePreprocessor?: StylePreprocessor;\n stylePipeline?: AngularStylePipelineOptions;\n hasTailwindCss: boolean;\n tailwindCss?: {\n rootStylesheet: string;\n prefixes?: string[];\n };\n isTest: boolean;\n isAstroIntegration: boolean;\n include: string[];\n additionalContentDirs: string[];\n debug?: DebugOption;\n}\n\nexport function compilationAPIPlugin(\n pluginOptions: CompilationAPIPluginOptions,\n): Plugin {\n let resolvedConfig: ResolvedConfig;\n let tsConfigResolutionContext: TsConfigResolutionContext | null = null;\n let watchMode = false;\n\n // Persistent compilation instance — kept alive across rebuilds so Angular\n // can diff prior state and emit `templateUpdates` for HMR.\n let angularCompilation:\n | Awaited<ReturnType<typeof createAngularCompilationType>>\n | undefined;\n const sourceFileCache: SourceFileCacheType = new SourceFileCache();\n const outputFiles = new Map<string, EmitFileResult>();\n const classNames = new Map<string, string>();\n let stylesheetRegistry: AnalogStylesheetRegistry | undefined;\n let compilationLock = Promise.resolve();\n let pendingCompilation: Promise<void> | null = null;\n let initialCompilation = false;\n let viteServer: ViteDevServer | undefined;\n\n const isTest = process.env['NODE_ENV'] === 'test' || !!process.env['VITEST'];\n const tsconfigResolver = new TsconfigResolver({\n workspaceRoot: pluginOptions.workspaceRoot,\n include: pluginOptions.include,\n liveReload: pluginOptions.liveReload,\n hasTailwindCss: pluginOptions.hasTailwindCss,\n isTest,\n });\n const isVitestVscode = !!process.env['VITEST_VSCODE'];\n let testWatchMode = isTestWatchMode();\n\n function hasViteHmrTransport(): boolean {\n return resolvedConfig ? resolvedConfig.server.hmr !== false : true;\n }\n\n function shouldEnableLiveReload(): boolean {\n const effectiveWatchMode = isTest ? testWatchMode : watchMode;\n return !!(\n effectiveWatchMode &&\n pluginOptions.liveReload &&\n hasViteHmrTransport()\n );\n }\n\n function shouldExternalizeStyles(): boolean {\n const effectiveWatchMode = isTest ? testWatchMode : watchMode;\n if (!effectiveWatchMode) return false;\n return !!(shouldEnableLiveReload() || pluginOptions.hasTailwindCss);\n }\n\n function resolveTsConfigPath() {\n const tsconfigValue = pluginOptions.tsconfigGetter();\n return getTsConfigPath(\n tsConfigResolutionContext!.root,\n tsconfigValue,\n tsConfigResolutionContext!.isProd,\n isTest,\n tsConfigResolutionContext!.isLib,\n );\n }\n\n function resolveCompilationApiTsConfigPath(\n resolvedTsConfigPath: string,\n config: ResolvedConfig,\n ): string {\n const includedFiles = tsconfigResolver.ensureIncludeCache();\n const cached = tsconfigResolver.getCachedTsconfigOptions(\n resolvedTsConfigPath,\n config,\n );\n const expandedGraphRoots = tsconfigResolver.collectExpandedTsconfigRoots(\n resolvedTsConfigPath,\n config,\n );\n const mergedRootNames = union(\n cached.rootNames,\n expandedGraphRoots,\n includedFiles,\n ).map((file) => normalizePath(file));\n\n if (mergedRootNames.length === cached.rootNames.length) {\n return resolvedTsConfigPath;\n }\n\n const resolvedCacheDir = isAbsolute(config.cacheDir)\n ? config.cacheDir\n : resolve(config.root, config.cacheDir);\n const wrapperDir = join(\n resolvedCacheDir,\n 'analog-angular',\n 'compilation-api',\n );\n const rawTsconfig = (ts.readConfigFile(\n resolvedTsConfigPath,\n ts.sys.readFile,\n ).config ?? {}) as { references?: unknown[] };\n const wrapperPayload = {\n extends: normalizePath(resolvedTsConfigPath),\n files: [...mergedRootNames].sort(),\n ...(rawTsconfig.references ? { references: rawTsconfig.references } : {}),\n };\n const wrapperHash = createHash('sha1')\n .update(JSON.stringify(wrapperPayload))\n .digest('hex')\n .slice(0, 12);\n const wrapperPath = join(\n wrapperDir,\n `tsconfig.includes.${wrapperHash}.json`,\n );\n\n mkdirSync(wrapperDir, { recursive: true });\n if (!existsSync(wrapperPath)) {\n writeFileSync(\n wrapperPath,\n `${JSON.stringify(wrapperPayload, null, 2)}\\n`,\n 'utf-8',\n );\n }\n\n debugCompilationApi('generated include wrapper tsconfig', {\n originalTsconfig: resolvedTsConfigPath,\n wrapperTsconfig: wrapperPath,\n includeCount: includedFiles.length,\n rootNameCount: mergedRootNames.length,\n });\n\n return wrapperPath;\n }\n\n const normalizeEmitterLookupId = (file: string) => {\n const normalizedFile = normalizePath(file);\n if (!normalizedFile.startsWith('/@fs/')) return normalizedFile;\n const fsPath = normalizedFile\n .slice('/@fs'.length)\n .replace(/^\\/([A-Za-z]:\\/)/, '$1');\n return normalizePath(fsPath);\n };\n\n let outputFile: ((file: string) => void) | undefined;\n const fileEmitter = (file: string) => {\n const normalizedFile = normalizeEmitterLookupId(file);\n outputFile?.(normalizedFile);\n return outputFiles.get(normalizedFile);\n };\n\n async function performAngularCompilation(\n config: ResolvedConfig,\n ids?: string[],\n ) {\n const compilation = (angularCompilation ??= await (\n createAngularCompilation as typeof createAngularCompilationType\n )(!!pluginOptions.jit, false));\n const modifiedFiles = ids?.length\n ? new Set(ids.map((file) => normalizePath(file)))\n : undefined;\n if (modifiedFiles?.size) {\n sourceFileCache.invalidate(modifiedFiles);\n }\n if (modifiedFiles?.size && compilation.update) {\n debugCompilationApi('incremental update', {\n files: [...modifiedFiles],\n });\n await compilation.update(modifiedFiles);\n }\n\n const resolvedTsConfigPath = resolveTsConfigPath();\n const compilationApiTsConfigPath = resolveCompilationApiTsConfigPath(\n resolvedTsConfigPath,\n config,\n );\n debugEmit('compilation initialize', {\n resolvedTsConfigPath,\n compilationApiTsConfigPath,\n modifiedFileCount: modifiedFiles?.size ?? 0,\n });\n const compilationResult = await compilation.initialize(\n compilationApiTsConfigPath,\n {\n fileReplacements: toAngularCompilationFileReplacements(\n pluginOptions.fileReplacements,\n pluginOptions.workspaceRoot,\n ),\n modifiedFiles,\n async transformStylesheet(\n data: string,\n containingFile: string,\n resourceFile: string | null,\n order: number,\n className: string | null,\n ) {\n const filename =\n resourceFile ??\n containingFile.replace(\n '.ts',\n `.${pluginOptions.inlineStylesExtension}`,\n );\n\n const preprocessed = preprocessStylesheetResult(\n data,\n filename,\n pluginOptions.stylePreprocessor,\n {\n filename,\n containingFile,\n resourceFile,\n className,\n order,\n inline: !resourceFile,\n },\n );\n\n if (shouldEnableLiveReload() && className && containingFile) {\n classNames.set(normalizePath(containingFile), className as string);\n }\n\n if (shouldExternalizeStyles()) {\n const stylesheetId = registerStylesheetContent(\n stylesheetRegistry!,\n {\n code: preprocessed.code,\n dependencies: normalizeStylesheetDependencies(\n preprocessed.dependencies,\n ),\n diagnostics: preprocessed.diagnostics,\n tags: preprocessed.tags,\n containingFile,\n className: className as string | undefined,\n order,\n inlineStylesExtension: pluginOptions.inlineStylesExtension,\n resourceFile: resourceFile ?? undefined,\n },\n );\n\n debugStyles('stylesheet deferred to Vite pipeline', {\n stylesheetId,\n resourceFile: resourceFile ?? '(inline)',\n });\n\n return stylesheetId;\n }\n\n debugStyles('stylesheet processed inline via preprocessCSS', {\n filename,\n resourceFile: resourceFile ?? '(inline)',\n dataLength: preprocessed.code.length,\n });\n if (!shouldPreprocessTestCss(resolvedConfig, filename)) {\n return '';\n }\n\n let stylesheetResult;\n try {\n stylesheetResult = await preprocessCSS(\n preprocessed.code,\n `${filename}?direct`,\n resolvedConfig,\n );\n } catch (e) {\n if (isTailwindReferenceError(e)) {\n throw e;\n }\n debugStyles('preprocessCSS error', {\n filename,\n resourceFile: resourceFile ?? '(inline)',\n error: String(e),\n });\n }\n\n return stylesheetResult?.code || '';\n },\n processWebWorker(_workerFile: string, _containingFile: string) {\n return '';\n },\n },\n (tsCompilerOptions: Record<string, unknown>) => {\n if (shouldExternalizeStyles()) {\n tsCompilerOptions['externalRuntimeStyles'] = true;\n }\n\n if (shouldEnableLiveReload()) {\n tsCompilerOptions['_enableHmr'] = true;\n tsCompilerOptions['supportTestBed'] = true;\n }\n\n debugCompiler('tsCompilerOptions (compilation API)', {\n liveReload: pluginOptions.liveReload,\n viteHmr: hasViteHmrTransport(),\n hasTailwindCss: pluginOptions.hasTailwindCss,\n watchMode,\n shouldExternalize: shouldExternalizeStyles(),\n externalRuntimeStyles: !!tsCompilerOptions['externalRuntimeStyles'],\n hmrEnabled: !!tsCompilerOptions['_enableHmr'],\n });\n\n if (tsCompilerOptions['compilationMode'] === 'partial') {\n tsCompilerOptions['supportTestBed'] = true;\n tsCompilerOptions['supportJitMode'] = true;\n }\n\n if (!isTest && resolvedConfig.build?.lib) {\n tsCompilerOptions['declaration'] = true;\n tsCompilerOptions['declarationMap'] = watchMode;\n tsCompilerOptions['inlineSources'] = true;\n }\n\n if (isTest) {\n tsCompilerOptions['supportTestBed'] = true;\n }\n\n return tsCompilerOptions;\n },\n );\n\n // Preprocess external stylesheets for Tailwind CSS @reference\n debugStyles('external stylesheets from compilation API', {\n count: compilationResult.externalStylesheets?.size ?? 0,\n hasPreprocessor: !!pluginOptions.stylePreprocessor,\n hasInlineMap: !!stylesheetRegistry,\n });\n const preprocessStats = { total: 0, injected: 0, skipped: 0, errors: 0 };\n for (const [key, value] of compilationResult.externalStylesheets ?? []) {\n preprocessStats.total++;\n const angularHash = `${value}.css`;\n stylesheetRegistry?.registerExternalRequest(angularHash, key);\n\n if (\n stylesheetRegistry &&\n pluginOptions.stylePreprocessor &&\n existsSync(key)\n ) {\n try {\n const rawCss = readFileSync(key, 'utf-8');\n const preprocessed = preprocessStylesheetResult(\n rawCss,\n key,\n pluginOptions.stylePreprocessor,\n );\n const servedCss = rewriteRelativeCssImports(preprocessed.code, key);\n stylesheetRegistry.registerServedStylesheet(\n {\n publicId: angularHash,\n sourcePath: key,\n originalCode: rawCss,\n normalizedCode: servedCss,\n dependencies: normalizeStylesheetDependencies(\n preprocessed.dependencies,\n ),\n diagnostics: preprocessed.diagnostics,\n tags: preprocessed.tags,\n },\n [key, normalizePath(key), basename(key), key.replace(/^\\//, '')],\n );\n\n if (servedCss && servedCss !== rawCss) {\n preprocessStats.injected++;\n } else {\n preprocessStats.skipped++;\n }\n } catch (e) {\n preprocessStats.errors++;\n console.warn(\n `[@analogjs/vite-plugin-angular] failed to preprocess external stylesheet: ${key}: ${e}`,\n );\n }\n } else {\n preprocessStats.skipped++;\n }\n }\n debugStyles('external stylesheet preprocessing complete', preprocessStats);\n\n const diagnostics = await compilation.diagnoseFiles(\n pluginOptions.disableTypeChecking\n ? DiagnosticModes.All & ~DiagnosticModes.Semantic\n : DiagnosticModes.All,\n );\n\n const errors = diagnostics.errors?.length ? diagnostics.errors : [];\n const warnings = diagnostics.warnings?.length ? diagnostics.warnings : [];\n\n const templateUpdates = mapTemplateUpdatesToFiles(\n compilationResult.templateUpdates,\n );\n if (templateUpdates.size > 0) {\n debugHmr('compilation API template updates', {\n count: templateUpdates.size,\n files: [...templateUpdates.keys()],\n });\n }\n\n const affectedFiles = await compilation.emitAffectedFiles();\n debugEmit('emitAffectedFiles summary', {\n count: affectedFiles.length,\n templateUpdateCount: templateUpdates.size,\n knownOutputCountBefore: outputFiles.size,\n });\n\n for (const file of affectedFiles) {\n const normalizedFilename = normalizePath(file.filename);\n const templateUpdate = templateUpdates.get(normalizedFilename);\n\n if (templateUpdate) {\n classNames.set(normalizedFilename, templateUpdate.className);\n }\n\n outputFiles.set(normalizedFilename, {\n content: file.contents,\n dependencies: [],\n errors: errors.map((error: { text?: string }) => error.text || ''),\n warnings: warnings.map(\n (warning: { text?: string }) => warning.text || '',\n ),\n hmrUpdateCode: templateUpdate?.code,\n hmrEligible: !!templateUpdate?.code,\n });\n }\n }\n\n async function performCompilation(config: ResolvedConfig, ids?: string[]) {\n let resolve: (() => unknown) | undefined;\n const previousLock = compilationLock;\n compilationLock = new Promise<void>((r) => {\n resolve = r;\n });\n try {\n await previousLock;\n await performAngularCompilation(config, ids);\n } finally {\n resolve!();\n }\n }\n\n function isComponentStyleSheet(id: string): boolean {\n return id.includes('ngcomp=');\n }\n\n function getFilenameFromPath(id: string): string {\n try {\n return new URL(id, 'http://localhost').pathname.replace(/^\\//, '');\n } catch {\n const queryIndex = id.indexOf('?');\n const pathname = queryIndex >= 0 ? id.slice(0, queryIndex) : id;\n return pathname.replace(/^\\//, '');\n }\n }\n\n function sendHMRComponentUpdate(server: ViteDevServer, id: string) {\n debugHmrV('ws send: angular component update', {\n id,\n timestamp: Date.now(),\n });\n server.ws.send('angular:component-update', {\n id: encodeURIComponent(id),\n timestamp: Date.now(),\n });\n classNames.delete(id);\n }\n\n return {\n name: '@analogjs/vite-plugin-angular-compilation-api',\n enforce: 'pre' as const,\n async config(config, { command }) {\n activateDeferredDebug(command);\n watchMode = command === 'serve';\n const isProd =\n config.mode === 'production' ||\n process.env['NODE_ENV'] === 'production';\n\n tsConfigResolutionContext = {\n root: config.root || '.',\n isProd,\n isLib: !!config?.build?.lib,\n };\n\n if (angularFullVersion < 200100) {\n console.warn(\n '[@analogjs/vite-plugin-angular]: The Angular Compilation API is only available with Angular v20.1 and later',\n );\n } else {\n debugCompilationApi('enabled (Angular %s)', angularFullVersion);\n }\n\n // Angular Compilation API handles TypeScript transforms — disable\n // esbuild/oxc so they don't compete.\n debugCompilationApi('esbuild/oxc disabled, Angular handles transforms');\n\n return {\n esbuild: undefined,\n oxc: undefined,\n optimizeDeps: {\n include: ['rxjs/operators', 'rxjs', 'tslib'],\n exclude: ['@angular/platform-server'],\n },\n resolve: {\n conditions: ['style', ...(config.resolve?.conditions ?? [])],\n },\n };\n },\n configResolved(config) {\n resolvedConfig = config;\n\n stylesheetRegistry = new AnalogStylesheetRegistry();\n configureStylePipelineRegistry(\n pluginOptions.stylePipeline,\n stylesheetRegistry,\n { workspaceRoot: pluginOptions.workspaceRoot },\n );\n debugStyles('stylesheet registry initialized (Angular Compilation API)');\n\n if (isTest) {\n testWatchMode =\n !(config.server.watch === null) ||\n (config as any).test?.watch === true ||\n testWatchMode;\n }\n },\n configureServer(server) {\n viteServer = server;\n\n const invalidateCompilation = async () => {\n tsconfigResolver.invalidateAll();\n await performCompilation(resolvedConfig);\n };\n server.watcher.on('add', invalidateCompilation);\n server.watcher.on('unlink', invalidateCompilation);\n server.watcher.on('change', (file) => {\n if (file.includes('tsconfig')) {\n tsconfigResolver.invalidateTsconfigCaches();\n }\n });\n },\n async buildStart() {\n if (!isVitestVscode) {\n await performCompilation(resolvedConfig);\n pendingCompilation = null;\n initialCompilation = true;\n }\n },\n async handleHotUpdate(ctx) {\n if (isIgnoredHmrFile(ctx.file)) {\n debugHmr('ignored file change', { file: ctx.file });\n return [];\n }\n\n if (TS_EXT_REGEX.test(ctx.file)) {\n const [fileId] = ctx.file.split('?');\n debugHmr('TS file changed', { file: ctx.file, fileId });\n\n pendingCompilation = performCompilation(resolvedConfig, [fileId]);\n\n let result;\n\n if (shouldEnableLiveReload()) {\n await pendingCompilation;\n pendingCompilation = null;\n result = fileEmitter(fileId);\n debugHmr('TS file emitted', {\n fileId,\n hmrEligible: !!result?.hmrEligible,\n hasClassName: !!classNames.get(fileId),\n });\n }\n\n if (\n shouldEnableLiveReload() &&\n result?.hmrEligible &&\n classNames.get(fileId)\n ) {\n const relativeFileId = `${normalizePath(\n relative(process.cwd(), fileId),\n )}@${classNames.get(fileId)}`;\n\n debugHmr('sending component update', { relativeFileId });\n sendHMRComponentUpdate(ctx.server, relativeFileId);\n\n return ctx.modules.map((mod) => {\n if (mod.id === ctx.file) {\n mod.isSelfAccepting = true;\n }\n return mod;\n });\n }\n }\n\n if (/\\.(html|htm)$/.test(ctx.file)) {\n debugHmr('template file changed', { file: ctx.file });\n // Recompile to pick up template changes\n pendingCompilation = performCompilation(resolvedConfig);\n }\n\n if (/\\.(css|less|sass|scss)$/.test(ctx.file)) {\n debugHmr('stylesheet file changed', { file: ctx.file });\n refreshStylesheetRegistryForFile(\n ctx.file,\n stylesheetRegistry,\n pluginOptions.stylePreprocessor,\n );\n }\n\n return ctx.modules;\n },\n resolveId(id) {\n // Map angular component stylesheets\n if (isComponentStyleSheet(id)) {\n const filename = getFilenameFromPath(id);\n\n if (stylesheetRegistry?.hasServed(filename)) {\n return id;\n }\n\n const componentStyles =\n stylesheetRegistry?.resolveExternalSource(filename);\n if (componentStyles) {\n return componentStyles + new URL(id, 'http://localhost').search;\n }\n }\n\n return undefined;\n },\n async load(id) {\n // Serve component stylesheets from registry\n if (isComponentStyleSheet(id)) {\n const filename = getFilenameFromPath(id);\n const componentStyles = stylesheetRegistry?.getServedContent(filename);\n if (componentStyles) {\n stylesheetRegistry?.registerActiveRequest(id);\n return componentStyles;\n }\n }\n\n return;\n },\n transform: {\n filter: {\n id: {\n include: [TS_EXT_REGEX],\n exclude: [/node_modules/, 'type=script', '@ng/component'],\n },\n },\n async handler(code, id) {\n if (\n pluginOptions.transformFilter &&\n !(pluginOptions.transformFilter(code, id) ?? true)\n ) {\n return;\n }\n\n // Skip non-Angular files — in compilation API mode, Angular\n // compiles TypeScript before this hook, so only Angular files\n // need processing.\n const isAngular =\n /(Component|Directive|Pipe|Injectable|NgModule)\\(/.test(code);\n if (!isAngular) {\n debugCompilationApi('transform skip (non-Angular file)', { id });\n return;\n }\n\n if (id.includes('?') && id.includes('analog-content-')) {\n return;\n }\n\n if (id.includes('.ts?')) {\n id = id.replace(/\\?(.*)/, '');\n }\n\n if (isTest) {\n if (isVitestVscode && !initialCompilation) {\n pendingCompilation = performCompilation(resolvedConfig);\n initialCompilation = true;\n }\n\n const tsMod = viteServer?.moduleGraph.getModuleById(id);\n if (tsMod) {\n const invalidated = tsMod.lastInvalidationTimestamp;\n if (testWatchMode && invalidated) {\n pendingCompilation = performCompilation(resolvedConfig, [id]);\n }\n }\n }\n\n if (pendingCompilation) {\n await pendingCompilation;\n pendingCompilation = null;\n }\n\n const typescriptResult = fileEmitter(id);\n if (!typescriptResult) {\n debugCompilationApi('transform skip (file not emitted)', { id });\n if (isAngular) {\n this.warn(\n `[@analogjs/vite-plugin-angular]: \"${id}\" contains Angular decorators but is not in the TypeScript program. ` +\n `Ensure it is included in your tsconfig.`,\n );\n }\n return;\n }\n\n if (typescriptResult.warnings && typescriptResult.warnings.length > 0) {\n this.warn(`${typescriptResult.warnings.join('\\n')}`);\n }\n\n if (typescriptResult.errors && typescriptResult.errors.length > 0) {\n this.error(`${typescriptResult.errors.join('\\n')}`);\n }\n\n let data = typescriptResult.content ?? '';\n\n // Re-inject @vite-ignore for Angular HMR dynamic imports\n if (data.includes('HmrLoad')) {\n const hasMetaUrl = data.includes('getReplaceMetadataURL');\n if (hasMetaUrl) {\n data = injectViteIgnoreForHmrMetadata(data);\n }\n }\n\n return {\n code: data,\n map: null,\n };\n },\n },\n closeBundle() {\n angularCompilation?.close?.();\n angularCompilation = undefined;\n },\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"compilation-api-plugin.js","names":[],"sources":["../../../../src/lib/compilation-api/compilation-api-plugin.ts"],"sourcesContent":["import { type createAngularCompilation as createAngularCompilationType } from '@angular/build/private';\nimport { union } from 'es-toolkit';\nimport { createHash } from 'node:crypto';\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { basename, isAbsolute, join, relative, resolve } from 'node:path';\nimport { createRequire } from 'node:module';\nimport {\n normalizePath,\n Plugin,\n preprocessCSS,\n ResolvedConfig,\n ViteDevServer,\n} from 'vite';\n\nimport {\n createAngularCompilation,\n SourceFileCache,\n angularFullVersion,\n} from '../utils/devkit.js';\nimport {\n activateDeferredDebug,\n debugCompilationApi,\n debugCompiler,\n debugEmit,\n debugHmr,\n debugHmrV,\n debugStyles,\n type DebugOption,\n} from '../utils/debug.js';\nimport {\n getTsConfigPath,\n TS_EXT_REGEX,\n type TsConfigResolutionContext,\n} from '../utils/plugin-config.js';\nimport { TsconfigResolver } from '../utils/tsconfig-resolver.js';\nimport { isTailwindReferenceError } from '../utils/tailwind-reference.js';\nimport {\n AnalogStylesheetRegistry,\n preprocessStylesheetResult,\n registerStylesheetContent,\n rewriteRelativeCssImports,\n} from '../stylesheet-registry.js';\nimport { normalizeStylesheetDependencies } from '../style-preprocessor.js';\nimport type { StylePreprocessor } from '../style-preprocessor.js';\nimport {\n AngularStylePipelineOptions,\n configureStylePipelineRegistry,\n} from '../style-pipeline.js';\nimport { type FileReplacement } from '../plugins/file-replacements.plugin.js';\nimport type { EmitFileResult } from '../models.js';\nimport type { SourceFileCache as SourceFileCacheType } from '../utils/source-file-cache.js';\nimport {\n injectViteIgnoreForHmrMetadata,\n isIgnoredHmrFile,\n toAngularCompilationFileReplacements,\n mapTemplateUpdatesToFiles,\n refreshStylesheetRegistryForFile,\n DiagnosticModes,\n isTestWatchMode,\n} from '../utils/compilation-shared.js';\n\nconst require = createRequire(import.meta.url);\nconst ts = require('typescript');\n\nexport interface CompilationAPIPluginOptions {\n tsconfigGetter: () => string;\n workspaceRoot: string;\n inlineStylesExtension: string;\n jit: boolean;\n liveReload: boolean;\n disableTypeChecking: boolean;\n supportedBrowsers: string[];\n transformFilter?: (code: string, id: string) => boolean;\n fileReplacements: FileReplacement[];\n stylePreprocessor?: StylePreprocessor;\n stylePipeline?: AngularStylePipelineOptions;\n hasTailwindCss: boolean;\n tailwindCss?: {\n rootStylesheet: string;\n prefixes?: string[];\n };\n isTest: boolean;\n isAstroIntegration: boolean;\n include: string[];\n additionalContentDirs: string[];\n debug?: DebugOption;\n}\n\nexport function compilationAPIPlugin(\n pluginOptions: CompilationAPIPluginOptions,\n): Plugin {\n let resolvedConfig: ResolvedConfig;\n let tsConfigResolutionContext: TsConfigResolutionContext | null = null;\n let watchMode = false;\n\n // Persistent compilation instance — kept alive across rebuilds so Angular\n // can diff prior state and emit `templateUpdates` for HMR.\n let angularCompilation:\n | Awaited<ReturnType<typeof createAngularCompilationType>>\n | undefined;\n const sourceFileCache: SourceFileCacheType = new SourceFileCache();\n const outputFiles = new Map<string, EmitFileResult>();\n const classNames = new Map<string, string>();\n let stylesheetRegistry: AnalogStylesheetRegistry | undefined;\n let compilationLock = Promise.resolve();\n let pendingCompilation: Promise<void> | null = null;\n let initialCompilation = false;\n let viteServer: ViteDevServer | undefined;\n\n const isTest = process.env['NODE_ENV'] === 'test' || !!process.env['VITEST'];\n const tsconfigResolver = new TsconfigResolver({\n workspaceRoot: pluginOptions.workspaceRoot,\n include: pluginOptions.include,\n liveReload: pluginOptions.liveReload,\n hasTailwindCss: pluginOptions.hasTailwindCss,\n isTest,\n });\n const isVitestVscode = !!process.env['VITEST_VSCODE'];\n let testWatchMode = isTestWatchMode();\n\n function hasViteHmrTransport(): boolean {\n return resolvedConfig ? resolvedConfig.server.hmr !== false : true;\n }\n\n function shouldEnableLiveReload(): boolean {\n const effectiveWatchMode = isTest ? testWatchMode : watchMode;\n return !!(\n effectiveWatchMode &&\n pluginOptions.liveReload &&\n hasViteHmrTransport()\n );\n }\n\n function shouldExternalizeStyles(): boolean {\n const effectiveWatchMode = isTest ? testWatchMode : watchMode;\n if (!effectiveWatchMode) return false;\n return !!(shouldEnableLiveReload() || pluginOptions.hasTailwindCss);\n }\n\n function resolveTsConfigPath() {\n const tsconfigValue = pluginOptions.tsconfigGetter();\n return getTsConfigPath(\n tsConfigResolutionContext!.root,\n tsconfigValue,\n tsConfigResolutionContext!.isProd,\n isTest,\n tsConfigResolutionContext!.isLib,\n );\n }\n\n function resolveCompilationApiTsConfigPath(\n resolvedTsConfigPath: string,\n config: ResolvedConfig,\n ): string {\n const includedFiles = tsconfigResolver.ensureIncludeCache();\n const cached = tsconfigResolver.getCachedTsconfigOptions(\n resolvedTsConfigPath,\n config,\n );\n const expandedGraphRoots = tsconfigResolver.collectExpandedTsconfigRoots(\n resolvedTsConfigPath,\n config,\n );\n const mergedRootNames = union(\n cached.rootNames,\n expandedGraphRoots,\n includedFiles,\n ).map((file) => normalizePath(file));\n\n if (mergedRootNames.length === cached.rootNames.length) {\n return resolvedTsConfigPath;\n }\n\n const resolvedCacheDir = isAbsolute(config.cacheDir)\n ? config.cacheDir\n : resolve(config.root, config.cacheDir);\n const wrapperDir = join(\n resolvedCacheDir,\n 'analog-angular',\n 'compilation-api',\n );\n const rawTsconfig = (ts.readConfigFile(\n resolvedTsConfigPath,\n ts.sys.readFile,\n ).config ?? {}) as { references?: unknown[] };\n const wrapperPayload = {\n extends: normalizePath(resolvedTsConfigPath),\n files: [...mergedRootNames].sort(),\n ...(rawTsconfig.references ? { references: rawTsconfig.references } : {}),\n };\n const wrapperHash = createHash('sha1')\n .update(JSON.stringify(wrapperPayload))\n .digest('hex')\n .slice(0, 12);\n const wrapperPath = join(\n wrapperDir,\n `tsconfig.includes.${wrapperHash}.json`,\n );\n\n mkdirSync(wrapperDir, { recursive: true });\n if (!existsSync(wrapperPath)) {\n writeFileSync(\n wrapperPath,\n `${JSON.stringify(wrapperPayload, null, 2)}\\n`,\n 'utf-8',\n );\n }\n\n debugCompilationApi('generated include wrapper tsconfig', {\n originalTsconfig: resolvedTsConfigPath,\n wrapperTsconfig: wrapperPath,\n includeCount: includedFiles.length,\n rootNameCount: mergedRootNames.length,\n });\n\n return wrapperPath;\n }\n\n const normalizeEmitterLookupId = (file: string) => {\n const normalizedFile = normalizePath(file);\n if (!normalizedFile.startsWith('/@fs/')) return normalizedFile;\n const fsPath = normalizedFile\n .slice('/@fs'.length)\n .replace(/^\\/([A-Za-z]:\\/)/, '$1');\n return normalizePath(fsPath);\n };\n\n let outputFile: ((file: string) => void) | undefined;\n const fileEmitter = (file: string) => {\n const normalizedFile = normalizeEmitterLookupId(file);\n outputFile?.(normalizedFile);\n return outputFiles.get(normalizedFile);\n };\n\n async function performAngularCompilation(\n config: ResolvedConfig,\n ids?: string[],\n ) {\n const compilation = (angularCompilation ??= await (\n createAngularCompilation as typeof createAngularCompilationType\n )(!!pluginOptions.jit, false));\n const modifiedFiles = ids?.length\n ? new Set(ids.map((file) => normalizePath(file)))\n : undefined;\n if (modifiedFiles?.size) {\n sourceFileCache.invalidate(modifiedFiles);\n }\n if (modifiedFiles?.size && compilation.update) {\n debugCompilationApi('incremental update', {\n files: [...modifiedFiles],\n });\n await compilation.update(modifiedFiles);\n }\n\n const resolvedTsConfigPath = resolveTsConfigPath();\n const compilationApiTsConfigPath = resolveCompilationApiTsConfigPath(\n resolvedTsConfigPath,\n config,\n );\n debugEmit('compilation initialize', {\n resolvedTsConfigPath,\n compilationApiTsConfigPath,\n modifiedFileCount: modifiedFiles?.size ?? 0,\n });\n const compilationResult = await compilation.initialize(\n compilationApiTsConfigPath,\n {\n fileReplacements: toAngularCompilationFileReplacements(\n pluginOptions.fileReplacements,\n pluginOptions.workspaceRoot,\n ),\n modifiedFiles,\n async transformStylesheet(\n data: string,\n containingFile: string,\n resourceFile: string | null,\n order: number,\n className: string | null,\n ) {\n const filename =\n resourceFile ??\n containingFile.replace(\n '.ts',\n `.${pluginOptions.inlineStylesExtension}`,\n );\n\n const preprocessed = preprocessStylesheetResult(\n data,\n filename,\n pluginOptions.stylePreprocessor,\n {\n filename,\n containingFile,\n resourceFile,\n className,\n order,\n inline: !resourceFile,\n },\n );\n\n if (shouldEnableLiveReload() && className && containingFile) {\n classNames.set(normalizePath(containingFile), className as string);\n }\n\n if (shouldExternalizeStyles()) {\n const stylesheetId = registerStylesheetContent(\n stylesheetRegistry!,\n {\n code: preprocessed.code,\n dependencies: normalizeStylesheetDependencies(\n preprocessed.dependencies,\n ),\n diagnostics: preprocessed.diagnostics,\n tags: preprocessed.tags,\n containingFile,\n className: className as string | undefined,\n order,\n inlineStylesExtension: pluginOptions.inlineStylesExtension,\n resourceFile: resourceFile ?? undefined,\n },\n );\n\n debugStyles('stylesheet deferred to Vite pipeline', {\n stylesheetId,\n resourceFile: resourceFile ?? '(inline)',\n });\n\n return stylesheetId;\n }\n\n debugStyles('stylesheet processed inline via preprocessCSS', {\n filename,\n resourceFile: resourceFile ?? '(inline)',\n dataLength: preprocessed.code.length,\n });\n\n let stylesheetResult;\n try {\n stylesheetResult = await preprocessCSS(\n preprocessed.code,\n `${filename}?direct`,\n resolvedConfig,\n );\n } catch (e) {\n if (isTailwindReferenceError(e)) {\n throw e;\n }\n debugStyles('preprocessCSS error', {\n filename,\n resourceFile: resourceFile ?? '(inline)',\n error: String(e),\n });\n }\n\n return stylesheetResult?.code || '';\n },\n processWebWorker(_workerFile: string, _containingFile: string) {\n return '';\n },\n },\n (tsCompilerOptions: Record<string, unknown>) => {\n if (shouldExternalizeStyles()) {\n tsCompilerOptions['externalRuntimeStyles'] = true;\n }\n\n if (shouldEnableLiveReload()) {\n tsCompilerOptions['_enableHmr'] = true;\n tsCompilerOptions['supportTestBed'] = true;\n }\n\n debugCompiler('tsCompilerOptions (compilation API)', {\n liveReload: pluginOptions.liveReload,\n viteHmr: hasViteHmrTransport(),\n hasTailwindCss: pluginOptions.hasTailwindCss,\n watchMode,\n shouldExternalize: shouldExternalizeStyles(),\n externalRuntimeStyles: !!tsCompilerOptions['externalRuntimeStyles'],\n hmrEnabled: !!tsCompilerOptions['_enableHmr'],\n });\n\n if (tsCompilerOptions['compilationMode'] === 'partial') {\n tsCompilerOptions['supportTestBed'] = true;\n tsCompilerOptions['supportJitMode'] = true;\n }\n\n if (!isTest && resolvedConfig.build?.lib) {\n tsCompilerOptions['declaration'] = true;\n tsCompilerOptions['declarationMap'] = watchMode;\n tsCompilerOptions['inlineSources'] = true;\n }\n\n if (isTest) {\n tsCompilerOptions['supportTestBed'] = true;\n }\n\n return tsCompilerOptions;\n },\n );\n\n // Preprocess external stylesheets for Tailwind CSS @reference\n debugStyles('external stylesheets from compilation API', {\n count: compilationResult.externalStylesheets?.size ?? 0,\n hasPreprocessor: !!pluginOptions.stylePreprocessor,\n hasInlineMap: !!stylesheetRegistry,\n });\n const preprocessStats = { total: 0, injected: 0, skipped: 0, errors: 0 };\n for (const [key, value] of compilationResult.externalStylesheets ?? []) {\n preprocessStats.total++;\n const angularHash = `${value}.css`;\n stylesheetRegistry?.registerExternalRequest(angularHash, key);\n\n if (\n stylesheetRegistry &&\n pluginOptions.stylePreprocessor &&\n existsSync(key)\n ) {\n try {\n const rawCss = readFileSync(key, 'utf-8');\n const preprocessed = preprocessStylesheetResult(\n rawCss,\n key,\n pluginOptions.stylePreprocessor,\n );\n const servedCss = rewriteRelativeCssImports(preprocessed.code, key);\n stylesheetRegistry.registerServedStylesheet(\n {\n publicId: angularHash,\n sourcePath: key,\n originalCode: rawCss,\n normalizedCode: servedCss,\n dependencies: normalizeStylesheetDependencies(\n preprocessed.dependencies,\n ),\n diagnostics: preprocessed.diagnostics,\n tags: preprocessed.tags,\n },\n [key, normalizePath(key), basename(key), key.replace(/^\\//, '')],\n );\n\n if (servedCss && servedCss !== rawCss) {\n preprocessStats.injected++;\n } else {\n preprocessStats.skipped++;\n }\n } catch (e) {\n preprocessStats.errors++;\n console.warn(\n `[@analogjs/vite-plugin-angular] failed to preprocess external stylesheet: ${key}: ${e}`,\n );\n }\n } else {\n preprocessStats.skipped++;\n }\n }\n debugStyles('external stylesheet preprocessing complete', preprocessStats);\n\n const diagnostics = await compilation.diagnoseFiles(\n pluginOptions.disableTypeChecking\n ? DiagnosticModes.All & ~DiagnosticModes.Semantic\n : DiagnosticModes.All,\n );\n\n const errors = diagnostics.errors?.length ? diagnostics.errors : [];\n const warnings = diagnostics.warnings?.length ? diagnostics.warnings : [];\n\n const templateUpdates = mapTemplateUpdatesToFiles(\n compilationResult.templateUpdates,\n );\n if (templateUpdates.size > 0) {\n debugHmr('compilation API template updates', {\n count: templateUpdates.size,\n files: [...templateUpdates.keys()],\n });\n }\n\n const affectedFiles = await compilation.emitAffectedFiles();\n debugEmit('emitAffectedFiles summary', {\n count: affectedFiles.length,\n templateUpdateCount: templateUpdates.size,\n knownOutputCountBefore: outputFiles.size,\n });\n\n for (const file of affectedFiles) {\n const normalizedFilename = normalizePath(file.filename);\n const templateUpdate = templateUpdates.get(normalizedFilename);\n\n if (templateUpdate) {\n classNames.set(normalizedFilename, templateUpdate.className);\n }\n\n outputFiles.set(normalizedFilename, {\n content: file.contents,\n dependencies: [],\n errors: errors.map((error: { text?: string }) => error.text || ''),\n warnings: warnings.map(\n (warning: { text?: string }) => warning.text || '',\n ),\n hmrUpdateCode: templateUpdate?.code,\n hmrEligible: !!templateUpdate?.code,\n });\n }\n }\n\n async function performCompilation(config: ResolvedConfig, ids?: string[]) {\n let resolve: (() => unknown) | undefined;\n const previousLock = compilationLock;\n compilationLock = new Promise<void>((r) => {\n resolve = r;\n });\n try {\n await previousLock;\n await performAngularCompilation(config, ids);\n } finally {\n resolve!();\n }\n }\n\n function isComponentStyleSheet(id: string): boolean {\n return id.includes('ngcomp=');\n }\n\n function getFilenameFromPath(id: string): string {\n try {\n return new URL(id, 'http://localhost').pathname.replace(/^\\//, '');\n } catch {\n const queryIndex = id.indexOf('?');\n const pathname = queryIndex >= 0 ? id.slice(0, queryIndex) : id;\n return pathname.replace(/^\\//, '');\n }\n }\n\n function sendHMRComponentUpdate(server: ViteDevServer, id: string) {\n debugHmrV('ws send: angular component update', {\n id,\n timestamp: Date.now(),\n });\n server.ws.send('angular:component-update', {\n id: encodeURIComponent(id),\n timestamp: Date.now(),\n });\n classNames.delete(id);\n }\n\n return {\n name: '@analogjs/vite-plugin-angular-compilation-api',\n enforce: 'pre' as const,\n async config(config, { command }) {\n activateDeferredDebug(command);\n watchMode = command === 'serve';\n const isProd =\n config.mode === 'production' ||\n process.env['NODE_ENV'] === 'production';\n\n tsConfigResolutionContext = {\n root: config.root || '.',\n isProd,\n isLib: !!config?.build?.lib,\n };\n\n if (angularFullVersion < 200100) {\n console.warn(\n '[@analogjs/vite-plugin-angular]: The Angular Compilation API is only available with Angular v20.1 and later',\n );\n } else {\n debugCompilationApi('enabled (Angular %s)', angularFullVersion);\n }\n\n // Angular Compilation API handles TypeScript transforms — disable\n // esbuild/oxc so they don't compete.\n debugCompilationApi('esbuild/oxc disabled, Angular handles transforms');\n\n return {\n esbuild: undefined,\n oxc: undefined,\n optimizeDeps: {\n include: ['rxjs/operators', 'rxjs', 'tslib'],\n exclude: ['@angular/platform-server'],\n },\n resolve: {\n conditions: ['style', ...(config.resolve?.conditions ?? [])],\n },\n };\n },\n configResolved(config) {\n resolvedConfig = config;\n\n stylesheetRegistry = new AnalogStylesheetRegistry();\n configureStylePipelineRegistry(\n pluginOptions.stylePipeline,\n stylesheetRegistry,\n { workspaceRoot: pluginOptions.workspaceRoot },\n );\n debugStyles('stylesheet registry initialized (Angular Compilation API)');\n\n if (isTest) {\n testWatchMode =\n !(config.server.watch === null) ||\n (config as any).test?.watch === true ||\n testWatchMode;\n }\n },\n configureServer(server) {\n viteServer = server;\n\n const invalidateCompilation = async () => {\n tsconfigResolver.invalidateAll();\n await performCompilation(resolvedConfig);\n };\n server.watcher.on('add', invalidateCompilation);\n server.watcher.on('unlink', invalidateCompilation);\n server.watcher.on('change', (file) => {\n if (file.includes('tsconfig')) {\n tsconfigResolver.invalidateTsconfigCaches();\n }\n });\n },\n async buildStart() {\n if (!isVitestVscode) {\n await performCompilation(resolvedConfig);\n pendingCompilation = null;\n initialCompilation = true;\n }\n },\n async handleHotUpdate(ctx) {\n if (isIgnoredHmrFile(ctx.file)) {\n debugHmr('ignored file change', { file: ctx.file });\n return [];\n }\n\n if (TS_EXT_REGEX.test(ctx.file)) {\n const [fileId] = ctx.file.split('?');\n debugHmr('TS file changed', { file: ctx.file, fileId });\n\n pendingCompilation = performCompilation(resolvedConfig, [fileId]);\n\n let result;\n\n if (shouldEnableLiveReload()) {\n await pendingCompilation;\n pendingCompilation = null;\n result = fileEmitter(fileId);\n debugHmr('TS file emitted', {\n fileId,\n hmrEligible: !!result?.hmrEligible,\n hasClassName: !!classNames.get(fileId),\n });\n }\n\n if (\n shouldEnableLiveReload() &&\n result?.hmrEligible &&\n classNames.get(fileId)\n ) {\n const relativeFileId = `${normalizePath(\n relative(process.cwd(), fileId),\n )}@${classNames.get(fileId)}`;\n\n debugHmr('sending component update', { relativeFileId });\n sendHMRComponentUpdate(ctx.server, relativeFileId);\n\n return ctx.modules.map((mod) => {\n if (mod.id === ctx.file) {\n mod.isSelfAccepting = true;\n }\n return mod;\n });\n }\n }\n\n if (/\\.(html|htm)$/.test(ctx.file)) {\n debugHmr('template file changed', { file: ctx.file });\n // Recompile to pick up template changes\n pendingCompilation = performCompilation(resolvedConfig);\n }\n\n if (/\\.(css|less|sass|scss)$/.test(ctx.file)) {\n debugHmr('stylesheet file changed', { file: ctx.file });\n refreshStylesheetRegistryForFile(\n ctx.file,\n stylesheetRegistry,\n pluginOptions.stylePreprocessor,\n );\n }\n\n return ctx.modules;\n },\n resolveId(id) {\n // Map angular component stylesheets\n if (isComponentStyleSheet(id)) {\n const filename = getFilenameFromPath(id);\n\n if (stylesheetRegistry?.hasServed(filename)) {\n return id;\n }\n\n const componentStyles =\n stylesheetRegistry?.resolveExternalSource(filename);\n if (componentStyles) {\n return componentStyles + new URL(id, 'http://localhost').search;\n }\n }\n\n return undefined;\n },\n async load(id) {\n // Serve component stylesheets from registry\n if (isComponentStyleSheet(id)) {\n const filename = getFilenameFromPath(id);\n const componentStyles = stylesheetRegistry?.getServedContent(filename);\n if (componentStyles) {\n stylesheetRegistry?.registerActiveRequest(id);\n return componentStyles;\n }\n }\n\n return;\n },\n transform: {\n filter: {\n id: {\n include: [TS_EXT_REGEX],\n exclude: [/node_modules/, 'type=script', '@ng/component'],\n },\n },\n async handler(code, id) {\n if (\n pluginOptions.transformFilter &&\n !(pluginOptions.transformFilter(code, id) ?? true)\n ) {\n return;\n }\n\n // Skip non-Angular files — in compilation API mode, Angular\n // compiles TypeScript before this hook, so only Angular files\n // need processing.\n const isAngular =\n /(Component|Directive|Pipe|Injectable|NgModule)\\(/.test(code);\n if (!isAngular) {\n debugCompilationApi('transform skip (non-Angular file)', { id });\n return;\n }\n\n if (id.includes('?') && id.includes('analog-content-')) {\n return;\n }\n\n if (id.includes('.ts?')) {\n id = id.replace(/\\?(.*)/, '');\n }\n\n if (isTest) {\n if (isVitestVscode && !initialCompilation) {\n pendingCompilation = performCompilation(resolvedConfig);\n initialCompilation = true;\n }\n\n const tsMod = viteServer?.moduleGraph.getModuleById(id);\n if (tsMod) {\n const invalidated = tsMod.lastInvalidationTimestamp;\n if (testWatchMode && invalidated) {\n pendingCompilation = performCompilation(resolvedConfig, [id]);\n }\n }\n }\n\n if (pendingCompilation) {\n await pendingCompilation;\n pendingCompilation = null;\n }\n\n const typescriptResult = fileEmitter(id);\n if (!typescriptResult) {\n debugCompilationApi('transform skip (file not emitted)', { id });\n if (isAngular) {\n this.warn(\n `[@analogjs/vite-plugin-angular]: \"${id}\" contains Angular decorators but is not in the TypeScript program. ` +\n `Ensure it is included in your tsconfig.`,\n );\n }\n return;\n }\n\n if (typescriptResult.warnings && typescriptResult.warnings.length > 0) {\n this.warn(`${typescriptResult.warnings.join('\\n')}`);\n }\n\n if (typescriptResult.errors && typescriptResult.errors.length > 0) {\n this.error(`${typescriptResult.errors.join('\\n')}`);\n }\n\n let data = typescriptResult.content ?? '';\n\n // Re-inject @vite-ignore for Angular HMR dynamic imports\n if (data.includes('HmrLoad')) {\n const hasMetaUrl = data.includes('getReplaceMetadataURL');\n if (hasMetaUrl) {\n data = injectViteIgnoreForHmrMetadata(data);\n }\n }\n\n return {\n code: data,\n map: null,\n };\n },\n },\n closeBundle() {\n angularCompilation?.close?.();\n angularCompilation = undefined;\n },\n };\n}\n"],"mappings":"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"}
@@ -1,4 +1,18 @@
1
1
  import { Plugin } from "vite";
2
+ import { type ComponentRegistry } from "./compiler/index.js";
3
+ declare global {
4
+ /**
5
+ * Shared convention for out-of-tree compilers (e.g. `@tsrx/analog`) that
6
+ * produce Angular Ivy definitions from a non-TS source format. Populate
7
+ * this map with directive/component metadata for any class fastCompile
8
+ * can't reach through its own tsconfig-driven scan, and the per-compile
9
+ * registry lookup in `fastCompilePlugin` will merge those entries in —
10
+ * so TS `@Component({ imports: [X] })` references to such classes
11
+ * resolve statically instead of hitting the `_unresolved-${className}`
12
+ * sentinel.
13
+ */
14
+ var __ANALOG_EXTERNAL_REGISTRY__: ComponentRegistry | undefined;
15
+ }
2
16
  export interface FastCompilePluginOptions {
3
17
  tsconfigGetter: () => string;
4
18
  workspaceRoot: string;
@@ -7,11 +7,14 @@ import { jitTransform } from "./compiler/jit-transform.js";
7
7
  import { generateHmrCode } from "./compiler/hmr.js";
8
8
  import { extractInlineStyles, inlineResourceUrls } from "./compiler/resource-inliner.js";
9
9
  import "./compiler/index.js";
10
+ import { toVirtualRawId } from "./utils/virtual-ids.js";
11
+ import { loadVirtualRawModule, rewriteHtmlRawImport } from "./utils/virtual-resources.js";
12
+ import { markStylePathSafe } from "./utils/safe-module-paths.js";
10
13
  import { promises } from "node:fs";
11
- import { dirname, resolve } from "node:path";
14
+ import { dirname, isAbsolute, resolve } from "node:path";
12
15
  import * as compilerCli from "@angular/compiler-cli";
13
16
  import * as vite from "vite";
14
- import { defaultClientConditions, preprocessCSS } from "vite";
17
+ import { defaultClientConditions, normalizePath, preprocessCSS } from "vite";
15
18
  //#region packages/vite-plugin-angular/src/lib/fast-compile-plugin.ts
16
19
  function fastCompilePlugin(pluginOptions) {
17
20
  let resolvedConfig;
@@ -123,10 +126,6 @@ function fastCompilePlugin(pluginOptions) {
123
126
  resolvedInlineStyles = /* @__PURE__ */ new Map();
124
127
  for (let i = 0; i < styleStrings.length; i++) try {
125
128
  const fakePath = id.replace(/\.ts$/, `.inline-${i}.${pluginOptions.inlineStylesExtension}`);
126
- if (!shouldPreprocessTestCss(resolvedConfig, fakePath)) {
127
- resolvedInlineStyles.set(i, styleStrings[i]);
128
- continue;
129
- }
130
129
  const processed = await preprocessCSS(styleStrings[i], fakePath, resolvedConfig);
131
130
  resolvedInlineStyles.set(i, processed.code);
132
131
  } catch (e) {
@@ -136,8 +135,14 @@ function fastCompilePlugin(pluginOptions) {
136
135
  }
137
136
  }
138
137
  ensureDtsRegistryForSource(code, id);
138
+ let compileRegistry = registry;
139
+ const externalRegistry = globalThis.__ANALOG_EXTERNAL_REGISTRY__;
140
+ if (externalRegistry && externalRegistry.size > 0) {
141
+ compileRegistry = new Map(registry);
142
+ for (const [k, v] of externalRegistry) compileRegistry.set(k, v);
143
+ }
139
144
  const result = compile(code, id, {
140
- registry,
145
+ registry: compileRegistry,
141
146
  resolvedStyles,
142
147
  resolvedInlineStyles,
143
148
  useDefineForClassFields,
@@ -221,6 +226,30 @@ function fastCompilePlugin(pluginOptions) {
221
226
  }
222
227
  return ctx.modules;
223
228
  },
229
+ resolveId(id, importer) {
230
+ if (id.startsWith("virtual:@analogjs/vite-plugin-angular:raw:")) return `\0${id}`;
231
+ if (pluginOptions.jit && id.startsWith("angular:jit:")) {
232
+ const filePath = normalizePath(resolve(dirname(importer), id.split(";")[1]));
233
+ if (id.includes(":style")) {
234
+ markStylePathSafe(resolvedConfig, filePath);
235
+ return filePath + "?inline";
236
+ }
237
+ return toVirtualRawId(filePath);
238
+ }
239
+ const rawRewrite = rewriteHtmlRawImport(id, importer);
240
+ if (rawRewrite) return rawRewrite;
241
+ if (/\.(css|scss|sass|less)\?inline$/.test(id) && importer) {
242
+ const filePath = id.split("?")[0];
243
+ const resolved = isAbsolute(filePath) ? normalizePath(filePath) : normalizePath(resolve(dirname(importer), filePath));
244
+ markStylePathSafe(resolvedConfig, resolved);
245
+ return resolved + "?inline";
246
+ }
247
+ },
248
+ async load(id) {
249
+ const rawModule = await loadVirtualRawModule(this, id);
250
+ if (rawModule !== void 0) return rawModule;
251
+ if (/\.(css|scss|sass|less)\?inline$/.test(id)) markStylePathSafe(resolvedConfig, id.split("?")[0]);
252
+ },
224
253
  transform: {
225
254
  filter: { id: {
226
255
  include: [TS_EXT_REGEX],
@@ -1 +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';\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 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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"}
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, isAbsolute, 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 { VIRTUAL_RAW_PREFIX, toVirtualRawId } from './utils/virtual-ids.js';\nimport {\n loadVirtualRawModule,\n rewriteHtmlRawImport,\n} from './utils/virtual-resources.js';\nimport { markStylePathSafe } from './utils/safe-module-paths.js';\n\ndeclare global {\n /**\n * Shared convention for out-of-tree compilers (e.g. `@tsrx/analog`) that\n * produce Angular Ivy definitions from a non-TS source format. Populate\n * this map with directive/component metadata for any class fastCompile\n * can't reach through its own tsconfig-driven scan, and the per-compile\n * registry lookup in `fastCompilePlugin` will merge those entries in —\n * so TS `@Component({ imports: [X] })` references to such classes\n * resolve statically instead of hitting the `_unresolved-${className}`\n * sentinel.\n */\n // eslint-disable-next-line no-var\n var __ANALOG_EXTERNAL_REGISTRY__: ComponentRegistry | undefined;\n}\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 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 // Merge entries from the shared external-registry global into this\n // compile's lookup view. Convention: out-of-tree compilers populate\n // `globalThis.__ANALOG_EXTERNAL_REGISTRY__` with directive metadata\n // for classes fastCompile can't reach through its tsconfig-driven\n // scan (e.g. `.tsrx` files compiled by `@tsrx/analog`). Without this\n // merge, a TS `@Component({ imports: [X] })` that references such a\n // class hits `_unresolved-${className}` as its selector and the tag\n // never matches at runtime.\n let compileRegistry: ComponentRegistry = registry;\n const externalRegistry = globalThis.__ANALOG_EXTERNAL_REGISTRY__;\n if (externalRegistry && externalRegistry.size > 0) {\n compileRegistry = new Map(registry);\n for (const [k, v] of externalRegistry) compileRegistry.set(k, v);\n }\n\n const result = compile(code, id, {\n registry: compileRegistry,\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 (id.startsWith(VIRTUAL_RAW_PREFIX)) {\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 if (id.includes(':style')) {\n markStylePathSafe(resolvedConfig, filePath);\n return filePath + '?inline';\n }\n return toVirtualRawId(filePath);\n }\n\n const rawRewrite = rewriteHtmlRawImport(id, importer);\n if (rawRewrite) return rawRewrite;\n\n // User `.scss?inline` / `.css?inline` imports: resolve and mark\n // safe so Vite's native CSS pipeline handles them.\n if (/\\.(css|scss|sass|less)\\?inline$/.test(id) && importer) {\n const filePath = id.split('?')[0];\n const resolved = isAbsolute(filePath)\n ? normalizePath(filePath)\n : normalizePath(resolve(dirname(importer), filePath));\n markStylePathSafe(resolvedConfig, resolved);\n return resolved + '?inline';\n }\n\n return undefined;\n },\n async load(id) {\n const rawModule = await loadVirtualRawModule(this, id);\n if (rawModule !== undefined) return rawModule;\n\n // Vitest fallback: module-runner can skip resolveId, so the bare\n // ?inline query reaches load. Mark safe and let Vite handle it.\n if (/\\.(css|scss|sass|less)\\?inline$/.test(id)) {\n markStylePathSafe(resolvedConfig, id.split('?')[0]);\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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"}
@@ -1,7 +1,14 @@
1
1
  /**
2
2
  * TypeScript file extension regex
3
- * Match .(c or m)ts, .ts extensions with an optional ? for query params
4
- * Ignore .tsx extensions
3
+ * Match .ts / .cts / .mts extensions with an optional ?query suffix.
4
+ * Reject .tsx — and any other `.ts<letter>…` extension like .tsrx — via
5
+ * a negative-lookahead on a following ASCII letter, so only genuine TS
6
+ * files pass.
7
+ *
8
+ * Previous form `/\.[cm]?(ts)[^x]?\??/` was intended to exclude `.tsx`
9
+ * specifically (`[^x]?` = not-an-x), but the `?` quantifier also allows
10
+ * zero characters, and any non-`x` letter was admitted — so `.tsrx`
11
+ * and similar extensions matched by accident.
5
12
  */
6
13
  export declare const TS_EXT_REGEX: unknown;
7
14
  export interface TsConfigResolutionContext {
@@ -5,10 +5,17 @@ import * as vite from "vite";
5
5
  //#region packages/vite-plugin-angular/src/lib/utils/plugin-config.ts
6
6
  /**
7
7
  * TypeScript file extension regex
8
- * Match .(c or m)ts, .ts extensions with an optional ? for query params
9
- * Ignore .tsx extensions
8
+ * Match .ts / .cts / .mts extensions with an optional ?query suffix.
9
+ * Reject .tsx — and any other `.ts<letter>…` extension like .tsrx — via
10
+ * a negative-lookahead on a following ASCII letter, so only genuine TS
11
+ * files pass.
12
+ *
13
+ * Previous form `/\.[cm]?(ts)[^x]?\??/` was intended to exclude `.tsx`
14
+ * specifically (`[^x]?` = not-an-x), but the `?` quantifier also allows
15
+ * zero characters, and any non-`x` letter was admitted — so `.tsrx`
16
+ * and similar extensions matched by accident.
10
17
  */
11
- var TS_EXT_REGEX = /\.[cm]?(ts)[^x]?\??/;
18
+ var TS_EXT_REGEX = /\.[cm]?ts(?![a-z])/;
12
19
  function getTsConfigPath(root, tsconfig, isProd, isTest, isLib) {
13
20
  if (tsconfig && isAbsolute(tsconfig)) {
14
21
  if (!existsSync(tsconfig)) console.error(`[@analogjs/vite-plugin-angular]: Unable to resolve tsconfig at ${tsconfig}. This causes compilation issues. Check the path or set the "tsconfig" property with an absolute path.`);
@@ -1 +1 @@
1
- {"version":3,"file":"plugin-config.js","names":[],"sources":["../../../../src/lib/utils/plugin-config.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { isAbsolute, resolve } from 'node:path';\nimport * as vite from 'vite';\nimport { defaultClientConditions } from 'vite';\n\nimport {\n createCompilerPlugin,\n createRolldownCompilerPlugin,\n} from '../compiler-plugin.js';\n\n/**\n * TypeScript file extension regex\n * Match .(c or m)ts, .ts extensions with an optional ? for query params\n * Ignore .tsx extensions\n */\nexport const TS_EXT_REGEX = /\\.[cm]?(ts)[^x]?\\??/;\n\nexport interface TsConfigResolutionContext {\n root: string;\n isProd: boolean;\n isLib: boolean;\n}\n\nexport function getTsConfigPath(\n root: string,\n tsconfig: string,\n isProd: boolean,\n isTest: boolean,\n isLib: boolean,\n) {\n if (tsconfig && isAbsolute(tsconfig)) {\n if (!existsSync(tsconfig)) {\n console.error(\n `[@analogjs/vite-plugin-angular]: Unable to resolve tsconfig at ${tsconfig}. This causes compilation issues. Check the path or set the \"tsconfig\" property with an absolute path.`,\n );\n }\n\n return tsconfig;\n }\n\n let tsconfigFilePath = './tsconfig.app.json';\n\n if (isLib) {\n tsconfigFilePath = isProd\n ? './tsconfig.lib.prod.json'\n : './tsconfig.lib.json';\n }\n\n if (isTest) {\n tsconfigFilePath = './tsconfig.spec.json';\n }\n\n if (tsconfig) {\n tsconfigFilePath = tsconfig;\n }\n\n const resolvedPath = resolve(root, tsconfigFilePath);\n\n if (!existsSync(resolvedPath)) {\n console.error(\n `[@analogjs/vite-plugin-angular]: Unable to resolve tsconfig at ${resolvedPath}. This causes compilation issues. Check the path or set the \"tsconfig\" property with an absolute path.`,\n );\n }\n\n return resolvedPath;\n}\n\nexport function createTsConfigGetter(\n tsconfigOrGetter?: string | (() => string),\n) {\n if (typeof tsconfigOrGetter === 'function') {\n return tsconfigOrGetter;\n }\n\n return () => tsconfigOrGetter || '';\n}\n\nexport interface DepOptimizerOptions {\n tsconfig: string;\n isProd: boolean;\n jit: boolean;\n watchMode: boolean;\n isTest: boolean;\n isAstroIntegration: boolean;\n}\n\nexport function createDepOptimizerConfig(opts: DepOptimizerOptions) {\n const defineOptions = {\n ngJitMode: 'false',\n ngI18nClosureMode: 'false',\n ...(opts.watchMode ? {} : { ngDevMode: 'false' }),\n };\n\n const rolldownOptions: vite.DepOptimizationOptions['rolldownOptions'] = {\n plugins: [\n createRolldownCompilerPlugin({\n tsconfig: opts.tsconfig,\n sourcemap: !opts.isProd,\n advancedOptimizations: opts.isProd,\n jit: opts.jit,\n incremental: opts.watchMode,\n }),\n ],\n };\n\n const esbuildOptions: vite.DepOptimizationOptions['esbuildOptions'] = {\n plugins: [\n createCompilerPlugin(\n {\n tsconfig: opts.tsconfig,\n sourcemap: !opts.isProd,\n advancedOptimizations: opts.isProd,\n jit: opts.jit,\n incremental: opts.watchMode,\n },\n opts.isTest,\n !opts.isAstroIntegration,\n ),\n ],\n define: defineOptions,\n };\n\n return {\n optimizeDeps: {\n include: ['rxjs/operators', 'rxjs'],\n exclude: ['@angular/platform-server'],\n ...(vite.rolldownVersion ? { rolldownOptions } : { esbuildOptions }),\n },\n resolve: {\n conditions: ['style'],\n },\n };\n}\n"],"mappings":";;;;;;;;;;AAeA,IAAa,eAAe;AAQ5B,SAAgB,gBACd,MACA,UACA,QACA,QACA,OACA;AACA,KAAI,YAAY,WAAW,SAAS,EAAE;AACpC,MAAI,CAAC,WAAW,SAAS,CACvB,SAAQ,MACN,kEAAkE,SAAS,wGAC5E;AAGH,SAAO;;CAGT,IAAI,mBAAmB;AAEvB,KAAI,MACF,oBAAmB,SACf,6BACA;AAGN,KAAI,OACF,oBAAmB;AAGrB,KAAI,SACF,oBAAmB;CAGrB,MAAM,eAAe,QAAQ,MAAM,iBAAiB;AAEpD,KAAI,CAAC,WAAW,aAAa,CAC3B,SAAQ,MACN,kEAAkE,aAAa,wGAChF;AAGH,QAAO;;AAGT,SAAgB,qBACd,kBACA;AACA,KAAI,OAAO,qBAAqB,WAC9B,QAAO;AAGT,cAAa,oBAAoB;;AAYnC,SAAgB,yBAAyB,MAA2B;CAClE,MAAM,gBAAgB;EACpB,WAAW;EACX,mBAAmB;EACnB,GAAI,KAAK,YAAY,EAAE,GAAG,EAAE,WAAW,SAAS;EACjD;CAED,MAAM,kBAAkE,EACtE,SAAS,CACP,6BAA6B;EAC3B,UAAU,KAAK;EACf,WAAW,CAAC,KAAK;EACjB,uBAAuB,KAAK;EAC5B,KAAK,KAAK;EACV,aAAa,KAAK;EACnB,CAAC,CACH,EACF;CAED,MAAM,iBAAgE;EACpE,SAAS,CACP,qBACE;GACE,UAAU,KAAK;GACf,WAAW,CAAC,KAAK;GACjB,uBAAuB,KAAK;GAC5B,KAAK,KAAK;GACV,aAAa,KAAK;GACnB,EACD,KAAK,QACL,CAAC,KAAK,mBACP,CACF;EACD,QAAQ;EACT;AAED,QAAO;EACL,cAAc;GACZ,SAAS,CAAC,kBAAkB,OAAO;GACnC,SAAS,CAAC,2BAA2B;GACrC,GAAI,KAAK,kBAAkB,EAAE,iBAAiB,GAAG,EAAE,gBAAgB;GACpE;EACD,SAAS,EACP,YAAY,CAAC,QAAQ,EACtB;EACF"}
1
+ {"version":3,"file":"plugin-config.js","names":[],"sources":["../../../../src/lib/utils/plugin-config.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { isAbsolute, resolve } from 'node:path';\nimport * as vite from 'vite';\nimport { defaultClientConditions } from 'vite';\n\nimport {\n createCompilerPlugin,\n createRolldownCompilerPlugin,\n} from '../compiler-plugin.js';\n\n/**\n * TypeScript file extension regex\n * Match .ts / .cts / .mts extensions with an optional ?query suffix.\n * Reject .tsx — and any other `.ts<letter>…` extension like .tsrx — via\n * a negative-lookahead on a following ASCII letter, so only genuine TS\n * files pass.\n *\n * Previous form `/\\.[cm]?(ts)[^x]?\\??/` was intended to exclude `.tsx`\n * specifically (`[^x]?` = not-an-x), but the `?` quantifier also allows\n * zero characters, and any non-`x` letter was admitted — so `.tsrx`\n * and similar extensions matched by accident.\n */\nexport const TS_EXT_REGEX = /\\.[cm]?ts(?![a-z])/;\n\nexport interface TsConfigResolutionContext {\n root: string;\n isProd: boolean;\n isLib: boolean;\n}\n\nexport function getTsConfigPath(\n root: string,\n tsconfig: string,\n isProd: boolean,\n isTest: boolean,\n isLib: boolean,\n) {\n if (tsconfig && isAbsolute(tsconfig)) {\n if (!existsSync(tsconfig)) {\n console.error(\n `[@analogjs/vite-plugin-angular]: Unable to resolve tsconfig at ${tsconfig}. This causes compilation issues. Check the path or set the \"tsconfig\" property with an absolute path.`,\n );\n }\n\n return tsconfig;\n }\n\n let tsconfigFilePath = './tsconfig.app.json';\n\n if (isLib) {\n tsconfigFilePath = isProd\n ? './tsconfig.lib.prod.json'\n : './tsconfig.lib.json';\n }\n\n if (isTest) {\n tsconfigFilePath = './tsconfig.spec.json';\n }\n\n if (tsconfig) {\n tsconfigFilePath = tsconfig;\n }\n\n const resolvedPath = resolve(root, tsconfigFilePath);\n\n if (!existsSync(resolvedPath)) {\n console.error(\n `[@analogjs/vite-plugin-angular]: Unable to resolve tsconfig at ${resolvedPath}. This causes compilation issues. Check the path or set the \"tsconfig\" property with an absolute path.`,\n );\n }\n\n return resolvedPath;\n}\n\nexport function createTsConfigGetter(\n tsconfigOrGetter?: string | (() => string),\n) {\n if (typeof tsconfigOrGetter === 'function') {\n return tsconfigOrGetter;\n }\n\n return () => tsconfigOrGetter || '';\n}\n\nexport interface DepOptimizerOptions {\n tsconfig: string;\n isProd: boolean;\n jit: boolean;\n watchMode: boolean;\n isTest: boolean;\n isAstroIntegration: boolean;\n}\n\nexport function createDepOptimizerConfig(opts: DepOptimizerOptions) {\n const defineOptions = {\n ngJitMode: 'false',\n ngI18nClosureMode: 'false',\n ...(opts.watchMode ? {} : { ngDevMode: 'false' }),\n };\n\n const rolldownOptions: vite.DepOptimizationOptions['rolldownOptions'] = {\n plugins: [\n createRolldownCompilerPlugin({\n tsconfig: opts.tsconfig,\n sourcemap: !opts.isProd,\n advancedOptimizations: opts.isProd,\n jit: opts.jit,\n incremental: opts.watchMode,\n }),\n ],\n };\n\n const esbuildOptions: vite.DepOptimizationOptions['esbuildOptions'] = {\n plugins: [\n createCompilerPlugin(\n {\n tsconfig: opts.tsconfig,\n sourcemap: !opts.isProd,\n advancedOptimizations: opts.isProd,\n jit: opts.jit,\n incremental: opts.watchMode,\n },\n opts.isTest,\n !opts.isAstroIntegration,\n ),\n ],\n define: defineOptions,\n };\n\n return {\n optimizeDeps: {\n include: ['rxjs/operators', 'rxjs'],\n exclude: ['@angular/platform-server'],\n ...(vite.rolldownVersion ? { rolldownOptions } : { esbuildOptions }),\n },\n resolve: {\n conditions: ['style'],\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAsBA,IAAa,eAAe;AAQ5B,SAAgB,gBACd,MACA,UACA,QACA,QACA,OACA;AACA,KAAI,YAAY,WAAW,SAAS,EAAE;AACpC,MAAI,CAAC,WAAW,SAAS,CACvB,SAAQ,MACN,kEAAkE,SAAS,wGAC5E;AAGH,SAAO;;CAGT,IAAI,mBAAmB;AAEvB,KAAI,MACF,oBAAmB,SACf,6BACA;AAGN,KAAI,OACF,oBAAmB;AAGrB,KAAI,SACF,oBAAmB;CAGrB,MAAM,eAAe,QAAQ,MAAM,iBAAiB;AAEpD,KAAI,CAAC,WAAW,aAAa,CAC3B,SAAQ,MACN,kEAAkE,aAAa,wGAChF;AAGH,QAAO;;AAGT,SAAgB,qBACd,kBACA;AACA,KAAI,OAAO,qBAAqB,WAC9B,QAAO;AAGT,cAAa,oBAAoB;;AAYnC,SAAgB,yBAAyB,MAA2B;CAClE,MAAM,gBAAgB;EACpB,WAAW;EACX,mBAAmB;EACnB,GAAI,KAAK,YAAY,EAAE,GAAG,EAAE,WAAW,SAAS;EACjD;CAED,MAAM,kBAAkE,EACtE,SAAS,CACP,6BAA6B;EAC3B,UAAU,KAAK;EACf,WAAW,CAAC,KAAK;EACjB,uBAAuB,KAAK;EAC5B,KAAK,KAAK;EACV,aAAa,KAAK;EACnB,CAAC,CACH,EACF;CAED,MAAM,iBAAgE;EACpE,SAAS,CACP,qBACE;GACE,UAAU,KAAK;GACf,WAAW,CAAC,KAAK;GACjB,uBAAuB,KAAK;GAC5B,KAAK,KAAK;GACV,aAAa,KAAK;GACnB,EACD,KAAK,QACL,CAAC,KAAK,mBACP,CACF;EACD,QAAQ;EACT;AAED,QAAO;EACL,cAAc;GACZ,SAAS,CAAC,kBAAkB,OAAO;GACnC,SAAS,CAAC,2BAA2B;GACrC,GAAI,KAAK,kBAAkB,EAAE,iBAAiB,GAAG,EAAE,gBAAgB;GACpE;EACD,SAAS,EACP,YAAY,CAAC,QAAQ,EACtB;EACF"}
@@ -0,0 +1,16 @@
1
+ import { type ResolvedConfig } from "vite";
2
+ /**
3
+ * Mark a style file path as safe in Vite's `safeModulePaths` set so the
4
+ * `?inline` import passes the Denied ID security check without needing
5
+ * the plugin to intercept the load.
6
+ *
7
+ * Vite's own import-analysis transform does the same thing (adds the clean
8
+ * URL to `safeModulePaths` during transform). We additionally add the
9
+ * `?inline` form because `isServerAccessDeniedForTransform` checks *both*
10
+ * `cleanUrl(id)` and the full `id` (with query) against the allow list.
11
+ *
12
+ * This lets `?inline` CSS flow through Vite's native CSS pipeline, which
13
+ * handles preprocessing, `test.css` semantics, and browser-vs-node
14
+ * differences without the plugin having to reimplement any of it.
15
+ */
16
+ export declare function markStylePathSafe(config: ResolvedConfig | undefined, absPath: string): void;
@@ -0,0 +1,29 @@
1
+ import { normalizePath } from "vite";
2
+ //#region packages/vite-plugin-angular/src/lib/utils/safe-module-paths.ts
3
+ /**
4
+ * Mark a style file path as safe in Vite's `safeModulePaths` set so the
5
+ * `?inline` import passes the Denied ID security check without needing
6
+ * the plugin to intercept the load.
7
+ *
8
+ * Vite's own import-analysis transform does the same thing (adds the clean
9
+ * URL to `safeModulePaths` during transform). We additionally add the
10
+ * `?inline` form because `isServerAccessDeniedForTransform` checks *both*
11
+ * `cleanUrl(id)` and the full `id` (with query) against the allow list.
12
+ *
13
+ * This lets `?inline` CSS flow through Vite's native CSS pipeline, which
14
+ * handles preprocessing, `test.css` semantics, and browser-vs-node
15
+ * differences without the plugin having to reimplement any of it.
16
+ */
17
+ function markStylePathSafe(config, absPath) {
18
+ if (!config) return;
19
+ const normalized = normalizePath(absPath);
20
+ const safeModulePaths = config.safeModulePaths;
21
+ if (safeModulePaths) {
22
+ safeModulePaths.add(normalized);
23
+ safeModulePaths.add(normalized + "?inline");
24
+ }
25
+ }
26
+ //#endregion
27
+ export { markStylePathSafe };
28
+
29
+ //# sourceMappingURL=safe-module-paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"safe-module-paths.js","names":[],"sources":["../../../../src/lib/utils/safe-module-paths.ts"],"sourcesContent":["import { normalizePath, type ResolvedConfig } from 'vite';\n\n/**\n * Mark a style file path as safe in Vite's `safeModulePaths` set so the\n * `?inline` import passes the Denied ID security check without needing\n * the plugin to intercept the load.\n *\n * Vite's own import-analysis transform does the same thing (adds the clean\n * URL to `safeModulePaths` during transform). We additionally add the\n * `?inline` form because `isServerAccessDeniedForTransform` checks *both*\n * `cleanUrl(id)` and the full `id` (with query) against the allow list.\n *\n * This lets `?inline` CSS flow through Vite's native CSS pipeline, which\n * handles preprocessing, `test.css` semantics, and browser-vs-node\n * differences without the plugin having to reimplement any of it.\n */\nexport function markStylePathSafe(\n config: ResolvedConfig | undefined,\n absPath: string,\n): void {\n if (!config) return;\n const normalized = normalizePath(absPath);\n const safeModulePaths = (config as any).safeModulePaths as\n | Set<string>\n | undefined;\n if (safeModulePaths) {\n safeModulePaths.add(normalized);\n safeModulePaths.add(normalized + '?inline');\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAgBA,SAAgB,kBACd,QACA,SACM;AACN,KAAI,CAAC,OAAQ;CACb,MAAM,aAAa,cAAc,QAAQ;CACzC,MAAM,kBAAmB,OAAe;AAGxC,KAAI,iBAAiB;AACnB,kBAAgB,IAAI,WAAW;AAC/B,kBAAgB,IAAI,aAAa,UAAU"}
@@ -1,8 +1,4 @@
1
- export declare const VIRTUAL_STYLE_PREFIX = "virtual:@analogjs/vite-plugin-angular:inline-style:";
2
1
  export declare const VIRTUAL_RAW_PREFIX = "virtual:@analogjs/vite-plugin-angular:raw:";
3
- export declare function toVirtualStyleId(absPath: string): string;
4
- export declare function isVirtualStyleId(id: string): boolean;
5
- export declare function fromVirtualStyleId(id: string): string;
6
2
  export declare function toVirtualRawId(absPath: string): string;
7
3
  export declare function isVirtualRawId(id: string): boolean;
8
4
  export declare function fromVirtualRawId(id: string): string;
@@ -1,5 +1,4 @@
1
1
  //#region packages/vite-plugin-angular/src/lib/utils/virtual-ids.ts
2
- var VIRTUAL_STYLE_PREFIX = "virtual:@analogjs/vite-plugin-angular:inline-style:";
3
2
  var VIRTUAL_RAW_PREFIX = "virtual:@analogjs/vite-plugin-angular:raw:";
4
3
  function encode(absPath) {
5
4
  return Buffer.from(absPath, "utf-8").toString("base64url");
@@ -7,17 +6,6 @@ function encode(absPath) {
7
6
  function decode(encoded) {
8
7
  return Buffer.from(encoded, "base64url").toString("utf-8");
9
8
  }
10
- function toVirtualStyleId(absPath) {
11
- return `${VIRTUAL_STYLE_PREFIX}${encode(absPath)}`;
12
- }
13
- function isVirtualStyleId(id) {
14
- return (id.startsWith("\0") ? id.slice(1) : id).startsWith(VIRTUAL_STYLE_PREFIX);
15
- }
16
- function fromVirtualStyleId(id) {
17
- const normalizedId = id.startsWith("\0") ? id.slice(1) : id;
18
- if (!normalizedId.startsWith("virtual:@analogjs/vite-plugin-angular:inline-style:")) throw new Error(`Invalid virtual style id: ${id}`);
19
- return decode(normalizedId.slice(51));
20
- }
21
9
  function toVirtualRawId(absPath) {
22
10
  return `${VIRTUAL_RAW_PREFIX}${encode(absPath)}`;
23
11
  }
@@ -30,6 +18,6 @@ function fromVirtualRawId(id) {
30
18
  return decode(normalizedId.slice(42));
31
19
  }
32
20
  //#endregion
33
- export { VIRTUAL_RAW_PREFIX, VIRTUAL_STYLE_PREFIX, fromVirtualRawId, fromVirtualStyleId, isVirtualRawId, isVirtualStyleId, toVirtualRawId, toVirtualStyleId };
21
+ export { VIRTUAL_RAW_PREFIX, fromVirtualRawId, isVirtualRawId, toVirtualRawId };
34
22
 
35
23
  //# sourceMappingURL=virtual-ids.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"virtual-ids.js","names":[],"sources":["../../../../src/lib/utils/virtual-ids.ts"],"sourcesContent":["// Virtual module id helpers for external component resources (template and\n// style files). Routing through virtual ids keeps Vite's built-in plugins\n// (vite:css, vite:asset, the server.fs Denied ID check) out of the picture:\n// the id Vite sees has no file extension, so extension-based matchers never\n// fire, and it does not match the /[?&](raw|inline)\\b/ security regex that\n// blocks user-facing ?raw and ?inline queries.\n//\n// Both prefixes share the same shape a literal prefix followed by a\n// base64url-encoded absolute file path so load hooks can round-trip back\n// to the source file for reading and watching. See #2263 / #2283.\n\nexport const VIRTUAL_STYLE_PREFIX =\n 'virtual:@analogjs/vite-plugin-angular:inline-style:';\n\nexport const VIRTUAL_RAW_PREFIX = 'virtual:@analogjs/vite-plugin-angular:raw:';\n\nfunction encode(absPath: string): string {\n return Buffer.from(absPath, 'utf-8').toString('base64url');\n}\n\nfunction decode(encoded: string): string {\n return Buffer.from(encoded, 'base64url').toString('utf-8');\n}\n\nexport function toVirtualStyleId(absPath: string): string {\n return `${VIRTUAL_STYLE_PREFIX}${encode(absPath)}`;\n}\n\nexport function isVirtualStyleId(id: string): boolean {\n const stripped = id.startsWith('\\0') ? id.slice(1) : id;\n return stripped.startsWith(VIRTUAL_STYLE_PREFIX);\n}\n\nexport function fromVirtualStyleId(id: string): string {\n const normalizedId = id.startsWith('\\0') ? id.slice(1) : id;\n if (!normalizedId.startsWith(VIRTUAL_STYLE_PREFIX)) {\n throw new Error(`Invalid virtual style id: ${id}`);\n }\n return decode(normalizedId.slice(VIRTUAL_STYLE_PREFIX.length));\n}\n\nexport function toVirtualRawId(absPath: string): string {\n return `${VIRTUAL_RAW_PREFIX}${encode(absPath)}`;\n}\n\nexport function isVirtualRawId(id: string): boolean {\n const stripped = id.startsWith('\\0') ? id.slice(1) : id;\n return stripped.startsWith(VIRTUAL_RAW_PREFIX);\n}\n\nexport function fromVirtualRawId(id: string): string {\n const normalizedId = id.startsWith('\\0') ? id.slice(1) : id;\n if (!normalizedId.startsWith(VIRTUAL_RAW_PREFIX)) {\n throw new Error(`Invalid virtual raw id: ${id}`);\n }\n return decode(normalizedId.slice(VIRTUAL_RAW_PREFIX.length));\n}\n"],"mappings":";AAWA,IAAa,uBACX;AAEF,IAAa,qBAAqB;AAElC,SAAS,OAAO,SAAyB;AACvC,QAAO,OAAO,KAAK,SAAS,QAAQ,CAAC,SAAS,YAAY;;AAG5D,SAAS,OAAO,SAAyB;AACvC,QAAO,OAAO,KAAK,SAAS,YAAY,CAAC,SAAS,QAAQ;;AAG5D,SAAgB,iBAAiB,SAAyB;AACxD,QAAO,GAAG,uBAAuB,OAAO,QAAQ;;AAGlD,SAAgB,iBAAiB,IAAqB;AAEpD,SADiB,GAAG,WAAW,KAAK,GAAG,GAAG,MAAM,EAAE,GAAG,IACrC,WAAW,qBAAqB;;AAGlD,SAAgB,mBAAmB,IAAoB;CACrD,MAAM,eAAe,GAAG,WAAW,KAAK,GAAG,GAAG,MAAM,EAAE,GAAG;AACzD,KAAI,CAAC,aAAa,WAAA,sDAAgC,CAChD,OAAM,IAAI,MAAM,6BAA6B,KAAK;AAEpD,QAAO,OAAO,aAAa,MAAM,GAA4B,CAAC;;AAGhE,SAAgB,eAAe,SAAyB;AACtD,QAAO,GAAG,qBAAqB,OAAO,QAAQ;;AAGhD,SAAgB,eAAe,IAAqB;AAElD,SADiB,GAAG,WAAW,KAAK,GAAG,GAAG,MAAM,EAAE,GAAG,IACrC,WAAW,mBAAmB;;AAGhD,SAAgB,iBAAiB,IAAoB;CACnD,MAAM,eAAe,GAAG,WAAW,KAAK,GAAG,GAAG,MAAM,EAAE,GAAG;AACzD,KAAI,CAAC,aAAa,WAAA,6CAA8B,CAC9C,OAAM,IAAI,MAAM,2BAA2B,KAAK;AAElD,QAAO,OAAO,aAAa,MAAM,GAA0B,CAAC"}
1
+ {"version":3,"file":"virtual-ids.js","names":[],"sources":["../../../../src/lib/utils/virtual-ids.ts"],"sourcesContent":["// Virtual module id helpers for external component resources (template files).\n// Routing through virtual ids keeps Vite's built-in plugins (vite:asset, the\n// server.fs Denied ID check) out of the picture: the id Vite sees has no\n// file extension, so extension-based matchers never fire, and it does not\n// match the /[?&](raw|inline)\\b/ security regex.\n//\n// Style ?inline imports now flow through Vite's native CSS pipeline via\n// safeModulePaths (see safe-module-paths.ts). Only template ?raw imports\n// still use virtual ids. See #2263 / #2283 / #2310.\n\nexport const VIRTUAL_RAW_PREFIX = 'virtual:@analogjs/vite-plugin-angular:raw:';\n\nfunction encode(absPath: string): string {\n return Buffer.from(absPath, 'utf-8').toString('base64url');\n}\n\nfunction decode(encoded: string): string {\n return Buffer.from(encoded, 'base64url').toString('utf-8');\n}\n\nexport function toVirtualRawId(absPath: string): string {\n return `${VIRTUAL_RAW_PREFIX}${encode(absPath)}`;\n}\n\nexport function isVirtualRawId(id: string): boolean {\n const stripped = id.startsWith('\\0') ? id.slice(1) : id;\n return stripped.startsWith(VIRTUAL_RAW_PREFIX);\n}\n\nexport function fromVirtualRawId(id: string): string {\n const normalizedId = id.startsWith('\\0') ? id.slice(1) : id;\n if (!normalizedId.startsWith(VIRTUAL_RAW_PREFIX)) {\n throw new Error(`Invalid virtual raw id: ${id}`);\n }\n return decode(normalizedId.slice(VIRTUAL_RAW_PREFIX.length));\n}\n"],"mappings":";AAUA,IAAa,qBAAqB;AAElC,SAAS,OAAO,SAAyB;AACvC,QAAO,OAAO,KAAK,SAAS,QAAQ,CAAC,SAAS,YAAY;;AAG5D,SAAS,OAAO,SAAyB;AACvC,QAAO,OAAO,KAAK,SAAS,YAAY,CAAC,SAAS,QAAQ;;AAG5D,SAAgB,eAAe,SAAyB;AACtD,QAAO,GAAG,qBAAqB,OAAO,QAAQ;;AAGhD,SAAgB,eAAe,IAAqB;AAElD,SADiB,GAAG,WAAW,KAAK,GAAG,GAAG,MAAM,EAAE,GAAG,IACrC,WAAW,mBAAmB;;AAGhD,SAAgB,iBAAiB,IAAoB;CACnD,MAAM,eAAe,GAAG,WAAW,KAAK,GAAG,GAAG,MAAM,EAAE,GAAG;AACzD,KAAI,CAAC,aAAa,WAAA,6CAA8B,CAC9C,OAAM,IAAI,MAAM,2BAA2B,KAAK;AAElD,QAAO,OAAO,aAAa,MAAM,GAA0B,CAAC"}