@caryhu/codemine-forge 0.0.1-alpha.3 → 0.0.1-alpha.4

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.
@@ -0,0 +1,12 @@
1
+ import type { ForgeVirtualFileSystem } from "../virtual-file-system";
2
+ import type { ForgeBuildPipelineDiagnostic } from "./types";
3
+ export interface InlineAngularComponentResourcesOptions {
4
+ readonly fileSystem: ForgeVirtualFileSystem;
5
+ readonly sourcePath: string;
6
+ readonly sourceText: string;
7
+ }
8
+ export interface InlineAngularComponentResourcesResult {
9
+ readonly outputText: string;
10
+ readonly diagnostics: readonly ForgeBuildPipelineDiagnostic[];
11
+ }
12
+ export declare function inlineAngularComponentResources(options: InlineAngularComponentResourcesOptions): Promise<InlineAngularComponentResourcesResult>;
@@ -0,0 +1,316 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.inlineAngularComponentResources = void 0;
27
+ const ts = __importStar(require("typescript"));
28
+ const virtual_file_system_1 = require("../virtual-file-system");
29
+ const diagnostics_1 = require("./diagnostics");
30
+ const COMPONENT_RESOURCE_PROPERTIES = new Set([
31
+ "templateUrl",
32
+ "styleUrl",
33
+ "styleUrls",
34
+ ]);
35
+ async function inlineAngularComponentResources(options) {
36
+ try {
37
+ const sourceFile = ts.createSourceFile(options.sourcePath, options.sourceText, ts.ScriptTarget.Latest, true, getScriptKind(options.sourcePath));
38
+ const componentObjects = collectComponentMetadataObjects(sourceFile);
39
+ if (componentObjects.length === 0) {
40
+ return {
41
+ outputText: options.sourceText,
42
+ diagnostics: [],
43
+ };
44
+ }
45
+ const diagnostics = [];
46
+ const rewrites = new Map();
47
+ for (const componentObject of componentObjects) {
48
+ const rewrite = await createComponentObjectRewrite(options, componentObject);
49
+ diagnostics.push(...rewrite.diagnostics);
50
+ if (rewrite.value !== undefined) {
51
+ rewrites.set(componentObject, rewrite.value);
52
+ }
53
+ }
54
+ if (diagnostics.length > 0) {
55
+ return {
56
+ outputText: options.sourceText,
57
+ diagnostics,
58
+ };
59
+ }
60
+ if (rewrites.size === 0) {
61
+ return {
62
+ outputText: options.sourceText,
63
+ diagnostics: [],
64
+ };
65
+ }
66
+ const transformer = (context) => {
67
+ const visitor = (node) => {
68
+ if (ts.isCallExpression(node) &&
69
+ node.arguments.length > 0 &&
70
+ ts.isObjectLiteralExpression(node.arguments[0]) &&
71
+ isAngularComponentDecoratorCall(node)) {
72
+ const componentObject = node.arguments[0];
73
+ const rewrite = rewrites.get(componentObject);
74
+ if (rewrite !== undefined) {
75
+ return ts.factory.updateCallExpression(node, node.expression, node.typeArguments, [
76
+ updateComponentObjectLiteral(componentObject, rewrite),
77
+ ...node.arguments.slice(1),
78
+ ]);
79
+ }
80
+ }
81
+ return ts.visitEachChild(node, visitor, context);
82
+ };
83
+ return (node) => ts.visitNode(node, visitor);
84
+ };
85
+ const result = ts.transform(sourceFile, [transformer]);
86
+ try {
87
+ const transformedSourceFile = result.transformed[0];
88
+ const printer = ts.createPrinter({
89
+ newLine: ts.NewLineKind.LineFeed,
90
+ });
91
+ return {
92
+ outputText: printer.printFile(transformedSourceFile),
93
+ diagnostics: [],
94
+ };
95
+ }
96
+ finally {
97
+ result.dispose();
98
+ }
99
+ }
100
+ catch (error) {
101
+ return {
102
+ outputText: options.sourceText,
103
+ diagnostics: [
104
+ (0, diagnostics_1.createAngularResourceTransformFailedDiagnostic)(options.sourcePath, error),
105
+ ],
106
+ };
107
+ }
108
+ }
109
+ exports.inlineAngularComponentResources = inlineAngularComponentResources;
110
+ function collectComponentMetadataObjects(sourceFile) {
111
+ const componentObjects = [];
112
+ function visit(node) {
113
+ if (ts.isCallExpression(node) &&
114
+ node.arguments.length > 0 &&
115
+ ts.isObjectLiteralExpression(node.arguments[0]) &&
116
+ isAngularComponentDecoratorCall(node) &&
117
+ hasComponentResourceProperty(node.arguments[0])) {
118
+ componentObjects.push(node.arguments[0]);
119
+ }
120
+ ts.forEachChild(node, visit);
121
+ }
122
+ visit(sourceFile);
123
+ return componentObjects;
124
+ }
125
+ async function createComponentObjectRewrite(options, componentObject) {
126
+ const diagnostics = [];
127
+ const styleResourceProperties = new Set();
128
+ const styleResources = [];
129
+ const templateResources = new Map();
130
+ for (const property of componentObject.properties) {
131
+ if (!ts.isPropertyAssignment(property)) {
132
+ continue;
133
+ }
134
+ const propertyName = getPropertyNameText(property.name);
135
+ if (propertyName === "templateUrl") {
136
+ const resourcePath = getStringLiteralText(property.initializer);
137
+ if (resourcePath === undefined) {
138
+ continue;
139
+ }
140
+ const resource = await readComponentResource(options, resourcePath);
141
+ diagnostics.push(...resource.diagnostics);
142
+ if (resource.content !== undefined) {
143
+ templateResources.set(property, resource.content);
144
+ }
145
+ continue;
146
+ }
147
+ if (propertyName === "styleUrl") {
148
+ const resourcePath = getStringLiteralText(property.initializer);
149
+ if (resourcePath === undefined) {
150
+ continue;
151
+ }
152
+ const resource = await readComponentResource(options, resourcePath);
153
+ diagnostics.push(...resource.diagnostics);
154
+ if (resource.content !== undefined) {
155
+ styleResourceProperties.add(property);
156
+ styleResources.push(resource.content);
157
+ }
158
+ continue;
159
+ }
160
+ if (propertyName === "styleUrls") {
161
+ const resourcePaths = getStringArrayLiteralText(property.initializer);
162
+ if (resourcePaths === undefined) {
163
+ continue;
164
+ }
165
+ for (const resourcePath of resourcePaths) {
166
+ const resource = await readComponentResource(options, resourcePath);
167
+ diagnostics.push(...resource.diagnostics);
168
+ if (resource.content !== undefined) {
169
+ styleResources.push(resource.content);
170
+ }
171
+ }
172
+ if (resourcePaths.length > 0) {
173
+ styleResourceProperties.add(property);
174
+ }
175
+ }
176
+ }
177
+ if (diagnostics.length > 0 ||
178
+ (styleResources.length === 0 && templateResources.size === 0)) {
179
+ return { diagnostics };
180
+ }
181
+ return {
182
+ value: {
183
+ styleResourceProperties,
184
+ styleResources,
185
+ templateResources,
186
+ },
187
+ diagnostics,
188
+ };
189
+ }
190
+ function updateComponentObjectLiteral(componentObject, rewrite) {
191
+ const existingStylesProperty = componentObject.properties.find((property) => ts.isPropertyAssignment(property) &&
192
+ getPropertyNameText(property.name) === "styles");
193
+ const firstStyleResourceProperty = componentObject.properties.find((property) => ts.isPropertyAssignment(property) &&
194
+ rewrite.styleResourceProperties.has(property));
195
+ const updatedProperties = [];
196
+ for (const property of componentObject.properties) {
197
+ if (ts.isPropertyAssignment(property) &&
198
+ rewrite.templateResources.has(property)) {
199
+ updatedProperties.push(ts.factory.createPropertyAssignment("template", ts.factory.createStringLiteral(rewrite.templateResources.get(property) ?? "")));
200
+ continue;
201
+ }
202
+ if (ts.isPropertyAssignment(property) &&
203
+ rewrite.styleResourceProperties.has(property)) {
204
+ if (existingStylesProperty === undefined &&
205
+ property === firstStyleResourceProperty) {
206
+ updatedProperties.push(createStylesProperty(rewrite.styleResources));
207
+ }
208
+ continue;
209
+ }
210
+ if (property === existingStylesProperty) {
211
+ updatedProperties.push(updateStylesProperty(existingStylesProperty, rewrite.styleResources));
212
+ continue;
213
+ }
214
+ updatedProperties.push(property);
215
+ }
216
+ if (existingStylesProperty === undefined &&
217
+ firstStyleResourceProperty === undefined &&
218
+ rewrite.styleResources.length > 0) {
219
+ updatedProperties.push(createStylesProperty(rewrite.styleResources));
220
+ }
221
+ return ts.factory.updateObjectLiteralExpression(componentObject, updatedProperties);
222
+ }
223
+ function createStylesProperty(styles) {
224
+ return ts.factory.createPropertyAssignment("styles", ts.factory.createArrayLiteralExpression(styles.map((style) => ts.factory.createStringLiteral(style))));
225
+ }
226
+ function updateStylesProperty(property, styleResources) {
227
+ const existingStyles = ts.isArrayLiteralExpression(property.initializer)
228
+ ? property.initializer.elements
229
+ : [property.initializer];
230
+ return ts.factory.updatePropertyAssignment(property, property.name, ts.factory.createArrayLiteralExpression([
231
+ ...existingStyles,
232
+ ...styleResources.map((style) => ts.factory.createStringLiteral(style)),
233
+ ]));
234
+ }
235
+ async function readComponentResource(options, resourcePath) {
236
+ if (isExternalResourceUrl(resourcePath)) {
237
+ return {
238
+ diagnostics: [
239
+ (0, diagnostics_1.createAngularExternalResourceUnsupportedDiagnostic)(options.sourcePath, resourcePath),
240
+ ],
241
+ };
242
+ }
243
+ for (const candidate of createResourcePathCandidates(options.sourcePath, resourcePath)) {
244
+ if (await options.fileSystem.exists(candidate)) {
245
+ return {
246
+ content: await options.fileSystem.readText(candidate),
247
+ diagnostics: [],
248
+ };
249
+ }
250
+ }
251
+ return {
252
+ diagnostics: [
253
+ (0, diagnostics_1.createAngularResourceNotFoundDiagnostic)(options.sourcePath, resourcePath),
254
+ ],
255
+ };
256
+ }
257
+ function createResourcePathCandidates(sourcePath, resourcePath) {
258
+ const candidates = [];
259
+ const relativeCandidate = resourcePath.startsWith("/")
260
+ ? resourcePath
261
+ : `${dirname(sourcePath)}/${resourcePath}`;
262
+ const rootCandidate = resourcePath.startsWith("/")
263
+ ? resourcePath
264
+ : `/${resourcePath.replace(/^\.\//, "")}`;
265
+ for (const candidate of [relativeCandidate, rootCandidate]) {
266
+ const normalized = (0, virtual_file_system_1.normalizeForgePath)(candidate);
267
+ if (normalized.ok && !candidates.includes(normalized.path)) {
268
+ candidates.push(normalized.path);
269
+ }
270
+ }
271
+ return candidates;
272
+ }
273
+ function hasComponentResourceProperty(componentObject) {
274
+ return componentObject.properties.some((property) => ts.isPropertyAssignment(property) &&
275
+ COMPONENT_RESOURCE_PROPERTIES.has(getPropertyNameText(property.name) ?? ""));
276
+ }
277
+ function isAngularComponentDecoratorCall(node) {
278
+ return (ts.isDecorator(node.parent) &&
279
+ ts.isIdentifier(node.expression) &&
280
+ node.expression.text === "Component");
281
+ }
282
+ function getPropertyNameText(name) {
283
+ if (ts.isIdentifier(name) || ts.isStringLiteral(name)) {
284
+ return name.text;
285
+ }
286
+ return undefined;
287
+ }
288
+ function getStringLiteralText(node) {
289
+ return ts.isStringLiteral(node) || ts.isNoSubstitutionTemplateLiteral(node)
290
+ ? node.text
291
+ : undefined;
292
+ }
293
+ function getStringArrayLiteralText(node) {
294
+ if (!ts.isArrayLiteralExpression(node)) {
295
+ return undefined;
296
+ }
297
+ const values = [];
298
+ for (const element of node.elements) {
299
+ const value = getStringLiteralText(element);
300
+ if (value === undefined) {
301
+ return undefined;
302
+ }
303
+ values.push(value);
304
+ }
305
+ return values;
306
+ }
307
+ function isExternalResourceUrl(resourcePath) {
308
+ return /^(?:https?:|data:|blob:)/i.test(resourcePath);
309
+ }
310
+ function getScriptKind(path) {
311
+ return path.endsWith(".tsx") ? ts.ScriptKind.TSX : ts.ScriptKind.TS;
312
+ }
313
+ function dirname(path) {
314
+ const index = path.lastIndexOf("/");
315
+ return index <= 0 ? "/" : path.slice(0, index);
316
+ }
@@ -10,9 +10,15 @@ interface CreateBrowserBundleOptions {
10
10
  readonly entry: string;
11
11
  readonly fileSystem: ForgeVirtualFileSystem;
12
12
  readonly packageResolution: ForgePackageResolutionResult;
13
+ readonly angularCompatibility?: ForgeBrowserBundleAngularCompatibility;
13
14
  readonly scriptTransformer?: ForgeBrowserBundleScriptTransformer;
14
15
  readonly viteConfig?: ForgeViteConfigMetadata;
15
16
  }
