@suss/recognize 0.12.0 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +294 -2
- package/dist/ast.d.cts +1 -1
- package/dist/ast.d.ts +1 -1
- package/dist/chain-BaxjT_-k.d.cts +530 -0
- package/dist/chain-BaxjT_-k.d.ts +530 -0
- package/dist/index.cjs +385 -85
- package/dist/index.d.cts +141 -40
- package/dist/index.d.ts +141 -40
- package/dist/index.js +383 -85
- package/package.json +4 -3
- package/dist/chain-DTSij2Mn.d.cts +0 -197
- package/dist/chain-DTSij2Mn.d.ts +0 -197
package/dist/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// src/compile.ts
|
|
2
2
|
import { storageBinding } from "@suss/behavioral-ir";
|
|
3
|
+
import { readSqlAccess, sqlFromParts } from "@suss/sql";
|
|
3
4
|
|
|
4
5
|
// src/ops.ts
|
|
5
6
|
function declaredBy(...importedFrom) {
|
|
@@ -14,104 +15,297 @@ function opsIn(ctx) {
|
|
|
14
15
|
}
|
|
15
16
|
|
|
16
17
|
// src/compile.ts
|
|
18
|
+
var MAX_RECEIVER_HOPS = 8;
|
|
17
19
|
function compile(chain, recognition) {
|
|
18
20
|
return (_call, ctx) => {
|
|
19
21
|
const ops = opsIn(ctx);
|
|
20
|
-
|
|
22
|
+
const methods = methodsIn(chain);
|
|
23
|
+
if (ops === null || methods === null) {
|
|
21
24
|
return null;
|
|
22
25
|
}
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
return
|
|
26
|
+
for (const subject of subjectsOf(chain, ops)) {
|
|
27
|
+
const method = operationOf(subject);
|
|
28
|
+
const meaning = method === null ? null : listed(methods, method);
|
|
29
|
+
if (method === null || meaning === null || !startsHere(chain, subject)) {
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
return YIELD[chain.ending.yields]({
|
|
33
|
+
ops,
|
|
34
|
+
subject,
|
|
35
|
+
method,
|
|
36
|
+
meaning,
|
|
37
|
+
chain,
|
|
38
|
+
recognition
|
|
39
|
+
});
|
|
30
40
|
}
|
|
31
|
-
return
|
|
32
|
-
ops,
|
|
33
|
-
method,
|
|
34
|
-
meaning,
|
|
35
|
-
chain,
|
|
36
|
-
recognition
|
|
37
|
-
});
|
|
41
|
+
return null;
|
|
38
42
|
};
|
|
39
43
|
}
|
|
40
|
-
function
|
|
41
|
-
const link = chain.links.find(
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
function linkIn(chain, asks) {
|
|
45
|
+
const link = chain.links.find((candidate) => candidate.asks === asks);
|
|
46
|
+
return link ?? null;
|
|
47
|
+
}
|
|
48
|
+
function methodsIn(chain) {
|
|
49
|
+
return linkIn(chain, "methods");
|
|
50
|
+
}
|
|
51
|
+
function operationOf(ops) {
|
|
52
|
+
return ops.method() ?? ops.calleeText();
|
|
53
|
+
}
|
|
54
|
+
function listed(link, method) {
|
|
47
55
|
if (!link.ignoringCase) {
|
|
48
56
|
return link.table[method] ?? null;
|
|
49
57
|
}
|
|
50
58
|
return link.table[method.toLowerCase()] ?? null;
|
|
51
59
|
}
|
|
60
|
+
function subjectsOf(chain, ops) {
|
|
61
|
+
const link = linkIn(chain, "subject");
|
|
62
|
+
return link === null ? [ops] : walk([ops], link.of);
|
|
63
|
+
}
|
|
64
|
+
var STEP = {
|
|
65
|
+
receiver: (step, ops) => receiversOf(ops, step.method),
|
|
66
|
+
argument: (step, ops) => argumentsOf(ops, step)
|
|
67
|
+
};
|
|
68
|
+
function walk(from, steps) {
|
|
69
|
+
let reached = [...from];
|
|
70
|
+
for (const step of steps) {
|
|
71
|
+
reached = reached.flatMap((ops) => STEP[step.to](step, ops));
|
|
72
|
+
}
|
|
73
|
+
return reached;
|
|
74
|
+
}
|
|
75
|
+
function receiversOf(ops, method) {
|
|
76
|
+
let step = ops.receiver();
|
|
77
|
+
for (let hops = 0; step !== null && hops < MAX_RECEIVER_HOPS; hops += 1) {
|
|
78
|
+
if (method === void 0 || step.method() === method) {
|
|
79
|
+
return [step];
|
|
80
|
+
}
|
|
81
|
+
step = step.receiver();
|
|
82
|
+
}
|
|
83
|
+
return [];
|
|
84
|
+
}
|
|
85
|
+
function argumentsOf(ops, step) {
|
|
86
|
+
const found = [];
|
|
87
|
+
for (const index of positions(ops, step.at)) {
|
|
88
|
+
const argument = ops.argument(index);
|
|
89
|
+
if (argument !== null && cameFrom(argument, step.origin)) {
|
|
90
|
+
found.push(argument);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return found;
|
|
94
|
+
}
|
|
95
|
+
function cameFrom(argument, origin) {
|
|
96
|
+
return origin === void 0 || argument.isFrom(origin);
|
|
97
|
+
}
|
|
98
|
+
function positions(ops, pick) {
|
|
99
|
+
if (typeof pick === "number") {
|
|
100
|
+
return [pick];
|
|
101
|
+
}
|
|
102
|
+
const first = "at" in pick ? pick.at : pick.from;
|
|
103
|
+
const last = "at" in pick ? pick.at + 1 : ops.argumentCount();
|
|
104
|
+
const found = [];
|
|
105
|
+
for (let index = first; index < last; index += 1) {
|
|
106
|
+
found.push(index);
|
|
107
|
+
}
|
|
108
|
+
return found;
|
|
109
|
+
}
|
|
52
110
|
var START = {
|
|
53
111
|
receiver: (start, ops) => ops.receiverIsFrom(start.origin)
|
|
54
112
|
};
|
|
55
|
-
function startsHere(chain,
|
|
113
|
+
function startsHere(chain, subject) {
|
|
56
114
|
return chain.links.every(
|
|
57
|
-
(link) => link.asks === "start" ? START[link.at.starts](link.at,
|
|
115
|
+
(link) => link.asks === "start" ? START[link.at.starts](link.at, subject) : true
|
|
58
116
|
);
|
|
59
117
|
}
|
|
60
118
|
var YIELD = {
|
|
61
|
-
storageAccess
|
|
119
|
+
storageAccess,
|
|
120
|
+
sqlAccess
|
|
62
121
|
};
|
|
63
122
|
function storageAccess(matched) {
|
|
64
|
-
const {
|
|
123
|
+
const { subject, chain } = matched;
|
|
124
|
+
const meaning = matched.meaning;
|
|
125
|
+
const unsettled = chain.ending.unsettledName;
|
|
126
|
+
const kind = kindOf(meaning.kind, subject, unsettled);
|
|
127
|
+
const link = linkIn(chain, "input");
|
|
128
|
+
const input = link === null ? null : statedValue(subject, link.at);
|
|
129
|
+
if (kind === null || link !== null && input === null) {
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
return reachedBy(chain, subject, unsettled).map(
|
|
133
|
+
(reached) => accessEffect(matched, { input, kind, reached, unsettled })
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
function accessEffect(matched, access) {
|
|
137
|
+
const { ops, subject, method, chain, recognition } = matched;
|
|
138
|
+
const meaning = matched.meaning;
|
|
65
139
|
const ending = chain.ending;
|
|
66
|
-
const
|
|
67
|
-
const
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
}
|
|
140
|
+
const { input, kind, reached, unsettled } = access;
|
|
141
|
+
const stated = { input, entry: reached.entry, kind };
|
|
142
|
+
const selector = namesFor(meaning.selector, subject, stated, unsettled);
|
|
143
|
+
const fields = namesFor(meaning.fields, subject, stated, unsettled);
|
|
144
|
+
return {
|
|
145
|
+
type: "interaction",
|
|
146
|
+
binding: storageBinding({
|
|
147
|
+
recognition,
|
|
148
|
+
storageSystem: ending.system,
|
|
149
|
+
...ending.transport === void 0 ? {} : { transport: ending.transport },
|
|
150
|
+
scope: ending.scope,
|
|
151
|
+
container: reached.entry === null ? containerOf(chain, selector, subject, unsettled) : reached.container,
|
|
152
|
+
accessPath: accessPathOf(chain, subject, unsettled)
|
|
153
|
+
}),
|
|
154
|
+
callee: ops.calleeText(),
|
|
155
|
+
interaction: {
|
|
156
|
+
class: "storage-access",
|
|
157
|
+
kind,
|
|
158
|
+
fields,
|
|
159
|
+
operation: namesAt(subject, meaning.operation, unsettled)[0] ?? method,
|
|
160
|
+
...selector.length > 0 ? { selector } : {}
|
|
88
161
|
}
|
|
89
|
-
|
|
162
|
+
};
|
|
90
163
|
}
|
|
91
|
-
function
|
|
92
|
-
const link = chain
|
|
93
|
-
|
|
94
|
-
)
|
|
95
|
-
|
|
164
|
+
function reachedBy(chain, subject, unsettled) {
|
|
165
|
+
const link = linkIn(chain, "containers");
|
|
166
|
+
const map = link === null ? null : statedValue(subject, link.in);
|
|
167
|
+
if (map === null) {
|
|
168
|
+
return [{ container: null, entry: null }];
|
|
169
|
+
}
|
|
170
|
+
return map.entries(unsettled).map((entry) => ({ container: entry.key, entry: entry.value }));
|
|
171
|
+
}
|
|
172
|
+
function kindOf(kind, subject, unsettled) {
|
|
173
|
+
if (typeof kind === "string") {
|
|
174
|
+
return kind;
|
|
175
|
+
}
|
|
176
|
+
const asked = kind;
|
|
177
|
+
const [answer] = namesAt(subject, asked.asks, unsettled);
|
|
178
|
+
const said = answer === void 0 ? void 0 : asked.means[answer];
|
|
179
|
+
return said ?? asked.otherwise ?? null;
|
|
180
|
+
}
|
|
181
|
+
function containerOf(chain, selector, subject, unsettled) {
|
|
182
|
+
const link = linkIn(chain, "container");
|
|
183
|
+
if (link === null) {
|
|
96
184
|
return selector[0] ?? null;
|
|
97
185
|
}
|
|
98
|
-
|
|
186
|
+
if ("from" in link) {
|
|
187
|
+
return link.from(selector, subject);
|
|
188
|
+
}
|
|
189
|
+
return namesAt(subject, link.argument, unsettled)[0] ?? null;
|
|
190
|
+
}
|
|
191
|
+
function accessPathOf(chain, subject, unsettled) {
|
|
192
|
+
const link = linkIn(chain, "accessPath");
|
|
193
|
+
return link === null ? null : namesAt(subject, link.argument, unsettled)[0] ?? null;
|
|
194
|
+
}
|
|
195
|
+
function statedValue(subject, pick) {
|
|
196
|
+
for (const ops of walk([subject], pick.of ?? [])) {
|
|
197
|
+
const stated = ops.valueAt(pick.at);
|
|
198
|
+
if (stated === null) {
|
|
199
|
+
continue;
|
|
200
|
+
}
|
|
201
|
+
if (pick.property === void 0) {
|
|
202
|
+
return stated;
|
|
203
|
+
}
|
|
204
|
+
for (const property of pick.property) {
|
|
205
|
+
const inside = stated.property(property);
|
|
206
|
+
if (inside !== null) {
|
|
207
|
+
return inside;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
return null;
|
|
99
212
|
}
|
|
100
|
-
|
|
213
|
+
var NOTHING_STATED = {
|
|
214
|
+
text: () => null,
|
|
215
|
+
flag: () => null,
|
|
216
|
+
entries: () => [],
|
|
217
|
+
items: () => [],
|
|
218
|
+
property: () => null,
|
|
219
|
+
parts: () => null,
|
|
220
|
+
holes: () => []
|
|
221
|
+
};
|
|
222
|
+
function namesFor(says, subject, stated, unsettled) {
|
|
223
|
+
if (says === void 0) {
|
|
224
|
+
return [];
|
|
225
|
+
}
|
|
226
|
+
if (Array.isArray(says)) {
|
|
227
|
+
return [...says];
|
|
228
|
+
}
|
|
229
|
+
if (typeof says === "function") {
|
|
230
|
+
const input2 = stated.input;
|
|
231
|
+
return input2 === null ? [] : [...says({ ...stated, input: input2 })];
|
|
232
|
+
}
|
|
233
|
+
const pointed = says;
|
|
234
|
+
if (!("by" in pointed)) {
|
|
235
|
+
return namesAt(subject, pointed, unsettled);
|
|
236
|
+
}
|
|
237
|
+
const input = statedValue(subject, pointed.of) ?? NOTHING_STATED;
|
|
238
|
+
return [...pointed.by({ ...stated, input })];
|
|
239
|
+
}
|
|
240
|
+
function namesAt(subject, pick, unsettled) {
|
|
101
241
|
if (pick === void 0) {
|
|
102
242
|
return [];
|
|
103
243
|
}
|
|
104
|
-
const last = "at" in pick ? pick.at + 1 : ops.argumentCount();
|
|
105
|
-
const first = "at" in pick ? pick.at : pick.from;
|
|
106
244
|
const names = [];
|
|
107
|
-
for (
|
|
108
|
-
const
|
|
109
|
-
|
|
110
|
-
|
|
245
|
+
for (const ops of walk([subject], pick.of ?? [])) {
|
|
246
|
+
for (const index of positions(ops, pick)) {
|
|
247
|
+
const name = nameOf(ops, pick, index, unsettled);
|
|
248
|
+
if (name !== null) {
|
|
249
|
+
names.push(name);
|
|
250
|
+
}
|
|
111
251
|
}
|
|
112
252
|
}
|
|
113
253
|
return names;
|
|
114
254
|
}
|
|
255
|
+
function nameOf(ops, pick, index, unsettled) {
|
|
256
|
+
if (pick.property === void 0) {
|
|
257
|
+
return ops.nameAt(index, unsettled);
|
|
258
|
+
}
|
|
259
|
+
for (const property of pick.property) {
|
|
260
|
+
const name = ops.propertyAt(index, property, unsettled);
|
|
261
|
+
if (name !== null) {
|
|
262
|
+
return name;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
return null;
|
|
266
|
+
}
|
|
267
|
+
function sqlAccess(matched) {
|
|
268
|
+
const { ops, subject, method, chain, recognition } = matched;
|
|
269
|
+
const ending = chain.ending;
|
|
270
|
+
const stated = statedValue(subject, matched.meaning.statement);
|
|
271
|
+
const parts = stated?.parts() ?? null;
|
|
272
|
+
if (stated === null || parts === null) {
|
|
273
|
+
return null;
|
|
274
|
+
}
|
|
275
|
+
const statement = sqlFromParts(parts, namesInHoles(chain, stated));
|
|
276
|
+
const accesses = readSqlAccess(statement, { dialect: ending.dialect });
|
|
277
|
+
return accesses.length === 0 ? null : accesses.map((access) => ({
|
|
278
|
+
type: "interaction",
|
|
279
|
+
binding: storageBinding({
|
|
280
|
+
recognition,
|
|
281
|
+
storageSystem: ending.system,
|
|
282
|
+
...ending.transport === void 0 ? {} : { transport: ending.transport },
|
|
283
|
+
scope: ending.scope,
|
|
284
|
+
container: access.table
|
|
285
|
+
}),
|
|
286
|
+
callee: ops.calleeText(),
|
|
287
|
+
interaction: {
|
|
288
|
+
class: "storage-access",
|
|
289
|
+
kind: access.kind,
|
|
290
|
+
fields: access.fields,
|
|
291
|
+
...access.selector.length > 0 ? { selector: access.selector } : {},
|
|
292
|
+
operation: method
|
|
293
|
+
}
|
|
294
|
+
}));
|
|
295
|
+
}
|
|
296
|
+
function namesInHoles(chain, stated) {
|
|
297
|
+
const link = linkIn(chain, "interpolates");
|
|
298
|
+
if (link === null) {
|
|
299
|
+
return [];
|
|
300
|
+
}
|
|
301
|
+
return stated.holes().map((hole) => nameInHole(hole, link));
|
|
302
|
+
}
|
|
303
|
+
function nameInHole(hole, link) {
|
|
304
|
+
if (hole === null || link.from !== void 0 && !hole.isFrom(link.from)) {
|
|
305
|
+
return null;
|
|
306
|
+
}
|
|
307
|
+
return namesAt(hole, link.named, "nothing")[0] ?? null;
|
|
308
|
+
}
|
|
115
309
|
|
|
116
310
|
// src/example.ts
|
|
117
311
|
function runExamples(pack2, run) {
|
|
@@ -134,24 +328,35 @@ function examplesMissing(pack2) {
|
|
|
134
328
|
}
|
|
135
329
|
|
|
136
330
|
// src/pack.ts
|
|
331
|
+
var DISPATCHED_ON = {
|
|
332
|
+
storageAccess: "invocation",
|
|
333
|
+
sqlAccess: "access"
|
|
334
|
+
};
|
|
335
|
+
function walkedBy(chains, walk2, recognizedAs) {
|
|
336
|
+
return chains.filter((chain) => DISPATCHED_ON[chain.ending.yields] === walk2).map((chain) => compile(chain, recognizedAs));
|
|
337
|
+
}
|
|
137
338
|
function pack(name, matches, spec) {
|
|
138
339
|
const chains = matches.map((match) => match.declared);
|
|
139
|
-
const
|
|
140
|
-
(chain) => compile(chain, spec.recognizedAs)
|
|
141
|
-
);
|
|
340
|
+
const access = walkedBy(chains, "access", spec.recognizedAs);
|
|
142
341
|
return {
|
|
143
342
|
name,
|
|
144
343
|
languages: spec.languages,
|
|
145
344
|
...spec.version === void 0 ? {} : { version: spec.version },
|
|
146
|
-
protocol: protocolOf(chains),
|
|
345
|
+
protocol: spec.protocol ?? protocolOf(chains),
|
|
147
346
|
discovery: [],
|
|
148
347
|
terminals: [],
|
|
149
348
|
inputMapping: { type: "positionalParams", params: [] },
|
|
150
|
-
requiresImport:
|
|
151
|
-
|
|
152
|
-
|
|
349
|
+
requiresImport: [
|
|
350
|
+
.../* @__PURE__ */ new Set([...gateOf(chains), ...spec.requiresImport ?? []])
|
|
351
|
+
],
|
|
352
|
+
invocationRecognizers: walkedBy(chains, "invocation", spec.recognizedAs),
|
|
353
|
+
...access.length === 0 ? {} : { accessRecognizers: access },
|
|
354
|
+
declarations: declarationsIn(matches)
|
|
153
355
|
};
|
|
154
356
|
}
|
|
357
|
+
function declarationsIn(matches) {
|
|
358
|
+
return { declarations: matches.map((match) => describe(match.declared)) };
|
|
359
|
+
}
|
|
155
360
|
function protocolOf(chains) {
|
|
156
361
|
const wires = new Set(
|
|
157
362
|
chains.map((chain) => chain.ending.transport ?? chain.ending.system)
|
|
@@ -167,42 +372,97 @@ function protocolOf(chains) {
|
|
|
167
372
|
function gateOf(chains) {
|
|
168
373
|
const modules = /* @__PURE__ */ new Set();
|
|
169
374
|
for (const chain of chains) {
|
|
170
|
-
for (const
|
|
171
|
-
|
|
172
|
-
continue;
|
|
173
|
-
}
|
|
174
|
-
for (const module of link.at.origin.importedFrom) {
|
|
375
|
+
for (const origin of originsIn(chain)) {
|
|
376
|
+
for (const module of origin.importedFrom) {
|
|
175
377
|
modules.add(module);
|
|
176
378
|
}
|
|
177
379
|
}
|
|
178
380
|
}
|
|
179
381
|
return [...modules];
|
|
180
382
|
}
|
|
383
|
+
function originsIn(chain) {
|
|
384
|
+
const found = [];
|
|
385
|
+
for (const link of chain.links) {
|
|
386
|
+
if (link.asks === "start" && link.at.starts === "receiver") {
|
|
387
|
+
found.push(link.at.origin);
|
|
388
|
+
}
|
|
389
|
+
if (link.asks === "interpolates" && link.from !== void 0) {
|
|
390
|
+
found.push(link.from);
|
|
391
|
+
}
|
|
392
|
+
if (link.asks !== "subject") {
|
|
393
|
+
continue;
|
|
394
|
+
}
|
|
395
|
+
for (const step of link.of) {
|
|
396
|
+
if (step.to === "argument" && step.origin !== void 0) {
|
|
397
|
+
found.push(step.origin);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
return found;
|
|
402
|
+
}
|
|
181
403
|
function describe(chain) {
|
|
182
|
-
const
|
|
404
|
+
const links = chain.links.filter(isFunctionLink);
|
|
405
|
+
const written = [
|
|
406
|
+
...links.map((link) => ({
|
|
407
|
+
asks: link.asks,
|
|
408
|
+
reachesAst: link.from.reachesAst === true
|
|
409
|
+
})),
|
|
410
|
+
...rulesIn(chain)
|
|
411
|
+
];
|
|
183
412
|
return {
|
|
184
413
|
name: chain.ending.system,
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
414
|
+
// A method table with a rule inside it is still a table, so that
|
|
415
|
+
// link stays counted as data and the rule is priced beside it.
|
|
416
|
+
dataLinks: chain.links.length - links.length,
|
|
417
|
+
functionLinks: written.map((rule) => rule.asks),
|
|
418
|
+
astLinks: written.filter((rule) => rule.reachesAst).map((rule) => rule.asks),
|
|
188
419
|
example: chain.example
|
|
189
420
|
};
|
|
190
421
|
}
|
|
191
422
|
function isFunctionLink(link) {
|
|
192
|
-
return link.asks === "container";
|
|
423
|
+
return link.asks === "container" && "from" in link;
|
|
424
|
+
}
|
|
425
|
+
function rulesIn(chain) {
|
|
426
|
+
const link = chain.links.find(
|
|
427
|
+
(candidate) => candidate.asks === "methods"
|
|
428
|
+
);
|
|
429
|
+
const written = /* @__PURE__ */ new Map();
|
|
430
|
+
for (const method of Object.values(link?.table ?? {})) {
|
|
431
|
+
for (const asks of ["selector", "fields"]) {
|
|
432
|
+
const rule = ruleFor(method[asks]);
|
|
433
|
+
if (rule !== null) {
|
|
434
|
+
written.set(asks, rule);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
return [...written].map(([asks, from]) => ({
|
|
439
|
+
asks,
|
|
440
|
+
reachesAst: from.reachesAst === true
|
|
441
|
+
}));
|
|
442
|
+
}
|
|
443
|
+
function ruleFor(says) {
|
|
444
|
+
if (typeof says === "function") {
|
|
445
|
+
return says;
|
|
446
|
+
}
|
|
447
|
+
if (says === void 0 || Array.isArray(says)) {
|
|
448
|
+
return null;
|
|
449
|
+
}
|
|
450
|
+
const pointed = says;
|
|
451
|
+
return "by" in pointed ? pointed.by : null;
|
|
193
452
|
}
|
|
194
453
|
|
|
195
|
-
// src/
|
|
196
|
-
function
|
|
454
|
+
// src/sqlStatements.ts
|
|
455
|
+
function sqlStatements(spec) {
|
|
197
456
|
const ending = {
|
|
198
|
-
yields: "
|
|
457
|
+
yields: "sqlAccess",
|
|
199
458
|
system: spec.system,
|
|
200
459
|
...spec.transport === void 0 ? {} : { transport: spec.transport },
|
|
201
460
|
scope: spec.scope ?? "default",
|
|
202
|
-
|
|
461
|
+
dialect: spec.dialect
|
|
203
462
|
};
|
|
463
|
+
const client = spec.client;
|
|
204
464
|
return chainFrom({
|
|
205
|
-
links: [{ asks: "start", at: { starts: "receiver", origin:
|
|
465
|
+
links: client === void 0 ? [] : [{ asks: "start", at: { starts: "receiver", origin: client } }],
|
|
206
466
|
ending,
|
|
207
467
|
example: null
|
|
208
468
|
});
|
|
@@ -216,17 +476,55 @@ function chainFrom(declared) {
|
|
|
216
476
|
table,
|
|
217
477
|
ignoringCase: options?.ignoringCase ?? false
|
|
218
478
|
}),
|
|
219
|
-
|
|
479
|
+
interpolating: (says) => adding({ asks: "interpolates", ...says }),
|
|
220
480
|
example: (code) => chainFrom({ ...declared, example: code })
|
|
221
481
|
};
|
|
222
482
|
}
|
|
483
|
+
|
|
484
|
+
// src/storage.ts
|
|
485
|
+
function storageCalls(spec) {
|
|
486
|
+
const ending = {
|
|
487
|
+
yields: "storageAccess",
|
|
488
|
+
system: spec.system,
|
|
489
|
+
...spec.transport === void 0 ? {} : { transport: spec.transport },
|
|
490
|
+
scope: spec.scope ?? "default",
|
|
491
|
+
unsettledName: spec.unsettledName ?? "reference"
|
|
492
|
+
};
|
|
493
|
+
const client = spec.client;
|
|
494
|
+
return chainFrom2({
|
|
495
|
+
links: client === void 0 ? [] : [{ asks: "start", at: { starts: "receiver", origin: client } }],
|
|
496
|
+
ending,
|
|
497
|
+
example: null
|
|
498
|
+
});
|
|
499
|
+
}
|
|
500
|
+
function chainFrom2(declared) {
|
|
501
|
+
const adding = (link) => chainFrom2({ ...declared, links: [...declared.links, link] });
|
|
502
|
+
return {
|
|
503
|
+
declared,
|
|
504
|
+
about: (...of) => adding({ asks: "subject", of }),
|
|
505
|
+
methods: (table, options) => adding({
|
|
506
|
+
asks: "methods",
|
|
507
|
+
table,
|
|
508
|
+
ignoringCase: options?.ignoringCase ?? false
|
|
509
|
+
}),
|
|
510
|
+
container: (says) => adding(
|
|
511
|
+
typeof says === "function" ? { asks: "container", from: says } : { asks: "container", argument: says }
|
|
512
|
+
),
|
|
513
|
+
accessPath: (says) => adding({ asks: "accessPath", argument: says }),
|
|
514
|
+
containersIn: (says) => adding({ asks: "containers", in: says }),
|
|
515
|
+
input: (says) => adding({ asks: "input", at: says }),
|
|
516
|
+
example: (code) => chainFrom2({ ...declared, example: code })
|
|
517
|
+
};
|
|
518
|
+
}
|
|
223
519
|
export {
|
|
224
520
|
compile,
|
|
225
521
|
constructedFrom,
|
|
522
|
+
declarationsIn,
|
|
226
523
|
declaredBy,
|
|
227
524
|
examplesMissing,
|
|
228
525
|
opsIn,
|
|
229
526
|
pack,
|
|
230
527
|
runExamples,
|
|
528
|
+
sqlStatements,
|
|
231
529
|
storageCalls
|
|
232
530
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@suss/recognize",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Write a pack as data: a chain of named links that any language adapter with the executor ops can run.",
|
|
6
6
|
"keywords": [
|
|
@@ -49,8 +49,9 @@
|
|
|
49
49
|
"typecheck": "tsc --noEmit"
|
|
50
50
|
},
|
|
51
51
|
"dependencies": {
|
|
52
|
-
"@suss/behavioral-ir": "0.
|
|
53
|
-
"@suss/extractor": "0.
|
|
52
|
+
"@suss/behavioral-ir": "0.13.0",
|
|
53
|
+
"@suss/extractor": "0.13.0",
|
|
54
|
+
"@suss/sql": "0.13.0"
|
|
54
55
|
},
|
|
55
56
|
"devDependencies": {
|
|
56
57
|
"tsup": "*",
|