@telorun/analyzer 0.1.1 → 0.1.2

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.
@@ -11,7 +11,7 @@ export class HttpAdapter {
11
11
  return { text: await response.text(), source: fetchUrl };
12
12
  }
13
13
  resolveRelative(base, relative) {
14
- const baseWithSlash = base.endsWith("/") ? base : `${base}/`;
15
- return new URL(relative, baseWithSlash).href;
14
+ const baseDir = base.endsWith("/") ? base : base.slice(0, base.lastIndexOf("/") + 1);
15
+ return new URL(relative, baseDir).href;
16
16
  }
17
17
  }
@@ -1,11 +1,15 @@
1
1
  import type { ManifestAdapter } from "../types.js";
2
2
  export declare class RegistryAdapter implements ManifestAdapter {
3
+ private registryUrl;
4
+ constructor(registryUrl?: string);
3
5
  supports(url: string): boolean;
4
6
  read(moduleRef: string): Promise<{
5
7
  text: string;
6
8
  source: string;
7
9
  }>;
8
10
  resolveRelative(base: string, relative: string): string;
11
+ private toRegistryModuleBase;
9
12
  private toRegistryUrl;
13
+ private parseModuleRef;
10
14
  }
11
15
  //# sourceMappingURL=registry-adapter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"registry-adapter.d.ts","sourceRoot":"","sources":["../../src/adapters/registry-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAInD,qBAAa,eAAgB,YAAW,eAAe;IACrD,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAWxB,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAWxE,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM;IAQvD,OAAO,CAAC,aAAa;CAOtB"}