17
+ interface ForgeBrowserBundleAngularCompatibility {
18
+ readonly injectZoneJs: boolean;
19
+ readonly inlineComponentResources: boolean;
20
+ readonly linker: "auto" | "diagnostic" | "disabled";
21
+ }
16
22
  export type ForgeBrowserBundleScriptLoader = "ts" | "tsx";
17
23
  export interface ForgeBrowserBundleScriptTransformRequest {
18
24
  readonly loader: ForgeBrowserBundleScriptLoader;
@@ -27,6 +27,7 @@ exports.createBrowserBundle = void 0;
27
27
  const compiler_sfc_1 = require("@vue/compiler-sfc");
28
28
  const ts = __importStar(require("typescript"));
29
29
  const virtual_file_system_1 = require("../virtual-file-system");
30
+ const angular_resources_1 = require("./angular-resources");
30
31
  const diagnostics_1 = require("./diagnostics");
31
32
  const BROWSER_IMPORT_MAP_PATH = "/.forge/build/browser-import-map.json";
32
33
  const DEFAULT_RESOLVE_EXTENSIONS = [
@@ -77,7 +78,7 @@ async function createBrowserBundle(options) {
77
78
  visiting.delete(sourcePath);
78
79
  return;
79
80
  }
80
- const source = await options.fileSystem.readText(sourcePath);
81
+ const source = maybeInjectAngularZoneJsImport(sourcePath, options.entry, await options.fileSystem.readText(sourcePath), options.angularCompatibility);
81
82
  const importSource = extension === ".vue" ? createVueSfcModule(sourcePath, source) : source;
82
83
  const imports = extractImportReferences(importSource).map((reference) => reference.specifier);
83
84
  const rewrites = new Map();
@@ -114,11 +115,18 @@ async function createBrowserBundle(options) {
114
115
  packageImports.set(specifier, packageImport.kind === "external"
115
116
  ? packageImport.url
116
117
  : packageImport.outputPath);
118
+ const linkerDiagnostic = packageImport.kind === "external"
119
+ ? createExternalAngularPartialLinkerDiagnostic(packageImport.packageRecord, options.angularCompatibility)
120
+ : undefined;
121
+ if (linkerDiagnostic !== undefined) {
122
+ diagnostics.push(linkerDiagnostic);
123
+ continue;
124
+ }
117
125
  if (packageImport.kind === "package-file") {
118
126
  await visitPackageModule(packageImport.packageRecord, packageImport.filePath);
119
127
  }
120
128
  }
121
- const transformResult = await transformWorkspaceModule(sourcePath, source, options.scriptTransformer, options.viteConfig?.define ?? {});
129
+ const transformResult = await transformWorkspaceModule(sourcePath, source, options.fileSystem, options.angularCompatibility, options.scriptTransformer, options.viteConfig?.define ?? {});
122
130
  if (!transformResult.success) {
123
131
  diagnostics.push(...transformResult.diagnostics);
124
132
  visiting.delete(sourcePath);
@@ -177,11 +185,18 @@ async function createBrowserBundle(options) {
177
185
  packageImports.set(specifier, packageImport.kind === "external"
178
186
  ? packageImport.url
179
187
  : packageImport.outputPath);
188
+ const linkerDiagnostic = packageImport.kind === "external"
189
+ ? createExternalAngularPartialLinkerDiagnostic(packageImport.packageRecord, options.angularCompatibility)
190
+ : undefined;
191
+ if (linkerDiagnostic !== undefined) {
192
+ diagnostics.push(linkerDiagnostic);
193
+ continue;
194
+ }
180
195
  if (packageImport.kind === "package-file") {
181
196
  await visitPackageModule(packageImport.packageRecord, packageImport.filePath);
182
197
  }
183
198
  }
184
- const transformResult = transformPackageModule(importer, normalizedFilePath, content);
199
+ const transformResult = transformPackageModule(importer, normalizedFilePath, content, packageRecord, options.angularCompatibility);
185
200
  if (!transformResult.success) {
186
201
  diagnostics.push(...transformResult.diagnostics);
187
202
  visitingPackageModules.delete(key);
@@ -254,7 +269,7 @@ function createBrowserBundleModules(workspaceModules, packageModules) {
254
269
  })),
255
270
  ].sort((left, right) => left.outputPath.localeCompare(right.outputPath));
256
271
  }
