@telorun/ide-support 0.102.0 → 0.103.1
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/completions/build.d.ts.map +1 -1
- package/dist/completions/build.js +26 -10
- package/dist/completions/detect-context.d.ts +4 -1
- package/dist/completions/detect-context.d.ts.map +1 -1
- package/dist/completions/detect-context.js +6 -3
- package/package.json +3 -3
- package/src/completions/build.ts +34 -10
- package/src/completions/detect-context.ts +12 -2
|
@@ -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,
|
|
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,
|
|
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,
|
|
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
|
|
73
|
-
if (
|
|
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 =
|
|
89
|
+
const resolved = slot.kinds.map((c) => registry.userFacingKindsForRef(c));
|
|
76
90
|
if (!resolved.some(Boolean))
|
|
77
91
|
return undefined;
|
|
78
|
-
|
|
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
|
|
170
|
-
?
|
|
171
|
-
:
|
|
172
|
-
return refNameCompletions(astDocs, ctx.refKind,
|
|
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":"AAAA,OAAO,EAIL,KAAK,WAAW,EAChB,KAAK,UAAU,
|
|
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
|
-
|
|
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
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@telorun/ide-support",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.103.1",
|
|
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.
|
|
41
|
-
"@telorun/templating": "0.
|
|
40
|
+
"@telorun/analyzer": "0.103.1",
|
|
41
|
+
"@telorun/templating": "0.103.1"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"@types/node": "^20.0.0",
|
package/src/completions/build.ts
CHANGED
|
@@ -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,
|
|
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
|
-
|
|
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
|
|
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 (
|
|
101
|
-
const resolved =
|
|
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
|
-
|
|
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
|
|
240
|
+
const slot =
|
|
217
241
|
registry && definition?.schema
|
|
218
|
-
?
|
|
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,
|
|
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
|
-
|
|
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
|