1
+ {"version":3,"file":"registry-adapter.d.ts","sourceRoot":"","sources":["../../src/adapters/registry-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAInD,qBAAa,eAAgB,YAAW,eAAe;IACzC,OAAO,CAAC,WAAW;gBAAX,WAAW,SAAuB;IAEtD,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAWxB,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAWxE,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM;IAMvD,OAAO,CAAC,oBAAoB;IAM5B,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,cAAc;CAmBvB"}
@@ -1,5 +1,9 @@
1
- const REGISTRY_BASE = "https://registry.telo.run";
1
+ const DEFAULT_REGISTRY_URL = "https://registry.telo.run";
2
2
  export class RegistryAdapter {
3
+ registryUrl;
4
+ constructor(registryUrl = DEFAULT_REGISTRY_URL) {
5
+ this.registryUrl = registryUrl;
6
+ }
3
7
  supports(url) {
4
8
  return (!url.startsWith("http://") &&
5
9
  !url.startsWith("https://") &&
@@ -17,17 +21,32 @@ export class RegistryAdapter {
17
21
  return { text: await response.text(), source: fetchUrl };
18
22
  }
19
23
  resolveRelative(base, relative) {
20
- const baseUrl = this.supports(base)
21
- ? this.toRegistryUrl(base).replace("/module.yaml", "")
22
- : base;
24
+ const baseUrl = this.supports(base) ? this.toRegistryModuleBase(base) : base;
23
25
  const baseWithSlash = baseUrl.endsWith("/") ? baseUrl : `${baseUrl}/`;
24
26
  return new URL(relative, baseWithSlash).href;
25
27
  }
28
+ toRegistryModuleBase(moduleRef) {
29
+ const parsed = this.parseModuleRef(moduleRef);
30
+ const normalizedBase = this.registryUrl.replace(/\/+$/, "");
31
+ return `${normalizedBase}/${parsed.modulePath}/${parsed.version}`;
32
+ }
26
33
  toRegistryUrl(moduleRef) {
34
+ return `${this.toRegistryModuleBase(moduleRef)}/module.yaml`;
35
+ }
36
+ parseModuleRef(moduleRef) {
27
37
  const atIdx = moduleRef.lastIndexOf("@");
38
+ if (atIdx <= 0 || atIdx === moduleRef.length - 1) {
39
+ throw new Error(`Invalid module reference '${moduleRef}', expected namespace/name@version`);
40
+ }
28
41
  const modulePath = moduleRef.slice(0, atIdx);
29
- const version = moduleRef.slice(atIdx + 1);
30
- const versionSegment = version.startsWith("v") ? version.substring(1) : version;
31
- return `${REGISTRY_BASE}/${modulePath}/${versionSegment}/module.yaml`;
42
+ if (!modulePath.includes("/")) {
43
+ throw new Error(`Invalid module reference '${moduleRef}', expected namespace/name@version`);
44
+ }
45
+ const rawVersion = moduleRef.slice(atIdx + 1);
46
+ const version = rawVersion.startsWith("v") ? rawVersion.substring(1) : rawVersion;
47
+ if (!version) {
48
+ throw new Error(`Invalid module reference '${moduleRef}', expected namespace/name@version`);
49
+ }
50
+ return { modulePath, version };
32
51
  }
33
52
  }
@@ -23,6 +23,8 @@ export declare class AnalysisRegistry {
23
23
  * controller registry) can iterate them without importing KERNEL_BUILTINS directly.
24
24
  */
25
25
  builtinDefinitions(): ResourceDefinition[];
26
+ resolveDefinition(kind: string): ResourceDefinition | undefined;
27
+ allKinds(): string[];
26
28
  /** @internal Bridge for StaticAnalyzer — do not use outside the analyzer package. */
27
29
  _context(): AnalysisContext;
28
30
  }
@@ -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,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD;;;;GAIG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA4B;IACjD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAuB;IAE/C,kBAAkB,CAAC,GAAG,EAAE,kBAAkB,GAAG,IAAI;IAIjD,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAIpE,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI;IAIpE,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAI7C;;;OAGG;IACH,mBAAmB,CACjB,QAAQ,EAAE,gBAAgB,EAC1B,KAAK,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,EAClC,OAAO,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,GACnC,IAAI;IAcP;;;;OAIG;IACH,kBAAkB,IAAI,kBAAkB,EAAE;IAI1C,qFAAqF;IACrF,QAAQ,IAAI,eAAe;CAG5B"}
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,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD;;;;GAIG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA4B;IACjD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAuB;IAE/C,kBAAkB,CAAC,GAAG,EAAE,kBAAkB,GAAG,IAAI;IAIjD,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAIpE,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI;IAIpE,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAI7C;;;OAGG;IACH,mBAAmB,CACjB,QAAQ,EAAE,gBAAgB,EAC1B,KAAK,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,EAClC,OAAO,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,GACnC,IAAI;IAcP;;;;OAIG;IACH,kBAAkB,IAAI,kBAAkB,EAAE;IAI1C,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS;IAM/D,QAAQ,IAAI,MAAM,EAAE;IAIpB,qFAAqF;IACrF,QAAQ,IAAI,eAAe;CAG5B"}
@@ -48,6 +48,14 @@ export class AnalysisRegistry {
48
48
  builtinDefinitions() {
49
49
  return KERNEL_BUILTINS;
50
50
  }
51
+ resolveDefinition(kind) {
52
+ const ctx = this._context();
53
+ const resolved = ctx.aliases?.resolveKind(kind);
54
+ return ctx.definitions?.resolve(kind) ?? (resolved ? ctx.definitions?.resolve(resolved) : undefined);
55
+ }
56
+ allKinds() {
57
+ return this._context().definitions?.kinds() ?? [];
58
+ }
51
59
  /** @internal Bridge for StaticAnalyzer — do not use outside the analyzer package. */
52
60
  _context() {
53
61
  return { aliases: this.aliases, definitions: this.defs };
@@ -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;AAEzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAW1D,OAAO,EAAsB,KAAK,kBAAkB,EAAE,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;AA+I/F,qBAAa,cAAc;IACzB,OAAO,CACL,SAAS,EAAE,gBAAgB,EAAE,EAC7B,OAAO,CAAC,EAAE,eAAe,EACzB,QAAQ,CAAC,EAAE,gBAAgB,GAC1B,kBAAkB,EAAE;IA0MvB,aAAa,CACX,SAAS,EAAE,gBAAgB,EAAE,EAC7B,OAAO,CAAC,EAAE,eAAe,EACzB,QAAQ,CAAC,EAAE,gBAAgB,GAC1B,kBAAkB,EAAE;IAMvB,SAAS,CAAC,SAAS,EAAE,gBAAgB,EAAE,EAAE,QAAQ,EAAE,gBAAgB,GAAG,gBAAgB,EAAE;IAKxF,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;CAiB5F"}
1
+ {"version":3,"file":"analyzer.d.ts","sourceRoot":"","sources":["../src/analyzer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAsB,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAW1D,OAAO,EAAsB,KAAK,kBAAkB,EAAE,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;AA0O/F,qBAAa,cAAc;IACzB,OAAO,CACL,SAAS,EAAE,gBAAgB,EAAE,EAC7B,OAAO,CAAC,EAAE,eAAe,EACzB,QAAQ,CAAC,EAAE,gBAAgB,GAC1B,kBAAkB,EAAE;IA+OvB,aAAa,CACX,SAAS,EAAE,gBAAgB,EAAE,EAC7B,OAAO,CAAC,EAAE,eAAe,EACzB,QAAQ,CAAC,EAAE,gBAAgB,GAC1B,kBAAkB,EAAE;IAMvB,SAAS,CAAC,SAAS,EAAE,gBAAgB,EAAE,EAAE,QAAQ,EAAE,gBAAgB,GAAG,gBAAgB,EAAE;IAKxF,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;CAiB5F"}
package/dist/analyzer.js CHANGED
@@ -5,7 +5,7 @@ import { buildDependencyGraph, formatCycle } from "./dependency-graph.js";
5
5
  import { normalizeInlineResources } from "./normalize-inline-resources.js";
6
6
  import { celTypeSatisfiesJsonSchema, substituteCelFields, validateAgainstSchema, } from "./schema-compat.js";
7
7
  import { DiagnosticSeverity } from "./types.js";
8
- import { extractAccessChains, pathMatchesScope, validateChainAgainstSchema, } from "./validate-cel-context.js";
8
+ import { extractAccessChains, getManifestItem, pathMatchesScope, resolveContextAnnotations, resolveTypeFieldToSchema, validateChainAgainstSchema, } from "./validate-cel-context.js";
9
9
  import { validateReferences } from "./validate-references.js";
10
10
  const TEMPLATE_REGEX = /\$\{\{\s*([^}]+?)\s*\}\}/g;
11
11
  function walkCelExpressions(value, path, cb) {
@@ -53,6 +53,81 @@ function extractContextsFromSchema(schema, path = "$") {
53
53
  }
54
54
  return results;
55
55
  }
56
+ /**
57
+ * Build a `steps` context schema from `x-telo-step-context` annotation.
58
+ * Walks each step in the manifest array, resolves the invoked resource's outputType,
59
+ * and builds `steps.<name>.result` context entries.
60
+ */
61
+ function buildStepContextSchema(manifest, defSchema, allManifests) {
62
+ const props = defSchema.properties;
63
+ if (!props)
64
+ return undefined;
65
+ for (const [fieldName, fieldSchema] of Object.entries(props)) {
66
+ const stepCtx = fieldSchema["x-telo-step-context"];
67
+ if (!stepCtx)
68
+ continue;
69
+ const invokeField = stepCtx.invoke;
70
+ const outputTypeField = stepCtx.outputType;
71
+ if (!invokeField || !outputTypeField)
72
+ continue;
73
+ const steps = manifest[fieldName];
74
+ if (!Array.isArray(steps))
75
+ continue;
76
+ const stepProperties = {};
77
+ const collectSteps = (items) => {
78
+ for (const step of items) {
79
+ if (!step || typeof step !== "object")
80
+ continue;
81
+ const s = step;
82
+ const name = s.name;
83
+ if (typeof name === "string") {
84
+ const invoke = s[invokeField];
85
+ let outputSchema;
86
+ if (invoke && typeof invoke === "object") {
87
+ const invokedKind = invoke.kind;
88
+ const invokedName = invoke.name;
89
+ if (invokedName) {
90
+ const invokedManifest = allManifests.find((m) => m.metadata?.name === invokedName &&
91
+ (!invokedKind || m.kind === invokedKind));
92
+ if (invokedManifest) {
93
+ outputSchema = resolveTypeFieldToSchema(invokedManifest[outputTypeField], allManifests);
94
+ }
95
+ }
96
+ else {
97
+ outputSchema = resolveTypeFieldToSchema(invoke[outputTypeField], allManifests);
98
+ }
99
+ }
100
+ stepProperties[name] = {
101
+ type: "object",
102
+ properties: {
103
+ result: outputSchema ?? { type: "object", additionalProperties: true },
104
+ },
105
+ };
106
+ }
107
+ // Recurse into nested step arrays (then, else, do, catch, finally, try, default, cases)
108
+ for (const nested of ["then", "else", "do", "catch", "finally", "try", "default"]) {
109
+ if (Array.isArray(s[nested]))
110
+ collectSteps(s[nested]);
111
+ }
112
+ // cases is an object map of arrays
113
+ if (s.cases && typeof s.cases === "object") {
114
+ for (const arr of Object.values(s.cases)) {
115
+ if (Array.isArray(arr))
116
+ collectSteps(arr);
117
+ }
118
+ }
119
+ }
120
+ };
121
+ collectSteps(steps);
122
+ if (Object.keys(stepProperties).length > 0) {
123
+ return {
124
+ type: "object",
125
+ properties: stepProperties,
126
+ };
127
+ }
128
+ }
129
+ return undefined;
130
+ }
56
131
  const CEL_PURE_RE = /^\s*\$\{\{[^}]*\}\}\s*$/;
57
132
  const CEL_EXPR_RE = /\$\{\{\s*([^}]+?)\s*\}\}/;
58
133
  /** Recursively walk `data`+`schema` together, type-checking every pure CEL template
@@ -239,6 +314,10 @@ export class StaticAnalyzer {
239
314
  const resource = { kind: m.kind, name: m.metadata?.name };
240
315
  const resolvedKind = aliases.resolveKind(m.kind);
241
316
  const mDefinition = defs.resolve(m.kind) ?? (resolvedKind ? defs.resolve(resolvedKind) : undefined);
317
+ // Pre-compute step context for manifests with x-telo-step-context
318
+ const stepContextSchema = mDefinition?.schema
319
+ ? buildStepContextSchema(m, mDefinition.schema, allManifests)
320
+ : undefined;
242
321
  walkCelExpressions(m, "", (expr, path) => {
243
322
  let parsed;
244
323
  try {
@@ -254,23 +333,42 @@ export class StaticAnalyzer {
254
333
  });
255
334
  return;
256
335
  }
336
+ const accessChains = extractAccessChains(parsed.ast);
257
337
  const contexts = mDefinition?.schema ? extractContextsFromSchema(mDefinition.schema) : [];
258
338
  const invocationContext = m.metadata?.xTeloInvocationContext;
259
- if (contexts.length === 0 && !invocationContext)
339
+ // If no static context but we have step context, inject it
340
+ if (contexts.length === 0 && !invocationContext && !stepContextSchema)
260
341
  return;
261
342
  let matchedContext;
343
+ let matchedScope;
262
344
  for (const ctx of contexts) {
263
345
  if (pathMatchesScope(path, ctx.scope)) {
264
346
  matchedContext = ctx.schema;
347
+ matchedScope = ctx.scope;
265
348
  break;
266
349
  }
267
350
  }
268
351
  if (!matchedContext)
269
352
  matchedContext = invocationContext;
353
+ // Merge step context into the effective context
354
+ if (stepContextSchema) {
355
+ const base = matchedContext ?? { type: "object", properties: {}, additionalProperties: true };
356
+ matchedContext = {
357
+ ...base,
358
+ properties: {
359
+ ...(base.properties ?? {}),
360
+ steps: stepContextSchema,
361
+ },
362
+ };
363
+ }
270
364
  if (!matchedContext)
271
365
  return;
272
- for (const chain of extractAccessChains(parsed.ast)) {
273
- const err = validateChainAgainstSchema(chain, matchedContext);
366
+ const manifestItem = matchedScope
367
+ ? getManifestItem(path, matchedScope, m)
368
+ : m;
369
+ const effectiveContext = resolveContextAnnotations(matchedContext, manifestItem, allManifests);
370
+ for (const chain of accessChains) {
371
+ const err = validateChainAgainstSchema(chain, effectiveContext);
274
372
  if (!err)
275
373
  continue;
276
374
  diagnostics.push({
package/dist/index.d.ts CHANGED
@@ -5,5 +5,5 @@ export { AnalysisRegistry } from "./analysis-registry.js";
5
5
  export { StaticAnalyzer } from "./analyzer.js";
6
6
  export { Loader } from "./manifest-loader.js";
7
7
  export { DiagnosticSeverity } from "./types.js";
8
- export type { AnalysisDiagnostic, AnalysisOptions, LoadOptions, ManifestAdapter, Position, PositionIndex, Range } from "./types.js";
8
+ export type { AnalysisDiagnostic, AnalysisOptions, LoaderInitOptions, LoadOptions, ManifestAdapter, Position, PositionIndex, Range } from "./types.js";
9
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC5E,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,YAAY,EACR,kBAAkB,EAClB,eAAe,EACf,WAAW,EACX,eAAe,EACf,QAAQ,EACR,aAAa,EACb,KAAK,EACR,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC5E,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,YAAY,EACR,kBAAkB,EAClB,eAAe,EAAE,iBAAiB,EAAE,WAAW,EAAE,eAAe,EAChE,QAAQ,EACR,aAAa,EACb,KAAK,EACR,MAAM,YAAY,CAAC"}
@@ -1,11 +1,13 @@
1
1
  import type { ResourceManifest } from "@telorun/sdk";
2
- import type { LoadOptions, ManifestAdapter } from "./types.js";
2
+ import type { LoadOptions, LoaderInitOptions, ManifestAdapter } from "./types.js";
3
3
  export declare class Loader {
4
4
  protected adapters: ManifestAdapter[];
5
- constructor(extraAdapters?: ManifestAdapter[]);
5
+ constructor(extraAdaptersOrOptions?: ManifestAdapter[] | LoaderInitOptions);
6
6
  register(adapter: ManifestAdapter): this;
7
7
  private pick;
8
+ resolveEntryPoint(url: string): Promise<string>;
8
9
  loadModule(url: string, options?: LoadOptions): Promise<ResourceManifest[]>;
10
+ loadModuleGraph(entryUrl: string, onError?: (url: string, error: Error) => void): Promise<Map<string, ResourceManifest[]>>;
9
11
  loadManifests(entryUrl: string): Promise<ResourceManifest[]>;
10
12
  }
11
13
  //# sourceMappingURL=manifest-loader.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"manifest-loader.d.ts","sourceRoot":"","sources":["../src/manifest-loader.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAKrD,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAA2B,MAAM,YAAY,CAAC;AAExF,qBAAa,MAAM;IACjB,SAAS,CAAC,QAAQ,EAAE,eAAe,EAAE,CAA8C;gBAEvE,aAAa,GAAE,eAAe,EAAO;IAIjD,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI;IAKxC,OAAO,CAAC,IAAI;IAMN,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAgE3E,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;CAwCnE"}
1
+ {"version":3,"file":"manifest-loader.d.ts","sourceRoot":"","sources":["../src/manifest-loader.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAKrD,OAAO,KAAK,EACV,WAAW,EACX,iBAAiB,EACjB,eAAe,EAGhB,MAAM,YAAY,CAAC;AAEpB,qBAAa,MAAM;IACjB,SAAS,CAAC,QAAQ,EAAE,eAAe,EAAE,CAAC;gBAE1B,sBAAsB,GAAE,eAAe,EAAE,GAAG,iBAAsB;IAiB9E,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI;IAKxC,OAAO,CAAC,IAAI;IAMN,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAK/C,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAyE3E,eAAe,CACnB,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,GAC5C,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,gBAAgB,EAAE,CAAC,CAAC;IAsCrC,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;CAoDnE"}
@@ -3,9 +3,21 @@ import { HttpAdapter } from "./adapters/http-adapter.js";
3
3
  import { RegistryAdapter } from "./adapters/registry-adapter.js";
4
4
  import { precompileDoc } from "./precompile.js";
5
5
  export class Loader {
6
- adapters = [new HttpAdapter(), new RegistryAdapter()];
7
- constructor(extraAdapters = []) {
8
- this.adapters.unshift(...extraAdapters);
6
+ adapters;
7
+ constructor(extraAdaptersOrOptions = []) {
8
+ const options = Array.isArray(extraAdaptersOrOptions)
9
+ ? { extraAdapters: extraAdaptersOrOptions }
10
+ : extraAdaptersOrOptions;
11
+ const includeHttpAdapter = options.includeHttpAdapter ?? true;
12
+ const includeRegistryAdapter = options.includeRegistryAdapter ?? true;
13
+ this.adapters = [];
14
+ if (includeHttpAdapter)
15
+ this.adapters.push(new HttpAdapter());
16
+ if (includeRegistryAdapter)
17
+ this.adapters.push(new RegistryAdapter(options.registryUrl));
18
+ if (options.extraAdapters?.length) {
19
+ this.adapters.unshift(...options.extraAdapters);
20
+ }
9
21
  }
10
22
  register(adapter) {
11
23
  this.adapters.unshift(adapter);
@@ -17,6 +29,10 @@ export class Loader {
17
29
  throw new Error(`No adapter found for: ${url}`);
18
30
  return a;
19
31
  }
32
+ async resolveEntryPoint(url) {
33
+ const { source } = await this.pick(url).read(url);
34
+ return source;
35
+ }
20
36
  async loadModule(url, options) {
21
37
  const { text, source } = await this.pick(url).read(url);
22
38
  const parsedDocuments = parseAllDocuments(text);
@@ -69,12 +85,58 @@ export class Loader {
69
85
  if (moduleName) {
70
86
  for (const manifest of resolved) {
71
87
  if (manifest.kind !== "Kernel.Module" && !manifest.metadata?.module) {
88
+ const pi = manifest.metadata?.positionIndex;
72
89
  manifest.metadata = { ...manifest.metadata, module: moduleName };
90
+ if (pi) {
91
+ Object.defineProperty(manifest.metadata, "positionIndex", {
92
+ value: pi,
93
+ enumerable: false,
94
+ writable: true,
95
+ configurable: true,
96
+ });
97
+ }
73
98
  }
74
99
  }
75
100
  }
76
101
  return resolved;
77
102
  }
103
+ async loadModuleGraph(entryUrl, onError) {
104
+ const visited = new Set([entryUrl]);
105
+ const result = new Map();
106
+ const entry = await this.loadModule(entryUrl);
107
+ result.set(entryUrl, entry);
108
+ const queue = [...entry];
109
+ while (queue.length > 0) {
110
+ const m = queue.shift();
111
+ if (m.kind !== "Kernel.Import")
112
+ continue;
113
+ const importSource = m.source;
114
+ if (!importSource)
115
+ continue;
116
+ const base = m.metadata?.source ?? entryUrl;
117
+ const importUrl = importSource.startsWith(".") || importSource.startsWith("/")
118
+ ? this.pick(base).resolveRelative(base, importSource)
119
+ : importSource;
120
+ if (visited.has(importUrl))
121
+ continue;
122
+ visited.add(importUrl);
123
+ let imported;
124
+ try {
125
+ imported = await this.loadModule(importUrl);
126
+ }
127
+ catch (err) {
128
+ const error = err instanceof Error ? err : new Error(String(err));
129
+ onError?.(importUrl, error);
130
+ continue;
131
+ }
132
+ result.set(importUrl, imported);
133
+ for (const im of imported) {
134
+ if (im.kind === "Kernel.Import")
135
+ queue.push(im);
136
+ }
137
+ }
138
+ return result;
139
+ }
78
140
  async loadManifests(entryUrl) {
79
141
  const visited = new Set([entryUrl]);
80
142
  const entry = await this.loadModule(entryUrl);
@@ -88,7 +150,9 @@ export class Loader {
88
150
  if (!importSource)
89
151
  continue;
90
152
  const base = m.metadata?.source ?? entryUrl;
91
- const importUrl = this.pick(base).resolveRelative(base, importSource);
153
+ const importUrl = importSource.startsWith(".") || importSource.startsWith("/")
154
+ ? this.pick(base).resolveRelative(base, importSource)
155
+ : importSource;
92
156
  if (visited.has(importUrl))
93
157
  continue;
94
158
  visited.add(importUrl);
@@ -103,11 +167,20 @@ export class Loader {
103
167
  }
104
168
  const importedModule = imported.find((im) => im.kind === "Kernel.Module");
105
169
  if (importedModule?.metadata?.name) {
170
+ const pi = m.metadata?.positionIndex;
106
171
  m.metadata = {
107
172
  ...m.metadata,
108
173
  resolvedModuleName: importedModule.metadata.name,
109
174
  resolvedNamespace: importedModule.metadata.namespace ?? null,
110
175
  };
176
+ if (pi) {
177
+ Object.defineProperty(m.metadata, "positionIndex", {
178
+ value: pi,
179
+ enumerable: false,
180
+ writable: true,
181
+ configurable: true,
182
+ });
183
+ }
111
184
  }
112
185
  for (const im of imported) {
113
186
  if (im.kind === "Kernel.Definition")
@@ -1 +1 @@
1
- {"version":3,"file":"schema-compat.d.ts","sourceRoot":"","sources":["../src/schema-compat.ts"],"names":[],"mappings":"AAGA,QAAA,MAAM,GAAG,KAA0C,CAAC;AAEpD;0FAC0F;AAC1F,wBAAgB,SAAS,IAAI,YAAY,CAAC,OAAO,GAAG,CAAC,CAMpD;AAID,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,OAAO,CAAC;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;oEAEoE;AACpE,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC1B,mBAAmB,CAIrB;AAiDD,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,GAAG,GAAG,MAAM,CAGlD;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,GAAG,EAAE,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAGxE;AAuBD,mFAAmF;AACnF,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,iFAAiF;IACjF,IAAI,EAAE,MAAM,CAAC;CACd;AAED,0GAA0G;AAC1G,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,WAAW,EAAE,CAY/F;AAED;qFACqF;AACrF,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAQ7E;AAED;;;;6DAI6D;AAC7D,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3B,IAAI,EAAE,MAAM,GACX,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,SAAS,CAsBjC;AAED,8DAA8D;AAC9D,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,SAAS,GAAG,MAAM,CAgBnF;AAED,wFAAwF;AACxF,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC1B,OAAO,CAqBT;AAED,6EAA6E;AAC7E,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAW5E;AAID;iGACiG;AACjG,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAqBvF"}
1
+ {"version":3,"file":"schema-compat.d.ts","sourceRoot":"","sources":["../src/schema-compat.ts"],"names":[],"mappings":"AAGA,QAAA,MAAM,GAAG,KAA0C,CAAC;AAEpD;0FAC0F;AAC1F,wBAAgB,SAAS,IAAI,YAAY,CAAC,OAAO,GAAG,CAAC,CAMpD;AAID,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,OAAO,CAAC;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;oEAEoE;AACpE,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC1B,mBAAmB,CAIrB;AAiDD,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,GAAG,GAAG,MAAM,CAelD;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,GAAG,EAAE,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAGxE;AAuBD,mFAAmF;AACnF,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,iFAAiF;IACjF,IAAI,EAAE,MAAM,CAAC;CACd;AAED,0GAA0G;AAC1G,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,WAAW,EAAE,CAY/F;AAED;qFACqF;AACrF,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAQ7E;AAED;;;;6DAI6D;AAC7D,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3B,IAAI,EAAE,MAAM,GACX,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,SAAS,CAsBjC;AAED,8DAA8D;AAC9D,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,SAAS,GAAG,MAAM,CAuBnF;AAED,wFAAwF;AACxF,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAqBhG;AAED,6EAA6E;AAC7E,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAiB5E;AAID;iGACiG;AACjG,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAqBvF"}
@@ -51,7 +51,19 @@ function checkProperty(source, target, path, issues) {
51
51
  }
52
52
  export function formatSingleError(err) {
53
53
  const p = err.instancePath || "/";
54
- return `${p} ${err.message ?? "is invalid"}`;
54
+ const params = err.params ?? {};
55
+ switch (err.keyword) {
56
+ case "additionalProperties":
57
+ return `${p} must NOT have additional properties ('${params.additionalProperty}' is not allowed)`;
58
+ case "required":
59
+ return `${p} is missing required property '${params.missingProperty}'`;
60
+ case "enum":
61
+ return `${p} ${err.message ?? "is invalid"} (${params.allowedValues?.join(" | ")})`;
62
+ case "type":
63
+ return `${p} must be ${params.type} (got ${typeof err.data})`;
64
+ default:
65
+ return `${p} ${err.message ?? "is invalid"}`;
66
+ }
55
67
  }
56
68
  export function formatAjvErrors(errors) {
57
69
  if (!errors || errors.length === 0)
@@ -153,13 +165,20 @@ export function jsonSchemaToCelType(schema) {
153
165
  if (Array.isArray(schema.type))
154
166
  return "dyn";
155
167
  switch (schema.type) {
156
- case "integer": return "int";
157
- case "number": return "double";
158
- case "string": return "string";
159
- case "boolean": return "bool";
160
- case "array": return "list";
161
- case "object": return "map";
162
- case "null": return "null_type";
168
+ case "integer":
169
+ return "int";
170
+ case "number":
171
+ return "double";
172
+ case "string":
173
+ return "string";
174
+ case "boolean":
175
+ return "bool";
176
+ case "array":
177
+ return "list";
178
+ case "object":
179
+ return "map";
180
+ case "null":
181
+ return "null_type";
163
182
  }
164
183
  if (schema.properties)
165
184
  return "map";
@@ -200,12 +219,18 @@ export function celPlaceholderForSchema(schema) {
200
219
  return schema.default;
201
220
  switch (schema.type) {
202
221
  case "integer":
203
- case "number": return schema.minimum ?? 0;
204
- case "string": return "";
205
- case "boolean": return false;
206
- case "array": return [];
207
- case "object": return {};
208
- default: return null;
222
+ case "number":
223
+ return schema.minimum ?? 0;
224
+ case "string":
225
+ return "";
226
+ case "boolean":
227
+ return false;
228
+ case "array":
229
+ return [];
230
+ case "object":
231
+ return {};
232
+ default:
233
+ return null;
209
234
  }
210
235
  }
211
236
  const CEL_PURE_RE = /^\s*\$\{\{[^}]*\}\}\s*$/;
package/dist/types.d.ts CHANGED
@@ -48,6 +48,16 @@ export interface LoadOptions {
48
48
  * the analyzer works on raw strings and does not need compiled values. */
49
49
  compile?: boolean;
50
50
  }
51
+ export interface LoaderInitOptions {
52
+ /** Adapters inserted with highest priority before built-ins. */
53
+ extraAdapters?: ManifestAdapter[];
54
+ /** Include built-in HttpAdapter. Defaults to true. */
55
+ includeHttpAdapter?: boolean;
56
+ /** Include built-in RegistryAdapter. Defaults to true. */
57
+ includeRegistryAdapter?: boolean;
58
+ /** Base URL used by built-in RegistryAdapter when enabled. */
59
+ registryUrl?: string;
60
+ }
51
61
  export interface AnalysisOptions {
52
62
  strictContexts?: boolean;
53
63
  }
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;qHACqH;AACrH,eAAO,MAAM,kBAAkB;;;;;CAKrB,CAAC;AACX,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,OAAO,kBAAkB,CAAC,CAAC;AAE9F,MAAM,WAAW,QAAQ;IACvB,0BAA0B;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,+BAA+B;IAC/B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,KAAK;IACpB,KAAK,EAAE,QAAQ,CAAC;IAChB,GAAG,EAAE,QAAQ,CAAC;CACf;AAED;;oDAEoD;AACpD,MAAM,MAAM,aAAa,GAAG,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAE/C;6EAC6E;AAC7E,MAAM,WAAW,kBAAkB;IACjC,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,QAAQ,CAAC,EAAE,kBAAkB,CAAC;IAC9B,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,2BAA2B;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,sEAAsE;IACtE,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IAC/B,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC7D,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC;CACzD;AAED,MAAM,WAAW,WAAW;IAC1B;;;+EAG2E;IAC3E,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;;;gEAKgE;AAChE,MAAM,WAAW,eAAe;IAC9B,OAAO,CAAC,EAAE,OAAO,qBAAqB,EAAE,aAAa,CAAC;IACtD,WAAW,CAAC,EAAE,OAAO,0BAA0B,EAAE,kBAAkB,CAAC;CACrE"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;qHACqH;AACrH,eAAO,MAAM,kBAAkB;;;;;CAKrB,CAAC;AACX,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,OAAO,kBAAkB,CAAC,CAAC;AAE9F,MAAM,WAAW,QAAQ;IACvB,0BAA0B;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,+BAA+B;IAC/B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,KAAK;IACpB,KAAK,EAAE,QAAQ,CAAC;IAChB,GAAG,EAAE,QAAQ,CAAC;CACf;AAED;;oDAEoD;AACpD,MAAM,MAAM,aAAa,GAAG,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAE/C;6EAC6E;AAC7E,MAAM,WAAW,kBAAkB;IACjC,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,QAAQ,CAAC,EAAE,kBAAkB,CAAC;IAC9B,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,2BAA2B;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,sEAAsE;IACtE,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IAC/B,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC7D,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC;CACzD;AAED,MAAM,WAAW,WAAW;IAC1B;;;+EAG2E;IAC3E,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,gEAAgE;IAChE,aAAa,CAAC,EAAE,eAAe,EAAE,CAAC;IAClC,sDAAsD;IACtD,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,0DAA0D;IAC1D,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,8DAA8D;IAC9D,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;;;gEAKgE;AAChE,MAAM,WAAW,eAAe;IAC9B,OAAO,CAAC,EAAE,OAAO,qBAAqB,EAAE,aAAa,CAAC;IACtD,WAAW,CAAC,EAAE,OAAO,0BAA0B,EAAE,kBAAkB,CAAC;CACrE"}
@@ -1,4 +1,11 @@
1
1
  import type { ASTNode } from "@marcbachmann/cel-js";
