@telorun/analyzer 0.71.0 → 0.73.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/analyzer.d.ts.map +1 -1
- package/dist/analyzer.js +92 -15
- package/dist/builtins.d.ts.map +1 -1
- package/dist/builtins.js +71 -97
- package/dist/catch-scope.d.ts +72 -0
- package/dist/catch-scope.d.ts.map +1 -0
- package/dist/catch-scope.js +102 -0
- package/dist/cel-scope-query.d.ts.map +1 -1
- package/dist/cel-scope-query.js +32 -11
- package/dist/cel-scope.d.ts.map +1 -1
- package/dist/cel-scope.js +1 -0
- package/dist/deprecation.d.ts +21 -0
- package/dist/deprecation.d.ts.map +1 -0
- package/dist/deprecation.js +26 -0
- package/dist/eval-paths.d.ts +36 -5
- package/dist/eval-paths.d.ts.map +1 -1
- package/dist/eval-paths.js +47 -6
- package/dist/extends-resolution.d.ts +12 -0
- package/dist/extends-resolution.d.ts.map +1 -1
- package/dist/extends-resolution.js +23 -0
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/manifest-visitor.d.ts +17 -1
- package/dist/manifest-visitor.d.ts.map +1 -1
- package/dist/manifest-visitor.js +5 -1
- package/dist/migrations/report.d.ts +1 -1
- package/dist/migrations/report.d.ts.map +1 -1
- package/dist/migrations/report.js +5 -0
- package/dist/nearest-name.d.ts +22 -0
- package/dist/nearest-name.d.ts.map +1 -0
- package/dist/nearest-name.js +43 -0
- package/dist/ref-slot.d.ts +15 -0
- package/dist/ref-slot.d.ts.map +1 -1
- package/dist/ref-slot.js +7 -0
- package/dist/release/destinations.d.ts +59 -0
- package/dist/release/destinations.d.ts.map +1 -0
- package/dist/release/destinations.js +75 -0
- package/dist/release/index.d.ts +6 -2
- package/dist/release/index.d.ts.map +1 -1
- package/dist/release/index.js +3 -1
- package/dist/release/ledger.d.ts +20 -11
- package/dist/release/ledger.d.ts.map +1 -1
- package/dist/release/ledger.js +43 -14
- package/dist/release/release-plan.d.ts +3 -2
- package/dist/release/release-plan.d.ts.map +1 -1
- package/dist/release/release-plan.js +12 -19
- package/dist/release/workspace-config.d.ts +114 -34
- package/dist/release/workspace-config.d.ts.map +1 -1
- package/dist/release/workspace-config.js +322 -38
- package/dist/release/workspace-schema.d.ts +41 -0
- package/dist/release/workspace-schema.d.ts.map +1 -0
- package/dist/release/workspace-schema.js +77 -0
- package/dist/resolve-throws-union.d.ts +29 -1
- package/dist/resolve-throws-union.d.ts.map +1 -1
- package/dist/resolve-throws-union.js +111 -16
- package/dist/schema-compat.d.ts.map +1 -1
- package/dist/schema-compat.js +13 -1
- package/dist/schema-error-report.d.ts +7 -0
- package/dist/schema-error-report.d.ts.map +1 -1
- package/dist/schema-error-report.js +57 -8
- package/dist/schema-keywords.d.ts.map +1 -1
- package/dist/schema-keywords.js +3 -1
- package/dist/schema-walk.d.ts +27 -0
- package/dist/schema-walk.d.ts.map +1 -1
- package/dist/schema-walk.js +44 -0
- package/dist/telo-version.d.ts +1 -1
- package/dist/telo-version.js +1 -1
- package/dist/template-body.d.ts +10 -0
- package/dist/template-body.d.ts.map +1 -1
- package/dist/template-body.js +25 -0
- package/dist/types.d.ts +17 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +11 -0
- package/dist/validate-cel-context.d.ts +23 -8
- package/dist/validate-cel-context.d.ts.map +1 -1
- package/dist/validate-cel-context.js +48 -16
- package/dist/validate-exports.d.ts +28 -0
- package/dist/validate-exports.d.ts.map +1 -0
- package/dist/validate-exports.js +146 -0
- package/dist/validate-extends.d.ts.map +1 -1
- package/dist/validate-extends.js +37 -1
- package/dist/validate-identifier-names.d.ts +2 -2
- package/dist/validate-identifier-names.d.ts.map +1 -1
- package/dist/validate-identifier-names.js +22 -7
- package/dist/validate-provider-coherence.d.ts +4 -8
- package/dist/validate-provider-coherence.d.ts.map +1 -1
- package/dist/validate-provider-coherence.js +12 -123
- package/dist/validate-ref-slots.d.ts +1 -1
- package/dist/validate-ref-slots.d.ts.map +1 -1
- package/dist/validate-ref-slots.js +34 -0
- package/dist/validate-references.d.ts.map +1 -1
- package/dist/validate-references.js +168 -63
- package/dist/validate-template-body.d.ts +36 -0
- package/dist/validate-template-body.d.ts.map +1 -0
- package/dist/validate-template-body.js +246 -0
- package/dist/validate-throws-coverage.d.ts.map +1 -1
- package/dist/validate-throws-coverage.js +236 -85
- package/package.json +3 -2
- package/src/analyzer.ts +118 -12
- package/src/builtins.ts +85 -97
- package/src/catch-scope.ts +157 -0
- package/src/cel-scope-query.ts +28 -9
- package/src/cel-scope.ts +1 -0
- package/src/deprecation.ts +36 -0
- package/src/eval-paths.ts +53 -6
- package/src/extends-resolution.ts +24 -0
- package/src/index.ts +9 -1
- package/src/manifest-visitor.ts +19 -2
- package/src/migrations/report.ts +5 -1
- package/src/nearest-name.ts +47 -0
- package/src/ref-slot.ts +19 -0
- package/src/release/destinations.ts +105 -0
- package/src/release/index.ts +33 -2
- package/src/release/ledger.ts +51 -21
- package/src/release/release-plan.ts +16 -26
- package/src/release/workspace-config.ts +483 -47
- package/src/release/workspace-schema.ts +99 -0
- package/src/resolve-throws-union.ts +139 -21
- package/src/schema-compat.ts +13 -0
- package/src/schema-error-report.ts +66 -10
- package/src/schema-keywords.ts +4 -1
- package/src/schema-walk.ts +56 -0
- package/src/telo-version.ts +1 -1
- package/src/template-body.ts +25 -0
- package/src/types.ts +18 -0
- package/src/validate-cel-context.ts +57 -16
- package/src/validate-exports.ts +185 -0
- package/src/validate-extends.ts +43 -0
- package/src/validate-identifier-names.ts +28 -9
- package/src/validate-provider-coherence.ts +17 -127
- package/src/validate-ref-slots.ts +41 -1
- package/src/validate-references.ts +174 -63
- package/src/validate-template-body.ts +274 -0
- package/src/validate-throws-coverage.ts +333 -92
- package/dist/validate-template-dispatch.d.ts +0 -27
- package/dist/validate-template-dispatch.d.ts.map +0 -1
- package/dist/validate-template-dispatch.js +0 -95
- package/src/validate-template-dispatch.ts +0 -99
|
@@ -13,6 +13,11 @@ export interface ContextResolveOpts {
|
|
|
13
13
|
aliases?: {
|
|
14
14
|
resolveKind(kind: string): string | undefined;
|
|
15
15
|
};
|
|
16
|
+
/** Per-declaring-module alias tables, so a kind read off a forwarded
|
|
17
|
+
* definition resolves in the module that wrote it. */
|
|
18
|
+
aliasesByModule?: ReadonlyMap<string, {
|
|
19
|
+
resolveKind(kind: string): string | undefined;
|
|
20
|
+
}>;
|
|
16
21
|
allManifests?: Record<string, any>[];
|
|
17
22
|
}
|
|
18
23
|
export declare function resolveTypeFieldToSchema(value: unknown, allManifests: Record<string, any>[], ancestry?: ReadonlySet<string>): Record<string, any> | undefined;
|
|
@@ -39,18 +44,20 @@ export declare function resolveTypeFieldToSchema(value: unknown, allManifests: R
|
|
|
39
44
|
* Example: `properties.self.x-telo-context-from-root: "schema"` reads
|
|
40
45
|
* `manifestRoot.schema` and uses it as the schema of the `self` CEL variable.
|
|
41
46
|
*
|
|
42
|
-
* - `x-telo-context-from-ref-kind`: reads a
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
47
|
+
* - `x-telo-context-from-ref-kind`: reads a KIND from `manifestRoot.<refPath>` —
|
|
48
|
+
* a field holding a kind name, or a definition's dispatch slot holding a
|
|
49
|
+
* `!ref` to a `resources:` entry (whose kind it is) — and returns the
|
|
50
|
+
* `<field>` schema (e.g. `outputType`/`inputType`) the entry itself declares,
|
|
51
|
+
* else the one the kind's definition declares. Used to type `result` against
|
|
52
|
+
* the dispatch target's declared output shape.
|
|
46
53
|
*
|
|
47
54
|
* Syntax: `<refPath>#<field>` — slashes traverse the manifest tree.
|
|
48
55
|
*
|
|
49
|
-
* Example: `x-telo-context-from-ref-kind: "provide
|
|
50
|
-
* `manifestRoot.provide
|
|
51
|
-
*
|
|
56
|
+
* Example: `x-telo-context-from-ref-kind: "provide#outputType"` resolves
|
|
57
|
+
* `manifestRoot.provide` (`!ref source`) to the entry named `source`, and
|
|
58
|
+
* returns its `outputType` schema, or its kind's.
|
|
52
59
|
*
|
|
53
|
-
* Accepts either a single string or an array of strings. With an array,
|
|
60
|
+
* Accepts either a single string or an array of strings. With an array, slots
|
|
54
61
|
* are tried in order and the first one that resolves to a usable schema wins —
|
|
55
62
|
* used by `result:` to find its dispatch target under whichever entry-point
|
|
56
63
|
* field (`provide:` or `invoke:`) the definition declares.
|
|
@@ -70,6 +77,14 @@ export declare function resolveContextAnnotations(schema: Record<string, any>, m
|
|
|
70
77
|
* e.g. exprPath="routes[0].inputs.q", scope="$.routes[*].inputs" → manifest.routes[0]
|
|
71
78
|
*/
|
|
72
79
|
export declare function getManifestItem(exprPath: string, scope: string, manifest: Record<string, any>): Record<string, any>;
|
|
80
|
+
/** The kind an `x-telo-context-from-ref-kind` path names: a field holding a
|
|
81
|
+
* kind NAME (`targetKind`), or a definition's dispatch slot holding a `!ref`
|
|
82
|
+
* to a `resources:` entry, which carries the kind — and, where it narrows
|
|
83
|
+
* one, the contract field itself. */
|
|
84
|
+
export declare function kindAtPath(manifestRoot: Record<string, any>, refPath: string): {
|
|
85
|
+
kind: string;
|
|
86
|
+
entry?: Record<string, any>;
|
|
87
|
+
} | undefined;
|
|
73
88
|
/**
|
|
74
89
|
* Walk a JSON Schema tree and collect all `x-telo-context` annotations,
|
|
75
90
|
* returning them as `{ scope, schema }` pairs using JSONPath-style scopes —
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate-cel-context.d.ts","sourceRoot":"","sources":["../src/validate-cel-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"validate-cel-context.d.ts","sourceRoot":"","sources":["../src/validate-cel-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AAetF,OAAO,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AA2B3E,MAAM,WAAW,kBAAkB;IACjC;mEAC+D;IAC/D,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACnC;;kDAE8C;IAC9C,IAAI,CAAC,EAAE;QACL,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,SAAS,CAAC;KACxD,CAAC;IACF,OAAO,CAAC,EAAE;QACR,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;KAC/C,CAAC;IACF;2DACuD;IACvD,eAAe,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE;QAAE,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;KAAE,CAAC,CAAC;IACzF,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC;CACtC;AA4CD,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,OAAO,EACd,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,EACnC,QAAQ,GAAE,WAAW,CAAC,MAAM,CAAa,GACxC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,SAAS,CA0EjC;AAyID;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AACH,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3B,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACjC,IAAI,CAAC,EAAE,kBAAkB,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,GAChD,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAgMrB;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC5B,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAuBrB;AAqBD;;;sCAGsC;AACtC,wBAAgB,UAAU,CACxB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACjC,OAAO,EAAE,MAAM,GACd;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;CAAE,GAAG,SAAS,CAa3D;AAED;;;;;;;;;GASG;AACH,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3B,IAAI,SAAM,GACT,KAAK,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;CAAE,CAAC,CAGvD"}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
export { extractAccessChains, validateChainAgainstSchema } from "@telorun/templating";
|
|
2
2
|
import { elementSchemaOf, isLiveSlot, mergeTypeSchemas, parseCanonicalTypeSchemaId, } from "@telorun/sdk";
|
|
3
3
|
import { KERNEL_BUILTINS } from "./builtins.js";
|
|
4
|
+
import { moduleAliasScope } from "./module-alias-scope.js";
|
|
4
5
|
import { withRefSlotsAsReadings } from "./ref-slot-reading.js";
|
|
6
|
+
import { dispatchTargetOf } from "./template-body.js";
|
|
5
7
|
// Where CEL is evaluated is one reader (`eval-paths.ts`), and the region half of
|
|
6
8
|
// it moved there so the scope walk and the `x-telo-eval` walk answer the same
|
|
7
9
|
// question in one place. Re-exported: this module is where every existing
|
|
@@ -279,18 +281,20 @@ function collectionBindingWithheld(schema, manifestRoot, allManifests) {
|
|
|
279
281
|
* Example: `properties.self.x-telo-context-from-root: "schema"` reads
|
|
280
282
|
* `manifestRoot.schema` and uses it as the schema of the `self` CEL variable.
|
|
281
283
|
*
|
|
282
|
-
* - `x-telo-context-from-ref-kind`: reads a
|
|
283
|
-
*
|
|
284
|
-
*
|
|
285
|
-
*
|
|
284
|
+
* - `x-telo-context-from-ref-kind`: reads a KIND from `manifestRoot.<refPath>` —
|
|
285
|
+
* a field holding a kind name, or a definition's dispatch slot holding a
|
|
286
|
+
* `!ref` to a `resources:` entry (whose kind it is) — and returns the
|
|
287
|
+
* `<field>` schema (e.g. `outputType`/`inputType`) the entry itself declares,
|
|
288
|
+
* else the one the kind's definition declares. Used to type `result` against
|
|
289
|
+
* the dispatch target's declared output shape.
|
|
286
290
|
*
|
|
287
291
|
* Syntax: `<refPath>#<field>` — slashes traverse the manifest tree.
|
|
288
292
|
*
|
|
289
|
-
* Example: `x-telo-context-from-ref-kind: "provide
|
|
290
|
-
* `manifestRoot.provide
|
|
291
|
-
*
|
|
293
|
+
* Example: `x-telo-context-from-ref-kind: "provide#outputType"` resolves
|
|
294
|
+
* `manifestRoot.provide` (`!ref source`) to the entry named `source`, and
|
|
295
|
+
* returns its `outputType` schema, or its kind's.
|
|
292
296
|
*
|
|
293
|
-
* Accepts either a single string or an array of strings. With an array,
|
|
297
|
+
* Accepts either a single string or an array of strings. With an array, slots
|
|
294
298
|
* are tried in order and the first one that resolves to a usable schema wins —
|
|
295
299
|
* used by `result:` to find its dispatch target under whichever entry-point
|
|
296
300
|
* field (`provide:` or `invoke:`) the definition declares.
|
|
@@ -311,7 +315,7 @@ export function resolveContextAnnotations(schema, manifestItem, opts) {
|
|
|
311
315
|
const normalizedOpts = Array.isArray(opts)
|
|
312
316
|
? { allManifests: opts }
|
|
313
317
|
: (opts ?? {});
|
|
314
|
-
const { manifestRoot = manifestItem, defs, aliases, allManifests } = normalizedOpts;
|
|
318
|
+
const { manifestRoot = manifestItem, defs, aliases, aliasesByModule, allManifests } = normalizedOpts;
|
|
315
319
|
const from = schema["x-telo-context-from"];
|
|
316
320
|
if (from) {
|
|
317
321
|
const navigated = navigatePath(manifestItem, from.split("/"));
|
|
@@ -391,20 +395,28 @@ export function resolveContextAnnotations(schema, manifestItem, opts) {
|
|
|
391
395
|
}
|
|
392
396
|
}
|
|
393
397
|
if (defs) {
|
|
398
|
+
// The kind is read off THIS document, so it is spelled in the alias scope
|
|
399
|
+
// of the module that declared it — a library's dispatch target is written
|
|
400
|
+
// through an import the consumer has no reason to have.
|
|
401
|
+
const scope = moduleAliasScope(manifestRoot.metadata, aliases, aliasesByModule);
|
|
394
402
|
for (const fromRefKind of fromRefKinds) {
|
|
395
403
|
const hashIdx = fromRefKind.indexOf("#");
|
|
396
404
|
if (hashIdx <= 0)
|
|
397
405
|
continue;
|
|
398
406
|
const refPath = fromRefKind.slice(0, hashIdx);
|
|
399
407
|
const field = fromRefKind.slice(hashIdx + 1);
|
|
400
|
-
const
|
|
401
|
-
if (
|
|
408
|
+
const target = kindAtPath(manifestRoot, refPath);
|
|
409
|
+
if (!target)
|
|
402
410
|
continue;
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
const
|
|
406
|
-
|
|
407
|
-
|
|
411
|
+
// The entry's own field first — a per-instance narrowing (`outputType:`
|
|
412
|
+
// on the entry) is what the kernel binds — then the kind's.
|
|
413
|
+
const own = target.entry?.[field];
|
|
414
|
+
const ownResolved = own !== undefined ? resolveTypeFieldToSchema(own, allManifests ?? []) : undefined;
|
|
415
|
+
if (ownResolved && typeof ownResolved === "object")
|
|
416
|
+
return ownResolved;
|
|
417
|
+
const canonical = scope?.resolveKind(target.kind) ?? target.kind;
|
|
418
|
+
const def = defs.resolve(canonical) ?? defs.resolve(target.kind);
|
|
419
|
+
const typeField = def ? def[field] : undefined;
|
|
408
420
|
const resolved = resolveTypeFieldToSchema(typeField, allManifests ?? []);
|
|
409
421
|
if (resolved && typeof resolved === "object") {
|
|
410
422
|
return resolved;
|
|
@@ -516,6 +528,26 @@ function navigatePath(obj, segments) {
|
|
|
516
528
|
}
|
|
517
529
|
return cur;
|
|
518
530
|
}
|
|
531
|
+
/** The kind an `x-telo-context-from-ref-kind` path names: a field holding a
|
|
532
|
+
* kind NAME (`targetKind`), or a definition's dispatch slot holding a `!ref`
|
|
533
|
+
* to a `resources:` entry, which carries the kind — and, where it narrows
|
|
534
|
+
* one, the contract field itself. */
|
|
535
|
+
export function kindAtPath(manifestRoot, refPath) {
|
|
536
|
+
const segments = refPath.split("/");
|
|
537
|
+
const value = navigatePath(manifestRoot, segments);
|
|
538
|
+
if (typeof value === "string")
|
|
539
|
+
return value.length > 0 ? { kind: value } : undefined;
|
|
540
|
+
// The dispatch-slot reading is a fact about ONE built-in document, not about
|
|
541
|
+
// the annotation: `resources:` is a `Telo.Definition`'s entry list. The
|
|
542
|
+
// annotation itself is generic vocabulary any kind may declare, and without
|
|
543
|
+
// this gate a third-party kind whose own `resources:` array means something
|
|
544
|
+
// else would have a slot silently resolved against it — a wrong answer with
|
|
545
|
+
// nothing reporting it, which is worse than no answer.
|
|
546
|
+
if (segments.length !== 1 || manifestRoot.kind !== "Telo.Definition")
|
|
547
|
+
return undefined;
|
|
548
|
+
const dispatch = dispatchTargetOf(manifestRoot, segments[0]);
|
|
549
|
+
return dispatch ? { kind: dispatch.kind, entry: dispatch.entry } : undefined;
|
|
550
|
+
}
|
|
519
551
|
/**
|
|
520
552
|
* Walk a JSON Schema tree and collect all `x-telo-context` annotations,
|
|
521
553
|
* returning them as `{ scope, schema }` pairs using JSONPath-style scopes —
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { ResourceManifest } from "@telorun/sdk";
|
|
2
|
+
import type { AliasResolver } from "./alias-resolver.js";
|
|
3
|
+
import type { DefinitionRegistry } from "./definition-registry.js";
|
|
4
|
+
import { type AnalysisDiagnostic } from "./types.js";
|
|
5
|
+
/**
|
|
6
|
+
* A LIBRARY'S EXPORT LIST IS CHECKED WHERE IT IS WRITTEN.
|
|
7
|
+
*
|
|
8
|
+
* `exports.kinds` and `exports.resources` are a library's public contract, and
|
|
9
|
+
* they were read as a GATE only: a listed name resolved when a consumer asked
|
|
10
|
+
* for it, and one that named nothing failed in the consumer's file
|
|
11
|
+
* (`UNDEFINED_KIND` on `kind: L.Client`, with nothing wrong in that file) while
|
|
12
|
+
* the author who could fix it saw a clean check. Both entries are resolved here,
|
|
13
|
+
* against what the library declares:
|
|
14
|
+
*
|
|
15
|
+
* - a bare kind names a `Telo.Definition` / `Telo.Abstract` of this module, and
|
|
16
|
+
* `Alias.Kind` re-exports through an import declared in this file
|
|
17
|
+
* (`EXPORT_KIND_UNKNOWN`). The one mistake that reads as intended — a bare
|
|
18
|
+
* name that IS a kind, of an imported module — gets the re-export spelling
|
|
19
|
+
* in its message, because a clean check was read as confirmation it worked;
|
|
20
|
+
* - a bare instance names a resource declared in this module, and
|
|
21
|
+
* `Alias.name` an instance the aliased import exports
|
|
22
|
+
* (`EXPORT_RESOURCE_UNKNOWN`).
|
|
23
|
+
*
|
|
24
|
+
* Runs on the library as an ENTRY — a consumer's flattened analysis drops the
|
|
25
|
+
* library doc, and the list is not the consumer's to fix. Browser-safe.
|
|
26
|
+
*/
|
|
27
|
+
export declare function validateExports(manifests: ResourceManifest[], registry: DefinitionRegistry, aliases: AliasResolver, rootModules: ReadonlySet<string>): AnalysisDiagnostic[];
|
|
28
|
+
//# sourceMappingURL=validate-exports.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate-exports.d.ts","sourceRoot":"","sources":["../src/validate-exports.ts"],"names":[],"mappings":"AACA,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;AAEnE,OAAO,EAAsB,KAAK,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAIzE;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,eAAe,CAC7B,SAAS,EAAE,gBAAgB,EAAE,EAC7B,QAAQ,EAAE,kBAAkB,EAC5B,OAAO,EAAE,aAAa,EACtB,WAAW,EAAE,WAAW,CAAC,MAAM,CAAC,GAC/B,kBAAkB,EAAE,CAoJtB"}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { nearestName } from "./nearest-name.js";
|
|
2
|
+
import { parseExportEntry } from "./flatten-for-analyzer.js";
|
|
3
|
+
import { DiagnosticSeverity } from "./types.js";
|
|
4
|
+
const SOURCE = "telo-analyzer";
|
|
5
|
+
/**
|
|
6
|
+
* A LIBRARY'S EXPORT LIST IS CHECKED WHERE IT IS WRITTEN.
|
|
7
|
+
*
|
|
8
|
+
* `exports.kinds` and `exports.resources` are a library's public contract, and
|
|
9
|
+
* they were read as a GATE only: a listed name resolved when a consumer asked
|
|
10
|
+
* for it, and one that named nothing failed in the consumer's file
|
|
11
|
+
* (`UNDEFINED_KIND` on `kind: L.Client`, with nothing wrong in that file) while
|
|
12
|
+
* the author who could fix it saw a clean check. Both entries are resolved here,
|
|
13
|
+
* against what the library declares:
|
|
14
|
+
*
|
|
15
|
+
* - a bare kind names a `Telo.Definition` / `Telo.Abstract` of this module, and
|
|
16
|
+
* `Alias.Kind` re-exports through an import declared in this file
|
|
17
|
+
* (`EXPORT_KIND_UNKNOWN`). The one mistake that reads as intended — a bare
|
|
18
|
+
* name that IS a kind, of an imported module — gets the re-export spelling
|
|
19
|
+
* in its message, because a clean check was read as confirmation it worked;
|
|
20
|
+
* - a bare instance names a resource declared in this module, and
|
|
21
|
+
* `Alias.name` an instance the aliased import exports
|
|
22
|
+
* (`EXPORT_RESOURCE_UNKNOWN`).
|
|
23
|
+
*
|
|
24
|
+
* Runs on the library as an ENTRY — a consumer's flattened analysis drops the
|
|
25
|
+
* library doc, and the list is not the consumer's to fix. Browser-safe.
|
|
26
|
+
*/
|
|
27
|
+
export function validateExports(manifests, registry, aliases, rootModules) {
|
|
28
|
+
const out = [];
|
|
29
|
+
for (const lib of manifests) {
|
|
30
|
+
if (lib.kind !== "Telo.Library")
|
|
31
|
+
continue;
|
|
32
|
+
const moduleName = lib.metadata?.name;
|
|
33
|
+
if (!moduleName || !rootModules.has(moduleName))
|
|
34
|
+
continue;
|
|
35
|
+
const exports = lib.exports;
|
|
36
|
+
if (!exports || typeof exports !== "object")
|
|
37
|
+
continue;
|
|
38
|
+
const filePath = lib.metadata?.source;
|
|
39
|
+
const resource = { kind: lib.kind, name: moduleName };
|
|
40
|
+
const own = (m) => {
|
|
41
|
+
const mod = m.metadata?.module;
|
|
42
|
+
return mod === undefined || mod === moduleName;
|
|
43
|
+
};
|
|
44
|
+
const declaredKinds = new Set();
|
|
45
|
+
const instances = new Set();
|
|
46
|
+
const importAliases = new Map();
|
|
47
|
+
const forwardedByModule = new Map();
|
|
48
|
+
for (const m of manifests) {
|
|
49
|
+
const name = m.metadata?.name;
|
|
50
|
+
if (typeof name !== "string")
|
|
51
|
+
continue;
|
|
52
|
+
const meta = m.metadata;
|
|
53
|
+
if (meta.forwardedExport && meta.module) {
|
|
54
|
+
let set = forwardedByModule.get(meta.module);
|
|
55
|
+
if (!set)
|
|
56
|
+
forwardedByModule.set(meta.module, (set = new Set()));
|
|
57
|
+
set.add(name);
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
if (!own(m))
|
|
61
|
+
continue;
|
|
62
|
+
if (m.kind === "Telo.Definition" || m.kind === "Telo.Abstract")
|
|
63
|
+
declaredKinds.add(name);
|
|
64
|
+
else if (m.kind === "Telo.Import")
|
|
65
|
+
importAliases.set(name, meta.resolvedModuleName);
|
|
66
|
+
else if (m.kind !== "Telo.Library" && m.kind !== "Telo.Application")
|
|
67
|
+
instances.add(name);
|
|
68
|
+
}
|
|
69
|
+
const report = (code, path, message, fix) => out.push({
|
|
70
|
+
severity: DiagnosticSeverity.Error,
|
|
71
|
+
code,
|
|
72
|
+
source: SOURCE,
|
|
73
|
+
message: `Telo.Library/${moduleName}: ${message}`,
|
|
74
|
+
data: { resource, filePath, path, ...(fix ? { fix: { replacement: fix } } : {}) },
|
|
75
|
+
});
|
|
76
|
+
const kinds = exports.kinds;
|
|
77
|
+
if (Array.isArray(kinds)) {
|
|
78
|
+
kinds.forEach((entry, i) => {
|
|
79
|
+
if (typeof entry !== "string")
|
|
80
|
+
return;
|
|
81
|
+
const path = `exports.kinds[${i}]`;
|
|
82
|
+
const { alias, name } = parseExportEntry(entry);
|
|
83
|
+
if (alias) {
|
|
84
|
+
if (!importAliases.has(alias)) {
|
|
85
|
+
report("EXPORT_KIND_UNKNOWN", path, `'exports.kinds: ${entry}' re-exports through '${alias}', which is not an import ` +
|
|
86
|
+
`of this library. Imports: ${[...importAliases.keys()].join(", ") || "(none)"}.`);
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
const canonical = aliases.resolveKind(entry);
|
|
90
|
+
if (canonical && !registry.resolve(canonical)) {
|
|
91
|
+
report("EXPORT_KIND_UNKNOWN", path, `'exports.kinds: ${entry}' names no kind '${name}' exported by '${alias}'.`);
|
|
92
|
+
}
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
if (declaredKinds.has(name))
|
|
96
|
+
return;
|
|
97
|
+
// The natural first attempt at a re-export: the imported kind's bare
|
|
98
|
+
// suffix. It resolves as a kind — just not as one this library owns.
|
|
99
|
+
const viaImport = [...importAliases.keys()].find((a) => {
|
|
100
|
+
const canonical = aliases.resolveKind(`${a}.${name}`);
|
|
101
|
+
return canonical !== undefined && registry.resolve(canonical) !== undefined;
|
|
102
|
+
});
|
|
103
|
+
if (viaImport) {
|
|
104
|
+
report("EXPORT_KIND_UNKNOWN", path, `'exports.kinds: ${name}' is not a kind this library declares — it is ` +
|
|
105
|
+
`'${viaImport}.${name}', an imported kind. Re-export it as '${viaImport}.${name}', ` +
|
|
106
|
+
`or declare a local kind that extends it.`, `${viaImport}.${name}`);
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
const suggestion = nearestName(name, [...declaredKinds]);
|
|
110
|
+
report("EXPORT_KIND_UNKNOWN", path, `'exports.kinds: ${name}' names no Telo.Definition or Telo.Abstract of this library. ` +
|
|
111
|
+
`Declared: ${[...declaredKinds].join(", ") || "(none)"}.` +
|
|
112
|
+
(suggestion ? ` Did you mean '${suggestion}'?` : ""), suggestion);
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
const resources = exports.resources;
|
|
116
|
+
if (Array.isArray(resources)) {
|
|
117
|
+
resources.forEach((entry, i) => {
|
|
118
|
+
if (typeof entry !== "string")
|
|
119
|
+
return;
|
|
120
|
+
const path = `exports.resources[${i}]`;
|
|
121
|
+
const { alias, name } = parseExportEntry(entry);
|
|
122
|
+
if (alias) {
|
|
123
|
+
if (!importAliases.has(alias)) {
|
|
124
|
+
report("EXPORT_RESOURCE_UNKNOWN", path, `'exports.resources: ${entry}' re-exports through '${alias}', which is not an ` +
|
|
125
|
+
`import of this library. Imports: ${[...importAliases.keys()].join(", ") || "(none)"}.`);
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
const targetModule = importAliases.get(alias);
|
|
129
|
+
const exported = targetModule ? forwardedByModule.get(targetModule) : undefined;
|
|
130
|
+
if (exported && !exported.has(name)) {
|
|
131
|
+
report("EXPORT_RESOURCE_UNKNOWN", path, `'exports.resources: ${entry}' names no instance '${name}' exported by '${alias}'. ` +
|
|
132
|
+
`Exported: ${[...exported].join(", ") || "(none)"}.`);
|
|
133
|
+
}
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
if (instances.has(name))
|
|
137
|
+
return;
|
|
138
|
+
const suggestion = nearestName(name, [...instances]);
|
|
139
|
+
report("EXPORT_RESOURCE_UNKNOWN", path, `'exports.resources: ${name}' names no resource declared in this library. ` +
|
|
140
|
+
`Declared: ${[...instances].join(", ") || "(none)"}.` +
|
|
141
|
+
(suggestion ? ` Did you mean '${suggestion}'?` : ""), suggestion);
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return out;
|
|
146
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate-extends.d.ts","sourceRoot":"","sources":["../src/validate-extends.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAsB,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"validate-extends.d.ts","sourceRoot":"","sources":["../src/validate-extends.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAsB,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AASnE,OAAO,EAAsB,KAAK,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAiCzE,wBAAgB,eAAe,CAC7B,SAAS,EAAE,gBAAgB,EAAE,EAC7B,QAAQ,EAAE,kBAAkB,EAC5B,OAAO,EAAE,aAAa,GACrB,kBAAkB,EAAE,CA2OtB"}
|
package/dist/validate-extends.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { controllerBearingAncestor, effectiveAuthorSchema, inheritedCapability, isInheritedDelegation, } from "./extends-resolution.js";
|
|
1
|
+
import { controllerBearingAncestor, effectiveAuthorSchema, hasOwnControllerOrTemplate, inheritedCapability, isInheritedDelegation, } from "./extends-resolution.js";
|
|
2
2
|
import { DiagnosticSeverity } from "./types.js";
|
|
3
3
|
const SOURCE = "telo-analyzer";
|
|
4
4
|
/** Alias-form pattern for `extends`: "<Alias>.<AbstractName>", two PascalCase segments. */
|
|
@@ -59,6 +59,39 @@ export function validateExtends(manifests, registry, aliases) {
|
|
|
59
59
|
const filePath = m.metadata?.source;
|
|
60
60
|
const resource = { kind: m.kind, name };
|
|
61
61
|
const label = `${m.kind}/${name}`;
|
|
62
|
+
// `base:` is read on exactly one path — the inherited-controller one, which
|
|
63
|
+
// the kernel takes only when the definition has NO body of its own. A
|
|
64
|
+
// `resources:` block or a dispatch slot selects the template path, and
|
|
65
|
+
// `base:` is then never evaluated: the kind silently became an empty
|
|
66
|
+
// template, and the failure landed in the CONSUMER's resource as a `{}`
|
|
67
|
+
// where a parent instance should have been. Refused here, where the two
|
|
68
|
+
// blocks sit side by side, and at registration in the kernel.
|
|
69
|
+
//
|
|
70
|
+
// WHETHER there is a body is `hasOwnControllerOrTemplate` — the same
|
|
71
|
+
// predicate the kernel branches on, so the two halves cannot disagree about
|
|
72
|
+
// what a body is. Deciding it here with a key scan did disagree: an empty
|
|
73
|
+
// `resources: []` is falsy to a length test and truthy to the kernel's, so
|
|
74
|
+
// it passed `telo check` and threw `ERR_BASE_WITH_TEMPLATE_BODY` at boot —
|
|
75
|
+
// a brand-new guard shipping with the very gap it was written to close. The
|
|
76
|
+
// scan survives for one job only: naming the offending key in the message.
|
|
77
|
+
if (m.base != null) {
|
|
78
|
+
const hasBody = hasOwnControllerOrTemplate(m);
|
|
79
|
+
const bodyKey = ["resources", "controllers", "invoke", "run", "provide", "mount"].find((key) => m[key] !== undefined) ?? "resources";
|
|
80
|
+
if (hasBody) {
|
|
81
|
+
diagnostics.push({
|
|
82
|
+
severity: DiagnosticSeverity.Error,
|
|
83
|
+
code: "BASE_WITH_TEMPLATE_BODY",
|
|
84
|
+
source: SOURCE,
|
|
85
|
+
message: `${label}: 'base:' maps this kind's config onto the inherited controller of ` +
|
|
86
|
+
`'${typeof extendsOf(m) === "string" ? extendsOf(m) : "<no extends>"}', so the ` +
|
|
87
|
+
`definition may not also declare '${bodyKey}:'. With '${bodyKey}:' the kind is a ` +
|
|
88
|
+
`template and 'base:' is never evaluated. Either drop 'base:' and dispatch to a ` +
|
|
89
|
+
`'resources:' entry with '!ref', or drop '${bodyKey}:' and build the parent's config ` +
|
|
90
|
+
`in 'base:' alone.`,
|
|
91
|
+
data: { resource, filePath, path: bodyKey },
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
}
|
|
62
95
|
// --- extends validation ---
|
|
63
96
|
// At this point `m.extends` is whatever the manifest declared (alias form, e.g.
|
|
64
97
|
// "Ai.Model"). Resolve through the AliasResolver to the canonical form before
|
|
@@ -219,3 +252,6 @@ export function validateExtends(manifests, registry, aliases) {
|
|
|
219
252
|
}
|
|
220
253
|
return diagnostics;
|
|
221
254
|
}
|
|
255
|
+
function extendsOf(m) {
|
|
256
|
+
return m.extends;
|
|
257
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ResourceManifest } from "@telorun/sdk";
|
|
2
|
-
import type
|
|
2
|
+
import { type AliasResolver, type ModuleScopes } from "./alias-resolver.js";
|
|
3
3
|
import type { CallGraph } from "./call-graph.js";
|
|
4
4
|
import type { DefinitionRegistry } from "./definition-registry.js";
|
|
5
5
|
import { type AnalysisDiagnostic } from "./types.js";
|
|
@@ -27,5 +27,5 @@ import { type AnalysisDiagnostic } from "./types.js";
|
|
|
27
27
|
*
|
|
28
28
|
* Browser-safe.
|
|
29
29
|
*/
|
|
30
|
-
export declare function validateIdentifierNames(manifests: ResourceManifest[], registry: DefinitionRegistry, aliases: AliasResolver, rootModules: Set<string>, graph: CallGraph): AnalysisDiagnostic[];
|
|
30
|
+
export declare function validateIdentifierNames(manifests: ResourceManifest[], registry: DefinitionRegistry, aliases: AliasResolver, rootModules: Set<string>, graph: CallGraph, scopes: ModuleScopes): AnalysisDiagnostic[];
|
|
31
31
|
//# sourceMappingURL=validate-identifier-names.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate-identifier-names.d.ts","sourceRoot":"","sources":["../src/validate-identifier-names.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"validate-identifier-names.d.ts","sourceRoot":"","sources":["../src/validate-identifier-names.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAsB,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEzE,OAAO,EAEL,KAAK,aAAa,EAClB,KAAK,YAAY,EAClB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AASnE,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAIrD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,gBAAgB,EAAE,EAC7B,QAAQ,EAAE,kBAAkB,EAC5B,OAAO,EAAE,aAAa,EACtB,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,EACxB,KAAK,EAAE,SAAS,EAChB,MAAM,EAAE,YAAY,GACnB,kBAAkB,EAAE,CAyEtB"}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { moduleScopedDefResolver, } from "./alias-resolver.js";
|
|
2
|
+
import { inheritedCapability } from "./extends-resolution.js";
|
|
1
3
|
import { TYPE_LEVEL_DOC_KINDS, checkName, } from "./identifier-name.js";
|
|
2
4
|
import { isInjectedDeclaration } from "./resource-input.js";
|
|
3
5
|
const SOURCE = "telo-analyzer";
|
|
@@ -25,8 +27,9 @@ const SOURCE = "telo-analyzer";
|
|
|
25
27
|
*
|
|
26
28
|
* Browser-safe.
|
|
27
29
|
*/
|
|
28
|
-
export function validateIdentifierNames(manifests, registry, aliases, rootModules, graph) {
|
|
30
|
+
export function validateIdentifierNames(manifests, registry, aliases, rootModules, graph, scopes) {
|
|
29
31
|
const out = [];
|
|
32
|
+
const resolveDef = moduleScopedDefResolver(registry, aliases, scopes);
|
|
30
33
|
for (const manifest of manifests) {
|
|
31
34
|
const metadata = manifest.metadata;
|
|
32
35
|
const name = typeof metadata?.name === "string" ? metadata.name : undefined;
|
|
@@ -45,7 +48,7 @@ export function validateIdentifierNames(manifests, registry, aliases, rootModule
|
|
|
45
48
|
const ownModule = metadata?.module;
|
|
46
49
|
if (ownModule && !rootModules.has(ownModule))
|
|
47
50
|
continue;
|
|
48
|
-
const level = levelFor(manifest,
|
|
51
|
+
const level = levelFor(manifest, resolveDef, ownModule);
|
|
49
52
|
push(out, checkName(name, level, surfaceFor(manifest.kind)), {
|
|
50
53
|
kind: manifest.kind,
|
|
51
54
|
name,
|
|
@@ -106,17 +109,29 @@ export function validateIdentifierNames(manifests, registry, aliases, rootModule
|
|
|
106
109
|
* a resource. Capability-driven rather than by kind name, so no resource kind
|
|
107
110
|
* is hardcoded here.
|
|
108
111
|
*
|
|
112
|
+
* **The capability is the INHERITED one**, not the leaf declaration. Capability
|
|
113
|
+
* is inherited and immutable along `extends` — a kind omits it to take its
|
|
114
|
+
* ancestor's — so reading the leaf answers `undefined` for every kind that does,
|
|
115
|
+
* and the fallback then calls a type a value. That is not hypothetical: it is
|
|
116
|
+
* exactly `Type.JsonSchema`, a pure alias of the built-in (`extends:
|
|
117
|
+
* Telo.JsonSchema`, no `capability:` of its own), so a shape declared through
|
|
118
|
+
* the deprecated spelling was reported as miscased while the identical
|
|
119
|
+
* declaration written as `kind: Telo.JsonSchema` was not. Renaming on that
|
|
120
|
+
* report is worse than the warning: `extends:` between two named shapes is not a
|
|
121
|
+
* reference slot, so the inheritance edge does not move with the name.
|
|
122
|
+
*
|
|
109
123
|
* An unresolvable kind falls back to value level — the honest default, since
|
|
110
124
|
* `UNDEFINED_KIND` already reports the real problem and guessing type level
|
|
111
125
|
* would stack a case error on top of it.
|
|
112
126
|
*/
|
|
113
|
-
function levelFor(manifest,
|
|
127
|
+
function levelFor(manifest, resolveDef, ownModule) {
|
|
114
128
|
if (TYPE_LEVEL_DOC_KINDS.has(manifest.kind))
|
|
115
129
|
return "type";
|
|
116
|
-
// The
|
|
117
|
-
//
|
|
118
|
-
|
|
119
|
-
|
|
130
|
+
// The top-level lookup is in the module that WROTE the `kind:` — a root one,
|
|
131
|
+
// the others having been skipped above — while the chain walk re-scopes at
|
|
132
|
+
// every hop, since an `extends` alias belongs to the file declaring it.
|
|
133
|
+
const def = resolveDef.in(manifest.kind, ownModule);
|
|
134
|
+
return inheritedCapability(def, resolveDef) === "Telo.Type" ? "type" : "value";
|
|
120
135
|
}
|
|
121
136
|
/** The noun phrase a diagnostic uses as its subject. */
|
|
122
137
|
function surfaceFor(kind) {
|
|
@@ -12,20 +12,16 @@ import { type AnalysisDiagnostic } from "./types.js";
|
|
|
12
12
|
* `capability` is not `Telo.Provider`.
|
|
13
13
|
* - PROVIDE_DISPATCHER_CONFLICT: `provide:` co-exists with `invoke:` or `run:`
|
|
14
14
|
* on the same definition.
|
|
15
|
-
* - PROVIDE_TARGET_UNKNOWN: `provide.name` does not resolve to an entry in
|
|
16
|
-
* `resources:`.
|
|
17
|
-
* - PROVIDE_TARGET_NOT_INVOCABLE: `provide.name` resolves to a resource whose
|
|
18
|
-
* kind is registered but not a `Telo.Invocable`.
|
|
19
15
|
* - PROVIDER_MISSING_IMPLEMENTATION: definition with `capability: Telo.Provider`
|
|
20
16
|
* declares neither `controllers:` (TS-backed) nor `provide:` (template-backed).
|
|
21
17
|
* - MOUNT_ON_NON_MOUNT: `mount:` declared on a definition whose `capability` is
|
|
22
18
|
* not `Telo.Mount`.
|
|
23
19
|
* - MOUNT_DISPATCHER_CONFLICT: `mount:` co-exists with another dispatch
|
|
24
20
|
* entry-point (`invoke:` / `run:` / `provide:`).
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
21
|
+
*
|
|
22
|
+
* What a dispatch slot NAMES — that it is a `!ref`, that the entry exists, that
|
|
23
|
+
* its capability carries the method — is `validate-template-body`'s, for every
|
|
24
|
+
* slot alike.
|
|
29
25
|
*/
|
|
30
26
|
export declare function validateProviderCoherence(manifests: ResourceManifest[], registry: DefinitionRegistry, aliases: AliasResolver): AnalysisDiagnostic[];
|
|
31
27
|
//# sourceMappingURL=validate-provider-coherence.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate-provider-coherence.d.ts","sourceRoot":"","sources":["../src/validate-provider-coherence.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAsB,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"validate-provider-coherence.d.ts","sourceRoot":"","sources":["../src/validate-provider-coherence.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAsB,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAMnE,OAAO,EAAsB,KAAK,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAIzE;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,gBAAgB,EAAE,EAC7B,QAAQ,EAAE,kBAAkB,EAC5B,OAAO,EAAE,aAAa,GACrB,kBAAkB,EAAE,CAiHtB"}
|