@telorun/analyzer 0.16.1 → 0.17.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/README.md +7 -14
- package/dist/flatten-for-analyzer.d.ts +23 -1
- package/dist/flatten-for-analyzer.d.ts.map +1 -1
- package/dist/flatten-for-analyzer.js +45 -28
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/src/flatten-for-analyzer.ts +53 -33
- package/src/index.ts +5 -1
package/README.md
CHANGED
|
@@ -54,20 +54,13 @@ metadata:
|
|
|
54
54
|
description: |
|
|
55
55
|
A complete feedback collection REST API — no code, pure YAML.
|
|
56
56
|
Persists entries to SQLite and serves them over HTTP.
|
|
57
|
+
imports:
|
|
58
|
+
Http: std/http-server@0.6.1
|
|
59
|
+
Sql: std/sql@0.5.1
|
|
57
60
|
targets:
|
|
58
61
|
- Migrations
|
|
59
62
|
- Server
|
|
60
63
|
---
|
|
61
|
-
kind: Telo.Import
|
|
62
|
-
metadata:
|
|
63
|
-
name: Http
|
|
64
|
-
source: std/http-server@0.5.0
|
|
65
|
-
---
|
|
66
|
-
kind: Telo.Import
|
|
67
|
-
metadata:
|
|
68
|
-
name: Sql
|
|
69
|
-
source: std/sql@0.3.0
|
|
70
|
-
---
|
|
71
64
|
# SQLite database — swap driver/host/database for PostgreSQL with zero YAML changes
|
|
72
65
|
kind: Sql.Connection
|
|
73
66
|
metadata:
|
|
@@ -127,7 +120,7 @@ routes:
|
|
|
127
120
|
minLength: 1
|
|
128
121
|
source:
|
|
129
122
|
type: string
|
|
130
|
-
required: [text]
|
|
123
|
+
required: [ text ]
|
|
131
124
|
handler:
|
|
132
125
|
kind: Sql.Exec
|
|
133
126
|
connection:
|
|
@@ -157,7 +150,7 @@ routes:
|
|
|
157
150
|
kind: Sql.Connection
|
|
158
151
|
name: Db
|
|
159
152
|
from: feedback
|
|
160
|
-
columns: [id, text, source, score, created_at]
|
|
153
|
+
columns: [ id, text, source, score, created_at ]
|
|
161
154
|
orderBy:
|
|
162
155
|
- { column: created_at, direction: desc }
|
|
163
156
|
response:
|
|
@@ -176,14 +169,14 @@ routes:
|
|
|
176
169
|
properties:
|
|
177
170
|
id:
|
|
178
171
|
type: integer
|
|
179
|
-
required: [id]
|
|
172
|
+
required: [ id ]
|
|
180
173
|
handler:
|
|
181
174
|
kind: Sql.Select
|
|
182
175
|
connection:
|
|
183
176
|
kind: Sql.Connection
|
|
184
177
|
name: Db
|
|
185
178
|
from: feedback
|
|
186
|
-
columns: [id, text, source, score, created_at]
|
|
179
|
+
columns: [ id, text, source, score, created_at ]
|
|
187
180
|
where:
|
|
188
181
|
- { column: id, op: "=", value: "${{ request.params.id }}" }
|
|
189
182
|
response:
|
|
@@ -1,9 +1,31 @@
|
|
|
1
1
|
import type { ResourceManifest } from "@telorun/sdk";
|
|
2
2
|
import type { LoadedGraph, LoadedModule } from "./loaded-types.js";
|
|
3
|
+
/** The import-boundary forwarding rule, shared by `flattenForAnalyzer` (the
|
|
4
|
+
* CLI / kernel loader path) and the telo-editor's workspace projection so the
|
|
5
|
+
* two cannot drift. Given one module's stamped manifests and whether that
|
|
6
|
+
* module is the analysis entry (root), returns the manifests that cross into
|
|
7
|
+
* the consumer's flat analysis list:
|
|
8
|
+
*
|
|
9
|
+
* - **Root module** — every manifest is local; returned unchanged. The root's
|
|
10
|
+
* internals (CEL / schema / refs) are validated in full.
|
|
11
|
+
* - **Imported module** — only `Telo.Definition` / `Telo.Abstract` /
|
|
12
|
+
* `Telo.Import` docs cross unconditionally, plus the instances named in the
|
|
13
|
+
* module's `exports.resources` (stamped `metadata.forwardedExport: true`).
|
|
14
|
+
* The module doc and internal (unexported) instances are dropped — they
|
|
15
|
+
* belong to that module's own analysis pass.
|
|
16
|
+
*
|
|
17
|
+
* `forwardedExport` marks an instance as a cross-module resolution TARGET only
|
|
18
|
+
* (keyed by `metadata.module`), so `resolveRefSentinels` files it under
|
|
19
|
+
* `byModuleName` and `!ref Alias.name` resolves, while `validate-references` /
|
|
20
|
+
* the per-resource validation loop never re-walk or re-validate it against the
|
|
21
|
+
* consumer's scope. A consumer that instead emits every module doc as a peer
|
|
22
|
+
* local manifest silently breaks both. */
|
|
23
|
+
export declare function selectModuleManifestsForAnalysis(moduleManifests: ResourceManifest[], isRoot: boolean): ResourceManifest[];
|
|
3
24
|
/** Produce the flat manifest list `analyze()` consumes today.
|
|
4
25
|
*
|
|
5
26
|
* Combines the entry module's manifests with `Telo.Definition`,
|
|
6
|
-
* `Telo.Abstract`, and `Telo.Import` docs forwarded from imported libraries
|
|
27
|
+
* `Telo.Abstract`, and `Telo.Import` docs forwarded from imported libraries
|
|
28
|
+
* (plus their `exports.resources` instances) via `selectModuleManifestsForAnalysis`.
|
|
7
29
|
* Stamps three flavours of metadata along the way:
|
|
8
30
|
*
|
|
9
31
|
* - `metadata.source` and `metadata.sourceLine` — already on each manifest
|
|
@@ -1 +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
|
|
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;;;;;;;;;;;;;;;;;;;2CAmB2C;AAC3C,wBAAgB,gCAAgC,CAC9C,eAAe,EAAE,gBAAgB,EAAE,EACnC,MAAM,EAAE,OAAO,GACd,gBAAgB,EAAE,CAwBpB;AAED;;;;;;;;;;;;;;;;;;;6EAmB6E;AAC7E,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,WAAW,GAAG,gBAAgB,EAAE,CA+CzE;AAED;;;;;6BAK6B;AAC7B,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,YAAY,GAAG,gBAAgB,EAAE,CAEzE"}
|
|
@@ -1,8 +1,50 @@
|
|
|
1
1
|
import { isModuleKind } from "./module-kinds.js";
|
|
2
|
+
/** The import-boundary forwarding rule, shared by `flattenForAnalyzer` (the
|
|
3
|
+
* CLI / kernel loader path) and the telo-editor's workspace projection so the
|
|
4
|
+
* two cannot drift. Given one module's stamped manifests and whether that
|
|
5
|
+
* module is the analysis entry (root), returns the manifests that cross into
|
|
6
|
+
* the consumer's flat analysis list:
|
|
7
|
+
*
|
|
8
|
+
* - **Root module** — every manifest is local; returned unchanged. The root's
|
|
9
|
+
* internals (CEL / schema / refs) are validated in full.
|
|
10
|
+
* - **Imported module** — only `Telo.Definition` / `Telo.Abstract` /
|
|
11
|
+
* `Telo.Import` docs cross unconditionally, plus the instances named in the
|
|
12
|
+
* module's `exports.resources` (stamped `metadata.forwardedExport: true`).
|
|
13
|
+
* The module doc and internal (unexported) instances are dropped — they
|
|
14
|
+
* belong to that module's own analysis pass.
|
|
15
|
+
*
|
|
16
|
+
* `forwardedExport` marks an instance as a cross-module resolution TARGET only
|
|
17
|
+
* (keyed by `metadata.module`), so `resolveRefSentinels` files it under
|
|
18
|
+
* `byModuleName` and `!ref Alias.name` resolves, while `validate-references` /
|
|
19
|
+
* the per-resource validation loop never re-walk or re-validate it against the
|
|
20
|
+
* consumer's scope. A consumer that instead emits every module doc as a peer
|
|
21
|
+
* local manifest silently breaks both. */
|
|
22
|
+
export function selectModuleManifestsForAnalysis(moduleManifests, isRoot) {
|
|
23
|
+
if (isRoot)
|
|
24
|
+
return moduleManifests;
|
|
25
|
+
const libDoc = moduleManifests.find((m) => isModuleKind(m.kind));
|
|
26
|
+
const exportedResources = new Set(libDoc?.exports?.resources ?? []);
|
|
27
|
+
const out = [];
|
|
28
|
+
for (const m of moduleManifests) {
|
|
29
|
+
if (m.kind === "Telo.Definition" || m.kind === "Telo.Abstract" || m.kind === "Telo.Import") {
|
|
30
|
+
out.push(m);
|
|
31
|
+
}
|
|
32
|
+
else if (!isModuleKind(m.kind) &&
|
|
33
|
+
typeof m.metadata?.name === "string" &&
|
|
34
|
+
exportedResources.has(m.metadata.name)) {
|
|
35
|
+
out.push({
|
|
36
|
+
...m,
|
|
37
|
+
metadata: { ...m.metadata, forwardedExport: true },
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return out;
|
|
42
|
+
}
|
|
2
43
|
/** Produce the flat manifest list `analyze()` consumes today.
|
|
3
44
|
*
|
|
4
45
|
* Combines the entry module's manifests with `Telo.Definition`,
|
|
5
|
-
* `Telo.Abstract`, and `Telo.Import` docs forwarded from imported libraries
|
|
46
|
+
* `Telo.Abstract`, and `Telo.Import` docs forwarded from imported libraries
|
|
47
|
+
* (plus their `exports.resources` instances) via `selectModuleManifestsForAnalysis`.
|
|
6
48
|
* Stamps three flavours of metadata along the way:
|
|
7
49
|
*
|
|
8
50
|
* - `metadata.source` and `metadata.sourceLine` — already on each manifest
|
|
@@ -20,8 +62,7 @@ import { isModuleKind } from "./module-kinds.js";
|
|
|
20
62
|
* callers look it up via `findPositions(graph, ...)` on the LoadedGraph. */
|
|
21
63
|
export function flattenForAnalyzer(graph) {
|
|
22
64
|
const result = [];
|
|
23
|
-
|
|
24
|
-
result.push(...stampedEntry);
|
|
65
|
+
result.push(...selectModuleManifestsForAnalysis(collectModuleManifests(graph.entry), true));
|
|
25
66
|
const seen = new Set([graph.rootSource]);
|
|
26
67
|
const queue = [graph.rootSource];
|
|
27
68
|
while (queue.length > 0) {
|
|
@@ -37,31 +78,7 @@ export function flattenForAnalyzer(graph) {
|
|
|
37
78
|
const targetModule = graph.modules.get(edge.targetSource);
|
|
38
79
|
if (!targetModule)
|
|
39
80
|
continue;
|
|
40
|
-
|
|
41
|
-
const libDoc = stamped.find((m) => isModuleKind(m.kind));
|
|
42
|
-
const exportedResources = new Set(libDoc?.exports?.resources ?? []);
|
|
43
|
-
for (const m of stamped) {
|
|
44
|
-
if (m.kind === "Telo.Definition" ||
|
|
45
|
-
m.kind === "Telo.Abstract" ||
|
|
46
|
-
m.kind === "Telo.Import") {
|
|
47
|
-
result.push(m);
|
|
48
|
-
}
|
|
49
|
-
else if (!isModuleKind(m.kind) &&
|
|
50
|
-
typeof m.metadata?.name === "string" &&
|
|
51
|
-
exportedResources.has(m.metadata.name)) {
|
|
52
|
-
// Forward instances listed in the library's `exports.resources` so the
|
|
53
|
-
// consumer's analyzer can resolve, gate, kind-check, and draw topology edges
|
|
54
|
-
// for cross-module `!ref Alias.name`. The gate IS this forwarding — only
|
|
55
|
-
// exported names cross the boundary. `metadata.forwardedExport` marks them as
|
|
56
|
-
// cross-module resolution targets only (keyed by `metadata.module`), so ref
|
|
57
|
-
// resolution / validation treats them as targets, never as local sources to
|
|
58
|
-
// re-validate or walk.
|
|
59
|
-
result.push({
|
|
60
|
-
...m,
|
|
61
|
-
metadata: { ...m.metadata, forwardedExport: true },
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
}
|
|
81
|
+
result.push(...selectModuleManifestsForAnalysis(collectModuleManifests(targetModule), false));
|
|
65
82
|
}
|
|
66
83
|
}
|
|
67
84
|
// Stamp resolved import identity on every Telo.Import in the result by
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { AnalysisRegistry } from "./analysis-registry.js";
|
|
2
2
|
export { StaticAnalyzer } from "./analyzer.js";
|
|
3
3
|
export type { GraphLoadError, ImportEdge, LoadedFile, LoadedGraph, LoadedModule, ParseError, } from "./loaded-types.js";
|
|
4
|
-
export { flattenForAnalyzer, flattenLoadedModule } from "./flatten-for-analyzer.js";
|
|
4
|
+
export { flattenForAnalyzer, flattenLoadedModule, selectModuleManifestsForAnalysis, } from "./flatten-for-analyzer.js";
|
|
5
5
|
export { visitManifest } from "./manifest-visitor.js";
|
|
6
6
|
export type { CelSiteEvent, ManifestVisitor, RefSiteEvent, ResourceEnterEvent, ResourceExitEvent, ScopeBoundaryEvent, SchemaFromSiteEvent, VisitOptions, } from "./manifest-visitor.js";
|
|
7
7
|
export { Loader } from "./manifest-loader.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,YAAY,EACR,cAAc,EACd,UAAU,EACV,UAAU,EACV,WAAW,EACX,YAAY,EACZ,UAAU,GACb,MAAM,mBAAmB,CAAC;AAC3B,OAAO,
|
|
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,EACH,kBAAkB,EAClB,mBAAmB,EACnB,gCAAgC,GACnC,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,YAAY,EACR,YAAY,EACZ,eAAe,EACf,YAAY,EACZ,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACnB,YAAY,GACf,MAAM,uBAAuB,CAAC;AAC/B,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,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC/E,YAAY,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AACnF,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,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AACvE,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,6 +1,6 @@
|
|
|
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
|
+
export { flattenForAnalyzer, flattenLoadedModule, selectModuleManifestsForAnalysis, } from "./flatten-for-analyzer.js";
|
|
4
4
|
export { visitManifest } from "./manifest-visitor.js";
|
|
5
5
|
export { Loader } from "./manifest-loader.js";
|
|
6
6
|
export { isModuleKind, MODULE_KINDS } from "./module-kinds.js";
|
package/package.json
CHANGED
|
@@ -2,10 +2,60 @@ import type { ResourceManifest } from "@telorun/sdk";
|
|
|
2
2
|
import type { LoadedFile, LoadedGraph, LoadedModule } from "./loaded-types.js";
|
|
3
3
|
import { isModuleKind } from "./module-kinds.js";
|
|
4
4
|
|
|
5
|
+
/** The import-boundary forwarding rule, shared by `flattenForAnalyzer` (the
|
|
6
|
+
* CLI / kernel loader path) and the telo-editor's workspace projection so the
|
|
7
|
+
* two cannot drift. Given one module's stamped manifests and whether that
|
|
8
|
+
* module is the analysis entry (root), returns the manifests that cross into
|
|
9
|
+
* the consumer's flat analysis list:
|
|
10
|
+
*
|
|
11
|
+
* - **Root module** — every manifest is local; returned unchanged. The root's
|
|
12
|
+
* internals (CEL / schema / refs) are validated in full.
|
|
13
|
+
* - **Imported module** — only `Telo.Definition` / `Telo.Abstract` /
|
|
14
|
+
* `Telo.Import` docs cross unconditionally, plus the instances named in the
|
|
15
|
+
* module's `exports.resources` (stamped `metadata.forwardedExport: true`).
|
|
16
|
+
* The module doc and internal (unexported) instances are dropped — they
|
|
17
|
+
* belong to that module's own analysis pass.
|
|
18
|
+
*
|
|
19
|
+
* `forwardedExport` marks an instance as a cross-module resolution TARGET only
|
|
20
|
+
* (keyed by `metadata.module`), so `resolveRefSentinels` files it under
|
|
21
|
+
* `byModuleName` and `!ref Alias.name` resolves, while `validate-references` /
|
|
22
|
+
* the per-resource validation loop never re-walk or re-validate it against the
|
|
23
|
+
* consumer's scope. A consumer that instead emits every module doc as a peer
|
|
24
|
+
* local manifest silently breaks both. */
|
|
25
|
+
export function selectModuleManifestsForAnalysis(
|
|
26
|
+
moduleManifests: ResourceManifest[],
|
|
27
|
+
isRoot: boolean,
|
|
28
|
+
): ResourceManifest[] {
|
|
29
|
+
if (isRoot) return moduleManifests;
|
|
30
|
+
|
|
31
|
+
const libDoc = moduleManifests.find((m) => isModuleKind(m.kind));
|
|
32
|
+
const exportedResources = new Set<string>(
|
|
33
|
+
(libDoc as { exports?: { resources?: string[] } } | undefined)?.exports?.resources ?? [],
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
const out: ResourceManifest[] = [];
|
|
37
|
+
for (const m of moduleManifests) {
|
|
38
|
+
if (m.kind === "Telo.Definition" || m.kind === "Telo.Abstract" || m.kind === "Telo.Import") {
|
|
39
|
+
out.push(m);
|
|
40
|
+
} else if (
|
|
41
|
+
!isModuleKind(m.kind) &&
|
|
42
|
+
typeof m.metadata?.name === "string" &&
|
|
43
|
+
exportedResources.has(m.metadata.name as string)
|
|
44
|
+
) {
|
|
45
|
+
out.push({
|
|
46
|
+
...m,
|
|
47
|
+
metadata: { ...m.metadata, forwardedExport: true } as ResourceManifest["metadata"],
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return out;
|
|
52
|
+
}
|
|
53
|
+
|
|
5
54
|
/** Produce the flat manifest list `analyze()` consumes today.
|
|
6
55
|
*
|
|
7
56
|
* Combines the entry module's manifests with `Telo.Definition`,
|
|
8
|
-
* `Telo.Abstract`, and `Telo.Import` docs forwarded from imported libraries
|
|
57
|
+
* `Telo.Abstract`, and `Telo.Import` docs forwarded from imported libraries
|
|
58
|
+
* (plus their `exports.resources` instances) via `selectModuleManifestsForAnalysis`.
|
|
9
59
|
* Stamps three flavours of metadata along the way:
|
|
10
60
|
*
|
|
11
61
|
* - `metadata.source` and `metadata.sourceLine` — already on each manifest
|
|
@@ -24,8 +74,7 @@ import { isModuleKind } from "./module-kinds.js";
|
|
|
24
74
|
export function flattenForAnalyzer(graph: LoadedGraph): ResourceManifest[] {
|
|
25
75
|
const result: ResourceManifest[] = [];
|
|
26
76
|
|
|
27
|
-
|
|
28
|
-
result.push(...stampedEntry);
|
|
77
|
+
result.push(...selectModuleManifestsForAnalysis(collectModuleManifests(graph.entry), true));
|
|
29
78
|
|
|
30
79
|
const seen = new Set<string>([graph.rootSource]);
|
|
31
80
|
const queue: string[] = [graph.rootSource];
|
|
@@ -43,36 +92,7 @@ export function flattenForAnalyzer(graph: LoadedGraph): ResourceManifest[] {
|
|
|
43
92
|
const targetModule = graph.modules.get(edge.targetSource);
|
|
44
93
|
if (!targetModule) continue;
|
|
45
94
|
|
|
46
|
-
|
|
47
|
-
const libDoc = stamped.find((m) => isModuleKind(m.kind));
|
|
48
|
-
const exportedResources = new Set<string>(
|
|
49
|
-
(libDoc as { exports?: { resources?: string[] } } | undefined)?.exports?.resources ?? [],
|
|
50
|
-
);
|
|
51
|
-
for (const m of stamped) {
|
|
52
|
-
if (
|
|
53
|
-
m.kind === "Telo.Definition" ||
|
|
54
|
-
m.kind === "Telo.Abstract" ||
|
|
55
|
-
m.kind === "Telo.Import"
|
|
56
|
-
) {
|
|
57
|
-
result.push(m);
|
|
58
|
-
} else if (
|
|
59
|
-
!isModuleKind(m.kind) &&
|
|
60
|
-
typeof m.metadata?.name === "string" &&
|
|
61
|
-
exportedResources.has(m.metadata.name as string)
|
|
62
|
-
) {
|
|
63
|
-
// Forward instances listed in the library's `exports.resources` so the
|
|
64
|
-
// consumer's analyzer can resolve, gate, kind-check, and draw topology edges
|
|
65
|
-
// for cross-module `!ref Alias.name`. The gate IS this forwarding — only
|
|
66
|
-
// exported names cross the boundary. `metadata.forwardedExport` marks them as
|
|
67
|
-
// cross-module resolution targets only (keyed by `metadata.module`), so ref
|
|
68
|
-
// resolution / validation treats them as targets, never as local sources to
|
|
69
|
-
// re-validate or walk.
|
|
70
|
-
result.push({
|
|
71
|
-
...m,
|
|
72
|
-
metadata: { ...m.metadata, forwardedExport: true } as ResourceManifest["metadata"],
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
}
|
|
95
|
+
result.push(...selectModuleManifestsForAnalysis(collectModuleManifests(targetModule), false));
|
|
76
96
|
}
|
|
77
97
|
}
|
|
78
98
|
|
package/src/index.ts
CHANGED
|
@@ -8,7 +8,11 @@ export type {
|
|
|
8
8
|
LoadedModule,
|
|
9
9
|
ParseError,
|
|
10
10
|
} from "./loaded-types.js";
|
|
11
|
-
export {
|
|
11
|
+
export {
|
|
12
|
+
flattenForAnalyzer,
|
|
13
|
+
flattenLoadedModule,
|
|
14
|
+
selectModuleManifestsForAnalysis,
|
|
15
|
+
} from "./flatten-for-analyzer.js";
|
|
12
16
|
export { visitManifest } from "./manifest-visitor.js";
|
|
13
17
|
export type {
|
|
14
18
|
CelSiteEvent,
|