@telorun/analyzer 0.43.0 → 0.44.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 +4 -4
- package/dist/analysis-registry.d.ts.map +1 -1
- package/dist/analysis-registry.js +3 -3
- package/dist/analyzer.d.ts.map +1 -1
- package/dist/analyzer.js +84 -1
- package/dist/builtins.js +7 -7
- package/dist/definition-registry.d.ts +49 -22
- package/dist/definition-registry.d.ts.map +1 -1
- package/dist/definition-registry.js +67 -61
- package/dist/loaded-types.d.ts +13 -6
- package/dist/loaded-types.d.ts.map +1 -1
- package/dist/manifest-loader.d.ts.map +1 -1
- package/dist/manifest-loader.js +1 -0
- package/dist/reconcile-module-versions.d.ts +2 -2
- package/dist/reconcile-module-versions.d.ts.map +1 -1
- package/dist/reconcile-module-versions.js +69 -17
- package/dist/reference-field-map.d.ts +2 -1
- package/dist/reference-field-map.d.ts.map +1 -1
- package/dist/resolve-schema-ref-kinds.d.ts +62 -0
- package/dist/resolve-schema-ref-kinds.d.ts.map +1 -0
- package/dist/resolve-schema-ref-kinds.js +81 -0
- package/dist/sources/manifest-cache.d.ts +14 -4
- package/dist/sources/manifest-cache.d.ts.map +1 -1
- package/dist/sources/manifest-cache.js +15 -6
- package/package.json +2 -2
- package/src/analysis-registry.ts +4 -4
- package/src/analyzer.ts +85 -2
- package/src/builtins.ts +7 -7
- package/src/definition-registry.ts +67 -66
- package/src/loaded-types.ts +13 -6
- package/src/manifest-loader.ts +1 -0
- package/src/reconcile-module-versions.ts +69 -17
- package/src/reference-field-map.ts +2 -1
- package/src/resolve-schema-ref-kinds.ts +118 -0
- package/src/sources/manifest-cache.ts +26 -8
|
@@ -10,7 +10,7 @@ export interface RefFieldInfo {
|
|
|
10
10
|
path: string;
|
|
11
11
|
/** True when the path traverses at least one array. */
|
|
12
12
|
isArray: boolean;
|
|
13
|
-
/** Accepted `x-telo-ref` constraint strings (e.g. `
|
|
13
|
+
/** Accepted `x-telo-ref` constraint strings, canonicalized (e.g. `Telo.Runnable`). */
|
|
14
14
|
refs: string[];
|
|
15
15
|
/** Distinct capabilities the slot may target (`Telo.Runnable`,
|
|
16
16
|
* `Telo.Service`, `Telo.Provider`, …) — one per resolvable constraint. The
|
|
@@ -55,9 +55,9 @@ export declare class AnalysisRegistry {
|
|
|
55
55
|
refFieldsForResource(resource: ResourceManifest): RefFieldInfo[];
|
|
56
56
|
/** Base capability an `x-telo-ref` constraint targets. A definition's declared
|
|
57
57
|
* `capability` is always one of the base capabilities, so it wins — this
|
|
58
|
-
* resolves user-defined abstracts (e.g. `
|
|
58
|
+
* resolves user-defined abstracts (e.g. `ai.Model`, declared
|
|
59
59
|
* `capability: Telo.Invocable`) to the capability instances satisfy, not the
|
|
60
|
-
* abstract kind. Builtin abstracts (`
|
|
60
|
+
* abstract kind. Builtin abstracts (`Telo.Runnable`) carry no `capability`
|
|
61
61
|
* field — there the kind itself *is* the capability. Undefined when
|
|
62
62
|
* unresolvable. */
|
|
63
63
|
capabilityForRef(xTeloRef: string): string | undefined;
|
|
@@ -137,7 +137,7 @@ export declare class AnalysisRegistry {
|
|
|
137
137
|
* resolved (e.g. unregistered identity). */
|
|
138
138
|
acceptedKindsForRef(xTeloRef: string): Set<string> | undefined;
|
|
139
139
|
/** Returns every user-facing (alias-form) kind that satisfies the given
|
|
140
|
-
* `x-telo-ref` constraint string (e.g. `"
|
|
140
|
+
* `x-telo-ref` constraint string, canonicalized (e.g. `"Telo.Invocable"`, `"sql.Connection"`).
|
|
141
141
|
* Resolution mirrors `validateReferences.checkKind`: abstract targets expand to
|
|
142
142
|
* the set of definitions extending them; concrete targets yield just themselves.
|
|
143
143
|
* Returns `undefined` when the ref can't be resolved (e.g. unregistered identity),
|
|
@@ -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;AAKzE,OAAO,EAAqC,KAAK,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAEhG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAGlD;;wDAEwD;AACxD,MAAM,WAAW,YAAY;IAC3B;0CACsC;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,uDAAuD;IACvD,OAAO,EAAE,OAAO,CAAC;IACjB,
|
|
1
|
+
{"version":3,"file":"analysis-registry.d.ts","sourceRoot":"","sources":["../src/analysis-registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -81,9 +81,9 @@ export class AnalysisRegistry {
|
|
|
81
81
|
}
|
|
82
82
|
/** Base capability an `x-telo-ref` constraint targets. A definition's declared
|
|
83
83
|
* `capability` is always one of the base capabilities, so it wins — this
|
|
84
|
-
* resolves user-defined abstracts (e.g. `
|
|
84
|
+
* resolves user-defined abstracts (e.g. `ai.Model`, declared
|
|
85
85
|
* `capability: Telo.Invocable`) to the capability instances satisfy, not the
|
|
86
|
-
* abstract kind. Builtin abstracts (`
|
|
86
|
+
* abstract kind. Builtin abstracts (`Telo.Runnable`) carry no `capability`
|
|
87
87
|
* field — there the kind itself *is* the capability. Undefined when
|
|
88
88
|
* unresolvable. */
|
|
89
89
|
capabilityForRef(xTeloRef) {
|
|
@@ -260,7 +260,7 @@ export class AnalysisRegistry {
|
|
|
260
260
|
return out;
|
|
261
261
|
}
|
|
262
262
|
/** Returns every user-facing (alias-form) kind that satisfies the given
|
|
263
|
-
* `x-telo-ref` constraint string (e.g. `"
|
|
263
|
+
* `x-telo-ref` constraint string, canonicalized (e.g. `"Telo.Invocable"`, `"sql.Connection"`).
|
|
264
264
|
* Resolution mirrors `validateReferences.checkKind`: abstract targets expand to
|
|
265
265
|
* the set of definitions extending them; concrete targets yield just themselves.
|
|
266
266
|
* Returns `undefined` when the ref can't be resolved (e.g. unregistered identity),
|
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;AAKzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAIL,KAAK,WAAW,EACjB,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"analyzer.d.ts","sourceRoot":"","sources":["../src/analyzer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAsB,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAKzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAIL,KAAK,WAAW,EACjB,MAAM,sBAAsB,CAAC;AAsB9B,OAAO,EAAsB,KAAK,kBAAkB,EAAE,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;AA8xB/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;;;;;;;;;;;;;;OAcG;IACH,OAAO,CACL,SAAS,EAAE,gBAAgB,EAAE,EAC7B,OAAO,CAAC,EAAE,eAAe,EACzB,QAAQ,CAAC,EAAE,gBAAgB,GAC1B,kBAAkB,EAAE;IA07BvB,aAAa,CACX,SAAS,EAAE,gBAAgB,EAAE,EAC7B,OAAO,CAAC,EAAE,eAAe,EACzB,QAAQ,CAAC,EAAE,gBAAgB,GAC1B,kBAAkB,EAAE;IAMvB,SAAS,CACP,SAAS,EAAE,gBAAgB,EAAE,EAC7B,QAAQ,EAAE,gBAAgB,EAI1B,kBAAkB,CAAC,EAAE,gBAAgB,EAAE,GACtC,gBAAgB,EAAE;IAmBrB,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
|
@@ -12,6 +12,7 @@ import { isModuleKind } from "./module-kinds.js";
|
|
|
12
12
|
import { normalizeInlineResources } from "./normalize-inline-resources.js";
|
|
13
13
|
import { REF_VALIDATION_SKIP_KINDS } from "./system-kinds.js";
|
|
14
14
|
import { resolveRefSentinels } from "./resolve-ref-sentinels.js";
|
|
15
|
+
import { resolveSchemaRefKinds } from "./resolve-schema-ref-kinds.js";
|
|
15
16
|
import { resolveSchemaTypeRefs } from "./resolve-schema-type-refs.js";
|
|
16
17
|
import { validateSchemaTypeRefs } from "./validate-schema-type-refs.js";
|
|
17
18
|
import { rewriteSyntheticOrigins } from "./rewrite-synthetic-origins.js";
|
|
@@ -865,6 +866,7 @@ export class StaticAnalyzer {
|
|
|
865
866
|
// declaring scope's resolver, so `extendedBy` is keyed by canonical kind regardless
|
|
866
867
|
// of alias choices. `capability` covers the legacy implements-this-abstract overload;
|
|
867
868
|
// `extends` is the canonical first-class form.
|
|
869
|
+
const refConstraintIssues = [];
|
|
868
870
|
for (const m of manifests) {
|
|
869
871
|
if (m.kind !== "Telo.Definition" && m.kind !== "Telo.Abstract")
|
|
870
872
|
continue;
|
|
@@ -873,6 +875,16 @@ export class StaticAnalyzer {
|
|
|
873
875
|
const scopeResolver = ownModule && !rootModules.has(ownModule)
|
|
874
876
|
? (aliasesByModule.get(ownModule) ?? new AliasResolver())
|
|
875
877
|
: aliases;
|
|
878
|
+
// Canonicalize alias-form `x-telo-ref` constraints in the DECLARING module's
|
|
879
|
+
// scope, before the schema reaches `register()` and the lazily-built field
|
|
880
|
+
// maps. Same pre-resolution `capability` / `extends` get below.
|
|
881
|
+
const issues = resolveSchemaRefKinds(m, scopeResolver);
|
|
882
|
+
// Report only for definitions the author can edit. A published dependency
|
|
883
|
+
// still on the deprecated form — or with a constraint that no longer
|
|
884
|
+
// resolves — is not the consumer's to fix, and every import would
|
|
885
|
+
// otherwise flood `telo check` with unactionable noise.
|
|
886
|
+
if (!ownModule || rootModules.has(ownModule))
|
|
887
|
+
refConstraintIssues.push(...issues);
|
|
876
888
|
const resolvedCapability = def.capability
|
|
877
889
|
? (scopeResolver.resolveKind(def.capability) ?? def.capability)
|
|
878
890
|
: def.capability;
|
|
@@ -891,6 +903,57 @@ export class StaticAnalyzer {
|
|
|
891
903
|
// distinguishable from the resolver's own substitution (after Phase 2/2.5
|
|
892
904
|
// they are the same object).
|
|
893
905
|
if (!options?.skipValidation) {
|
|
906
|
+
for (const issue of refConstraintIssues) {
|
|
907
|
+
// An `unknown` prefix is also what an ALREADY-CANONICAL value looks like
|
|
908
|
+
// (`kv-store.Store` names a module, not an alias). Now that every kind is
|
|
909
|
+
// registered, the registry separates the two — anything it resolves was
|
|
910
|
+
// canonical, anything it doesn't names nothing at all.
|
|
911
|
+
if (issue.reason === "unknown" && defs.resolve(issue.ref))
|
|
912
|
+
continue;
|
|
913
|
+
const resource = {
|
|
914
|
+
kind: issue.manifest.kind,
|
|
915
|
+
name: issue.manifest.metadata?.name,
|
|
916
|
+
};
|
|
917
|
+
const filePath = issue.manifest.metadata?.source;
|
|
918
|
+
const data = { resource, filePath, path: issue.path };
|
|
919
|
+
if (issue.reason === "legacy") {
|
|
920
|
+
diagnostics.push({
|
|
921
|
+
severity: DiagnosticSeverity.Warning,
|
|
922
|
+
code: "X_TELO_REF_LEGACY_IDENTITY",
|
|
923
|
+
source: SOURCE,
|
|
924
|
+
message: `x-telo-ref '${issue.ref}' at '${issue.path}' uses the deprecated ` +
|
|
925
|
+
`'<namespace>/<module>#<Kind>' form. Write the target as an alias-qualified kind ` +
|
|
926
|
+
`instead — '<Alias>.<Kind>' for a module declared in this file's 'imports:' map, ` +
|
|
927
|
+
`'Self.<Kind>' for a kind in this library, or 'Telo.<Kind>' for a built-in capability.`,
|
|
928
|
+
data,
|
|
929
|
+
});
|
|
930
|
+
}
|
|
931
|
+
else if (issue.reason === "gated") {
|
|
932
|
+
diagnostics.push({
|
|
933
|
+
severity: DiagnosticSeverity.Error,
|
|
934
|
+
code: "KIND_NOT_EXPORTED",
|
|
935
|
+
source: SOURCE,
|
|
936
|
+
message: `x-telo-ref '${issue.ref}' at '${issue.path}' targets a kind module ` +
|
|
937
|
+
`'${issue.gate?.module}' does not export. Add ` +
|
|
938
|
+
`'${issue.ref.slice(issue.ref.indexOf(".") + 1)}' to that module's exports.kinds. ` +
|
|
939
|
+
`Exported kinds: ${issue.gate?.exported.join(", ") || "(none)"}.`,
|
|
940
|
+
data,
|
|
941
|
+
});
|
|
942
|
+
}
|
|
943
|
+
else {
|
|
944
|
+
diagnostics.push({
|
|
945
|
+
severity: DiagnosticSeverity.Error,
|
|
946
|
+
code: "X_TELO_REF_UNRESOLVED",
|
|
947
|
+
source: SOURCE,
|
|
948
|
+
message: `x-telo-ref '${issue.ref}' at '${issue.path}' names no kind. The prefix must be an ` +
|
|
949
|
+
`import alias declared in this file's 'imports:' map, 'Self' for a kind in this ` +
|
|
950
|
+
`library, or 'Telo' for a built-in capability. An unresolvable constraint would ` +
|
|
951
|
+
`leave the slot accepting any resource. Known aliases: ` +
|
|
952
|
+
`${issue.knownAliases?.join(", ") || "(none)"}.`,
|
|
953
|
+
data,
|
|
954
|
+
});
|
|
955
|
+
}
|
|
956
|
+
}
|
|
894
957
|
diagnostics.push(...validateReferenceForms(manifests, defs, aliases, aliasesByModule));
|
|
895
958
|
}
|
|
896
959
|
// Phase 2: extract inline resources from x-telo-ref slots into first-class manifests
|
|
@@ -914,7 +977,27 @@ export class StaticAnalyzer {
|
|
|
914
977
|
const canonicalKind = scopeResolver.resolveKind(m.kind) ?? m.kind;
|
|
915
978
|
if (defs.resolve(canonicalKind)?.capability !== "Telo.Type")
|
|
916
979
|
continue;
|
|
917
|
-
|
|
980
|
+
const typeName = m.metadata.name;
|
|
981
|
+
const registered = defs.registerNamedTypeSchema(canonicalTypeSchemaId(ownModule, typeName), m.schema);
|
|
982
|
+
// Kinds and named types share one `telo://<module>/<Name>` id space. A
|
|
983
|
+
// collision would leave every `$ref` to that id resolving to the kind's
|
|
984
|
+
// schema — validating the wrong shape, silently — so it is an error, not
|
|
985
|
+
// a last-writer-wins.
|
|
986
|
+
if (!registered && !options?.skipValidation) {
|
|
987
|
+
diagnostics.push({
|
|
988
|
+
severity: DiagnosticSeverity.Error,
|
|
989
|
+
code: "DUPLICATE_SCHEMA_ID",
|
|
990
|
+
source: SOURCE,
|
|
991
|
+
message: `Type '${typeName}' collides with the kind '${ownModule}.${typeName}': both claim the ` +
|
|
992
|
+
`schema id '${canonicalTypeSchemaId(ownModule, typeName)}'. A '$ref' to it would ` +
|
|
993
|
+
`resolve to the kind's schema. Rename one of them.`,
|
|
994
|
+
data: {
|
|
995
|
+
resource: { kind: m.kind, name: typeName },
|
|
996
|
+
filePath: m.metadata?.source,
|
|
997
|
+
path: "metadata.name",
|
|
998
|
+
},
|
|
999
|
+
});
|
|
1000
|
+
}
|
|
918
1001
|
}
|
|
919
1002
|
if (!options?.skipValidation) {
|
|
920
1003
|
diagnostics.push(...validateSchemaTypeRefs(allManifests, defs, aliases, aliasesByModule, rootModules));
|
package/dist/builtins.js
CHANGED
|
@@ -89,7 +89,7 @@ const ROOT_LOGGING_SCHEMA = {
|
|
|
89
89
|
type: "array",
|
|
90
90
|
items: {
|
|
91
91
|
type: "object",
|
|
92
|
-
"x-telo-ref": "
|
|
92
|
+
"x-telo-ref": "Telo.LogSink",
|
|
93
93
|
"x-telo-inline": true,
|
|
94
94
|
},
|
|
95
95
|
},
|
|
@@ -435,8 +435,8 @@ export const KERNEL_BUILTINS = [
|
|
|
435
435
|
type: "array",
|
|
436
436
|
items: {
|
|
437
437
|
anyOf: [
|
|
438
|
-
{ type: "string", "x-telo-ref": "
|
|
439
|
-
{ type: "string", "x-telo-ref": "
|
|
438
|
+
{ type: "string", "x-telo-ref": "Telo.Runnable" },
|
|
439
|
+
{ type: "string", "x-telo-ref": "Telo.Service" },
|
|
440
440
|
// Post-resolution shape that `resolveRefSentinels`
|
|
441
441
|
// substitutes a `!ref <name>` sentinel into. The
|
|
442
442
|
// adjacent `x-telo-ref` constraints govern the kind
|
|
@@ -460,8 +460,8 @@ export const KERNEL_BUILTINS = [
|
|
|
460
460
|
properties: {
|
|
461
461
|
ref: {
|
|
462
462
|
anyOf: [
|
|
463
|
-
{ type: "string", "x-telo-ref": "
|
|
464
|
-
{ type: "string", "x-telo-ref": "
|
|
463
|
+
{ type: "string", "x-telo-ref": "Telo.Runnable" },
|
|
464
|
+
{ type: "string", "x-telo-ref": "Telo.Service" },
|
|
465
465
|
{
|
|
466
466
|
type: "object",
|
|
467
467
|
required: ["kind", "name"],
|
|
@@ -501,8 +501,8 @@ export const KERNEL_BUILTINS = [
|
|
|
501
501
|
},
|
|
502
502
|
additionalProperties: true,
|
|
503
503
|
anyOf: [
|
|
504
|
-
{ "x-telo-ref": "
|
|
505
|
-
{ "x-telo-ref": "
|
|
504
|
+
{ "x-telo-ref": "Telo.Invocable" },
|
|
505
|
+
{ "x-telo-ref": "Telo.Runnable" },
|
|
506
506
|
],
|
|
507
507
|
},
|
|
508
508
|
inputs: { type: "object", additionalProperties: true },
|
|
@@ -9,36 +9,52 @@ export declare class DefinitionRegistry {
|
|
|
9
9
|
* across analyze() calls and no unbounded growth across the process lifetime. */
|
|
10
10
|
private readonly ajv;
|
|
11
11
|
private readonly registeredSchemaIds;
|
|
12
|
+
/** The subset of `registeredSchemaIds` claimed by a kind's schema. Kinds and
|
|
13
|
+
* named `Telo.Type`s share one `telo://<module>/<Name>` id space, so this is
|
|
14
|
+
* what lets a colliding type name be reported instead of silently dropped. */
|
|
15
|
+
private readonly definitionSchemaIds;
|
|
12
16
|
private readonly defs;
|
|
13
17
|
private readonly fieldMaps;
|
|
14
18
|
/** Reverse inheritance index: parent kind → direct child kinds. */
|
|
15
19
|
private readonly extendedBy;
|
|
16
|
-
/**
|
|
17
|
-
* "
|
|
20
|
+
/** DEPRECATED module identity table: identity string → canonical module name
|
|
21
|
+
* ("std/pipeline" → "pipeline"). Serves only the legacy
|
|
22
|
+
* `<namespace>/<module>#<Kind>` form of `x-telo-ref`, kept resolvable for
|
|
23
|
+
* module versions published before constraints named their target by import
|
|
24
|
+
* alias. Fed by `metadata.namespace`, which nothing else reads. */
|
|
18
25
|
private readonly identityMap;
|
|
19
|
-
/** Reverse identity table: canonical module name → full identity string.
|
|
20
|
-
* "Telo" → "telo", "pipeline" → "std/pipeline", etc.
|
|
21
|
-
* Used to compute definition $id values for the AJV schema store. */
|
|
22
|
-
private readonly reverseIdentityMap;
|
|
23
26
|
register(definition: ResourceDefinition): void;
|
|
24
27
|
private addExtendedBy;
|
|
25
|
-
/** Register a module identity
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
28
|
+
/** DEPRECATED. Register a module identity so the legacy
|
|
29
|
+
* `<namespace>/<module>#<Kind>` form of `x-telo-ref` still resolves for module
|
|
30
|
+
* versions published before constraints named their target by import alias.
|
|
31
|
+
* New manifests declare no namespace and need no identity — their constraints
|
|
32
|
+
* are canonicalized to `<module>.<Kind>` before registration.
|
|
33
|
+
*
|
|
34
|
+
* The "telo" identity is reserved for the built-in module and is populated
|
|
35
|
+
* automatically when a `Telo.Abstract` registers. A namespace-less module must
|
|
36
|
+
* not claim it: overwriting the entry would repoint every legacy `telo#…`
|
|
37
|
+
* constraint at a module that declares no such kind, and the resulting
|
|
38
|
+
* unresolvable ref reads as partial context rather than an error.
|
|
39
|
+
*
|
|
40
|
+
* @param namespace The module's `metadata.namespace`, or null when it declares none.
|
|
41
|
+
* @param moduleName The module's `metadata.name` (e.g. "pipeline", "http-server"). */
|
|
29
42
|
registerModuleIdentity(namespace: string | null, moduleName: string): void;
|
|
30
43
|
/** Registers a named `Telo.Type` resource's schema under its canonical
|
|
31
44
|
* module-scoped URI `$id` (`telo://<module>/<name>`), so a sibling schema's
|
|
32
45
|
* `$ref: "telo://Self/<name>"` (rewritten to the canonical form by
|
|
33
46
|
* `resolveSchemaTypeRefs`) resolves during AJV compilation. Mirrors the
|
|
34
|
-
* kernel type controller's `registerSchema(canonicalTypeSchemaId(...))`.
|
|
35
|
-
|
|
47
|
+
* kernel type controller's `registerSchema(canonicalTypeSchemaId(...))`.
|
|
48
|
+
*
|
|
49
|
+
* Returns `false` when a kind schema in the same module already owns the id —
|
|
50
|
+
* a name collision between a kind and a named type. Definitions register
|
|
51
|
+
* first, so the type is the one that would be dropped, and every
|
|
52
|
+
* `$ref: "telo://<module>/<Name>"` would then silently validate against the
|
|
53
|
+
* kind's schema instead. The caller reports it; nothing is overwritten. */
|
|
54
|
+
registerNamedTypeSchema(id: string, schema: Record<string, any>): boolean;
|
|
36
55
|
/** True when a schema is registered under `id` (a canonical `telo://` type id
|
|
37
56
|
* or a definition `$id`). Used to flag schema `$ref`s that resolve to nothing. */
|
|
38
57
|
hasSchemaId(id: string): boolean;
|
|
39
|
-
/** Computes the $id for a definition schema: "<identity>/<TypeName>".
|
|
40
|
-
* Returns undefined when the module identity is not yet registered. */
|
|
41
|
-
computeId(moduleName: string, typeName: string): string | undefined;
|
|
42
58
|
/** Validates data against a schema using this registry's AJV instance, which has all
|
|
43
59
|
* registered definition schemas loaded — enabling cross-module $ref resolution.
|
|
44
60
|
* A compile failure returns `[]` here; it is surfaced loudly (once, on the
|
|
@@ -53,16 +69,27 @@ export declare class DefinitionRegistry {
|
|
|
53
69
|
* `validateWithRefs` would swallow the failure and silently skip every
|
|
54
70
|
* resource of that kind. */
|
|
55
71
|
schemaCompileError(schema: Record<string, any>): string | undefined;
|
|
72
|
+
/** Registers a definition schema under the same module-scoped `telo://` id a
|
|
73
|
+
* named `Telo.Type` uses, so a kind schema and a type schema are addressable
|
|
74
|
+
* the same way and a `$ref` between them resolves at AJV compile time. One id
|
|
75
|
+
* space per module: a kind and a named type may not share a name, which
|
|
76
|
+
* `registerNamedTypeSchema` reports rather than resolving silently. */
|
|
56
77
|
private tryRegisterSchema;
|
|
57
|
-
/** Resolves an x-telo-ref
|
|
58
|
-
*
|
|
59
|
-
*
|
|
78
|
+
/** Resolves an `x-telo-ref` constraint to a canonical registry kind key.
|
|
79
|
+
*
|
|
80
|
+
* The constraint is already canonical `<module>.<Kind>`: alias-form values
|
|
81
|
+
* (`KvStore.Store`, `Self.Store`, `Telo.Invocable`) are rewritten in the
|
|
82
|
+
* declaring module's scope by `resolveSchemaRefKinds` before registration, so
|
|
83
|
+
* no module context is needed here.
|
|
84
|
+
*
|
|
85
|
+
* The legacy `<namespace>/<module>#<Kind>` form still resolves through the
|
|
86
|
+
* identity table for module versions published before the alias form existed:
|
|
60
87
|
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
* "std/http-server#Server" → "http-server.Server"
|
|
88
|
+
* "telo#Invocable" → "Telo.Invocable"
|
|
89
|
+
* "std/http-server#Server" → "http-server.Server"
|
|
64
90
|
*
|
|
65
|
-
* Returns undefined when
|
|
91
|
+
* Returns undefined when a legacy string is malformed or its identity was
|
|
92
|
+
* never registered. */
|
|
66
93
|
resolveRef(xTeloRef: string): string | undefined;
|
|
67
94
|
resolve(kind: string): ResourceDefinition | undefined;
|
|
68
95
|
/** Returns the reference field map for the given kind, computed lazily from the
|
|
@@ -1 +1 @@
|
|
|
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;
|
|
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;AAEzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,OAAO,EAIL,KAAK,iBAAiB,EACvB,MAAM,0BAA0B,CAAC;AAIlC,+EAA+E;AAC/E,qBAAa,kBAAkB;;IAK7B;;sFAEkF;IAClF,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;IACnC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAqB;IACzD;;mFAE+E;IAC/E,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;;;;wEAIoE;IACpE,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA6B;IAEzD,QAAQ,CAAC,UAAU,EAAE,kBAAkB,GAAG,IAAI;IAoC9C,OAAO,CAAC,aAAa;IASrB;;;;;;;;;;;;;2FAauF;IACvF,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI;IAK1E;;;;;;;;;;gFAU4E;IAC5E,uBAAuB,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO;IAQzE;uFACmF;IACnF,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAIhC;;;;oFAIgF;IAChF,gBAAgB,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,EAAE;IAWtE;;;;;;iCAM6B;IAC7B,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,GAAG,SAAS;IASnE;;;;4EAIwE;IACxE,OAAO,CAAC,iBAAiB;IAkBzB;;;;;;;;;;;;;;4BAcwB;IACxB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAShD,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS;IAIrD;;;uCAGmC;IACnC,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS;IAWxD,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;IAkChC,OAAO,CAAC,uBAAuB;IA+B/B;;qEAEiE;IACjE,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,kBAAkB,EAAE;IAgBxD,KAAK,IAAI,MAAM,EAAE;CAGlB"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { canonicalTypeSchemaId } from "@telorun/sdk";
|
|
1
2
|
import { KERNEL_BUILTINS } from "./builtins.js";
|
|
2
3
|
import { buildFieldMapAtPath, buildReferenceFieldMap, isSchemaFromEntry, } from "./reference-field-map.js";
|
|
3
4
|
import { createAjv, formatSingleError, navigateJsonPointer } from "./schema-compat.js";
|
|
@@ -13,17 +14,20 @@ export class DefinitionRegistry {
|
|
|
13
14
|
* across analyze() calls and no unbounded growth across the process lifetime. */
|
|
14
15
|
ajv = createAjv();
|
|
15
16
|
registeredSchemaIds = new Set();
|
|
17
|
+
/** The subset of `registeredSchemaIds` claimed by a kind's schema. Kinds and
|
|
18
|
+
* named `Telo.Type`s share one `telo://<module>/<Name>` id space, so this is
|
|
19
|
+
* what lets a colliding type name be reported instead of silently dropped. */
|
|
20
|
+
definitionSchemaIds = new Set();
|
|
16
21
|
defs = new Map();
|
|
17
22
|
fieldMaps = new Map();
|
|
18
23
|
/** Reverse inheritance index: parent kind → direct child kinds. */
|
|
19
24
|
extendedBy = new Map();
|
|
20
|
-
/**
|
|
21
|
-
* "
|
|
25
|
+
/** DEPRECATED module identity table: identity string → canonical module name
|
|
26
|
+
* ("std/pipeline" → "pipeline"). Serves only the legacy
|
|
27
|
+
* `<namespace>/<module>#<Kind>` form of `x-telo-ref`, kept resolvable for
|
|
28
|
+
* module versions published before constraints named their target by import
|
|
29
|
+
* alias. Fed by `metadata.namespace`, which nothing else reads. */
|
|
22
30
|
identityMap = new Map();
|
|
23
|
-
/** Reverse identity table: canonical module name → full identity string.
|
|
24
|
-
* "Telo" → "telo", "pipeline" → "std/pipeline", etc.
|
|
25
|
-
* Used to compute definition $id values for the AJV schema store. */
|
|
26
|
-
reverseIdentityMap = new Map();
|
|
27
31
|
register(definition) {
|
|
28
32
|
const { name, module: mod } = definition.metadata;
|
|
29
33
|
const key = mod ? `${mod}.${name}` : name;
|
|
@@ -50,12 +54,11 @@ export class DefinitionRegistry {
|
|
|
50
54
|
if (definition.extends) {
|
|
51
55
|
this.addExtendedBy(definition.extends, key);
|
|
52
56
|
}
|
|
53
|
-
// Auto-register the telo identity when any Telo built-in is registered
|
|
57
|
+
// Auto-register the legacy telo identity when any Telo built-in is registered,
|
|
58
|
+
// so an already-published `x-telo-ref: "telo#Invocable"` still resolves.
|
|
54
59
|
if (definition.kind === "Telo.Abstract" && mod === "Telo") {
|
|
55
60
|
this.identityMap.set("telo", "Telo");
|
|
56
|
-
this.reverseIdentityMap.set("Telo", "telo");
|
|
57
61
|
}
|
|
58
|
-
// If identity is already known, register the schema in AJV immediately.
|
|
59
62
|
if (mod && definition.schema) {
|
|
60
63
|
this.tryRegisterSchema(mod, name, definition.schema);
|
|
61
64
|
}
|
|
@@ -70,61 +73,50 @@ export class DefinitionRegistry {
|
|
|
70
73
|
this.extendedBy.set(parent, [child]);
|
|
71
74
|
}
|
|
72
75
|
}
|
|
73
|
-
/** Register a module identity
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
76
|
+
/** DEPRECATED. Register a module identity so the legacy
|
|
77
|
+
* `<namespace>/<module>#<Kind>` form of `x-telo-ref` still resolves for module
|
|
78
|
+
* versions published before constraints named their target by import alias.
|
|
79
|
+
* New manifests declare no namespace and need no identity — their constraints
|
|
80
|
+
* are canonicalized to `<module>.<Kind>` before registration.
|
|
81
|
+
*
|
|
82
|
+
* The "telo" identity is reserved for the built-in module and is populated
|
|
83
|
+
* automatically when a `Telo.Abstract` registers. A namespace-less module must
|
|
84
|
+
* not claim it: overwriting the entry would repoint every legacy `telo#…`
|
|
85
|
+
* constraint at a module that declares no such kind, and the resulting
|
|
86
|
+
* unresolvable ref reads as partial context rather than an error.
|
|
87
|
+
*
|
|
88
|
+
* @param namespace The module's `metadata.namespace`, or null when it declares none.
|
|
89
|
+
* @param moduleName The module's `metadata.name` (e.g. "pipeline", "http-server"). */
|
|
77
90
|
registerModuleIdentity(namespace, moduleName) {
|
|
78
|
-
|
|
79
|
-
// populated automatically when a Telo.Abstract definition registers (see
|
|
80
|
-
// `register` below). A user app / library without a namespace must NOT
|
|
81
|
-
// claim it — silently overwriting the built-in entry breaks every
|
|
82
|
-
// x-telo-ref that resolves through "telo#…". Concretely, the
|
|
83
|
-
// `Http.Api.routes[].handler` slot in the http-server schema carries
|
|
84
|
-
// `x-telo-ref: "telo#Invocable"`. If the entry application is, say,
|
|
85
|
-
// `Telo.Application/HelloApi` (no namespace), this method previously
|
|
86
|
-
// overwrote `"telo" → "Telo"` with `"telo" → "HelloApi"`. The handler's
|
|
87
|
-
// ref then resolved to a nonexistent `HelloApi.Invocable`, the
|
|
88
|
-
// kind-mismatch check inside `validate-references.ts` short-circuited
|
|
89
|
-
// on partial context, and the analyzer reported zero issues for a
|
|
90
|
-
// manifest that explodes at runtime. Skip non-Telo no-namespace modules;
|
|
91
|
-
// they have no x-telo-ref identity to declare anyway.
|
|
92
|
-
if (!namespace && moduleName !== "Telo")
|
|
91
|
+
if (!namespace || moduleName === "Telo")
|
|
93
92
|
return;
|
|
94
|
-
|
|
95
|
-
this.identityMap.set(identity, moduleName);
|
|
96
|
-
this.reverseIdentityMap.set(moduleName, identity);
|
|
97
|
-
// Retroactively register AJV schemas for definitions of this module already in the registry.
|
|
98
|
-
for (const def of this.defs.values()) {
|
|
99
|
-
if (def.metadata.module === moduleName && def.schema) {
|
|
100
|
-
this.tryRegisterSchema(moduleName, def.metadata.name, def.schema);
|
|
101
|
-
}
|
|
102
|
-
}
|
|
93
|
+
this.identityMap.set(`${namespace}/${moduleName}`, moduleName);
|
|
103
94
|
}
|
|
104
95
|
/** Registers a named `Telo.Type` resource's schema under its canonical
|
|
105
96
|
* module-scoped URI `$id` (`telo://<module>/<name>`), so a sibling schema's
|
|
106
97
|
* `$ref: "telo://Self/<name>"` (rewritten to the canonical form by
|
|
107
98
|
* `resolveSchemaTypeRefs`) resolves during AJV compilation. Mirrors the
|
|
108
|
-
* kernel type controller's `registerSchema(canonicalTypeSchemaId(...))`.
|
|
99
|
+
* kernel type controller's `registerSchema(canonicalTypeSchemaId(...))`.
|
|
100
|
+
*
|
|
101
|
+
* Returns `false` when a kind schema in the same module already owns the id —
|
|
102
|
+
* a name collision between a kind and a named type. Definitions register
|
|
103
|
+
* first, so the type is the one that would be dropped, and every
|
|
104
|
+
* `$ref: "telo://<module>/<Name>"` would then silently validate against the
|
|
105
|
+
* kind's schema instead. The caller reports it; nothing is overwritten. */
|
|
109
106
|
registerNamedTypeSchema(id, schema) {
|
|
107
|
+
if (this.definitionSchemaIds.has(id))
|
|
108
|
+
return false;
|
|
110
109
|
if (this.registeredSchemaIds.has(id) || this.ajv.getSchema(id))
|
|
111
|
-
return;
|
|
110
|
+
return true;
|
|
112
111
|
this.ajv.addSchema(schema, id);
|
|
113
112
|
this.registeredSchemaIds.add(id);
|
|
113
|
+
return true;
|
|
114
114
|
}
|
|
115
115
|
/** True when a schema is registered under `id` (a canonical `telo://` type id
|
|
116
116
|
* or a definition `$id`). Used to flag schema `$ref`s that resolve to nothing. */
|
|
117
117
|
hasSchemaId(id) {
|
|
118
118
|
return this.registeredSchemaIds.has(id) || this.ajv.getSchema(id) !== undefined;
|
|
119
119
|
}
|
|
120
|
-
/** Computes the $id for a definition schema: "<identity>/<TypeName>".
|
|
121
|
-
* Returns undefined when the module identity is not yet registered. */
|
|
122
|
-
computeId(moduleName, typeName) {
|
|
123
|
-
const identity = this.reverseIdentityMap.get(moduleName);
|
|
124
|
-
if (!identity)
|
|
125
|
-
return undefined;
|
|
126
|
-
return `${identity}/${typeName}`;
|
|
127
|
-
}
|
|
128
120
|
/** Validates data against a schema using this registry's AJV instance, which has all
|
|
129
121
|
* registered definition schemas loaded — enabling cross-module $ref resolution.
|
|
130
122
|
* A compile failure returns `[]` here; it is surfaced loudly (once, on the
|
|
@@ -158,35 +150,49 @@ export class DefinitionRegistry {
|
|
|
158
150
|
return err instanceof Error ? err.message : String(err);
|
|
159
151
|
}
|
|
160
152
|
}
|
|
153
|
+
/** Registers a definition schema under the same module-scoped `telo://` id a
|
|
154
|
+
* named `Telo.Type` uses, so a kind schema and a type schema are addressable
|
|
155
|
+
* the same way and a `$ref` between them resolves at AJV compile time. One id
|
|
156
|
+
* space per module: a kind and a named type may not share a name, which
|
|
157
|
+
* `registerNamedTypeSchema` reports rather than resolving silently. */
|
|
161
158
|
tryRegisterSchema(moduleName, typeName, schema) {
|
|
162
|
-
const id =
|
|
163
|
-
if (
|
|
159
|
+
const id = canonicalTypeSchemaId(moduleName, typeName);
|
|
160
|
+
if (this.registeredSchemaIds.has(id)) {
|
|
161
|
+
this.definitionSchemaIds.add(id);
|
|
164
162
|
return;
|
|
163
|
+
}
|
|
165
164
|
if (this.ajv.getSchema(id)) {
|
|
166
165
|
throw new Error(`Duplicate definition schema $id: "${id}" is already registered`);
|
|
167
166
|
}
|
|
168
167
|
this.ajv.addSchema(schema, id);
|
|
169
168
|
this.registeredSchemaIds.add(id);
|
|
169
|
+
this.definitionSchemaIds.add(id);
|
|
170
170
|
}
|
|
171
|
-
/** Resolves an x-telo-ref
|
|
172
|
-
*
|
|
173
|
-
*
|
|
171
|
+
/** Resolves an `x-telo-ref` constraint to a canonical registry kind key.
|
|
172
|
+
*
|
|
173
|
+
* The constraint is already canonical `<module>.<Kind>`: alias-form values
|
|
174
|
+
* (`KvStore.Store`, `Self.Store`, `Telo.Invocable`) are rewritten in the
|
|
175
|
+
* declaring module's scope by `resolveSchemaRefKinds` before registration, so
|
|
176
|
+
* no module context is needed here.
|
|
177
|
+
*
|
|
178
|
+
* The legacy `<namespace>/<module>#<Kind>` form still resolves through the
|
|
179
|
+
* identity table for module versions published before the alias form existed:
|
|
174
180
|
*
|
|
175
|
-
*
|
|
176
|
-
*
|
|
177
|
-
* "std/http-server#Server" → "http-server.Server"
|
|
181
|
+
* "telo#Invocable" → "Telo.Invocable"
|
|
182
|
+
* "std/http-server#Server" → "http-server.Server"
|
|
178
183
|
*
|
|
179
|
-
* Returns undefined when
|
|
184
|
+
* Returns undefined when a legacy string is malformed or its identity was
|
|
185
|
+
* never registered. */
|
|
180
186
|
resolveRef(xTeloRef) {
|
|
181
187
|
const hash = xTeloRef.indexOf("#");
|
|
182
|
-
if (hash === -1
|
|
188
|
+
if (hash === -1)
|
|
189
|
+
return xTeloRef;
|
|
190
|
+
if (hash === xTeloRef.length - 1)
|
|
183
191
|
return undefined;
|
|
184
|
-
const
|
|
185
|
-
const typeName = xTeloRef.slice(hash + 1);
|
|
186
|
-
const moduleName = this.identityMap.get(identity);
|
|
192
|
+
const moduleName = this.identityMap.get(xTeloRef.slice(0, hash));
|
|
187
193
|
if (!moduleName)
|
|
188
194
|
return undefined;
|
|
189
|
-
return `${moduleName}.${
|
|
195
|
+
return `${moduleName}.${xTeloRef.slice(hash + 1)}`;
|
|
190
196
|
}
|
|
191
197
|
resolve(kind) {
|
|
192
198
|
return this.defs.get(kind);
|
package/dist/loaded-types.d.ts
CHANGED
|
@@ -46,18 +46,25 @@ export interface LoadedModule {
|
|
|
46
46
|
partials: LoadedFile[];
|
|
47
47
|
}
|
|
48
48
|
/** Resolved Telo.Import edge: where the import points and what library
|
|
49
|
-
* identity it resolves to. Carrying name
|
|
50
|
-
* `flattenForAnalyzer` can stamp `metadata.resolvedModuleName`
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
49
|
+
* identity it resolves to. Carrying the name on the edge means
|
|
50
|
+
* `flattenForAnalyzer` can stamp `metadata.resolvedModuleName` from this
|
|
51
|
+
* single source rather than re-deriving the target from manifest metadata,
|
|
52
|
+
* which would silently miss whenever a future projection forgets to stamp
|
|
53
|
+
* `metadata.source` consistently. */
|
|
54
54
|
export interface ImportEdge {
|
|
55
55
|
/** Canonical resolved URL of the target — a key into `modules`. */
|
|
56
56
|
targetSource: string;
|
|
57
|
+
/** The import's `source` exactly as authored — a registry ref, an `oci://`
|
|
58
|
+
* or `https://` ref, or a relative path. Version reconciliation keys on
|
|
59
|
+
* this (minus its version), since it names the module's location
|
|
60
|
+
* independently of what the module declares about itself. */
|
|
61
|
+
targetRef: string;
|
|
57
62
|
/** Target library's `metadata.name`, or `null` when the target had no
|
|
58
63
|
* Telo.Library doc (an error case captured in `LoadedGraph.errors`). */
|
|
59
64
|
targetModuleName: string | null;
|
|
60
|
-
/** Target library's `metadata.namespace
|
|
65
|
+
/** DEPRECATED. Target library's `metadata.namespace`, or `null` when it
|
|
66
|
+
* declares none. Feeds only the legacy `<namespace>/<module>#<Kind>` form
|
|
67
|
+
* of `x-telo-ref`; nothing else reads it. */
|
|
61
68
|
targetNamespace: string | null;
|
|
62
69
|
}
|
|
63
70
|
/** An entry plus every transitively-imported library. Returned by
|
|
@@ -1 +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,kBAAkB,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD;;;;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;;+EAE2E;IAC3E,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB;+EAC2E;IAC3E,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,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;;;;;
|
|
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,kBAAkB,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD;;;;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;;+EAE2E;IAC3E,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB;+EAC2E;IAC3E,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,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;;;;;sCAKsC;AACtC,MAAM,WAAW,UAAU;IACzB,mEAAmE;IACnE,YAAY,EAAE,MAAM,CAAC;IACrB;;;kEAG8D;IAC9D,SAAS,EAAE,MAAM,CAAC;IAClB;6EACyE;IACzE,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC;;kDAE8C;IAC9C,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;;;;2BAIuB;IACvB,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;IAClD;;;iFAG6E;IAC7E,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B;;;iDAG6C;IAC7C,kBAAkB,EAAE,kBAAkB,EAAE,CAAC;IACzC;;;8EAG0E;IAC1E,gBAAgB,EAAE,kBAAkB,EAAE,CAAC;IACvC;yCACqC;IACrC,MAAM,EAAE,cAAc,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,cAAc;IAC7B;8BAC0B;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ;;qEAEiE;IACjE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2EAA2E;IAC3E,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B;;gFAE4E;IAC5E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4EAA4E;IAC5E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,KAAK,CAAC;CACd"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest-loader.d.ts","sourceRoot":"","sources":["../src/manifest-loader.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAGV,UAAU,EACV,WAAW,EACX,YAAY,EACb,MAAM,mBAAmB,CAAC;AAK3B,OAAO,EAIL,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACpB,MAAM,YAAY,CAAC;AAwCpB,qBAAa,MAAM;IACjB;;;yEAGqE;IACrE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAiC;IAE3D;;;;;8BAK0B;IAC1B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA6B;IAEzD,SAAS,CAAC,OAAO,EAAE,cAAc,EAAE,CAAC;IACpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAc;IAErC;;;;mBAIe;gBACH,OAAO,GAAE,cAAc,EAAO,EAAE,OAAO,GAAE,iBAAsB;IAK3E,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI;IAKtC,OAAO,CAAC,IAAI;IAMN,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAUrD;;;;2CAIuC;IACvC,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAM7C;;;+BAG2B;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;IAyCvE;;;;gEAI4D;IAC5D,OAAO,CAAC,oBAAoB;IAa5B;gFAC4E;IAC5E,OAAO,CAAC,cAAc;IAQtB;;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;
|
|
1
|
+
{"version":3,"file":"manifest-loader.d.ts","sourceRoot":"","sources":["../src/manifest-loader.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAGV,UAAU,EACV,WAAW,EACX,YAAY,EACb,MAAM,mBAAmB,CAAC;AAK3B,OAAO,EAIL,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACpB,MAAM,YAAY,CAAC;AAwCpB,qBAAa,MAAM;IACjB;;;yEAGqE;IACrE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAiC;IAE3D;;;;;8BAK0B;IAC1B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA6B;IAEzD,SAAS,CAAC,OAAO,EAAE,cAAc,EAAE,CAAC;IACpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAc;IAErC;;;;mBAIe;gBACH,OAAO,GAAE,cAAc,EAAO,EAAE,OAAO,GAAE,iBAAsB;IAK3E,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI;IAKtC,OAAO,CAAC,IAAI;IAMN,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAUrD;;;;2CAIuC;IACvC,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAM7C;;;+BAG2B;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;IAyCvE;;;;gEAI4D;IAC5D,OAAO,CAAC,oBAAoB;IAa5B;gFAC4E;IAC5E,OAAO,CAAC,cAAc;IAQtB;;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;IAiI9E;;;;;;;;sBAQkB;IAClB,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM;IAOlE,OAAO,CAAC,6BAA6B;IAarC,OAAO,CAAC,mCAAmC;IAc3C,OAAO,CAAC,2BAA2B;YAkCrB,eAAe;IAmB7B;;;0CAGsC;IAChC,gBAAgB,CACpB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CAAC;QAAE,KAAK,EAAE,WAAW,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CA0B5D"}
|