2
+ /**
3
+ * Resolve a type field value (string name, inline type, or raw schema) to a JSON Schema.
4
+ * - String: look up the named type in allManifests (Type.JsonSchema resources)
5
+ * - Object with `kind` + `schema`: inline type definition → return the `schema`
6
+ * - Object with `type` or `properties`: raw JSON Schema, return as-is
7
+ */
8
+ export declare function resolveTypeFieldToSchema(value: unknown, allManifests: Record<string, any>[]): Record<string, any> | undefined;
2
9
  /**
3
10
  * Extract all member-access chains from a CEL AST.
4
11
  * Returns arrays like ["request", "query", "name"] for `request.query.name`.
@@ -14,11 +21,26 @@ export declare function extractAccessChains(node: ASTNode): string[][];
14
21
  */
15
22
  export declare function validateChainAgainstSchema(chain: string[], schema: Record<string, any>): string | null;
16
23
  /**
17
- * Returns true when a CEL expression path (from walkCelExpressions, e.g. "routes[0].handler.inputs.name")
18
- * falls within the container region of a context scope (e.g. "$.routes[*].handler").
24
+ * Returns true when a CEL expression path (from walkCelExpressions, e.g. "routes[0].inputs.q")
25
+ * falls within the scope of a context (e.g. "$.routes[*].inputs").
19
26
  *
20
- * The container is derived by stripping the last dot-separated segment from the scope, so that
21
- * sibling fields within the same parent (e.g. routes[*].response) also match.
27
+ * The scope is matched directly (no sibling sharing): a context at "$.routes[*].inputs" only
28
+ * applies to expressions whose path starts with "routes[N].inputs", not to other sibling fields.
22
29
  */
