@telorun/analyzer 0.8.1 → 0.10.0
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/analysis-registry.d.ts +5 -0
- package/dist/analysis-registry.d.ts.map +1 -1
- package/dist/analysis-registry.js +7 -2
- package/dist/analyzer.d.ts.map +1 -1
- package/dist/analyzer.js +5 -5
- package/dist/definition-registry.d.ts +13 -1
- package/dist/definition-registry.d.ts.map +1 -1
- package/dist/definition-registry.js +58 -2
- package/dist/dependency-graph.d.ts +1 -1
- package/dist/dependency-graph.d.ts.map +1 -1
- package/dist/dependency-graph.js +8 -2
- package/dist/flatten-for-analyzer.d.ts +30 -0
- package/dist/flatten-for-analyzer.d.ts.map +1 -0
- package/dist/flatten-for-analyzer.js +119 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/loaded-types.d.ts +81 -0
- package/dist/loaded-types.d.ts.map +1 -0
- package/dist/loaded-types.js +1 -0
- package/dist/manifest-loader.d.ts +30 -9
- package/dist/manifest-loader.d.ts.map +1 -1
- package/dist/manifest-loader.js +197 -417
- package/dist/normalize-inline-resources.d.ts +1 -1
- package/dist/normalize-inline-resources.d.ts.map +1 -1
- package/dist/normalize-inline-resources.js +7 -2
- package/dist/parse-loaded-file.d.ts +12 -0
- package/dist/parse-loaded-file.d.ts.map +1 -0
- package/dist/parse-loaded-file.js +50 -0
- package/dist/position-metadata.d.ts +27 -0
- package/dist/position-metadata.d.ts.map +1 -0
- package/dist/position-metadata.js +88 -0
- package/dist/reference-field-map.d.ts +5 -0
- package/dist/reference-field-map.d.ts.map +1 -1
- package/dist/reference-field-map.js +9 -0
- package/dist/types.d.ts +6 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/validate-references.d.ts.map +1 -1
- package/dist/validate-references.js +68 -1
- package/package.json +3 -3
- package/src/analysis-registry.ts +11 -2
- package/src/analyzer.ts +17 -5
- package/src/definition-registry.ts +76 -3
- package/src/dependency-graph.ts +9 -1
- package/src/flatten-for-analyzer.ts +134 -0
- package/src/index.ts +18 -0
- package/src/loaded-types.ts +86 -0
- package/src/manifest-loader.ts +230 -459
- package/src/normalize-inline-resources.ts +8 -1
- package/src/parse-loaded-file.ts +70 -0
- package/src/position-metadata.ts +106 -0
- package/src/reference-field-map.ts +13 -0
- package/src/types.ts +6 -0
- package/src/validate-references.ts +74 -1
|
@@ -8,6 +8,7 @@ import type { AnalysisContext } from "./types.js";
|
|
|
8
8
|
export declare class AnalysisRegistry {
|
|
9
9
|
private readonly defs;
|
|
10
10
|
private readonly aliases;
|
|
11
|
+
private readonly aliasesByModule;
|
|
11
12
|
registerDefinition(def: ResourceDefinition): void;
|
|
12
13
|
registerModuleIdentity(namespace: string | null, name: string): void;
|
|
13
14
|
registerImport(alias: string, target: string, kinds: string[]): void;
|
|
@@ -15,6 +16,10 @@ export declare class AnalysisRegistry {
|
|
|
15
16
|
/**
|
|
16
17
|
* Iterates a resource's reference and scope fields as declared by its definition.
|
|
17
18
|
* Calls onRef for each plain reference field and onScope for each scope field.
|
|
19
|
+
*
|
|
20
|
+
* Uses the expanded field map so x-telo-schema-from entries contribute their
|
|
21
|
+
* nested ref/scope slots — Phase 5 injection sees encoders that live inside a
|
|
22
|
+
* sub-schema (e.g. Server.notFoundHandler.returns[].content[mime].encoder).
|
|
18
23
|
*/
|
|
19
24
|
iterateFieldEntries(resource: ResourceManifest, onRef: (fieldPath: string) => void, onScope: (fieldPath: string) => void): void;
|
|
20
25
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analysis-registry.d.ts","sourceRoot":"","sources":["../src/analysis-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAMzE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD;;;;GAIG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA4B;IACjD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAuB;
|
|
1
|
+
{"version":3,"file":"analysis-registry.d.ts","sourceRoot":"","sources":["../src/analysis-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAMzE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD;;;;GAIG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA4B;IACjD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAuB;IAC/C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAoC;IAEpE,kBAAkB,CAAC,GAAG,EAAE,kBAAkB,GAAG,IAAI;IAIjD,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAIpE,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI;IAIpE,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAI7C;;;;;;;OAOG;IACH,mBAAmB,CACjB,QAAQ,EAAE,gBAAgB,EAC1B,KAAK,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,EAClC,OAAO,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,GACnC,IAAI;IAkBP;;;;OAIG;IACH,kBAAkB,IAAI,kBAAkB,EAAE;IAI1C,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS;IAM/D,QAAQ,IAAI,MAAM,EAAE;IAIpB;mEAC+D;IAC/D,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE;IAIxC;;;gCAG4B;IAC5B,oBAAoB,IAAI,MAAM,EAAE;IAIhC;wEACoE;IACpE,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAIhD,qFAAqF;IACrF,QAAQ,IAAI,eAAe;CAG5B"}
|
|
@@ -11,6 +11,7 @@ import { isRefEntry, isScopeEntry } from "./reference-field-map.js";
|
|
|
11
11
|
export class AnalysisRegistry {
|
|
12
12
|
defs = new DefinitionRegistry();
|
|
13
13
|
aliases = new AliasResolver();
|
|
14
|
+
aliasesByModule = new Map();
|
|
14
15
|
registerDefinition(def) {
|
|
15
16
|
this.defs.register(def);
|
|
16
17
|
}
|
|
@@ -26,9 +27,13 @@ export class AnalysisRegistry {
|
|
|
26
27
|
/**
|
|
27
28
|
* Iterates a resource's reference and scope fields as declared by its definition.
|
|
28
29
|
* Calls onRef for each plain reference field and onScope for each scope field.
|
|
30
|
+
*
|
|
31
|
+
* Uses the expanded field map so x-telo-schema-from entries contribute their
|
|
32
|
+
* nested ref/scope slots — Phase 5 injection sees encoders that live inside a
|
|
33
|
+
* sub-schema (e.g. Server.notFoundHandler.returns[].content[mime].encoder).
|
|
29
34
|
*/
|
|
30
35
|
iterateFieldEntries(resource, onRef, onScope) {
|
|
31
|
-
const fieldMap = this.defs.
|
|
36
|
+
const fieldMap = this.defs.expandedFieldMapForResource(resource, this.aliases, this.aliasesByModule);
|
|
32
37
|
if (!fieldMap)
|
|
33
38
|
return;
|
|
34
39
|
for (const [fieldPath, entry] of fieldMap) {
|
|
@@ -76,6 +81,6 @@ export class AnalysisRegistry {
|
|
|
76
81
|
}
|
|
77
82
|
/** @internal Bridge for StaticAnalyzer — do not use outside the analyzer package. */
|
|
78
83
|
_context() {
|
|
79
|
-
return { aliases: this.aliases, definitions: this.defs };
|
|
84
|
+
return { aliases: this.aliases, definitions: this.defs, aliasesByModule: this.aliasesByModule };
|
|
80
85
|
}
|
|
81
86
|
}
|
package/dist/analyzer.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analyzer.d.ts","sourceRoot":"","sources":["../src/analyzer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAsB,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAIzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAGL,KAAK,WAAW,EACjB,MAAM,sBAAsB,CAAC;AAa9B,OAAO,EAAsB,KAAK,kBAAkB,EAAE,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;AAgX/F,MAAM,WAAW,qBAAqB;IACpC,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAc;gBAEzB,OAAO,GAAE,qBAA0B;IAI/C,OAAO,CACL,SAAS,EAAE,gBAAgB,EAAE,EAC7B,OAAO,CAAC,EAAE,eAAe,EACzB,QAAQ,CAAC,EAAE,gBAAgB,GAC1B,kBAAkB,EAAE;
|
|
1
|
+
{"version":3,"file":"analyzer.d.ts","sourceRoot":"","sources":["../src/analyzer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAsB,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAIzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAGL,KAAK,WAAW,EACjB,MAAM,sBAAsB,CAAC;AAa9B,OAAO,EAAsB,KAAK,kBAAkB,EAAE,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;AAgX/F,MAAM,WAAW,qBAAqB;IACpC,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAc;gBAEzB,OAAO,GAAE,qBAA0B;IAI/C,OAAO,CACL,SAAS,EAAE,gBAAgB,EAAE,EAC7B,OAAO,CAAC,EAAE,eAAe,EACzB,QAAQ,CAAC,EAAE,gBAAgB,GAC1B,kBAAkB,EAAE;IAqUvB,aAAa,CACX,SAAS,EAAE,gBAAgB,EAAE,EAC7B,OAAO,CAAC,EAAE,eAAe,EACzB,QAAQ,CAAC,EAAE,gBAAgB,GAC1B,kBAAkB,EAAE;IAMvB,SAAS,CAAC,SAAS,EAAE,gBAAgB,EAAE,EAAE,QAAQ,EAAE,gBAAgB,GAAG,gBAAgB,EAAE;IAUxF,OAAO,CACL,SAAS,EAAE,gBAAgB,EAAE,EAC7B,QAAQ,EAAE,gBAAgB,GACzB;QAAE,WAAW,EAAE,kBAAkB,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;QAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE;CAsB5F"}
|
package/dist/analyzer.js
CHANGED
|
@@ -324,7 +324,7 @@ export class StaticAnalyzer {
|
|
|
324
324
|
rootModules.add(m.metadata.name);
|
|
325
325
|
}
|
|
326
326
|
}
|
|
327
|
-
const aliasesByModule = new Map();
|
|
327
|
+
const aliasesByModule = ctx?.aliasesByModule ?? new Map();
|
|
328
328
|
for (const m of manifests) {
|
|
329
329
|
if (isModuleKind(m.kind)) {
|
|
330
330
|
const namespace = m.metadata.namespace ?? null;
|
|
@@ -412,7 +412,7 @@ export class StaticAnalyzer {
|
|
|
412
412
|
defs.register(normalized);
|
|
413
413
|
}
|
|
414
414
|
// Phase 2: extract inline resources from x-telo-ref slots into first-class manifests
|
|
415
|
-
const allManifests = normalizeInlineResources(manifests, defs, aliases);
|
|
415
|
+
const allManifests = normalizeInlineResources(manifests, defs, aliases, aliasesByModule);
|
|
416
416
|
// Build a name→manifest map for looking up referenced resources
|
|
417
417
|
const byName = new Map();
|
|
418
418
|
for (const m of allManifests) {
|
|
@@ -575,7 +575,7 @@ export class StaticAnalyzer {
|
|
|
575
575
|
});
|
|
576
576
|
}
|
|
577
577
|
// Validate resource references (Phase 3)
|
|
578
|
-
diagnostics.push(...validateReferences(allManifests, { aliases, definitions: defs }));
|
|
578
|
+
diagnostics.push(...validateReferences(allManifests, { aliases, definitions: defs, aliasesByModule }));
|
|
579
579
|
// Validate `extends` fields and flag legacy `capability: <UserAbstract>` overload.
|
|
580
580
|
diagnostics.push(...validateExtends(allManifests, defs, aliases));
|
|
581
581
|
// Validate throws: declarations and catches: coverage (rules 1, 2, 4, 7)
|
|
@@ -587,7 +587,7 @@ export class StaticAnalyzer {
|
|
|
587
587
|
}
|
|
588
588
|
normalize(manifests, registry) {
|
|
589
589
|
const ctx = registry._context();
|
|
590
|
-
return normalizeInlineResources(manifests, ctx.definitions, ctx.aliases);
|
|
590
|
+
return normalizeInlineResources(manifests, ctx.definitions, ctx.aliases, ctx.aliasesByModule);
|
|
591
591
|
}
|
|
592
592
|
prepare(manifests, registry) {
|
|
593
593
|
const ctx = registry._context();
|
|
@@ -596,7 +596,7 @@ export class StaticAnalyzer {
|
|
|
596
596
|
if (errors.length > 0) {
|
|
597
597
|
return { diagnostics: errors, order: null, cycleError: null };
|
|
598
598
|
}
|
|
599
|
-
const graph = buildDependencyGraph(manifests, ctx.definitions, ctx.aliases);
|
|
599
|
+
const graph = buildDependencyGraph(manifests, ctx.definitions, ctx.aliases, ctx.aliasesByModule);
|
|
600
600
|
if (graph.cycle) {
|
|
601
601
|
return { diagnostics: [], order: null, cycleError: formatCycle(graph.cycle) };
|
|
602
602
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { ResourceDefinition } from "@telorun/sdk";
|
|
1
|
+
import type { ResourceDefinition, ResourceManifest } from "@telorun/sdk";
|
|
2
|
+
import type { AliasResolver } from "./alias-resolver.js";
|
|
2
3
|
import { type ReferenceFieldMap } from "./reference-field-map.js";
|
|
3
4
|
/** Pure kind → ResourceDefinition map. No controller loading, no lifecycle. */
|
|
4
5
|
export declare class DefinitionRegistry {
|
|
@@ -50,6 +51,17 @@ export declare class DefinitionRegistry {
|
|
|
50
51
|
getFieldMapForKind(kind: string, aliases?: {
|
|
51
52
|
resolveKind(k: string): string | undefined;
|
|
52
53
|
}): ReferenceFieldMap | undefined;
|
|
54
|
+
/** Returns the field map for `resource.kind` with x-telo-schema-from entries replaced
|
|
55
|
+
* by their nested ref/scope slots — so Phase 2 inline normalization and Phase 5
|
|
56
|
+
* injection see encoders nested behind a schema-from indirection (e.g.
|
|
57
|
+
* http-server `Server.notFoundHandler.returns[].content[mime].encoder`).
|
|
58
|
+
*
|
|
59
|
+
* Only static absolute schema-from paths with a dotted alias anchor are expanded
|
|
60
|
+
* (e.g. "HttpDispatch.Outcomes/$defs/Returns"). Relative and unqualified absolute
|
|
61
|
+
* anchors depend on a sibling property at runtime and stay unexpanded; the
|
|
62
|
+
* analyzer's reference validation phase already flags the cases that matter. */
|
|
63
|
+
expandedFieldMapForResource(resource: ResourceManifest, aliases: AliasResolver, aliasesByModule: Map<string, AliasResolver>): ReferenceFieldMap | undefined;
|
|
64
|
+
private resolveSchemaFromSubMap;
|
|
53
65
|
/** Returns all definitions that transitively extend the given abstract kind.
|
|
54
66
|
* Follows the capability chain to any depth (equivalent to instanceof in OOP).
|
|
55
67
|
* Definitions are included regardless of registration order. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definition-registry.d.ts","sourceRoot":"","sources":["../src/definition-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"definition-registry.d.ts","sourceRoot":"","sources":["../src/definition-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,OAAO,EAIL,KAAK,iBAAiB,EACvB,MAAM,0BAA0B,CAAC;AAGlC,+EAA+E;AAC/E,qBAAa,kBAAkB;;IAK7B;;sFAEkF;IAClF,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;IACnC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAqB;IAEzD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAyC;IAC9D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAwC;IAClE,mEAAmE;IACnE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA+B;IAC1D;6DACyD;IACzD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA6B;IACzD;;0EAEsE;IACtE,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAA6B;IAEhE,QAAQ,CAAC,UAAU,EAAE,kBAAkB,GAAG,IAAI;IAiC9C,OAAO,CAAC,aAAa;IASrB;;;yFAGqF;IACrF,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI;IAgB1E;4EACwE;IACxE,SAAS,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAMnE;wFACoF;IACpF,gBAAgB,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,EAAE;IAWtE,OAAO,CAAC,iBAAiB;IAczB;;;;;;;;4FAQwF;IACxF,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAUhD,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS;IAIrD,+FAA+F;IAC/F,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS;IAIxD,gGAAgG;IAChG,kBAAkB,CAChB,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE;QAAE,WAAW,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;KAAE,GACvD,iBAAiB,GAAG,SAAS;IAOhC;;;;;;;;qFAQiF;IACjF,2BAA2B,CACzB,QAAQ,EAAE,gBAAgB,EAC1B,OAAO,EAAE,aAAa,EACtB,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,GAC1C,iBAAiB,GAAG,SAAS;IAuBhC,OAAO,CAAC,uBAAuB;IA+B/B;;qEAEiE;IACjE,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,kBAAkB,EAAE;IAgBxD,KAAK,IAAI,MAAM,EAAE;CAGlB"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { KERNEL_BUILTINS } from "./builtins.js";
|
|
2
|
-
import { buildReferenceFieldMap } from "./reference-field-map.js";
|
|
3
|
-
import { createAjv, formatSingleError } from "./schema-compat.js";
|
|
2
|
+
import { buildFieldMapAtPath, buildReferenceFieldMap, isSchemaFromEntry, } from "./reference-field-map.js";
|
|
3
|
+
import { createAjv, formatSingleError, navigateJsonPointer } from "./schema-compat.js";
|
|
4
4
|
/** Pure kind → ResourceDefinition map. No controller loading, no lifecycle. */
|
|
5
5
|
export class DefinitionRegistry {
|
|
6
6
|
constructor() {
|
|
@@ -147,6 +147,62 @@ export class DefinitionRegistry {
|
|
|
147
147
|
const resolved = aliases?.resolveKind(kind);
|
|
148
148
|
return resolved ? this.getFieldMap(resolved) : undefined;
|
|
149
149
|
}
|
|
150
|
+
/** Returns the field map for `resource.kind` with x-telo-schema-from entries replaced
|
|
151
|
+
* by their nested ref/scope slots — so Phase 2 inline normalization and Phase 5
|
|
152
|
+
* injection see encoders nested behind a schema-from indirection (e.g.
|
|
153
|
+
* http-server `Server.notFoundHandler.returns[].content[mime].encoder`).
|
|
154
|
+
*
|
|
155
|
+
* Only static absolute schema-from paths with a dotted alias anchor are expanded
|
|
156
|
+
* (e.g. "HttpDispatch.Outcomes/$defs/Returns"). Relative and unqualified absolute
|
|
157
|
+
* anchors depend on a sibling property at runtime and stay unexpanded; the
|
|
158
|
+
* analyzer's reference validation phase already flags the cases that matter. */
|
|
159
|
+
expandedFieldMapForResource(resource, aliases, aliasesByModule) {
|
|
160
|
+
const baseMap = this.getFieldMapForKind(resource.kind, aliases);
|
|
161
|
+
if (!baseMap)
|
|
162
|
+
return undefined;
|
|
163
|
+
const resolvedKind = aliases.resolveKind(resource.kind) ?? resource.kind;
|
|
164
|
+
const def = this.resolve(resource.kind) ?? this.resolve(resolvedKind);
|
|
165
|
+
const ownerModule = def?.metadata?.module;
|
|
166
|
+
const ownerScope = (ownerModule ? aliasesByModule.get(ownerModule) : undefined) ?? aliases;
|
|
167
|
+
const expanded = new Map();
|
|
168
|
+
for (const [path, entry] of baseMap) {
|
|
169
|
+
if (!isSchemaFromEntry(entry)) {
|
|
170
|
+
expanded.set(path, entry);
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
const sub = this.resolveSchemaFromSubMap(entry.schemaFrom, path, ownerScope);
|
|
174
|
+
if (!sub)
|
|
175
|
+
continue;
|
|
176
|
+
for (const [subPath, subEntry] of sub)
|
|
177
|
+
expanded.set(subPath, subEntry);
|
|
178
|
+
}
|
|
179
|
+
return expanded;
|
|
180
|
+
}
|
|
181
|
+
resolveSchemaFromSubMap(schemaFrom, fieldPath, ownerScope) {
|
|
182
|
+
const isAbsolute = schemaFrom.startsWith("/");
|
|
183
|
+
const expr = isAbsolute ? schemaFrom.slice(1) : schemaFrom;
|
|
184
|
+
const slashIdx = expr.indexOf("/");
|
|
185
|
+
if (slashIdx === -1)
|
|
186
|
+
return null;
|
|
187
|
+
const anchorName = expr.slice(0, slashIdx);
|
|
188
|
+
const jsonPointer = "/" + expr.slice(slashIdx + 1);
|
|
189
|
+
// Static form: absolute path whose anchor is a dotted alias (e.g.
|
|
190
|
+
// "HttpDispatch.Outcomes/$defs/Returns"). Polymorphic forms — relative
|
|
191
|
+
// anchors or single-segment absolute anchors — only resolve once we know a
|
|
192
|
+
// sibling property's value, which is per-resource.
|
|
193
|
+
if (!anchorName.includes("."))
|
|
194
|
+
return null;
|
|
195
|
+
const targetKind = ownerScope.resolveKind(anchorName);
|
|
196
|
+
if (!targetKind)
|
|
197
|
+
return null;
|
|
198
|
+
const targetDef = this.resolve(targetKind);
|
|
199
|
+
if (!targetDef?.schema)
|
|
200
|
+
return null;
|
|
201
|
+
const subSchema = navigateJsonPointer(targetDef.schema, jsonPointer);
|
|
202
|
+
if (!subSchema || typeof subSchema !== "object")
|
|
203
|
+
return null;
|
|
204
|
+
return buildFieldMapAtPath(subSchema, fieldPath);
|
|
205
|
+
}
|
|
150
206
|
/** Returns all definitions that transitively extend the given abstract kind.
|
|
151
207
|
* Follows the capability chain to any depth (equivalent to instanceof in OOP).
|
|
152
208
|
* Definitions are included regardless of registration order. */
|
|
@@ -25,7 +25,7 @@ export interface DependencyGraph {
|
|
|
25
25
|
* The registry is queried for each resource's field map by kind — callers do
|
|
26
26
|
* not pre-compute or pass field maps separately.
|
|
27
27
|
*/
|
|
28
|
-
export declare function buildDependencyGraph(resources: ResourceManifest[], registry: DefinitionRegistry, aliases?: AliasResolver): DependencyGraph;
|
|
28
|
+
export declare function buildDependencyGraph(resources: ResourceManifest[], registry: DefinitionRegistry, aliases?: AliasResolver, aliasesByModule?: Map<string, AliasResolver>): DependencyGraph;
|
|
29
29
|
/**
|
|
30
30
|
* Formats a cycle result into a human-readable error string matching the spec:
|
|
31
31
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dependency-graph.d.ts","sourceRoot":"","sources":["../src/dependency-graph.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAGnE,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,eAAe;IAC9B;kDAC8C;IAC9C,KAAK,CAAC,EAAE,aAAa,CAAC,YAAY,CAAC,CAAC;IACpC;oFACgF;IAChF,KAAK,CAAC,EAAE,aAAa,CAAC,YAAY,CAAC,CAAC;CACrC;AAcD;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,gBAAgB,EAAE,EAC7B,QAAQ,EAAE,kBAAkB,EAC5B,OAAO,CAAC,EAAE,aAAa,
|
|
1
|
+
{"version":3,"file":"dependency-graph.d.ts","sourceRoot":"","sources":["../src/dependency-graph.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAGnE,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,eAAe;IAC9B;kDAC8C;IAC9C,KAAK,CAAC,EAAE,aAAa,CAAC,YAAY,CAAC,CAAC;IACpC;oFACgF;IAChF,KAAK,CAAC,EAAE,aAAa,CAAC,YAAY,CAAC,CAAC;CACrC;AAcD;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,gBAAgB,EAAE,EAC7B,QAAQ,EAAE,kBAAkB,EAC5B,OAAO,CAAC,EAAE,aAAa,EACvB,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,GAC3C,eAAe,CA6FjB;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,aAAa,CAAC,YAAY,CAAC,GAAG,MAAM,CAOtE"}
|
package/dist/dependency-graph.js
CHANGED
|
@@ -21,7 +21,7 @@ const nodeKey = (kind, name) => `${kind}\0${name}`;
|
|
|
21
21
|
* The registry is queried for each resource's field map by kind — callers do
|
|
22
22
|
* not pre-compute or pass field maps separately.
|
|
23
23
|
*/
|
|
24
|
-
export function buildDependencyGraph(resources, registry, aliases) {
|
|
24
|
+
export function buildDependencyGraph(resources, registry, aliases, aliasesByModule) {
|
|
25
25
|
// --- Build node set ---
|
|
26
26
|
const nodes = new Map();
|
|
27
27
|
for (const r of resources) {
|
|
@@ -38,7 +38,13 @@ export function buildDependencyGraph(resources, registry, aliases) {
|
|
|
38
38
|
if (!r.metadata?.name || !r.kind || SYSTEM_KINDS.has(r.kind))
|
|
39
39
|
continue;
|
|
40
40
|
const sourceKey = nodeKey(r.kind, r.metadata.name);
|
|
41
|
-
|
|
41
|
+
// Use the expanded map so refs nested behind x-telo-schema-from contribute
|
|
42
|
+
// edges to the DAG. Without these, a parent (e.g. Http.Server) can init
|
|
43
|
+
// before its extracted encoder and Phase 5 injection fires against a
|
|
44
|
+
// not-yet-created dependency.
|
|
45
|
+
const fieldMap = aliases && aliasesByModule
|
|
46
|
+
? registry.expandedFieldMapForResource(r, aliases, aliasesByModule)
|
|
47
|
+
: registry.getFieldMapForKind(r.kind, aliases);
|
|
42
48
|
if (!fieldMap)
|
|
43
49
|
continue;
|
|
44
50
|
// Collect names of resources declared inside scope fields — these are initialized
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { ResourceManifest } from "@telorun/sdk";
|
|
2
|
+
import type { LoadedGraph, LoadedModule } from "./loaded-types.js";
|
|
3
|
+
/** Produce the flat manifest list `analyze()` consumes today.
|
|
4
|
+
*
|
|
5
|
+
* Combines the entry module's manifests with `Telo.Definition`,
|
|
6
|
+
* `Telo.Abstract`, and `Telo.Import` docs forwarded from imported libraries.
|
|
7
|
+
* Stamps three flavours of metadata along the way:
|
|
8
|
+
*
|
|
9
|
+
* - `metadata.source` and `metadata.sourceLine` — already on each manifest
|
|
10
|
+
* from `parseLoadedFile`, copied here unchanged.
|
|
11
|
+
* - `metadata.module` — the owning module's `Telo.Application` /
|
|
12
|
+
* `Telo.Library` `metadata.name`, applied to non-module manifests that
|
|
13
|
+
* don't already carry one.
|
|
14
|
+
* - `metadata.resolvedModuleName` / `metadata.resolvedNamespace` — for every
|
|
15
|
+
* `Telo.Import` manifest, looked up via `graph.importEdges` to find the
|
|
16
|
+
* target module's own `Telo.Library` identity. Without this, the
|
|
17
|
+
* analyzer's alias resolver and `validate-extends` fall back to
|
|
18
|
+
* path-derived identity and produce spurious diagnostics.
|
|
19
|
+
*
|
|
20
|
+
* Position metadata (`positionIndex`) is NOT stamped on manifests —
|
|
21
|
+
* callers look it up via `findPositions(graph, ...)` on the LoadedGraph. */
|
|
22
|
+
export declare function flattenForAnalyzer(graph: LoadedGraph): ResourceManifest[];
|
|
23
|
+
/** Project a LoadedModule (owner + partials) to a flat ResourceManifest[]
|
|
24
|
+
* with `metadata.module` stamped on non-module docs. The kernel's runtime
|
|
25
|
+
* entry load uses this to convert a `Loader.loadModule` result into the
|
|
26
|
+
* classic ResourceManifest[] shape it iterates over. Imports are not
|
|
27
|
+
* followed — the kernel's import-controller loads each import's module
|
|
28
|
+
* separately at runtime. */
|
|
29
|
+
export declare function flattenLoadedModule(mod: LoadedModule): ResourceManifest[];
|
|
30
|
+
//# sourceMappingURL=flatten-for-analyzer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flatten-for-analyzer.d.ts","sourceRoot":"","sources":["../src/flatten-for-analyzer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,KAAK,EAAc,WAAW,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAG/E;;;;;;;;;;;;;;;;;;6EAkB6E;AAC7E,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,WAAW,GAAG,gBAAgB,EAAE,CAyDzE;AAED;;;;;6BAK6B;AAC7B,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,YAAY,GAAG,gBAAgB,EAAE,CAEzE"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { isModuleKind } from "./module-kinds.js";
|
|
2
|
+
/** Produce the flat manifest list `analyze()` consumes today.
|
|
3
|
+
*
|
|
4
|
+
* Combines the entry module's manifests with `Telo.Definition`,
|
|
5
|
+
* `Telo.Abstract`, and `Telo.Import` docs forwarded from imported libraries.
|
|
6
|
+
* Stamps three flavours of metadata along the way:
|
|
7
|
+
*
|
|
8
|
+
* - `metadata.source` and `metadata.sourceLine` — already on each manifest
|
|
9
|
+
* from `parseLoadedFile`, copied here unchanged.
|
|
10
|
+
* - `metadata.module` — the owning module's `Telo.Application` /
|
|
11
|
+
* `Telo.Library` `metadata.name`, applied to non-module manifests that
|
|
12
|
+
* don't already carry one.
|
|
13
|
+
* - `metadata.resolvedModuleName` / `metadata.resolvedNamespace` — for every
|
|
14
|
+
* `Telo.Import` manifest, looked up via `graph.importEdges` to find the
|
|
15
|
+
* target module's own `Telo.Library` identity. Without this, the
|
|
16
|
+
* analyzer's alias resolver and `validate-extends` fall back to
|
|
17
|
+
* path-derived identity and produce spurious diagnostics.
|
|
18
|
+
*
|
|
19
|
+
* Position metadata (`positionIndex`) is NOT stamped on manifests —
|
|
20
|
+
* callers look it up via `findPositions(graph, ...)` on the LoadedGraph. */
|
|
21
|
+
export function flattenForAnalyzer(graph) {
|
|
22
|
+
const result = [];
|
|
23
|
+
const stampedEntry = collectModuleManifests(graph.entry);
|
|
24
|
+
result.push(...stampedEntry);
|
|
25
|
+
const seen = new Set([graph.rootSource]);
|
|
26
|
+
const queue = [graph.rootSource];
|
|
27
|
+
while (queue.length > 0) {
|
|
28
|
+
const fromSource = queue.shift();
|
|
29
|
+
const edges = graph.importEdges.get(fromSource);
|
|
30
|
+
if (!edges)
|
|
31
|
+
continue;
|
|
32
|
+
for (const edge of edges.values()) {
|
|
33
|
+
if (seen.has(edge.targetSource))
|
|
34
|
+
continue;
|
|
35
|
+
seen.add(edge.targetSource);
|
|
36
|
+
queue.push(edge.targetSource);
|
|
37
|
+
const targetModule = graph.modules.get(edge.targetSource);
|
|
38
|
+
if (!targetModule)
|
|
39
|
+
continue;
|
|
40
|
+
const stamped = collectModuleManifests(targetModule);
|
|
41
|
+
for (const m of stamped) {
|
|
42
|
+
if (m.kind === "Telo.Definition" ||
|
|
43
|
+
m.kind === "Telo.Abstract" ||
|
|
44
|
+
m.kind === "Telo.Import") {
|
|
45
|
+
result.push(m);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
// Stamp resolved import identity on every Telo.Import in the result by
|
|
51
|
+
// reading the edge's pre-resolved name/namespace — no re-derivation from
|
|
52
|
+
// manifest metadata. The edge is keyed by (owner-file, alias) which is
|
|
53
|
+
// exactly the (metadata.source, metadata.name) pair on each Telo.Import.
|
|
54
|
+
for (let i = 0; i < result.length; i++) {
|
|
55
|
+
const m = result[i];
|
|
56
|
+
if (m.kind !== "Telo.Import")
|
|
57
|
+
continue;
|
|
58
|
+
const owner = m.metadata?.source;
|
|
59
|
+
const alias = m.metadata?.name;
|
|
60
|
+
if (!owner || !alias)
|
|
61
|
+
continue;
|
|
62
|
+
const edge = graph.importEdges.get(owner)?.get(alias);
|
|
63
|
+
if (!edge?.targetModuleName)
|
|
64
|
+
continue;
|
|
65
|
+
const newMetadata = {
|
|
66
|
+
...m.metadata,
|
|
67
|
+
resolvedModuleName: edge.targetModuleName,
|
|
68
|
+
resolvedNamespace: edge.targetNamespace,
|
|
69
|
+
};
|
|
70
|
+
result[i] = { ...m, metadata: newMetadata };
|
|
71
|
+
}
|
|
72
|
+
return result;
|
|
73
|
+
}
|
|
74
|
+
/** Project a LoadedModule (owner + partials) to a flat ResourceManifest[]
|
|
75
|
+
* with `metadata.module` stamped on non-module docs. The kernel's runtime
|
|
76
|
+
* entry load uses this to convert a `Loader.loadModule` result into the
|
|
77
|
+
* classic ResourceManifest[] shape it iterates over. Imports are not
|
|
78
|
+
* followed — the kernel's import-controller loads each import's module
|
|
79
|
+
* separately at runtime. */
|
|
80
|
+
export function flattenLoadedModule(mod) {
|
|
81
|
+
return collectModuleManifests(mod);
|
|
82
|
+
}
|
|
83
|
+
function collectModuleManifests(mod) {
|
|
84
|
+
const owner = stampFile(mod.owner, ownerModuleName(mod.owner));
|
|
85
|
+
const partials = [];
|
|
86
|
+
for (const p of mod.partials) {
|
|
87
|
+
partials.push(...stampFile(p, ownerModuleName(mod.owner)));
|
|
88
|
+
}
|
|
89
|
+
return [...owner, ...partials];
|
|
90
|
+
}
|
|
91
|
+
function ownerModuleName(file) {
|
|
92
|
+
for (const m of file.manifests) {
|
|
93
|
+
if (m && isModuleKind(m.kind)) {
|
|
94
|
+
const name = m.metadata?.name;
|
|
95
|
+
if (typeof name === "string")
|
|
96
|
+
return name;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return undefined;
|
|
100
|
+
}
|
|
101
|
+
function stampFile(file, ownerModule) {
|
|
102
|
+
const out = [];
|
|
103
|
+
for (let i = 0; i < file.manifests.length; i++) {
|
|
104
|
+
const m = file.manifests[i];
|
|
105
|
+
if (m === null || m === undefined)
|
|
106
|
+
continue;
|
|
107
|
+
const { sourceLine } = file.positions[i];
|
|
108
|
+
const metadata = {
|
|
109
|
+
...m.metadata,
|
|
110
|
+
source: file.source,
|
|
111
|
+
sourceLine,
|
|
112
|
+
};
|
|
113
|
+
if (ownerModule && !isModuleKind(m.kind) && !metadata.module) {
|
|
114
|
+
metadata.module = ownerModule;
|
|
115
|
+
}
|
|
116
|
+
out.push({ ...m, metadata: metadata });
|
|
117
|
+
}
|
|
118
|
+
return out;
|
|
119
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
export { AnalysisRegistry } from "./analysis-registry.js";
|
|
2
2
|
export { StaticAnalyzer } from "./analyzer.js";
|
|
3
|
+
export type { GraphLoadError, ImportEdge, LoadedFile, LoadedGraph, LoadedModule, ParseError, } from "./loaded-types.js";
|
|
4
|
+
export { flattenForAnalyzer, flattenLoadedModule } from "./flatten-for-analyzer.js";
|
|
3
5
|
export { Loader } from "./manifest-loader.js";
|
|
4
6
|
export { isModuleKind, MODULE_KINDS } from "./module-kinds.js";
|
|
5
7
|
export type { ModuleKind } from "./module-kinds.js";
|
|
8
|
+
export { parseLoadedFile } from "./parse-loaded-file.js";
|
|
9
|
+
export type { ParseOptions } from "./parse-loaded-file.js";
|
|
10
|
+
export { buildDocumentPositions, buildLineOffsets, buildPositionIndex, documentLineOffsets, } from "./position-metadata.js";
|
|
11
|
+
export type { DocumentPosition } from "./position-metadata.js";
|
|
6
12
|
export { HttpSource } from "./sources/http-source.js";
|
|
7
13
|
export { RegistrySource } from "./sources/registry-source.js";
|
|
8
14
|
export { DEFAULT_MANIFEST_FILENAME, DiagnosticSeverity } from "./types.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC/D,YAAY,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,yBAAyB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAC3E,YAAY,EACR,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,WAAW,EACX,cAAc,EACd,QAAQ,EACR,aAAa,EACb,KAAK,EACR,MAAM,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,YAAY,EACR,cAAc,EACd,UAAU,EACV,UAAU,EACV,WAAW,EACX,YAAY,EACZ,UAAU,GACb,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AACpF,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC/D,YAAY,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,YAAY,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EACH,sBAAsB,EACtB,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,GACtB,MAAM,wBAAwB,CAAC;AAChC,YAAY,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,yBAAyB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAC3E,YAAY,EACR,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,WAAW,EACX,cAAc,EACd,QAAQ,EACR,aAAa,EACb,KAAK,EACR,MAAM,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
export { AnalysisRegistry } from "./analysis-registry.js";
|
|
2
2
|
export { StaticAnalyzer } from "./analyzer.js";
|
|
3
|
+
export { flattenForAnalyzer, flattenLoadedModule } from "./flatten-for-analyzer.js";
|
|
3
4
|
export { Loader } from "./manifest-loader.js";
|
|
4
5
|
export { isModuleKind, MODULE_KINDS } from "./module-kinds.js";
|
|
6
|
+
export { parseLoadedFile } from "./parse-loaded-file.js";
|
|
7
|
+
export { buildDocumentPositions, buildLineOffsets, buildPositionIndex, documentLineOffsets, } from "./position-metadata.js";
|
|
5
8
|
export { HttpSource } from "./sources/http-source.js";
|
|
6
9
|
export { RegistrySource } from "./sources/registry-source.js";
|
|
7
10
|
export { DEFAULT_MANIFEST_FILENAME, DiagnosticSeverity } from "./types.js";
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import type { ResourceManifest } from "@telorun/sdk";
|
|
2
|
+
import type { Document } from "yaml";
|
|
3
|
+
import type { DocumentPosition } from "./position-metadata.js";
|
|
4
|
+
import type { Range } from "./types.js";
|
|
5
|
+
/** One physical file's parsed result. Returned for the owner manifest, for
|
|
6
|
+
* each `include:` partial, and for each external import target.
|
|
7
|
+
*
|
|
8
|
+
* Identity rule: every map key, every cross-reference, every editor-side
|
|
9
|
+
* cache uses `source` — the URL the source adapter's `read()` returned. */
|
|
10
|
+
export interface LoadedFile {
|
|
11
|
+
/** Canonical identity. The URL the source adapter's `read()` returned —
|
|
12
|
+
* HTTPS for http/registry, an absolute path for local. */
|
|
13
|
+
source: string;
|
|
14
|
+
/** The URL the caller supplied (e.g. registry ref `std/javascript@0.3.0`).
|
|
15
|
+
* Differs from `source` only for adapter-resolved URLs. */
|
|
16
|
+
requestedUrl: string;
|
|
17
|
+
/** Raw text exactly as `read()` returned it. */
|
|
18
|
+
text: string;
|
|
19
|
+
/** Per-document parsed AST, in source order. */
|
|
20
|
+
documents: Document[];
|
|
21
|
+
/** Per-document JSON projection (`doc.toJSON()`). Aligned to `documents`. */
|
|
22
|
+
manifests: Array<ResourceManifest | null>;
|
|
23
|
+
/** Per-document `{sourceLine, positionIndex}`. Aligned to `documents`. */
|
|
24
|
+
positions: DocumentPosition[];
|
|
25
|
+
/** Document-level parse errors aggregated from `yaml.Document.errors`. */
|
|
26
|
+
parseErrors: ParseError[];
|
|
27
|
+
}
|
|
28
|
+
export interface ParseError {
|
|
29
|
+
documentIndex: number;
|
|
30
|
+
message: string;
|
|
31
|
+
/** Line/character of the failure, when the yaml parser provided one. */
|
|
32
|
+
range?: Range;
|
|
33
|
+
}
|
|
34
|
+
/** An owner file plus the partial files it includes. The unit
|
|
35
|
+
* `Loader.loadModule` returns. */
|
|
36
|
+
export interface LoadedModule {
|
|
37
|
+
owner: LoadedFile;
|
|
38
|
+
/** Each `include:` target as its own LoadedFile. Empty when no `include:`.
|
|
39
|
+
* Order matches the `include:` list (after glob expansion). */
|
|
40
|
+
partials: LoadedFile[];
|
|
41
|
+
}
|
|
42
|
+
/** Resolved Telo.Import edge: where the import points and what library
|
|
43
|
+
* identity it resolves to. Carrying name/namespace on the edge means
|
|
44
|
+
* `flattenForAnalyzer` can stamp `metadata.resolvedModuleName` /
|
|
45
|
+
* `resolvedNamespace` from this single source rather than re-deriving
|
|
46
|
+
* the target from manifest metadata, which would silently miss whenever
|
|
47
|
+
* a future projection forgets to stamp `metadata.source` consistently. */
|
|
48
|
+
export interface ImportEdge {
|
|
49
|
+
/** Canonical resolved URL of the target — a key into `modules`. */
|
|
50
|
+
targetSource: string;
|
|
51
|
+
/** Target library's `metadata.name`, or `null` when the target had no
|
|
52
|
+
* Telo.Library doc (an error case captured in `LoadedGraph.errors`). */
|
|
53
|
+
targetModuleName: string | null;
|
|
54
|
+
/** Target library's `metadata.namespace` (or `null` when unset). */
|
|
55
|
+
targetNamespace: string | null;
|
|
56
|
+
}
|
|
57
|
+
/** An entry plus every transitively-imported library. Returned by
|
|
58
|
+
* `Loader.loadGraph`. */
|
|
59
|
+
export interface LoadedGraph {
|
|
60
|
+
/** Canonical entry source — equals `entry.owner.source`. */
|
|
61
|
+
rootSource: string;
|
|
62
|
+
entry: LoadedModule;
|
|
63
|
+
/** Map keyed by `LoadedFile.source` (canonical resolved URL). Includes
|
|
64
|
+
* entry, partials, and every transitively reachable Telo.Import target +
|
|
65
|
+
* its partials. */
|
|
66
|
+
modules: Map<string, LoadedModule>;
|
|
67
|
+
/** Per-Telo.Import resolution. Keyed by the resolved URL of the file the
|
|
68
|
+
* Telo.Import was declared in, then by the import's PascalCase alias. */
|
|
69
|
+
importEdges: Map<string, Map<string, ImportEdge>>;
|
|
70
|
+
/** Surface-level errors that did not abort the graph load (e.g. an import
|
|
71
|
+
* whose target failed to fetch). */
|
|
72
|
+
errors: GraphLoadError[];
|
|
73
|
+
}
|
|
74
|
+
export interface GraphLoadError {
|
|
75
|
+
/** URL of the file that failed to load. */
|
|
76
|
+
url: string;
|
|
77
|
+
/** Source of the import that triggered the load, or null for the entry. */
|
|
78
|
+
fromSource: string | null;
|
|
79
|
+
error: Error;
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=loaded-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loaded-types.d.ts","sourceRoot":"","sources":["../src/loaded-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC;;;;4EAI4E;AAC5E,MAAM,WAAW,UAAU;IACzB;+DAC2D;IAC3D,MAAM,EAAE,MAAM,CAAC;IACf;gEAC4D;IAC5D,YAAY,EAAE,MAAM,CAAC;IACrB,gDAAgD;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,gDAAgD;IAChD,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,6EAA6E;IAC7E,SAAS,EAAE,KAAK,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;IAC1C,0EAA0E;IAC1E,SAAS,EAAE,gBAAgB,EAAE,CAAC;IAC9B,0EAA0E;IAC1E,WAAW,EAAE,UAAU,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,UAAU;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,wEAAwE;IACxE,KAAK,CAAC,EAAE,KAAK,CAAC;CACf;AAED;mCACmC;AACnC,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,UAAU,CAAC;IAClB;oEACgE;IAChE,QAAQ,EAAE,UAAU,EAAE,CAAC;CACxB;AAED;;;;;2EAK2E;AAC3E,MAAM,WAAW,UAAU;IACzB,mEAAmE;IACnE,YAAY,EAAE,MAAM,CAAC;IACrB;6EACyE;IACzE,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,oEAAoE;IACpE,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAED;0BAC0B;AAC1B,MAAM,WAAW,WAAW;IAC1B,4DAA4D;IAC5D,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,YAAY,CAAC;IACpB;;wBAEoB;IACpB,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IACnC;8EAC0E;IAC1E,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;IAClD;yCACqC;IACrC,MAAM,EAAE,cAAc,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,cAAc;IAC7B,2CAA2C;IAC3C,GAAG,EAAE,MAAM,CAAC;IACZ,2EAA2E;IAC3E,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,KAAK,EAAE,KAAK,CAAC;CACd"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,22 +1,43 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { LoadedFile, LoadedGraph, LoadedModule } from "./loaded-types.js";
|
|
2
2
|
import { type LoadOptions, type LoaderInitOptions, type ManifestSource } from "./types.js";
|
|
3
3
|
export declare class Loader {
|
|
4
|
-
|
|
4
|
+
/** LoadedFile cache keyed by `${compile ? "compiled" : "raw"}:${source}`.
|
|
5
|
+
* Same dual-keying as the legacy ResourceManifest[] cache: a compile-mode
|
|
6
|
+
* caller (kernel) and a raw-mode caller (analyzer/editor) on the same file
|
|
7
|
+
* get distinct entries, so neither sees the wrong manifest tree. */
|
|
8
|
+
private readonly fileCache;
|
|
5
9
|
protected sources: ManifestSource[];
|
|
6
10
|
private readonly celEnv;
|
|
7
11
|
constructor(extraSourcesOrOptions?: ManifestSource[] | LoaderInitOptions);
|
|
8
12
|
register(source: ManifestSource): this;
|
|
9
13
|
private pick;
|
|
10
14
|
resolveEntryPoint(url: string): Promise<string>;
|
|
11
|
-
|
|
15
|
+
/** Read one file via the source chain and parse it into a LoadedFile.
|
|
16
|
+
* The result is shared with `Loader.fileCache`. Callers that want a
|
|
17
|
+
* private mutable copy must call `parseLoadedFile` directly with the
|
|
18
|
+
* LoadedFile's `text`. */
|
|
19
|
+
loadFile(url: string, options?: LoadOptions): Promise<LoadedFile>;
|
|
20
|
+
/** Load an owner file plus every partial reachable through its `include:`
|
|
21
|
+
* list. Globs are expanded via the owning source's `expandGlob`. The
|
|
22
|
+
* partials list is empty when the owner declares no `include:`. */
|
|
23
|
+
loadModule(url: string, options?: LoadOptions): Promise<LoadedModule>;
|
|
24
|
+
/** Load a module and every transitively-imported library. Returns the full
|
|
25
|
+
* LoadedGraph: `entry`, `modules` keyed by canonical source, and
|
|
26
|
+
* `importEdges` mapping each importing file's PascalCase aliases to their
|
|
27
|
+
* target's canonical source. */
|
|
28
|
+
loadGraph(entryUrl: string, options?: LoadOptions): Promise<LoadedGraph>;
|
|
29
|
+
private resolveImportUrl;
|
|
30
|
+
private assertSingleModuleDeclaration;
|
|
31
|
+
private assertNoSystemKindsInPartialContext;
|
|
32
|
+
private assertImportTargetIsLibrary;
|
|
12
33
|
private resolveIncludes;
|
|
13
|
-
|
|
14
|
-
|
|
34
|
+
/** Find the owning telo.yaml for `fileUrl` (or use it directly if it's an
|
|
35
|
+
* owner) and return the `LoadedGraph` rooted at that owner. Returns
|
|
36
|
+
* `null` only when `fileUrl` is neither an owner nor reachable from one
|
|
37
|
+
* via parent-directory traversal. */
|
|
38
|
+
loadGraphForFile(fileUrl: string): Promise<{
|
|
39
|
+
graph: LoadedGraph;
|
|
15
40
|
ownerUrl: string;
|
|
16
|
-
manifests: ResourceManifest[];
|
|
17
|
-
sourceManifests: Map<string, ResourceManifest[]>;
|
|
18
41
|
} | null>;
|
|
19
|
-
loadModuleGraph(entryUrl: string, onError?: (url: string, error: Error) => void): Promise<Map<string, ResourceManifest[]>>;
|
|
20
|
-
loadManifests(entryUrl: string): Promise<ResourceManifest[]>;
|
|
21
42
|
}
|
|
22
43
|
//# sourceMappingURL=manifest-loader.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest-loader.d.ts","sourceRoot":"","sources":["../src/manifest-loader.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"manifest-loader.d.ts","sourceRoot":"","sources":["../src/manifest-loader.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAGV,UAAU,EACV,WAAW,EACX,YAAY,EACb,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACpB,MAAM,YAAY,CAAC;AASpB,qBAAa,MAAM;IACjB;;;yEAGqE;IACrE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAiC;IAE3D,SAAS,CAAC,OAAO,EAAE,cAAc,EAAE,CAAC;IACpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAc;gBAEzB,qBAAqB,GAAE,cAAc,EAAE,GAAG,iBAAsB;IAmB5E,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI;IAKtC,OAAO,CAAC,IAAI;IAMN,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAOrD;;;+BAG2B;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;IAcvE;;wEAEoE;IAC9D,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IAsB3E;;;qCAGiC;IAC3B,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IAwG9E,OAAO,CAAC,gBAAgB;IAOxB,OAAO,CAAC,6BAA6B;IAarC,OAAO,CAAC,mCAAmC;IAc3C,OAAO,CAAC,2BAA2B;YAkCrB,eAAe;IAmB7B;;;0CAGsC;IAChC,gBAAgB,CACpB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC;QAAE,KAAK,EAAE,WAAW,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CA0B5D"}
|