@ng-prism/core 21.10.1 → 21.10.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/builder/scanner/component.scanner.d.ts.map +1 -1
- package/dist/builder/scanner/component.scanner.js +5 -0
- package/dist/builder/scanner/entry-point.scanner.d.ts +15 -4
- package/dist/builder/scanner/entry-point.scanner.d.ts.map +1 -1
- package/dist/builder/scanner/entry-point.scanner.js +26 -13
- package/dist/builder/scanner/index.d.ts +2 -2
- package/dist/builder/scanner/index.d.ts.map +1 -1
- package/dist/builder/scanner/scanner.d.ts +15 -6
- package/dist/builder/scanner/scanner.d.ts.map +1 -1
- package/dist/builder/scanner/scanner.js +44 -7
- package/dist/builder/shared/prism-pipeline.d.ts +3 -1
- package/dist/builder/shared/prism-pipeline.d.ts.map +1 -1
- package/dist/builder/shared/prism-pipeline.js +53 -27
- package/dist/schematics/ng-add/index.js +1 -2
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"component.scanner.d.ts","sourceRoot":"","sources":["../../../src/builder/scanner/component.scanner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAiBrE;;GAEG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,EAAE,CAAC,MAAM,EAAE,EACpB,OAAO,EAAE,EAAE,CAAC,WAAW,GACtB,gBAAgB,EAAE,
|
|
1
|
+
{"version":3,"file":"component.scanner.d.ts","sourceRoot":"","sources":["../../../src/builder/scanner/component.scanner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAiBrE;;GAEG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,EAAE,CAAC,MAAM,EAAE,EACpB,OAAO,EAAE,EAAE,CAAC,WAAW,GACtB,gBAAgB,EAAE,CA8CpB"}
|
|
@@ -16,6 +16,11 @@ export function scanComponents(exports, checker) {
|
|
|
16
16
|
const classDecl = resolved.declarations?.find(ts.isClassDeclaration);
|
|
17
17
|
if (!classDecl)
|
|
18
18
|
continue;
|
|
19
|
+
// Perf: cheap pre-filter — skip the full decorator walk for files that don't
|
|
20
|
+
// mention Showcase at all. False positives (string-literal containing "@Showcase")
|
|
21
|
+
// just lose the optimization for that file; correctness is unaffected.
|
|
22
|
+
if (!classDecl.getSourceFile().text.includes('@Showcase'))
|
|
23
|
+
continue;
|
|
19
24
|
const showcaseDecorator = findDecorator(classDecl, 'Showcase');
|
|
20
25
|
if (!showcaseDecorator)
|
|
21
26
|
continue;
|
|
@@ -1,11 +1,22 @@
|
|
|
1
1
|
import ts from 'typescript';
|
|
2
|
-
export interface
|
|
3
|
-
|
|
2
|
+
export interface EntryPointInput {
|
|
3
|
+
entryFile: string;
|
|
4
|
+
importPath: string;
|
|
5
|
+
}
|
|
6
|
+
export interface ResolvedEntryPoint extends EntryPointInput {
|
|
4
7
|
exports: ts.Symbol[];
|
|
5
8
|
}
|
|
9
|
+
export interface MultiEntryResult {
|
|
10
|
+
program: ts.Program;
|
|
11
|
+
entries: ResolvedEntryPoint[];
|
|
12
|
+
}
|
|
6
13
|
/**
|
|
7
|
-
* Resolve all exported symbols
|
|
14
|
+
* Resolve all exported symbols for one or more entry-point files (e.g. public-api.ts).
|
|
15
|
+
* A single shared `ts.Program` is created with every entry file as a root name, so the
|
|
16
|
+
* transitive type graph (Angular framework typings, etc.) is parsed once and reused
|
|
17
|
+
* across all entries via the shared `TypeChecker`.
|
|
18
|
+
*
|
|
8
19
|
* Re-exports (`export * from '...'`) are resolved automatically by TypeScript.
|
|
9
20
|
*/
|
|
10
|
-
export declare function resolveEntryPointExports(
|
|
21
|
+
export declare function resolveEntryPointExports(entryPoints: ReadonlyArray<EntryPointInput>, compilerOptions: ts.CompilerOptions, previousProgram?: ts.Program): MultiEntryResult;
|
|
11
22
|
//# sourceMappingURL=entry-point.scanner.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entry-point.scanner.d.ts","sourceRoot":"","sources":["../../../src/builder/scanner/entry-point.scanner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC;IACpB,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"entry-point.scanner.d.ts","sourceRoot":"","sources":["../../../src/builder/scanner/entry-point.scanner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,kBAAmB,SAAQ,eAAe;IACzD,OAAO,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC;IACpB,OAAO,EAAE,kBAAkB,EAAE,CAAC;CAC/B;AAED;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CACtC,WAAW,EAAE,aAAa,CAAC,eAAe,CAAC,EAC3C,eAAe,EAAE,EAAE,CAAC,eAAe,EACnC,eAAe,CAAC,EAAE,EAAE,CAAC,OAAO,GAC3B,gBAAgB,CAoClB"}
|
|
@@ -1,19 +1,32 @@
|
|
|
1
1
|
import ts from 'typescript';
|
|
2
2
|
/**
|
|
3
|
-
* Resolve all exported symbols
|
|
3
|
+
* Resolve all exported symbols for one or more entry-point files (e.g. public-api.ts).
|
|
4
|
+
* A single shared `ts.Program` is created with every entry file as a root name, so the
|
|
5
|
+
* transitive type graph (Angular framework typings, etc.) is parsed once and reused
|
|
6
|
+
* across all entries via the shared `TypeChecker`.
|
|
7
|
+
*
|
|
4
8
|
* Re-exports (`export * from '...'`) are resolved automatically by TypeScript.
|
|
5
9
|
*/
|
|
6
|
-
export function resolveEntryPointExports(
|
|
7
|
-
const program = ts.createProgram(
|
|
10
|
+
export function resolveEntryPointExports(entryPoints, compilerOptions, previousProgram) {
|
|
11
|
+
const program = ts.createProgram(entryPoints.map((e) => e.entryFile), compilerOptions, undefined, previousProgram);
|
|
8
12
|
const checker = program.getTypeChecker();
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
13
|
+
const entries = entryPoints.map(({ entryFile, importPath }) => {
|
|
14
|
+
try {
|
|
15
|
+
const sourceFile = program.getSourceFile(entryFile);
|
|
16
|
+
if (!sourceFile) {
|
|
17
|
+
console.warn(`⚠ ng-prism: source file not found for entry point ${entryFile}, skipping.`);
|
|
18
|
+
return { entryFile, importPath, exports: [] };
|
|
19
|
+
}
|
|
20
|
+
const moduleSymbol = checker.getSymbolAtLocation(sourceFile);
|
|
21
|
+
const exports = moduleSymbol
|
|
22
|
+
? checker.getExportsOfModule(moduleSymbol)
|
|
23
|
+
: [];
|
|
24
|
+
return { entryFile, importPath, exports };
|
|
25
|
+
}
|
|
26
|
+
catch (err) {
|
|
27
|
+
console.error(`⚠ ng-prism: failed to resolve exports for ${entryFile}: ${err instanceof Error ? err.message : String(err)}`);
|
|
28
|
+
return { entryFile, importPath, exports: [] };
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
return { program, entries };
|
|
19
32
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { createScanner } from './scanner.js';
|
|
2
|
-
export type { CreateScannerOptions, Scanner } from './scanner.js';
|
|
2
|
+
export type { CreateScannerOptions, Scanner, ScanResult } from './scanner.js';
|
|
3
3
|
export { resolveEntryPointExports } from './entry-point.scanner.js';
|
|
4
|
-
export type {
|
|
4
|
+
export type { EntryPointInput, ResolvedEntryPoint, MultiEntryResult, } from './entry-point.scanner.js';
|
|
5
5
|
export { scanComponents } from './component.scanner.js';
|
|
6
6
|
export { extractInputs, extractOutputs } from './input.extractor.js';
|
|
7
7
|
export { generateManifest } from './manifest.generator.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/builder/scanner/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,YAAY,EAAE,oBAAoB,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/builder/scanner/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,YAAY,EAAE,oBAAoB,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC9E,OAAO,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AACpE,YAAY,EACV,eAAe,EACf,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC"}
|
|
@@ -1,16 +1,25 @@
|
|
|
1
1
|
import ts from 'typescript';
|
|
2
|
-
import type {
|
|
2
|
+
import type { ScannedComponent } from '../../plugin/plugin.types.js';
|
|
3
|
+
import { type EntryPointInput } from './entry-point.scanner.js';
|
|
3
4
|
export interface CreateScannerOptions {
|
|
4
|
-
|
|
5
|
+
entryPoints: ReadonlyArray<EntryPointInput>;
|
|
5
6
|
compilerOptions?: ts.CompilerOptions;
|
|
6
7
|
}
|
|
8
|
+
export interface ScanResult {
|
|
9
|
+
components: ScannedComponent[];
|
|
10
|
+
}
|
|
7
11
|
export interface Scanner {
|
|
8
|
-
/** Scan
|
|
9
|
-
scan():
|
|
12
|
+
/** Scan all entry points. Reuses TypeScript program state from previous scans. */
|
|
13
|
+
scan(): ScanResult;
|
|
10
14
|
}
|
|
11
15
|
/**
|
|
12
|
-
* Create a stateful scanner that retains the previous ts.Program between scans.
|
|
13
|
-
*
|
|
16
|
+
* Create a stateful multi-entry scanner that retains the previous ts.Program between scans.
|
|
17
|
+
* A single shared program is created with every entry-point file as a root name, so the
|
|
18
|
+
* transitive type graph (Angular framework typings, etc.) is parsed once and shared via
|
|
19
|
+
* the program's `TypeChecker` — instead of N programs that each load Material/CDK/RxJS.
|
|
20
|
+
*
|
|
21
|
+
* TypeScript reuses parsed SourceFile objects from the old program on rebuild, making
|
|
22
|
+
* incremental scans fast.
|
|
14
23
|
*/
|
|
15
24
|
export declare function createScanner(options: CreateScannerOptions): Scanner;
|
|
16
25
|
//# sourceMappingURL=scanner.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../../../src/builder/scanner/scanner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../../../src/builder/scanner/scanner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAEL,KAAK,eAAe,EACrB,MAAM,0BAA0B,CAAC;AAGlC,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;IAC5C,eAAe,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC;CACtC;AAED,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,gBAAgB,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,OAAO;IACtB,kFAAkF;IAClF,IAAI,IAAI,UAAU,CAAC;CACpB;AAkBD;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAoDpE"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import ts from 'typescript';
|
|
2
|
-
import { resolveEntryPointExports } from './entry-point.scanner.js';
|
|
2
|
+
import { resolveEntryPointExports, } from './entry-point.scanner.js';
|
|
3
3
|
import { scanComponents } from './component.scanner.js';
|
|
4
4
|
const DEFAULT_COMPILER_OPTIONS = {
|
|
5
5
|
target: ts.ScriptTarget.ES2022,
|
|
@@ -8,21 +8,58 @@ const DEFAULT_COMPILER_OPTIONS = {
|
|
|
8
8
|
experimentalDecorators: true,
|
|
9
9
|
strict: true,
|
|
10
10
|
skipLibCheck: true,
|
|
11
|
+
// Perf: skip auto-loading every @types/* package; library source rarely needs ambient globals.
|
|
12
|
+
// Users with explicit needs can pass `types: ['node']` via tsconfig.json paths.
|
|
13
|
+
types: [],
|
|
14
|
+
// Perf: we never call program.emit(); skip emit-related setup work.
|
|
15
|
+
noEmit: true,
|
|
16
|
+
// Perf: complement to skipLibCheck — also skip type-checking lib.*.d.ts files.
|
|
17
|
+
skipDefaultLibCheck: true,
|
|
11
18
|
};
|
|
12
19
|
/**
|
|
13
|
-
* Create a stateful scanner that retains the previous ts.Program between scans.
|
|
14
|
-
*
|
|
20
|
+
* Create a stateful multi-entry scanner that retains the previous ts.Program between scans.
|
|
21
|
+
* A single shared program is created with every entry-point file as a root name, so the
|
|
22
|
+
* transitive type graph (Angular framework typings, etc.) is parsed once and shared via
|
|
23
|
+
* the program's `TypeChecker` — instead of N programs that each load Material/CDK/RxJS.
|
|
24
|
+
*
|
|
25
|
+
* TypeScript reuses parsed SourceFile objects from the old program on rebuild, making
|
|
26
|
+
* incremental scans fast.
|
|
15
27
|
*/
|
|
16
28
|
export function createScanner(options) {
|
|
17
|
-
const compilerOptions = {
|
|
29
|
+
const compilerOptions = {
|
|
30
|
+
...DEFAULT_COMPILER_OPTIONS,
|
|
31
|
+
...options.compilerOptions,
|
|
32
|
+
};
|
|
18
33
|
let previousProgram;
|
|
19
34
|
return {
|
|
20
35
|
scan() {
|
|
21
|
-
const { program,
|
|
36
|
+
const { program, entries } = resolveEntryPointExports(options.entryPoints, compilerOptions, previousProgram);
|
|
22
37
|
previousProgram = program;
|
|
23
38
|
const checker = program.getTypeChecker();
|
|
24
|
-
const
|
|
25
|
-
|
|
39
|
+
const allComponents = [];
|
|
40
|
+
for (const { exports, importPath } of entries) {
|
|
41
|
+
const components = scanComponents(exports, checker);
|
|
42
|
+
for (const c of components)
|
|
43
|
+
c.importPath = importPath;
|
|
44
|
+
allComponents.push(...components);
|
|
45
|
+
}
|
|
46
|
+
// Dedupe by (filePath, className): if a component class is re-exported from
|
|
47
|
+
// multiple entry points (e.g. atoms/button + barrel index.ts), we keep the first
|
|
48
|
+
// occurrence. The duplicate would otherwise produce duplicate imports in the
|
|
49
|
+
// generated manifest and a runtime collision in the Prism shell.
|
|
50
|
+
const seen = new Set();
|
|
51
|
+
const unique = [];
|
|
52
|
+
for (const c of allComponents) {
|
|
53
|
+
const key = `${c.filePath}::${c.className}`;
|
|
54
|
+
if (seen.has(key)) {
|
|
55
|
+
console.warn(`⚠ ng-prism: ${c.className} is exported by multiple entry points; ` +
|
|
56
|
+
`keeping the first occurrence (importPath: ${unique.find((u) => u.className === c.className && u.filePath === c.filePath)?.importPath}).`);
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
seen.add(key);
|
|
60
|
+
unique.push(c);
|
|
61
|
+
}
|
|
62
|
+
return { components: unique };
|
|
26
63
|
},
|
|
27
64
|
};
|
|
28
65
|
}
|
|
@@ -14,7 +14,9 @@ export interface PrismPipelineResult {
|
|
|
14
14
|
written: boolean;
|
|
15
15
|
}
|
|
16
16
|
export interface PrismPipelineState {
|
|
17
|
-
|
|
17
|
+
scanner: Scanner | undefined;
|
|
18
|
+
/** Sorted, joined entry-file paths — used to detect when the entry set changed between rebuilds. */
|
|
19
|
+
lastEntrySetKey: string | undefined;
|
|
18
20
|
}
|
|
19
21
|
export declare function createPipelineState(): PrismPipelineState;
|
|
20
22
|
export declare function runPrismPipeline(options: PrismPipelineOptions, context: BuilderContext, state: PrismPipelineState): Promise<PrismPipelineResult>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prism-pipeline.d.ts","sourceRoot":"","sources":["../../../src/builder/shared/prism-pipeline.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"prism-pipeline.d.ts","sourceRoot":"","sources":["../../../src/builder/shared/prism-pipeline.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAGhE,OAAO,EAAiB,KAAK,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAOpE,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,mBAAmB;IAClC,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,mGAAmG;IACnG,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,GAAG,SAAS,CAAC;IAC7B,oGAAoG;IACpG,eAAe,EAAE,MAAM,GAAG,SAAS,CAAC;CACrC;AAED,wBAAgB,mBAAmB,IAAI,kBAAkB,CAExD;AAED,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,oBAAoB,EAC7B,OAAO,EAAE,cAAc,EACvB,KAAK,EAAE,kBAAkB,GACxB,OAAO,CAAC,mBAAmB,CAAC,CAoD9B"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { join, dirname } from 'path';
|
|
2
|
-
import { writeFileSync, readFileSync, mkdirSync, statSync, renameSync, existsSync, unlinkSync } from 'fs';
|
|
2
|
+
import { writeFileSync, readFileSync, mkdirSync, statSync, renameSync, existsSync, unlinkSync, } from 'fs';
|
|
3
3
|
import ts from 'typescript';
|
|
4
4
|
import { createScanner } from '../scanner/scanner.js';
|
|
5
5
|
import { discoverSecondaryEntryPoints } from '../scanner/entry-point-discovery.js';
|
|
@@ -7,7 +7,7 @@ import { loadConfig } from '../config-loader/config-loader.js';
|
|
|
7
7
|
import { runPluginHooks } from '../plugin-runner/plugin-runner.js';
|
|
8
8
|
import { generateRuntimeManifest } from '../manifest/runtime-manifest.generator.js';
|
|
9
9
|
export function createPipelineState() {
|
|
10
|
-
return {
|
|
10
|
+
return { scanner: undefined, lastEntrySetKey: undefined };
|
|
11
11
|
}
|
|
12
12
|
export async function runPrismPipeline(options, context, state) {
|
|
13
13
|
const { workspaceRoot } = context;
|
|
@@ -28,8 +28,8 @@ export async function runPrismPipeline(options, context, state) {
|
|
|
28
28
|
pages: manifest.pages,
|
|
29
29
|
});
|
|
30
30
|
const projectMeta = await context.getProjectMetadata(options.prismProject);
|
|
31
|
-
const sourceRoot = projectMeta['sourceRoot']
|
|
32
|
-
|
|
31
|
+
const sourceRoot = projectMeta['sourceRoot'] ??
|
|
32
|
+
join('projects', options.prismProject, 'src');
|
|
33
33
|
const manifestPath = join(workspaceRoot, sourceRoot, 'prism-manifest.ts');
|
|
34
34
|
mkdirSync(join(workspaceRoot, sourceRoot), { recursive: true });
|
|
35
35
|
const written = writeManifestIfChanged(manifestPath, source);
|
|
@@ -63,7 +63,9 @@ function writeManifestIfChanged(manifestPath, newContent) {
|
|
|
63
63
|
try {
|
|
64
64
|
unlinkSync(tempPath);
|
|
65
65
|
}
|
|
66
|
-
catch {
|
|
66
|
+
catch {
|
|
67
|
+
/* best-effort cleanup */
|
|
68
|
+
}
|
|
67
69
|
}
|
|
68
70
|
throw err;
|
|
69
71
|
}
|
|
@@ -77,6 +79,18 @@ function isDirectory(path) {
|
|
|
77
79
|
return false;
|
|
78
80
|
}
|
|
79
81
|
}
|
|
82
|
+
function findLibraryRoot(filePath) {
|
|
83
|
+
let dir = dirname(filePath);
|
|
84
|
+
let parent = dirname(dir);
|
|
85
|
+
while (dir !== parent) {
|
|
86
|
+
if (existsSync(join(dir, 'ng-package.json'))) {
|
|
87
|
+
return dir;
|
|
88
|
+
}
|
|
89
|
+
dir = parent;
|
|
90
|
+
parent = dirname(dir);
|
|
91
|
+
}
|
|
92
|
+
return undefined;
|
|
93
|
+
}
|
|
80
94
|
function resolveTsconfigPaths(entryPointDir) {
|
|
81
95
|
const configPath = ts.findConfigFile(entryPointDir, ts.sys.fileExists, 'tsconfig.json');
|
|
82
96
|
if (!configPath)
|
|
@@ -92,29 +106,41 @@ function resolveTsconfigPaths(entryPointDir) {
|
|
|
92
106
|
result.baseUrl = parsed.options.baseUrl;
|
|
93
107
|
return result;
|
|
94
108
|
}
|
|
95
|
-
function
|
|
109
|
+
function resolveEntryPoints(workspaceRoot, options) {
|
|
96
110
|
const absoluteEntryPoint = join(workspaceRoot, options.entryPoint);
|
|
97
|
-
const
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
const
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
111
|
+
const compilerOptions = resolveTsconfigPaths(dirname(absoluteEntryPoint));
|
|
112
|
+
const entryIsDirectory = isDirectory(absoluteEntryPoint);
|
|
113
|
+
const libraryRoot = entryIsDirectory
|
|
114
|
+
? absoluteEntryPoint
|
|
115
|
+
: findLibraryRoot(absoluteEntryPoint);
|
|
116
|
+
const discovered = libraryRoot
|
|
117
|
+
? discoverSecondaryEntryPoints(libraryRoot, options.libraryImportPath)
|
|
118
|
+
: [];
|
|
119
|
+
// Fallback to a direct file scan when:
|
|
120
|
+
// - the entry is a file and no ng-package.json was found above it, OR
|
|
121
|
+
// - the entry is a file with an ng-package.json above it but discovery found nothing
|
|
122
|
+
// (e.g. primary-only library, root ng-package.json carries `dest`).
|
|
123
|
+
const entryPoints = discovered.length === 0 && !entryIsDirectory
|
|
124
|
+
? [
|
|
125
|
+
{
|
|
126
|
+
entryFile: absoluteEntryPoint,
|
|
127
|
+
importPath: options.libraryImportPath,
|
|
128
|
+
},
|
|
129
|
+
]
|
|
130
|
+
: discovered;
|
|
131
|
+
return { entryPoints, compilerOptions };
|
|
112
132
|
}
|
|
113
|
-
function
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
133
|
+
function scanEntryPoints(workspaceRoot, options, state) {
|
|
134
|
+
const { entryPoints, compilerOptions } = resolveEntryPoints(workspaceRoot, options);
|
|
135
|
+
const newKey = entryPoints
|
|
136
|
+
.map((e) => e.entryFile)
|
|
137
|
+
.slice()
|
|
138
|
+
.sort()
|
|
139
|
+
.join('|');
|
|
140
|
+
if (newKey !== state.lastEntrySetKey) {
|
|
141
|
+
state.scanner = undefined;
|
|
142
|
+
state.lastEntrySetKey = newKey;
|
|
118
143
|
}
|
|
119
|
-
|
|
144
|
+
state.scanner ??= createScanner({ entryPoints, compilerOptions });
|
|
145
|
+
return state.scanner.scan();
|
|
120
146
|
}
|
|
@@ -141,8 +141,7 @@ function addBuilderTargets(options) {
|
|
|
141
141
|
const project = workspace.projects[options.project];
|
|
142
142
|
const prismProjectName = `${options.project}-prism`;
|
|
143
143
|
const port = options.port ?? 4400;
|
|
144
|
-
const
|
|
145
|
-
const entryPoint = `${sourceRoot}/public-api.ts`;
|
|
144
|
+
const entryPoint = project.root ?? project.sourceRoot ?? `projects/${options.project}`;
|
|
146
145
|
if (!project.architect) {
|
|
147
146
|
project.architect = {};
|
|
148
147
|
}
|
package/package.json
CHANGED