257
- async function transformWorkspaceModule(sourcePath, source, scriptTransformer, defineReplacements) {
272
+ async function transformWorkspaceModule(sourcePath, source, fileSystem, angularCompatibility, scriptTransformer, defineReplacements) {
258
273
  const extension = getExtension(sourcePath);
259
274
  if (extension === ".css") {
260
275
  return transformSuccess(createWorkspaceCssModule(sourcePath, source));
@@ -269,18 +284,35 @@ async function transformWorkspaceModule(sourcePath, source, scriptTransformer, d
269
284
  if (!SCRIPT_EXTENSIONS.has(extension)) {
270
285
  return transformSuccess(source);
271
286
  }
287
+ const angularResourceResult = angularCompatibility?.inlineComponentResources === true
288
+ ? await (0, angular_resources_1.inlineAngularComponentResources)({
289
+ fileSystem,
290
+ sourcePath,
291
+ sourceText: source,
292
+ })
293
+ : {
294
+ outputText: source,
295
+ diagnostics: [],
296
+ };
297
+ if (angularResourceResult.diagnostics.length > 0) {
298
+ return {
299
+ success: false,
300
+ diagnostics: angularResourceResult.diagnostics,
301
+ };
302
+ }
303
+ const sourceText = angularResourceResult.outputText;
272
304
  const loader = scriptLoaderForExtension(extension);
273
305
  if (loader !== undefined && scriptTransformer !== undefined) {
274
306
  const transformResult = await scriptTransformer({
275
307
  loader,
276
308
  sourcePath,
277
- sourceText: source,
309
+ sourceText,
278
310
  });
279
311
  return transformResult.success
280
312
  ? transformSuccess(applyDefines(transformResult.outputText))
281
313
  : transformResult;
282
314
  }
283
- return transformSuccess(applyDefines(transpileScript(sourcePath, source)));
315
+ return transformSuccess(applyDefines(transpileScript(sourcePath, sourceText)));
284
316
  }
285
317
  function transpileScript(sourcePath, source) {
286
318
  return ts.transpileModule(source, {
@@ -304,7 +336,7 @@ function transformSuccess(outputText) {
304
336
  diagnostics: [],
305
337
  };
306
338
  }
307
- function transformPackageModule(importer, filePath, content) {
339
+ function transformPackageModule(importer, filePath, content, packageRecord, angularCompatibility) {
308
340
  const extension = getExtension(filePath);
309
341
  if (typeof content !== "string" &&
310
342
  !SCRIPT_EXTENSIONS.has(extension) &&
@@ -322,8 +354,52 @@ function transformPackageModule(importer, filePath, content) {
322
354
  if (!SCRIPT_EXTENSIONS.has(extension)) {
323
355
  return transformSuccess(source);
324
356
  }
357
+ if (shouldDiagnoseAngularPartialDeclarations(angularCompatibility) &&
358
+ hasAngularPartialDeclaration(source)) {
359
+ return {
360
+ success: false,
361
+ diagnostics: [
362
+ (0, diagnostics_1.createAngularPartialLinkerRequiredDiagnostic)(packageRecord.name, packageRecord.version, importer),
363
+ ],
364
+ };
365
+ }
325
366
  return transformSuccess(transpileScript(importer, source));
326
367
  }
368
+ function maybeInjectAngularZoneJsImport(sourcePath, entry, source, angularCompatibility) {
369
+ if (angularCompatibility?.injectZoneJs !== true ||
370
+ sourcePath !== entry ||
371
+ hasBareImport(source, "zone.js")) {
372
+ return source;
373
+ }
374
+ return `import "zone.js";\n${source}`;
375
+ }
376
+ function createExternalAngularPartialLinkerDiagnostic(packageRecord, angularCompatibility) {
377
+ if (!shouldDiagnoseAngularPartialDeclarations(angularCompatibility) ||
378
+ !packageRecordHasAngularPartialDeclaration(packageRecord)) {
379
+ return undefined;
380
+ }
381
+ return (0, diagnostics_1.createAngularPartialLinkerRequiredDiagnostic)(packageRecord.name, packageRecord.version, packageRecord.entryUrl ?? createPackageImporterPath(packageRecord, packageRecord.entry));
382
+ }
383
+ function shouldDiagnoseAngularPartialDeclarations(angularCompatibility) {
384
+ return angularCompatibility?.linker === "auto" ||
385
+ angularCompatibility?.linker === "diagnostic";
386
+ }
387
+ function packageRecordHasAngularPartialDeclaration(packageRecord) {
388
+ return Object.values(packageRecord.files).some((file) => typeof file.content === "string" &&
389
+ hasAngularPartialDeclaration(file.content));
390
+ }
391
+ function hasAngularPartialDeclaration(source) {
392
+ return ANGULAR_PARTIAL_DECLARATION_MARKERS.some((marker) => source.includes(marker));
393
+ }
394
+ const ANGULAR_PARTIAL_DECLARATION_MARKERS = [
395
+ "\u0275\u0275ngDeclareComponent",
396
+ "\u0275\u0275ngDeclareDirective",
397
+ "\u0275\u0275ngDeclareFactory",
398
+ "\u0275\u0275ngDeclareInjectable",
399
+ "\u0275\u0275ngDeclareInjector",
400
+ "\u0275\u0275ngDeclareNgModule",
401
+ "\u0275\u0275ngDeclarePipe",
402
+ ];
327
403
  function createVueSfcModule(sourcePath, source) {
328
404
  const filename = sourcePath;
329
405
  const id = `forge-vue-${hashText(sourcePath)}`;
@@ -495,6 +571,9 @@ function extractImportReferences(source) {
495
571
  }
496
572
  return references;
497
573
  }
574
+ function hasBareImport(source, specifier) {
575
+ return extractImportReferences(source).some((reference) => reference.specifier === specifier);
576
+ }
498
577
  function resolveAliasSpecifier(specifier, aliases) {
499
578
  for (const [find, replacement] of Object.entries(aliases).sort(([left], [right]) => right.length - left.length || left.localeCompare(right))) {
500
579
  if (specifier === find) {
@@ -554,6 +633,7 @@ function resolvePackageImport(packages, specifier) {
554
633
  if (packageRecord.entryUrl !== undefined && parsed.subpath === "") {
555
634
  return {
556
635
  kind: "external",
636
+ packageRecord,
557
637
  url: packageRecord.entryUrl,
558
638
  };
559
639
  }
@@ -565,6 +645,7 @@ function resolvePackageImport(packages, specifier) {
565
645
  (parsed.subpath === normalizedEntry || parsed.subpath === entryWithoutExtension)) {
566
646
  return {
567
647
  kind: "external",
648
+ packageRecord,
568
649
  url: packageRecord.entryUrl,
569
650
  };
570
651
  }
@@ -5,4 +5,9 @@ export declare function createMissingBuildScriptDiagnostic(): ForgeBuildPipeline
5
5
  export declare function createUnsupportedBuildScriptDiagnostic(script: string): ForgeBuildPipelineDiagnostic;
6
6
  export declare function createMissingEntryDiagnostic(): ForgeBuildPipelineDiagnostic;
7
7
  export declare function createUnresolvedImportDiagnostic(importSpecifier: string, importer: string): ForgeBuildPipelineDiagnostic;
8
+ export declare function createAngularResourceNotFoundDiagnostic(path: string, resourcePath: string): ForgeBuildPipelineDiagnostic;
9
+ export declare function createAngularExternalResourceUnsupportedDiagnostic(path: string, resourcePath: string): ForgeBuildPipelineDiagnostic;
10
+ export declare function createAngularResourceTransformFailedDiagnostic(path: string, cause: unknown): ForgeBuildPipelineDiagnostic;
11
+ export declare function createAngularZoneJsRequiredDiagnostic(path: string): ForgeBuildPipelineDiagnostic;
12
+ export declare function createAngularPartialLinkerRequiredDiagnostic(packageName: string, packageVersion: string, path: string): ForgeBuildPipelineDiagnostic;
8
13
  export declare function createViteConfigNotExecutedDiagnostic(path: string): ForgeBuildPipelineDiagnostic;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createViteConfigNotExecutedDiagnostic = exports.createUnresolvedImportDiagnostic = exports.createMissingEntryDiagnostic = exports.createUnsupportedBuildScriptDiagnostic = exports.createMissingBuildScriptDiagnostic = exports.createBuildCancelledDiagnostic = exports.createEsbuildWorkerTransformDiagnostic = void 0;
3
+ exports.createViteConfigNotExecutedDiagnostic = exports.createAngularPartialLinkerRequiredDiagnostic = exports.createAngularZoneJsRequiredDiagnostic = exports.createAngularResourceTransformFailedDiagnostic = exports.createAngularExternalResourceUnsupportedDiagnostic = exports.createAngularResourceNotFoundDiagnostic = exports.createUnresolvedImportDiagnostic = exports.createMissingEntryDiagnostic = exports.createUnsupportedBuildScriptDiagnostic = exports.createMissingBuildScriptDiagnostic = exports.createBuildCancelledDiagnostic = exports.createEsbuildWorkerTransformDiagnostic = void 0;
4
4
  function createEsbuildWorkerTransformDiagnostic(path, cause) {
5
5
  return {
6
6
  code: "esbuild_worker_transform_failed",
@@ -59,6 +59,57 @@ function createUnresolvedImportDiagnostic(importSpecifier, importer) {
59
59
  };
60
60
  }
61
61
  exports.createUnresolvedImportDiagnostic = createUnresolvedImportDiagnostic;
62
+ function createAngularResourceNotFoundDiagnostic(path, resourcePath) {
63
+ return {
64
+ code: "angular_resource_not_found",
65
+ severity: "error",
66
+ message: `Angular component resource '${resourcePath}' could not be resolved from ${path}.`,
67
+ path,
68
+ resourcePath,
69
+ };
70
+ }
71
+ exports.createAngularResourceNotFoundDiagnostic = createAngularResourceNotFoundDiagnostic;
72
+ function createAngularExternalResourceUnsupportedDiagnostic(path, resourcePath) {
73
+ return {
74
+ code: "angular_external_resource_unsupported",
75
+ severity: "error",
76
+ message: `Angular component resource '${resourcePath}' is external and cannot be inlined by Forge.`,
77
+ path,
78
+ resourcePath,
79
+ };
80
+ }
81
+ exports.createAngularExternalResourceUnsupportedDiagnostic = createAngularExternalResourceUnsupportedDiagnostic;
82
+ function createAngularResourceTransformFailedDiagnostic(path, cause) {
83
+ return {
84
+ code: "angular_resource_transform_failed",
85
+ severity: "error",
86
+ message: "Forge failed to transform Angular component resources.",
87
+ path,
88
+ cause,
89
+ };
90
+ }
91
+ exports.createAngularResourceTransformFailedDiagnostic = createAngularResourceTransformFailedDiagnostic;
92
+ function createAngularZoneJsRequiredDiagnostic(path) {
93
+ return {
94
+ code: "angular_zonejs_required",
95
+ severity: "error",
96
+ message: "Angular NgModule bootstrap requires zone.js, but Forge could not resolve a compatible package.",
97
+ path,
98
+ dependencyName: "zone.js",
99
+ };
100
+ }
101
+ exports.createAngularZoneJsRequiredDiagnostic = createAngularZoneJsRequiredDiagnostic;
102
+ function createAngularPartialLinkerRequiredDiagnostic(packageName, packageVersion, path) {
103
+ return {
104
+ code: "angular_partial_linker_required",
105
+ severity: "error",
106
+ message: `Angular package ${packageName}@${packageVersion} contains partial Ivy declarations and needs linked browser ESM or Forge Angular linker support.`,
107
+ packageName,
108
+ packageVersion,
109
+ path,
110
+ };
111
+ }
112
+ exports.createAngularPartialLinkerRequiredDiagnostic = createAngularPartialLinkerRequiredDiagnostic;
62
113
  function createViteConfigNotExecutedDiagnostic(path) {
63
114
  return {
64
115
  code: "vite_config_not_executed",
@@ -1,3 +1,3 @@
1
- export { createBuildCancelledDiagnostic, createEsbuildWorkerTransformDiagnostic, createMissingBuildScriptDiagnostic, createMissingEntryDiagnostic, createUnresolvedImportDiagnostic, createUnsupportedBuildScriptDiagnostic, createViteConfigNotExecutedDiagnostic, } from "./diagnostics";
2
- export { createBuildPipeline, DefaultBuildPipeline, isSupportedViteBuildScript, } from "./pipeline";
1
+ export { createAngularExternalResourceUnsupportedDiagnostic, createAngularPartialLinkerRequiredDiagnostic, createAngularResourceNotFoundDiagnostic, createAngularResourceTransformFailedDiagnostic, createAngularZoneJsRequiredDiagnostic, createBuildCancelledDiagnostic, createEsbuildWorkerTransformDiagnostic, createMissingEntryDiagnostic, createUnresolvedImportDiagnostic, createViteConfigNotExecutedDiagnostic, } from "./diagnostics";
2
+ export { createBuildPipeline, DefaultBuildPipeline, } from "./pipeline";
3
3
  export { BUILD_PIPELINE_CAPABILITY, type ForgeBrowserBundle, type ForgeBrowserBundleManifest, type ForgeBrowserBundleModule, type ForgeBrowserBundleModuleOrigin, type ForgeBuildDiagnostic, type ForgeBuildManifest, type ForgeBuildMode, type ForgeBuildOutputFile, type ForgeBuildPipeline, type ForgeBuildPipelineDiagnostic, type ForgeBuildPipelineDiagnosticCode, type ForgeBuildPipelineOptions, type ForgeBuildRequest, type ForgeBuildResult, type ForgeBuildTiming, type ForgeViteConfigMetadata, } from "./types";
@@ -1,17 +1,19 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.BUILD_PIPELINE_CAPABILITY = exports.isSupportedViteBuildScript = exports.DefaultBuildPipeline = exports.createBuildPipeline = exports.createViteConfigNotExecutedDiagnostic = exports.createUnsupportedBuildScriptDiagnostic = exports.createUnresolvedImportDiagnostic = exports.createMissingEntryDiagnostic = exports.createMissingBuildScriptDiagnostic = exports.createEsbuildWorkerTransformDiagnostic = exports.createBuildCancelledDiagnostic = void 0;
3
+ exports.BUILD_PIPELINE_CAPABILITY = exports.DefaultBuildPipeline = exports.createBuildPipeline = exports.createViteConfigNotExecutedDiagnostic = exports.createUnresolvedImportDiagnostic = exports.createMissingEntryDiagnostic = exports.createEsbuildWorkerTransformDiagnostic = exports.createBuildCancelledDiagnostic = exports.createAngularZoneJsRequiredDiagnostic = exports.createAngularResourceTransformFailedDiagnostic = exports.createAngularResourceNotFoundDiagnostic = exports.createAngularPartialLinkerRequiredDiagnostic = exports.createAngularExternalResourceUnsupportedDiagnostic = void 0;
4
4
  var diagnostics_1 = require("./diagnostics");
5
+ Object.defineProperty(exports, "createAngularExternalResourceUnsupportedDiagnostic", { enumerable: true, get: function () { return diagnostics_1.createAngularExternalResourceUnsupportedDiagnostic; } });
6
+ Object.defineProperty(exports, "createAngularPartialLinkerRequiredDiagnostic", { enumerable: true, get: function () { return diagnostics_1.createAngularPartialLinkerRequiredDiagnostic; } });
7
+ Object.defineProperty(exports, "createAngularResourceNotFoundDiagnostic", { enumerable: true, get: function () { return diagnostics_1.createAngularResourceNotFoundDiagnostic; } });
8
+ Object.defineProperty(exports, "createAngularResourceTransformFailedDiagnostic", { enumerable: true, get: function () { return diagnostics_1.createAngularResourceTransformFailedDiagnostic; } });
9
+ Object.defineProperty(exports, "createAngularZoneJsRequiredDiagnostic", { enumerable: true, get: function () { return diagnostics_1.createAngularZoneJsRequiredDiagnostic; } });
5
10
  Object.defineProperty(exports, "createBuildCancelledDiagnostic", { enumerable: true, get: function () { return diagnostics_1.createBuildCancelledDiagnostic; } });
6
11
  Object.defineProperty(exports, "createEsbuildWorkerTransformDiagnostic", { enumerable: true, get: function () { return diagnostics_1.createEsbuildWorkerTransformDiagnostic; } });
7
- Object.defineProperty(exports, "createMissingBuildScriptDiagnostic", { enumerable: true, get: function () { return diagnostics_1.createMissingBuildScriptDiagnostic; } });
8
12
  Object.defineProperty(exports, "createMissingEntryDiagnostic", { enumerable: true, get: function () { return diagnostics_1.createMissingEntryDiagnostic; } });
9
13
  Object.defineProperty(exports, "createUnresolvedImportDiagnostic", { enumerable: true, get: function () { return diagnostics_1.createUnresolvedImportDiagnostic; } });
10
- Object.defineProperty(exports, "createUnsupportedBuildScriptDiagnostic", { enumerable: true, get: function () { return diagnostics_1.createUnsupportedBuildScriptDiagnostic; } });
11
14
  Object.defineProperty(exports, "createViteConfigNotExecutedDiagnostic", { enumerable: true, get: function () { return diagnostics_1.createViteConfigNotExecutedDiagnostic; } });
12
15
  var pipeline_1 = require("./pipeline");
13
16
  Object.defineProperty(exports, "createBuildPipeline", { enumerable: true, get: function () { return pipeline_1.createBuildPipeline; } });
14
17
  Object.defineProperty(exports, "DefaultBuildPipeline", { enumerable: true, get: function () { return pipeline_1.DefaultBuildPipeline; } });
15
- Object.defineProperty(exports, "isSupportedViteBuildScript", { enumerable: true, get: function () { return pipeline_1.isSupportedViteBuildScript; } });
16
18
  var types_1 = require("./types");
17
19
  Object.defineProperty(exports, "BUILD_PIPELINE_CAPABILITY", { enumerable: true, get: function () { return types_1.BUILD_PIPELINE_CAPABILITY; } });