@telorun/ide-support 0.24.0 → 0.103.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.
@@ -1 +1 @@
1
- {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/completions/build.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,gBAAgB,EACrB,KAAK,WAAW,EAEhB,KAAK,gBAAgB,EACtB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAuK3E,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,gBAAgB,GAAG,SAAS,EACtC,OAAO,CAAC,EAAE,qBAAqB,EAC/B,IAAI,CAAC,EAAE,WAAW,EAAE;AACpB;;gCAEgC;AAChC,QAAQ,CAAC,EAAE,gBAAgB,GAC1B,OAAO,CAAC,gBAAgB,EAAE,CAAC,CA2D7B"}
1
+ {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/completions/build.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,gBAAgB,EACrB,KAAK,WAAW,EAEhB,KAAK,gBAAgB,EAEtB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AA8L3E,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,gBAAgB,GAAG,SAAS,EACtC,OAAO,CAAC,EAAE,qBAAqB,EAC/B,IAAI,CAAC,EAAE,WAAW,EAAE;AACpB;;gCAEgC;AAChC,QAAQ,CAAC,EAAE,gBAAgB,GAC1B,OAAO,CAAC,gBAAgB,EAAE,CAAC,CA2D7B"}
@@ -2,7 +2,7 @@ import { parseToAst, } from "@telorun/analyzer";
2
2
  import { callInputsAt } from "./call-inputs.js";
3
3
  import { celCompletions } from "./cel-completions.js";
4
4
  import { docIdentity } from "../doc-identity.js";
5
- import { detectContext, lookupRefConstraints, navigateSchema } from "./detect-context.js";
5
+ import { detectContext, lookupRefSlot, navigateSchema } from "./detect-context.js";
6
6
  import { importSourceCompletions } from "./import-source.js";
7
7
  import { moduleFileCompletions } from "./module-file-completions.js";
8
8
  import { valueTagCompletions } from "./value-tag-completions.js";
@@ -27,8 +27,9 @@ function extractInFileResources(docs) {
27
27
  * kind match. Falls back to listing every in-file resource so the
28
28
  * user still sees something rather than nothing when the registry
29
29
  * doesn't recognize the kind yet. */
30
- function refNameCompletions(docs, refKind, refConstraints, registry, replaceRange) {
30
+ function refNameCompletions(docs, refKind, slot, registry, analysis, replaceRange) {
31
31
  const resources = extractInFileResources(docs);
32
+ const refConstraints = slot?.kinds ?? [];
32
33
  let acceptable;
33
34
  if (refKind) {
34
35
  acceptable = new Set([refKind]);
@@ -47,6 +48,11 @@ function refNameCompletions(docs, refKind, refConstraints, registry, replaceRang
47
48
  for (const r of resources) {
48
49
  if (acceptable && !acceptable.has(r.kind))
49
50
  continue;
51
+ // A target `telo check` refuses for what it returns is not a candidate. The
52
+ // analysis resolves the instance's own contract; without one the kind's
53
+ // decides.
54
+ if (slot && outputRefused(slot, r, registry, analysis))
55
+ continue;
50
56
  if (seen.has(r.name))
51
57
  continue;
52
58
  seen.add(r.name);
@@ -61,6 +67,14 @@ function refNameCompletions(docs, refKind, refConstraints, registry, replaceRang
61
67
  }
62
68
  return out;
63
69
  }
70
+ function outputRefused(slot, candidate, registry, analysis) {
71
+ if (!slot.outputType)
72
+ return false;
73
+ const refusal = analysis
74
+ ? analysis.outputRefusal(slot, { kind: candidate.kind, name: candidate.name })
75
+ : (registry?.outputRefusal(slot, { kind: candidate.kind }) ?? []);
76
+ return refusal.length > 0;
77
+ }
64
78
  /** Resolve the kinds that satisfy the `x-telo-ref` slot at `parentDocKind` +
65
79
  * `parentYamlPath`. Returns `undefined` (caller falls back to the full list)
66
80
  * when there's no constraint, the path doesn't resolve, or the ref can't
@@ -69,13 +83,15 @@ function refConstrainedKinds(registry, parentDocKind, parentYamlPath) {
69
83
  const definition = registry.resolveDefinition(parentDocKind);
70
84
  if (!definition?.schema)
71
85
  return undefined;
72
- const constraints = lookupRefConstraints(definition.schema, parentYamlPath, (from) => registry.resolveSchemaFrom(from, parentDocKind));
73
- if (constraints.length === 0)
86
+ const slot = lookupRefSlot(definition.schema, parentYamlPath, (from) => registry.resolveSchemaFrom(from, parentDocKind));
87
+ if (!slot || slot.kinds.length === 0)
74
88
  return undefined;
75
- const resolved = constraints.map((c) => registry.userFacingKindsForRef(c));
89
+ const resolved = slot.kinds.map((c) => registry.userFacingKindsForRef(c));
76
90
  if (!resolved.some(Boolean))
77
91
  return undefined;
78
- return [...new Set(resolved.flatMap((kinds) => kinds ?? []))];
92
+ // An inline declaration of a kind whose output the slot refuses would be
93
+ // refused by `telo check` the moment it is written.
94
+ return [...new Set(resolved.flatMap((kinds) => kinds ?? []))].filter((kind) => !outputRefused(slot, { kind }, registry, undefined));
79
95
  }
80
96
  function kindCompletions(registry, docKind, yamlPath, replaceRange) {
81
97
  let kinds;
@@ -166,10 +182,10 @@ analysis) {
166
182
  }
167
183
  if (ctx.type === "ref-name") {
168
184
  const definition = registry?.resolveDefinition(ctx.docKind);
169
- const refConstraints = registry && definition?.schema
170
- ? lookupRefConstraints(definition.schema, ctx.yamlPath, (from) => registry.resolveSchemaFrom(from, ctx.docKind))
171
- : [];
172
- return refNameCompletions(astDocs, ctx.refKind, refConstraints, registry, ctx.replaceRange);
185
+ const slot = registry && definition?.schema
186
+ ? lookupRefSlot(definition.schema, ctx.yamlPath, (from) => registry.resolveSchemaFrom(from, ctx.docKind))
187
+ : undefined;
188
+ return refNameCompletions(astDocs, ctx.refKind, slot, registry, analysis, ctx.replaceRange);
173
189
  }
174
190
  if (ctx.type === "field-value") {
175
191
  if (ctx.field === "import-source") {
@@ -1,4 +1,4 @@
1
- import { type AstDocument, type CelSegment } from "@telorun/analyzer";
1
+ import { type AstDocument, type CelSegment, type RefSlot } from "@telorun/analyzer";
2
2
  import type { ReplaceRange } from "../types.js";
3
3
  export type { ReplaceRange };
4
4
  export type CompletionCtx = {
@@ -137,6 +137,9 @@ export declare function fieldSchemaAt(schema: Record<string, any>, path: string[
137
137
  * `anyOf` / `oneOf` branches alike, so completion now offers what the slot
138
138
  * actually takes. */
139
139
  export declare function lookupRefConstraints(definitionSchema: Record<string, any>, yamlPath: string[], schemaFrom?: SchemaFromResolver): string[];
140
+ /** The whole `x-telo-ref` slot at `yamlPath` — its kinds and what it asks of a
141
+ * target's output — or undefined when the path declares none. */
142
+ export declare function lookupRefSlot(definitionSchema: Record<string, any>, yamlPath: string[], schemaFrom?: SchemaFromResolver): RefSlot | undefined;
140
143
  /** Derive a `CompletionCtx` from the AST-resolved cursor (Approach B). The
141
144
  * structural resolution lives in `resolveNodeAtPosition`; this only maps a
142
145
  * resolved slot onto the completion the editor should offer. `docs` lets a
@@ -1 +1 @@
1
- {"version":3,"file":"detect-context.d.ts","sourceRoot":"","sources":["../../src/completions/detect-context.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"detect-context.d.ts","sourceRoot":"","sources":["../../src/completions/detect-context.ts"],"names":[],"mappings":"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"}
@@ -230,10 +230,13 @@ function unionLeaves(parent, leaves) {
230
230
  * `anyOf` / `oneOf` branches alike, so completion now offers what the slot
231
231
  * actually takes. */
232
232
  export function lookupRefConstraints(definitionSchema, yamlPath, schemaFrom) {
233
+ return lookupRefSlot(definitionSchema, yamlPath, schemaFrom)?.kinds ?? [];
234
+ }
235
+ /** The whole `x-telo-ref` slot at `yamlPath` — its kinds and what it asks of a
236
+ * target's output — or undefined when the path declares none. */
237
+ export function lookupRefSlot(definitionSchema, yamlPath, schemaFrom) {
233
238
  const node = navigateSchema(definitionSchema, yamlPath, schemaFrom);
234
- if (!node)
235
- return [];
236
- return readRefSlot(node)?.kinds ?? [];
239
+ return node ? readRefSlot(node) : undefined;
237
240
  }
238
241
  /** Derive a `CompletionCtx` from the AST-resolved cursor (Approach B). The
239
242
  * structural resolution lives in `resolveNodeAtPosition`; this only maps a
@@ -20,9 +20,9 @@ export interface ModuleVersion {
20
20
  *
21
21
  * Deliberately NOT `adapter.listVersionsForRef`, which answers `string[]`:
22
22
  * completion offers names, an upgrade writes a pin, so the two want different
23
- * things from one route. A host backed by the hub fetches
24
- * `GET /module/versions` and passes the body through
25
- * {@link parseModuleVersions}. */
23
+ * things from one route. A host backed by the hub reads
24
+ * `GET /module/versions`, carrying an `integrity` only when it is a canonical
25
+ * pin. */
26
26
  export type ModuleVersionLookup = (baseRef: string) => Promise<ModuleVersion[]>;
27
27
  /** Everything an upgrade needs from its host: what versions exist, and whether
28
28
  * this runtime can host one.
@@ -1 +1 @@
1
- {"version":3,"file":"build-import-upgrades.d.ts","sourceRoot":"","sources":["../../src/import-upgrades/build-import-upgrades.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"build-import-upgrades.d.ts","sourceRoot":"","sources":["../../src/import-upgrades/build-import-upgrades.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,6 @@
1
1
  export { buildImportUpgrades, describeReason, describeRemedy, } from "./build-import-upgrades.js";
2
2
  export type { ImportPin, ImportUpgrade, ImportUpgradeEdit, ImportUpgradeEnvironment, ImportUpgradeSet, ImportUpgradeSkip, ModuleVersion, ModuleVersionLookup, } from "./build-import-upgrades.js";
3
3
  export { moduleManifestCacheUrl } from "./manifest-cache-url.js";
4
- export { parseModuleVersions } from "./parse-module-versions.js";
5
4
  export { findImportEntries } from "./find-import-entries.js";
6
5
  export type { ImportEntry, ImportEntryIntegrity, ImportsBlock, } from "./find-import-entries.js";
7
6
  export { createVersionCompatibility, markVersionCompatibility, noneRunnableReason, selectCompatibleVersion, uncheckedVersionCompatibility, } from "./version-compatibility.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/import-upgrades/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,cAAc,EACd,cAAc,GACf,MAAM,4BAA4B,CAAC;AACpC,YAAY,EACV,SAAS,EACT,aAAa,EACb,iBAAiB,EACjB,wBAAwB,EACxB,gBAAgB,EAChB,iBAAiB,EACjB,aAAa,EACb,mBAAmB,GACpB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AACjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,YAAY,EACV,WAAW,EACX,oBAAoB,EACpB,YAAY,GACb,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,0BAA0B,EAC1B,wBAAwB,EACxB,kBAAkB,EAClB,uBAAuB,EACvB,6BAA6B,GAC9B,MAAM,4BAA4B,CAAC;AACpC,YAAY,EACV,qBAAqB,EACrB,aAAa,EACb,mBAAmB,EACnB,oBAAoB,EACpB,yBAAyB,EACzB,gBAAgB,GACjB,MAAM,4BAA4B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/import-upgrades/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,cAAc,EACd,cAAc,GACf,MAAM,4BAA4B,CAAC;AACpC,YAAY,EACV,SAAS,EACT,aAAa,EACb,iBAAiB,EACjB,wBAAwB,EACxB,gBAAgB,EAChB,iBAAiB,EACjB,aAAa,EACb,mBAAmB,GACpB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,YAAY,EACV,WAAW,EACX,oBAAoB,EACpB,YAAY,GACb,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,0BAA0B,EAC1B,wBAAwB,EACxB,kBAAkB,EAClB,uBAAuB,EACvB,6BAA6B,GAC9B,MAAM,4BAA4B,CAAC;AACpC,YAAY,EACV,qBAAqB,EACrB,aAAa,EACb,mBAAmB,EACnB,oBAAoB,EACpB,yBAAyB,EACzB,gBAAgB,GACjB,MAAM,4BAA4B,CAAC"}
@@ -1,5 +1,4 @@
1
1
  export { buildImportUpgrades, describeReason, describeRemedy, } from "./build-import-upgrades.js";
2
2
  export { moduleManifestCacheUrl } from "./manifest-cache-url.js";
3
- export { parseModuleVersions } from "./parse-module-versions.js";
4
3
  export { findImportEntries } from "./find-import-entries.js";
5
4
  export { createVersionCompatibility, markVersionCompatibility, noneRunnableReason, selectCompatibleVersion, uncheckedVersionCompatibility, } from "./version-compatibility.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@telorun/ide-support",
3
- "version": "0.24.0",
3
+ "version": "0.103.0",
4
4
  "description": "Editor-host-agnostic IDE support (completions, diagnostic normalization) for Telo manifests.",
5
5
  "keywords": [
6
6
  "telo",
@@ -37,8 +37,8 @@
37
37
  ],
38
38
  "dependencies": {
39
39
  "yaml": "^2.8.3",
40
- "@telorun/analyzer": "0.84.0",
41
- "@telorun/templating": "0.25.0"
40
+ "@telorun/analyzer": "0.103.0",
41
+ "@telorun/templating": "0.103.0"
42
42
  },
43
43
  "devDependencies": {
44
44
  "@types/node": "^20.0.0",
@@ -4,13 +4,14 @@ import {
4
4
  type AstDocument,
5
5
  type AstMap,
6
6
  type ManifestAnalysis,
7
+ type RefSlot,
7
8
  } from "@telorun/analyzer";
8
9
  import type { CompletionResult, IdeEnvironmentAdapter } from "../types.js";
9
10
  import type { ReplaceRange } from "./detect-context.js";
10
11
  import { callInputsAt } from "./call-inputs.js";
11
12
  import { celCompletions } from "./cel-completions.js";
12
13
  import { docIdentity } from "../doc-identity.js";
13
- import { detectContext, lookupRefConstraints, navigateSchema } from "./detect-context.js";
14
+ import { detectContext, lookupRefSlot, navigateSchema } from "./detect-context.js";
14
15
  import { importSourceCompletions } from "./import-source.js";
15
16
  import { moduleFileCompletions } from "./module-file-completions.js";
16
17
  import { valueTagCompletions } from "./value-tag-completions.js";
@@ -44,11 +45,13 @@ function extractInFileResources(docs: AstDocument[]): ResourceRecord[] {
44
45
  function refNameCompletions(
45
46
  docs: AstDocument[],
46
47
  refKind: string | undefined,
47
- refConstraints: string[],
48
+ slot: RefSlot | undefined,
48
49
  registry: AnalysisRegistry | undefined,
50
+ analysis: ManifestAnalysis | undefined,
49
51
  replaceRange: ReplaceRange,
50
52
  ): CompletionResult[] {
51
53
  const resources = extractInFileResources(docs);
54
+ const refConstraints = slot?.kinds ?? [];
52
55
  let acceptable: Set<string> | undefined;
53
56
 
54
57
  if (refKind) {
@@ -67,6 +70,10 @@ function refNameCompletions(
67
70
  const out: CompletionResult[] = [];
68
71
  for (const r of resources) {
69
72
  if (acceptable && !acceptable.has(r.kind)) continue;
73
+ // A target `telo check` refuses for what it returns is not a candidate. The
74
+ // analysis resolves the instance's own contract; without one the kind's
75
+ // decides.
76
+ if (slot && outputRefused(slot, r, registry, analysis)) continue;
70
77
  if (seen.has(r.name)) continue;
71
78
  seen.add(r.name);
72
79
  out.push({
@@ -81,6 +88,19 @@ function refNameCompletions(
81
88
  return out;
82
89
  }
83
90
 
91
+ function outputRefused(
92
+ slot: RefSlot,
93
+ candidate: { kind: string; name?: string },
94
+ registry: AnalysisRegistry | undefined,
95
+ analysis: ManifestAnalysis | undefined,
96
+ ): boolean {
97
+ if (!slot.outputType) return false;
98
+ const refusal = analysis
99
+ ? analysis.outputRefusal(slot, { kind: candidate.kind, name: candidate.name })
100
+ : (registry?.outputRefusal(slot, { kind: candidate.kind }) ?? []);
101
+ return refusal.length > 0;
102
+ }
103
+
84
104
  /** Resolve the kinds that satisfy the `x-telo-ref` slot at `parentDocKind` +
85
105
  * `parentYamlPath`. Returns `undefined` (caller falls back to the full list)
86
106
  * when there's no constraint, the path doesn't resolve, or the ref can't
@@ -92,15 +112,19 @@ function refConstrainedKinds(
92
112
  ): string[] | undefined {
93
113
  const definition = registry.resolveDefinition(parentDocKind);
94
114
  if (!definition?.schema) return undefined;
95
- const constraints = lookupRefConstraints(
115
+ const slot = lookupRefSlot(
96
116
  definition.schema as Record<string, any>,
97
117
  parentYamlPath,
98
118
  (from) => registry.resolveSchemaFrom(from, parentDocKind),
99
119
  );
100
- if (constraints.length === 0) return undefined;
101
- const resolved = constraints.map((c) => registry.userFacingKindsForRef(c));
120
+ if (!slot || slot.kinds.length === 0) return undefined;
121
+ const resolved = slot.kinds.map((c) => registry.userFacingKindsForRef(c));
102
122
  if (!resolved.some(Boolean)) return undefined;
103
- return [...new Set(resolved.flatMap((kinds) => kinds ?? []))];
123
+ // An inline declaration of a kind whose output the slot refuses would be
124
+ // refused by `telo check` the moment it is written.
125
+ return [...new Set(resolved.flatMap((kinds) => kinds ?? []))].filter(
126
+ (kind) => !outputRefused(slot, { kind }, registry, undefined),
127
+ );
104
128
  }
105
129
 
106
130
  function kindCompletions(
@@ -213,13 +237,13 @@ export async function buildCompletions(
213
237
  }
214
238
  if (ctx.type === "ref-name") {
215
239
  const definition = registry?.resolveDefinition(ctx.docKind);
216
- const refConstraints =
240
+ const slot =
217
241
  registry && definition?.schema
218
- ? lookupRefConstraints(definition.schema as Record<string, any>, ctx.yamlPath, (from) =>
242
+ ? lookupRefSlot(definition.schema as Record<string, any>, ctx.yamlPath, (from) =>
219
243
  registry.resolveSchemaFrom(from, ctx.docKind),
220
244
  )
221
- : [];
222
- return refNameCompletions(astDocs, ctx.refKind, refConstraints, registry, ctx.replaceRange);
245
+ : undefined;
246
+ return refNameCompletions(astDocs, ctx.refKind, slot, registry, analysis, ctx.replaceRange);
223
247
  }
224
248
  if (ctx.type === "field-value") {
225
249
  if (ctx.field === "import-source") {
@@ -4,6 +4,7 @@ import {
4
4
  refSlotAnnotation,
5
5
  type AstDocument,
6
6
  type CelSegment,
7
+ type RefSlot,
7
8
  } from "@telorun/analyzer";
8
9
  import type { ReplaceRange } from "../types.js";
9
10
  import { valueTag } from "../value-tags/offered-value-tags.js";
@@ -366,9 +367,18 @@ export function lookupRefConstraints(
366
367
  yamlPath: string[],
367
368
  schemaFrom?: SchemaFromResolver,
368
369
  ): string[] {
370
+ return lookupRefSlot(definitionSchema, yamlPath, schemaFrom)?.kinds ?? [];
371
+ }
372
+
373
+ /** The whole `x-telo-ref` slot at `yamlPath` — its kinds and what it asks of a
374
+ * target's output — or undefined when the path declares none. */
375
+ export function lookupRefSlot(
376
+ definitionSchema: Record<string, any>,
377
+ yamlPath: string[],
378
+ schemaFrom?: SchemaFromResolver,
379
+ ): RefSlot | undefined {
369
380
  const node = navigateSchema(definitionSchema, yamlPath, schemaFrom);
370
- if (!node) return [];
371
- return readRefSlot(node)?.kinds ?? [];
381
+ return node ? readRefSlot(node) : undefined;
372
382
  }
373
383
 
374
384
  /** Derive a `CompletionCtx` from the AST-resolved cursor (Approach B). The
@@ -42,9 +42,9 @@ export interface ModuleVersion {
42
42
  *
43
43
  * Deliberately NOT `adapter.listVersionsForRef`, which answers `string[]`:
44
44
  * completion offers names, an upgrade writes a pin, so the two want different
45
- * things from one route. A host backed by the hub fetches
46
- * `GET /module/versions` and passes the body through
47
- * {@link parseModuleVersions}. */
45
+ * things from one route. A host backed by the hub reads
46
+ * `GET /module/versions`, carrying an `integrity` only when it is a canonical
47
+ * pin. */
48
48
  export type ModuleVersionLookup = (baseRef: string) => Promise<ModuleVersion[]>;
49
49
 
50
50
  /** Everything an upgrade needs from its host: what versions exist, and whether
@@ -14,7 +14,6 @@ export type {
14
14
  ModuleVersionLookup,
15
15
  } from "./build-import-upgrades.js";
16
16
  export { moduleManifestCacheUrl } from "./manifest-cache-url.js";
17
- export { parseModuleVersions } from "./parse-module-versions.js";
18
17
  export { findImportEntries } from "./find-import-entries.js";
19
18
  export type {
20
19
  ImportEntry,
@@ -1,19 +0,0 @@
1
- import type { ModuleVersion } from "./build-import-upgrades.js";
2
- /**
3
- * Read the hub's `GET /module/versions` payload into {@link ModuleVersion}s,
4
- * newest first (the route's own ordering, preserved).
5
- *
6
- * Pure — the host owns the `fetch`, as everything else in this package does.
7
- * It lives here rather than in each host because the shape is this package's:
8
- * three hosts parsing the same route by hand is how one of them was left
9
- * filtering for strings after the route started returning objects, which
10
- * TypeScript could not catch behind the response cast and which surfaced only
11
- * as a silently empty version list.
12
- *
13
- * Tolerant by design: an entry with no usable `version` is dropped rather than
14
- * throwing, and an `integrity` that is not a canonical `sha256-<base64url>` is
15
- * discarded rather than carried — a pin is spliced into the author's YAML, so a
16
- * malformed one has to become "no pin", never corrupt text.
17
- */
18
- export declare function parseModuleVersions(payload: unknown): ModuleVersion[];
19
- //# sourceMappingURL=parse-module-versions.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"parse-module-versions.d.ts","sourceRoot":"","sources":["../../src/import-upgrades/parse-module-versions.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAEhE;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,aAAa,EAAE,CAUrE"}
@@ -1,29 +0,0 @@
1
- import { isCanonicalIntegrity } from "@telorun/analyzer";
2
- /**
3
- * Read the hub's `GET /module/versions` payload into {@link ModuleVersion}s,
4
- * newest first (the route's own ordering, preserved).
5
- *
6
- * Pure — the host owns the `fetch`, as everything else in this package does.
7
- * It lives here rather than in each host because the shape is this package's:
8
- * three hosts parsing the same route by hand is how one of them was left
9
- * filtering for strings after the route started returning objects, which
10
- * TypeScript could not catch behind the response cast and which surfaced only
11
- * as a silently empty version list.
12
- *
13
- * Tolerant by design: an entry with no usable `version` is dropped rather than
14
- * throwing, and an `integrity` that is not a canonical `sha256-<base64url>` is
15
- * discarded rather than carried — a pin is spliced into the author's YAML, so a
16
- * malformed one has to become "no pin", never corrupt text.
17
- */
18
- export function parseModuleVersions(payload) {
19
- const versions = payload?.versions;
20
- if (!Array.isArray(versions))
21
- return [];
22
- return versions.flatMap((entry) => {
23
- const version = entry?.version;
24
- if (typeof version !== "string" || version === "")
25
- return [];
26
- const integrity = entry.integrity;
27
- return [isCanonicalIntegrity(integrity) ? { version, integrity } : { version }];
28
- });
29
- }
@@ -1,30 +0,0 @@
1
- import { isCanonicalIntegrity } from "@telorun/analyzer";
2
- import type { ModuleVersion } from "./build-import-upgrades.js";
3
-
4
- /**
5
- * Read the hub's `GET /module/versions` payload into {@link ModuleVersion}s,
6
- * newest first (the route's own ordering, preserved).
7
- *
8
- * Pure — the host owns the `fetch`, as everything else in this package does.
9
- * It lives here rather than in each host because the shape is this package's:
10
- * three hosts parsing the same route by hand is how one of them was left
11
- * filtering for strings after the route started returning objects, which
12
- * TypeScript could not catch behind the response cast and which surfaced only
13
- * as a silently empty version list.
14
- *
15
- * Tolerant by design: an entry with no usable `version` is dropped rather than
16
- * throwing, and an `integrity` that is not a canonical `sha256-<base64url>` is
17
- * discarded rather than carried — a pin is spliced into the author's YAML, so a
18
- * malformed one has to become "no pin", never corrupt text.
19
- */
20
- export function parseModuleVersions(payload: unknown): ModuleVersion[] {
21
- const versions = (payload as { versions?: unknown } | null | undefined)?.versions;
22
- if (!Array.isArray(versions)) return [];
23
-
24
- return versions.flatMap((entry) => {
25
- const version = (entry as { version?: unknown } | null)?.version;
26
- if (typeof version !== "string" || version === "") return [];
27
- const integrity = (entry as { integrity?: unknown }).integrity;
28
- return [isCanonicalIntegrity(integrity) ? { version, integrity } : { version }];
29
- });
30
- }