@beehexa/hexasync-template-context 2608.20.18 → 2608.20.32
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/completion.d.ts +80 -0
- package/dist/completion.d.ts.map +1 -0
- package/dist/completion.js +202 -0
- package/dist/completion.js.map +1 -0
- package/dist/detect.d.ts +38 -0
- package/dist/detect.d.ts.map +1 -0
- package/dist/detect.js +35 -0
- package/dist/detect.js.map +1 -0
- package/dist/environment.d.ts +79 -0
- package/dist/environment.d.ts.map +1 -0
- package/dist/environment.js +239 -0
- package/dist/environment.js.map +1 -0
- package/dist/hints.d.ts +62 -0
- package/dist/hints.d.ts.map +1 -0
- package/dist/hints.js +198 -0
- package/dist/hints.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/item.d.ts +87 -0
- package/dist/item.d.ts.map +1 -0
- package/dist/item.js +222 -0
- package/dist/item.js.map +1 -0
- package/dist/position.d.ts +36 -0
- package/dist/position.d.ts.map +1 -0
- package/dist/position.js +31 -0
- package/dist/position.js.map +1 -0
- package/dist/references.d.ts +60 -0
- package/dist/references.d.ts.map +1 -0
- package/dist/references.js +217 -0
- package/dist/references.js.map +1 -0
- package/dist/shape.d.ts +68 -0
- package/dist/shape.d.ts.map +1 -0
- package/dist/shape.js +23 -0
- package/dist/shape.js.map +1 -0
- package/dist/stepOutputs.d.ts +52 -0
- package/dist/stepOutputs.d.ts.map +1 -0
- package/dist/stepOutputs.js +102 -0
- package/dist/stepOutputs.js.map +1 -0
- package/dist/survival.d.ts +47 -0
- package/dist/survival.d.ts.map +1 -0
- package/dist/survival.js +50 -0
- package/dist/survival.js.map +1 -0
- package/dist/walk.d.ts +36 -0
- package/dist/walk.d.ts.map +1 -0
- package/dist/walk.js +162 -0
- package/dist/walk.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import type { Environment } from './environment.js';
|
|
2
|
+
/**
|
|
3
|
+
* One offer, as any surface can render it — a completion item in the editor, a line in a CLI answer, an entry in the
|
|
4
|
+
* agent's environment. It carries no editor type, which is what lets all four read it.
|
|
5
|
+
*/
|
|
6
|
+
export interface Offer {
|
|
7
|
+
readonly label: string;
|
|
8
|
+
/** What to insert. Differs from the label when accepting has to finish a thought (Story 8.5). */
|
|
9
|
+
readonly insert: string;
|
|
10
|
+
readonly detail: string;
|
|
11
|
+
readonly documentation?: string;
|
|
12
|
+
/**
|
|
13
|
+
* A correction that outranks every plain offer.
|
|
14
|
+
*
|
|
15
|
+
* ⛔ Story 8.2 AC-4: an author who types `item.` inside a transformation has made the single most common mistake
|
|
16
|
+
* this engine exists to catch, and the honest response is not an empty list — an empty list reads as "there is
|
|
17
|
+
* nothing here", which is the opposite of true. The bare fields are offered AND the prefix removal is offered
|
|
18
|
+
* above them.
|
|
19
|
+
*/
|
|
20
|
+
readonly fix?: {
|
|
21
|
+
readonly removePrefix: string;
|
|
22
|
+
readonly why: string;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* A second field this choice determines — Story 8.5 AC-1.
|
|
26
|
+
*
|
|
27
|
+
* ⛔ Accepting a validation's `fieldName` determines its `dataType`: the column already declares one, and
|
|
28
|
+
* `metadata.dataType` selects the SQL form (`DateTime` → `hexasync_datetime_equal(…)`). Leaving the author to
|
|
29
|
+
* remember it is leaving them to get it wrong in a way that only shows up as a validation that quietly never
|
|
30
|
+
* matches.
|
|
31
|
+
*/
|
|
32
|
+
readonly coFill?: {
|
|
33
|
+
readonly field: string;
|
|
34
|
+
readonly value: string;
|
|
35
|
+
};
|
|
36
|
+
/** True where `insert` is a whole expression rather than a bare path — see `wrapFor`. */
|
|
37
|
+
readonly wrapped?: boolean;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* The dialect wrapper a position requires — Story 8.5 AC-2.
|
|
41
|
+
*
|
|
42
|
+
* The three dialects are not interchangeable: `$( )` JSONata and `$$( )` JSONPath return STRUCTURE, `{{ }}` Scriban
|
|
43
|
+
* returns TEXT. Inserting a bare `item.lines` where the field needs a structured value produces the string
|
|
44
|
+
* "item.lines", which is the failure mode this fills in against.
|
|
45
|
+
*/
|
|
46
|
+
export type Dialect = 'scriban' | 'jsonata' | 'jsonpath' | 'none';
|
|
47
|
+
export declare function wrapFor(dialect: Dialect, path: string): string;
|
|
48
|
+
/** What a surface says about where the caret is. Story 8.2 AC-6 — the position is stated, never guessed at. */
|
|
49
|
+
export declare const positionBanner: (environment: Environment) => string;
|
|
50
|
+
/**
|
|
51
|
+
* The offers at one caret, given what the author has typed so far.
|
|
52
|
+
*
|
|
53
|
+
* `typed` is the text before the caret on this expression — `''` at a fresh caret, `'item.'` for the mistake AC-4
|
|
54
|
+
* names, `'puller.current.'` for a nested walk.
|
|
55
|
+
*/
|
|
56
|
+
export interface OfferOptions {
|
|
57
|
+
/** Wrap the inserted path for this dialect, where the position needs a whole expression, not a fragment. */
|
|
58
|
+
readonly dialect?: Dialect;
|
|
59
|
+
/** More candidates than a list should carry — escalate through the surface's existing picker (AC-4). */
|
|
60
|
+
readonly listCeiling?: number;
|
|
61
|
+
}
|
|
62
|
+
/** The sentinel every surface already uses to escalate a long list into its picker. Not a second mechanism. */
|
|
63
|
+
export declare const MORE_SENTINEL = "__hexasync_more__";
|
|
64
|
+
export declare function offersFor(environment: Environment, typed?: string, options?: OfferOptions): readonly Offer[];
|
|
65
|
+
/**
|
|
66
|
+
* The trailing run of path characters, scanned BACKWARDS from the end.
|
|
67
|
+
*
|
|
68
|
+
* ⛔ This was `/([\w.[\]]*)$/.exec(trimmed)`, and CodeQL was right (`js/polynomial-redos`, High). With `$`
|
|
69
|
+
* anchored and `*` unbounded, the engine retries the class from every position in the string, so a value of N
|
|
70
|
+
* dots costs O(N²) — and this runs on the line under the caret on every keystroke, which is the worst place in
|
|
71
|
+
* the extension to put a quadratic.
|
|
72
|
+
*
|
|
73
|
+
* A backward scan is what the regex was describing anyway: the longest suffix made only of word characters,
|
|
74
|
+
* `.`, `[` and `]`. One pass, no backtracking, byte-identical result for every input.
|
|
75
|
+
*
|
|
76
|
+
* Exported for `__tests__/redos.spec.ts`, which pins both halves: the same answer the regex gave, and a bound
|
|
77
|
+
* on the time it takes.
|
|
78
|
+
*/
|
|
79
|
+
export declare function trailingPathToken(text: string): string;
|
|
80
|
+
//# sourceMappingURL=completion.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"completion.d.ts","sourceRoot":"","sources":["../src/completion.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAIpD;;;GAGG;AACH,MAAM,WAAW,KAAK;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,iGAAiG;IACjG,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC;;;;;;;OAOG;IACH,QAAQ,CAAC,GAAG,CAAC,EAAE;QAAE,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IACvE;;;;;;;OAOG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE;QAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IACrE,yFAAyF;IACzF,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED;;;;;;GAMG;AACH,MAAM,MAAM,OAAO,GAAG,SAAS,GAAG,SAAS,GAAG,UAAU,GAAG,MAAM,CAAC;AAElE,wBAAgB,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAW9D;AAED,+GAA+G;AAC/G,eAAO,MAAM,cAAc,gBAAiB,WAAW,KAAG,MACO,CAAC;AAiClE;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,4GAA4G;IAC5G,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B,wGAAwG;IACxG,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,+GAA+G;AAC/G,eAAO,MAAM,aAAa,sBAAsB,CAAC;AAEjD,wBAAgB,SAAS,CACvB,WAAW,EAAE,WAAW,EACxB,KAAK,SAAK,EACV,OAAO,GAAE,YAAiB,GACzB,SAAS,KAAK,EAAE,CAuHlB;AA0CD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAItD"}
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { ALLOWS_NESTING, POSITION_LABEL } from './position.js';
|
|
2
|
+
export function wrapFor(dialect, path) {
|
|
3
|
+
switch (dialect) {
|
|
4
|
+
case 'scriban':
|
|
5
|
+
return `{{ ${path} }}`;
|
|
6
|
+
case 'jsonata':
|
|
7
|
+
return `$( ${path} )`;
|
|
8
|
+
case 'jsonpath':
|
|
9
|
+
return `$$( ${path} )`;
|
|
10
|
+
default:
|
|
11
|
+
return path;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
/** What a surface says about where the caret is. Story 8.2 AC-6 — the position is stated, never guessed at. */
|
|
15
|
+
export const positionBanner = (environment) => `${POSITION_LABEL[environment.position]} — ${environment.note}`;
|
|
16
|
+
const offerFor = (field, insert) => ({
|
|
17
|
+
label: field.name,
|
|
18
|
+
insert: insert ?? field.name,
|
|
19
|
+
detail: detailOf(field),
|
|
20
|
+
...(field.description === undefined
|
|
21
|
+
? {}
|
|
22
|
+
: { documentation: field.description }),
|
|
23
|
+
});
|
|
24
|
+
function detailOf(field) {
|
|
25
|
+
const shape = field.shape;
|
|
26
|
+
const kind = shape.kind === 'scalar'
|
|
27
|
+
? (shape.scalarType ?? 'scalar')
|
|
28
|
+
: shape.kind === 'unknown'
|
|
29
|
+
? 'unknown'
|
|
30
|
+
: shape.kind;
|
|
31
|
+
switch (field.provenance.kind) {
|
|
32
|
+
case 'column':
|
|
33
|
+
return `${kind} · column${field.provenance.dataType ? ` (${field.provenance.dataType})` : ''}`;
|
|
34
|
+
case 'transformation':
|
|
35
|
+
return `${kind} · from ${field.provenance.type} at index ${field.provenance.index}`;
|
|
36
|
+
case 'step':
|
|
37
|
+
return `${kind} · output of ${field.provenance.stepKey}`;
|
|
38
|
+
case 'hint':
|
|
39
|
+
return `${kind} · declared hint`;
|
|
40
|
+
default:
|
|
41
|
+
return `${kind} · built in`;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/** The sentinel every surface already uses to escalate a long list into its picker. Not a second mechanism. */
|
|
45
|
+
export const MORE_SENTINEL = '__hexasync_more__';
|
|
46
|
+
export function offersFor(environment, typed = '', options = {}) {
|
|
47
|
+
const trimmed = typed.trim();
|
|
48
|
+
/**
|
|
49
|
+
* ⛔ The `item.` correction. In a transformation the context object IS the item, so `item.sku` resolves to nothing
|
|
50
|
+
* — silently, at run time, in a value that ends up empty. It is right one position away, in a pusher step, which
|
|
51
|
+
* is why authors write it here.
|
|
52
|
+
*/
|
|
53
|
+
if (environment.position === 'transformation-expression' &&
|
|
54
|
+
/(^|[^\w.])item\.$/.test(trimmed)) {
|
|
55
|
+
const bare = [...environment.roots.values()]
|
|
56
|
+
.filter((field) => field.name !== '__this')
|
|
57
|
+
.map((field) => offerFor(field));
|
|
58
|
+
return [
|
|
59
|
+
{
|
|
60
|
+
label: 'Remove the `item.` prefix',
|
|
61
|
+
insert: '',
|
|
62
|
+
detail: 'the context object IS the item here',
|
|
63
|
+
documentation: 'A transformation expression is evaluated with the item as its context, so its fields are referenced ' +
|
|
64
|
+
'bare — `sku`, not `item.sku`. The prefixed form resolves to nothing at run time, with no error.',
|
|
65
|
+
fix: {
|
|
66
|
+
removePrefix: 'item.',
|
|
67
|
+
why: 'A transformation is evaluated with the item as its context.',
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
...bare,
|
|
71
|
+
];
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* ⛔ The trailing PATH TOKEN, not the whole expression.
|
|
75
|
+
*
|
|
76
|
+
* `{{ puller.current.` splits on `.` into `['{{ puller', 'current', '']`, and `{{ puller` is a root that exists
|
|
77
|
+
* nowhere — so every nested walk inside a real template returned an empty list while the unit fixtures, which pass
|
|
78
|
+
* bare paths, all passed. The dialect opener and any preceding text are not part of the path.
|
|
79
|
+
*/
|
|
80
|
+
const token = trailingPathToken(trimmed);
|
|
81
|
+
const segments = token.split('.').filter((segment) => segment !== '');
|
|
82
|
+
// A path is walked only where the position allows nesting. ⚠️ A validation's field is interpolated into SQL, so a
|
|
83
|
+
// nested path there is a column name that does not exist, not a deeper lookup.
|
|
84
|
+
if (segments.length === 0 || !ALLOWS_NESTING[environment.position]) {
|
|
85
|
+
return finish([...environment.roots.values()].map((field) => offerFor(field)), environment, options);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* ⛔ A segment may carry an index — `lines[0]` — and the index is not part of the field's NAME.
|
|
89
|
+
*
|
|
90
|
+
* The first version looked up a field literally called `lines[0]`, found nothing, and returned an empty list for
|
|
91
|
+
* the exact path this engine had just told the author to insert: Story 8.4 makes an array offer insert its index
|
|
92
|
+
* precisely so the next completion resolves the element. Offering a path and then failing to walk it is worse than
|
|
93
|
+
* not offering it.
|
|
94
|
+
*/
|
|
95
|
+
const step = (shape, segment) => {
|
|
96
|
+
const match = /^([^[\]]+)((?:\[\d*\])*)$/.exec(segment);
|
|
97
|
+
if (!match)
|
|
98
|
+
return undefined;
|
|
99
|
+
let next = shape?.fields?.get(match[1])?.shape;
|
|
100
|
+
// One `element` hop per `[…]` written, so `matrix[0][0]` resolves as far as the shape actually goes.
|
|
101
|
+
for (let index = 0; index < (match[2]?.match(/\[/g)?.length ?? 0); index += 1) {
|
|
102
|
+
next = next?.kind === 'array' ? next.element : undefined;
|
|
103
|
+
}
|
|
104
|
+
return next;
|
|
105
|
+
};
|
|
106
|
+
const first = /^([^[\]]+)/.exec(segments[0])?.[1] ?? segments[0];
|
|
107
|
+
let shape = environment.roots.get(first)?.shape;
|
|
108
|
+
for (let index = 0; index < (segments[0].match(/\[/g)?.length ?? 0); index += 1) {
|
|
109
|
+
shape = shape?.kind === 'array' ? shape.element : undefined;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* ⛔ AC-3 — an already-complete path RE-OPENS at its own level.
|
|
113
|
+
*
|
|
114
|
+
* An author who has typed `item.sku` and asks again is asking *"what else is here"*, not *"is this valid"*. The
|
|
115
|
+
* walk therefore remembers the last level that had fields: landing on a scalar offers its SIBLINGS rather than the
|
|
116
|
+
* empty list a leaf would otherwise produce.
|
|
117
|
+
*/
|
|
118
|
+
let parent;
|
|
119
|
+
for (const segment of segments.slice(1)) {
|
|
120
|
+
if (shape?.kind === 'object' && shape.fields)
|
|
121
|
+
parent = shape;
|
|
122
|
+
shape = step(shape, segment);
|
|
123
|
+
}
|
|
124
|
+
if (shape?.kind === 'array')
|
|
125
|
+
shape = shape.element;
|
|
126
|
+
const level = shape?.kind === 'object' && shape.fields
|
|
127
|
+
? shape
|
|
128
|
+
: parent?.kind === 'object' && parent.fields
|
|
129
|
+
? parent
|
|
130
|
+
: undefined;
|
|
131
|
+
if (!level?.fields)
|
|
132
|
+
return [];
|
|
133
|
+
return finish([...level.fields.values()].map((field) =>
|
|
134
|
+
// Story 8.4: an array field inserts its index, so the NEXT completion resolves the element rather than the array.
|
|
135
|
+
offerFor(field, field.shape.kind === 'array' ? `${field.name}[0]` : field.name)), environment, options);
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* What acceptance has to finish: the co-filled field, the dialect wrapper, and the escalation.
|
|
139
|
+
*
|
|
140
|
+
* ⚠️ ONE place, applied to every return path. A first draft wrapped at one of the two returns only, so a root-level
|
|
141
|
+
* completion inserted a bare fragment while a nested one inserted a whole expression — the same list behaving two
|
|
142
|
+
* ways depending on how far the author had already typed.
|
|
143
|
+
*/
|
|
144
|
+
function finish(offers, environment, options) {
|
|
145
|
+
const withExtras = offers.map((offer) => {
|
|
146
|
+
const source = environment.roots.get(offer.label);
|
|
147
|
+
const dataType = environment.position === 'validation-field' &&
|
|
148
|
+
source?.provenance.kind === 'column'
|
|
149
|
+
? source.provenance.dataType
|
|
150
|
+
: undefined;
|
|
151
|
+
return {
|
|
152
|
+
...offer,
|
|
153
|
+
...(options.dialect && options.dialect !== 'none'
|
|
154
|
+
? { insert: wrapFor(options.dialect, offer.insert), wrapped: true }
|
|
155
|
+
: {}),
|
|
156
|
+
...(dataType ? { coFill: { field: 'dataType', value: dataType } } : {}),
|
|
157
|
+
};
|
|
158
|
+
});
|
|
159
|
+
const ceiling = options.listCeiling;
|
|
160
|
+
if (ceiling === undefined || withExtras.length <= ceiling)
|
|
161
|
+
return withExtras;
|
|
162
|
+
return [
|
|
163
|
+
...withExtras.slice(0, ceiling),
|
|
164
|
+
{
|
|
165
|
+
label: `${withExtras.length - ceiling} more…`,
|
|
166
|
+
insert: MORE_SENTINEL,
|
|
167
|
+
detail: 'Open the picker to search all of them',
|
|
168
|
+
},
|
|
169
|
+
];
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* The trailing run of path characters, scanned BACKWARDS from the end.
|
|
173
|
+
*
|
|
174
|
+
* ⛔ This was `/([\w.[\]]*)$/.exec(trimmed)`, and CodeQL was right (`js/polynomial-redos`, High). With `$`
|
|
175
|
+
* anchored and `*` unbounded, the engine retries the class from every position in the string, so a value of N
|
|
176
|
+
* dots costs O(N²) — and this runs on the line under the caret on every keystroke, which is the worst place in
|
|
177
|
+
* the extension to put a quadratic.
|
|
178
|
+
*
|
|
179
|
+
* A backward scan is what the regex was describing anyway: the longest suffix made only of word characters,
|
|
180
|
+
* `.`, `[` and `]`. One pass, no backtracking, byte-identical result for every input.
|
|
181
|
+
*
|
|
182
|
+
* Exported for `__tests__/redos.spec.ts`, which pins both halves: the same answer the regex gave, and a bound
|
|
183
|
+
* on the time it takes.
|
|
184
|
+
*/
|
|
185
|
+
export function trailingPathToken(text) {
|
|
186
|
+
let at = text.length;
|
|
187
|
+
while (at > 0 && isPathChar(text.charCodeAt(at - 1)))
|
|
188
|
+
at -= 1;
|
|
189
|
+
return text.slice(at);
|
|
190
|
+
}
|
|
191
|
+
/** `[\w.[\]]` — a word character, a dot, or a bracket. `\w` is `[A-Za-z0-9_]`, ASCII only, as the regex was. */
|
|
192
|
+
function isPathChar(code) {
|
|
193
|
+
return ((code >= 48 && code <= 57) || // 0-9
|
|
194
|
+
(code >= 65 && code <= 90) || // A-Z
|
|
195
|
+
(code >= 97 && code <= 122) || // a-z
|
|
196
|
+
code === 95 || // _
|
|
197
|
+
code === 46 || // .
|
|
198
|
+
code === 91 || // [
|
|
199
|
+
code === 93 // ]
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
//# sourceMappingURL=completion.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"completion.js","sourceRoot":"","sources":["../src/completion.ts"],"names":[],"mappings":"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"}
|
package/dist/detect.d.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { Position } from './position.js';
|
|
2
|
+
/**
|
|
3
|
+
* Which of the five alphabets a caret is in.
|
|
4
|
+
*
|
|
5
|
+
* ⛔ The classification is here, not in a surface, because getting it wrong is invisible: every position produces a
|
|
6
|
+
* plausible-looking list, and the author only finds out at run time when the path resolved to an empty string. Two
|
|
7
|
+
* surfaces classifying independently is two chances to be differently wrong.
|
|
8
|
+
*
|
|
9
|
+
* The rules, in the order they must be applied:
|
|
10
|
+
*
|
|
11
|
+
* | test | position |
|
|
12
|
+
* | --- | --- |
|
|
13
|
+
* | the path runs through `transformations` | `transformation-expression` |
|
|
14
|
+
* | the path runs through `validations` | `validation-field` |
|
|
15
|
+
* | the component is a pusher | `pusher-step` |
|
|
16
|
+
* | the puller declares a non-empty `steps` array | `new-kind-puller-step` |
|
|
17
|
+
* | otherwise | `legacy-puller-step` |
|
|
18
|
+
*
|
|
19
|
+
* ⚠️ Order matters. A transformation is declared under a task, which is reached through the same document as a
|
|
20
|
+
* puller's steps — so testing "is this a puller" first would classify every transformation expression in a puller's
|
|
21
|
+
* project as a puller step and offer `puller.*` where the context object is the item.
|
|
22
|
+
*/
|
|
23
|
+
export interface DetectRequest {
|
|
24
|
+
/** The component being edited, as authored. */
|
|
25
|
+
readonly component?: unknown;
|
|
26
|
+
/** The caret's path through the document, e.g. `['pullers', 0, 'pullSteps', 2, 'data', 'url']`. */
|
|
27
|
+
readonly yamlPath?: readonly (string | number)[];
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* ⛔ A non-empty `steps` array is the ONLY thing that decides the puller kind — `PullStepAccessor.IsNewKind`.
|
|
31
|
+
*
|
|
32
|
+
* Not the presence of the key, and not a `kind` field: a puller carrying `steps: []` is legacy, because the accessor
|
|
33
|
+
* tests the array's length. Reading the key alone would flip every such puller onto an alphabet that shares no root
|
|
34
|
+
* with the one it is written in.
|
|
35
|
+
*/
|
|
36
|
+
export declare function isNewKindPuller(component: unknown): boolean;
|
|
37
|
+
export declare function detectPosition(request: DetectRequest): Position | undefined;
|
|
38
|
+
//# sourceMappingURL=detect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect.d.ts","sourceRoot":"","sources":["../src/detect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,WAAW,aAAa;IAC5B,+CAA+C;IAC/C,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAC7B,mGAAmG;IACnG,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;CAClD;AAOD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,OAAO,GAAG,OAAO,CAG3D;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,aAAa,GAAG,QAAQ,GAAG,SAAS,CAsB3E"}
|
package/dist/detect.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
const record = (value) => typeof value === 'object' && value !== null && !Array.isArray(value)
|
|
2
|
+
? value
|
|
3
|
+
: undefined;
|
|
4
|
+
/**
|
|
5
|
+
* ⛔ A non-empty `steps` array is the ONLY thing that decides the puller kind — `PullStepAccessor.IsNewKind`.
|
|
6
|
+
*
|
|
7
|
+
* Not the presence of the key, and not a `kind` field: a puller carrying `steps: []` is legacy, because the accessor
|
|
8
|
+
* tests the array's length. Reading the key alone would flip every such puller onto an alphabet that shares no root
|
|
9
|
+
* with the one it is written in.
|
|
10
|
+
*/
|
|
11
|
+
export function isNewKindPuller(component) {
|
|
12
|
+
const steps = record(component)?.['steps'];
|
|
13
|
+
return Array.isArray(steps) && steps.length > 0;
|
|
14
|
+
}
|
|
15
|
+
export function detectPosition(request) {
|
|
16
|
+
const path = request.yamlPath ?? [];
|
|
17
|
+
if (path.length === 0)
|
|
18
|
+
return undefined;
|
|
19
|
+
if (path.includes('transformations'))
|
|
20
|
+
return 'transformation-expression';
|
|
21
|
+
if (path.includes('validations'))
|
|
22
|
+
return 'validation-field';
|
|
23
|
+
const component = record(record(request.component)?.['value'] ?? request.component);
|
|
24
|
+
if (path.includes('pushers') ||
|
|
25
|
+
record(component)?.['pushSteps'] !== undefined) {
|
|
26
|
+
return 'pusher-step';
|
|
27
|
+
}
|
|
28
|
+
if (path.includes('pullers') || component !== undefined) {
|
|
29
|
+
return isNewKindPuller(component)
|
|
30
|
+
? 'new-kind-puller-step'
|
|
31
|
+
: 'legacy-puller-step';
|
|
32
|
+
}
|
|
33
|
+
return undefined;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=detect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect.js","sourceRoot":"","sources":["../src/detect.ts"],"names":[],"mappings":"AA8BA,MAAM,MAAM,GAAG,CAAC,KAAc,EAAuC,EAAE,CACrE,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;IAClE,CAAC,CAAE,KAAiC;IACpC,CAAC,CAAC,SAAS,CAAC;AAEhB;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAAC,SAAkB;IAChD,MAAM,KAAK,GAAG,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC;IAC3C,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,OAAsB;IACnD,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,IAAI,EAAE,CAAC;IACpC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAExC,IAAI,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC;QAAE,OAAO,2BAA2B,CAAC;IACzE,IAAI,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC;QAAE,OAAO,kBAAkB,CAAC;IAE5D,MAAM,SAAS,GAAG,MAAM,CACtB,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,SAAS,CAC1D,CAAC;IACF,IACE,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC;QACxB,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,WAAW,CAAC,KAAK,SAAS,EAC9C,CAAC;QACD,OAAO,aAAa,CAAC;IACvB,CAAC;IACD,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QACxD,OAAO,eAAe,CAAC,SAAS,CAAC;YAC/B,CAAC,CAAC,sBAAsB;YACxB,CAAC,CAAC,oBAAoB,CAAC;IAC3B,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { type Position } from './position.js';
|
|
2
|
+
import { type Field, type Shape } from './shape.js';
|
|
3
|
+
/**
|
|
4
|
+
* The resolved environment: a map from context path to the shape at that path, and nothing else (Story 8.1 AC-1).
|
|
5
|
+
*
|
|
6
|
+
* "Nothing else" is the constraint that makes four surfaces possible. The moment this carried a completion item, a
|
|
7
|
+
* diagnostic range or a markdown string, it would belong to whichever surface that shape came from and the other three
|
|
8
|
+
* would each need their own pass.
|
|
9
|
+
*/
|
|
10
|
+
export interface Environment {
|
|
11
|
+
/** Which of the five alphabets this is — stated, because a surface must be able to say it (Story 8.2 AC-6). */
|
|
12
|
+
readonly position: Position;
|
|
13
|
+
/** The roots available here, by name. A root absent from this map does not exist at this caret. */
|
|
14
|
+
readonly roots: ReadonlyMap<string, Field>;
|
|
15
|
+
/**
|
|
16
|
+
* Why the environment is what it is, in one sentence an author can read. Not decoration: the two puller kinds are
|
|
17
|
+
* disjoint and look identical in the file, so "this puller declares a `steps` array, so it is a new-kind puller"
|
|
18
|
+
* is the difference between a confusing empty list and an understood one.
|
|
19
|
+
*/
|
|
20
|
+
readonly note: string;
|
|
21
|
+
}
|
|
22
|
+
/** What the caller must tell the engine about one step, so nothing here reads a file. */
|
|
23
|
+
export interface StepFacts {
|
|
24
|
+
readonly key: string;
|
|
25
|
+
/** The union of the step's `responseFilters` engine keys, where the document declares them. */
|
|
26
|
+
readonly outputs?: Shape;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Read a step's facts straight from the authored step, so a caller never has to derive the output shape itself.
|
|
30
|
+
*
|
|
31
|
+
* ⚠️ The whole point of `stepOutputs` living beside this is that `…current.STEP_X.<field>` is EXACT — the union of
|
|
32
|
+
* the step's response-filter keys, written twenty lines above the caret — rather than a guess. A caller that built
|
|
33
|
+
* `StepFacts` by hand would be re-deriving that, which is how two surfaces start disagreeing.
|
|
34
|
+
*/
|
|
35
|
+
export declare function stepFactsFrom(step: unknown): StepFacts;
|
|
36
|
+
/** What the caller must tell the engine about the component being edited. */
|
|
37
|
+
export interface ComponentFacts {
|
|
38
|
+
readonly collection: 'pullers' | 'pushers';
|
|
39
|
+
/** ⛔ A non-empty `steps` array is the ONLY thing that decides the puller kind (`PullStepAccessor.IsNewKind`). */
|
|
40
|
+
readonly hasStepsArray: boolean;
|
|
41
|
+
readonly optionKeys?: readonly string[];
|
|
42
|
+
readonly argumentKeys?: readonly string[];
|
|
43
|
+
/** The steps of each phase, in declaration order — the order IS the rule (§2.3). */
|
|
44
|
+
readonly phases?: Readonly<Record<string, readonly StepFacts[]>>;
|
|
45
|
+
}
|
|
46
|
+
export interface ResolveRequest {
|
|
47
|
+
readonly position: Position;
|
|
48
|
+
readonly component?: ComponentFacts;
|
|
49
|
+
/** The phase the caret is in, and how far along it — everything after this index is a forward reference. */
|
|
50
|
+
readonly phase?: string;
|
|
51
|
+
readonly stepIndex?: number;
|
|
52
|
+
/** The item as the caller has resolved it — columns, transformation output and hints, already layered. */
|
|
53
|
+
readonly item?: Shape;
|
|
54
|
+
/** The task's declared columns, flat, for the one position that takes nothing else. */
|
|
55
|
+
readonly columns?: readonly Field[];
|
|
56
|
+
readonly ownArguments?: readonly Field[];
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* ⛔ **Earlier steps in the phase, plus the step itself.**
|
|
60
|
+
*
|
|
61
|
+
* `StepIterator` calls the context handler in each step's success path with the accumulated outputs, so after
|
|
62
|
+
* `STEP_A` the phase holds `{STEP_A}` and after `STEP_B` it holds `{STEP_A, STEP_B}`. A forward reference resolves
|
|
63
|
+
* to nothing — no error, no diagnostic, an empty string in a URL or a body.
|
|
64
|
+
*
|
|
65
|
+
* The step ITSELF is included, and that is not an off-by-one: each pagination iteration calls `ExecuteSteps` afresh
|
|
66
|
+
* with an empty outputs dict, so at the top of page 2 `puller.current` still holds page 1's values. Reading
|
|
67
|
+
* `puller.lastToken.PULL_DATA.offset` from inside `PULL_DATA` is the pagination idiom, not a mistake — it is why the
|
|
68
|
+
* alias is called `lastToken`.
|
|
69
|
+
*/
|
|
70
|
+
export declare function visibleSteps(steps: readonly StepFacts[], stepIndex: number | undefined): readonly StepFacts[];
|
|
71
|
+
/**
|
|
72
|
+
* Resolve one caret into one environment.
|
|
73
|
+
*
|
|
74
|
+
* ⛔ Pure. It reads no file, spawns nothing and imports nothing from an editor — Story 8.1 AC-5, and the reason the
|
|
75
|
+
* CLI and the extension cannot disagree: there is one function and they both call it. A test asserting "the editor
|
|
76
|
+
* and the CLI produce the same environment" is only worth writing because it could otherwise have been two engines.
|
|
77
|
+
*/
|
|
78
|
+
export declare function resolveEnvironment(request: ResolveRequest): Environment;
|
|
79
|
+
//# sourceMappingURL=environment.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"environment.d.ts","sourceRoot":"","sources":["../src/environment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAkB,MAAM,eAAe,CAAC;AAE9D,OAAO,EAML,KAAK,KAAK,EACV,KAAK,KAAK,EACX,MAAM,YAAY,CAAC;AAEpB;;;;;;GAMG;AACH,MAAM,WAAW,WAAW;IAC1B,+GAA+G;IAC/G,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,mGAAmG;IACnG,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAC3C;;;;OAIG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAoHD,yFAAyF;AACzF,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,+FAA+F;IAC/F,QAAQ,CAAC,OAAO,CAAC,EAAE,KAAK,CAAC;CAC1B;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,OAAO,GAAG,SAAS,CAGtD;AAED,6EAA6E;AAC7E,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,UAAU,EAAE,SAAS,GAAG,SAAS,CAAC;IAC3C,iHAAiH;IACjH,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1C,oFAAoF;IACpF,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,SAAS,EAAE,CAAC,CAAC,CAAC;CAClE;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,SAAS,CAAC,EAAE,cAAc,CAAC;IACpC,4GAA4G;IAC5G,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,0GAA0G;IAC1G,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC;IACtB,uFAAuF;IACvF,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,KAAK,EAAE,CAAC;IACpC,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,KAAK,EAAE,CAAC;CAC1C;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,SAAS,SAAS,EAAE,EAC3B,SAAS,EAAE,MAAM,GAAG,SAAS,GAC5B,SAAS,SAAS,EAAE,CAGtB;AA2KD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,cAAc,GAAG,WAAW,CAmIvE"}
|