23
30
  export declare function pathMatchesScope(exprPath: string, scope: string): boolean;
31
+ /**
32
+ * Resolves `x-telo-context-from` annotations in a context schema using the concrete
33
+ * manifest item. Navigates the manifest item at the given slash-separated path and merges
34
+ * the result as named properties into the annotated node (locking additionalProperties: false).
35
+ *
36
+ * Example: `x-telo-context-from: "request/schema"` on the `request` context node replaces
37
+ * the open `request` schema with a closed schema whose properties are the keys of
38
+ * `manifestItem.request.schema` (e.g. `query`, `body`, `params`, `headers`).
39
+ */
40
+ export declare function resolveContextAnnotations(schema: Record<string, any>, manifestItem: Record<string, any>, allManifests?: Record<string, any>[]): Record<string, any>;
41
+ /**
42
+ * Extracts the concrete manifest array item for a given expression path + scope.
43
+ * e.g. exprPath="routes[0].inputs.q", scope="$.routes[*].inputs" → manifest.routes[0]
44
+ */
45
+ export declare function getManifestItem(exprPath: string, scope: string, manifest: Record<string, any>): Record<string, any>;
24
46
  //# sourceMappingURL=validate-cel-context.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"validate-cel-context.d.ts","sourceRoot":"","sources":["../src/validate-cel-context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAEpD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,EAAE,EAAE,CAI7D;AAwED;;;;;GAKG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,MAAM,EAAE,EACf,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC1B,MAAM,GAAG,IAAI,CAiBf;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAsBzE"}
1
+ {"version":3,"file":"validate-cel-context.d.ts","sourceRoot":"","sources":["../src/validate-cel-context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAEpD;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,OAAO,EACd,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,GAClC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,SAAS,CA6BjC;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,EAAE,EAAE,CAI7D;AAwED;;;;;GAKG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,MAAM,EAAE,EACf,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC1B,MAAM,GAAG,IAAI,CAmBf;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAoBzE;AAED;;;;;;;;GAQG;AACH,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3B,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACjC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,GACnC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAqDrB;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,CAQrB"}