@sanoma-ai/workflows 0.0.0-stage → 0.2.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/LICENSE +105 -0
- package/README.md +544 -2
- package/dist/apply-steps.d.ts +6 -0
- package/dist/apply-steps.js +93 -0
- package/dist/apply-steps.js.map +1 -0
- package/dist/apply.d.ts +197 -0
- package/dist/apply.js +470 -0
- package/dist/apply.js.map +1 -0
- package/dist/approvals.d.ts +46 -0
- package/dist/approvals.js +111 -0
- package/dist/approvals.js.map +1 -0
- package/dist/ast.d.ts +57 -0
- package/dist/ast.js +81 -0
- package/dist/ast.js.map +1 -0
- package/dist/call.d.ts +37 -0
- package/dist/call.js +417 -0
- package/dist/call.js.map +1 -0
- package/dist/client.d.ts +203 -0
- package/dist/client.js +457 -0
- package/dist/client.js.map +1 -0
- package/dist/config.d.ts +126 -0
- package/dist/config.js +264 -0
- package/dist/config.js.map +1 -0
- package/dist/credentials.d.ts +55 -0
- package/dist/credentials.js +261 -0
- package/dist/credentials.js.map +1 -0
- package/dist/cucumber.d.ts +64 -0
- package/dist/cucumber.js +158 -0
- package/dist/cucumber.js.map +1 -0
- package/dist/datafile.d.ts +71 -0
- package/dist/datafile.js +380 -0
- package/dist/datafile.js.map +1 -0
- package/dist/db.d.ts +58 -0
- package/dist/db.js +179 -0
- package/dist/db.js.map +1 -0
- package/dist/define.d.ts +205 -0
- package/dist/define.js +103 -0
- package/dist/define.js.map +1 -0
- package/dist/describe.d.ts +141 -0
- package/dist/describe.js +135 -0
- package/dist/describe.js.map +1 -0
- package/dist/drift.d.ts +127 -0
- package/dist/drift.js +167 -0
- package/dist/drift.js.map +1 -0
- package/dist/env.d.ts +49 -0
- package/dist/env.js +83 -0
- package/dist/env.js.map +1 -0
- package/dist/errors.d.ts +88 -0
- package/dist/errors.js +148 -0
- package/dist/errors.js.map +1 -0
- package/dist/expectations.d.ts +26 -0
- package/dist/expectations.js +162 -0
- package/dist/expectations.js.map +1 -0
- package/dist/fake.d.ts +55 -0
- package/dist/fake.js +87 -0
- package/dist/fake.js.map +1 -0
- package/dist/fill.d.ts +9 -0
- package/dist/fill.js +17 -0
- package/dist/fill.js.map +1 -0
- package/dist/host.d.ts +56 -0
- package/dist/host.js +45 -0
- package/dist/host.js.map +1 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.js +29 -0
- package/dist/index.js.map +1 -0
- package/dist/ledger.d.ts +217 -0
- package/dist/ledger.js +251 -0
- package/dist/ledger.js.map +1 -0
- package/dist/lint.d.ts +32 -0
- package/dist/lint.js +168 -0
- package/dist/lint.js.map +1 -0
- package/dist/lockfile.d.ts +36 -0
- package/dist/lockfile.js +69 -0
- package/dist/lockfile.js.map +1 -0
- package/dist/log.d.ts +24 -0
- package/dist/log.js +83 -0
- package/dist/log.js.map +1 -0
- package/dist/op.d.ts +260 -0
- package/dist/op.js +188 -0
- package/dist/op.js.map +1 -0
- package/dist/outline.d.ts +179 -0
- package/dist/outline.js +506 -0
- package/dist/outline.js.map +1 -0
- package/dist/paths.d.ts +11 -0
- package/dist/paths.js +30 -0
- package/dist/paths.js.map +1 -0
- package/dist/plugin.d.ts +28 -0
- package/dist/plugin.js +25 -0
- package/dist/plugin.js.map +1 -0
- package/dist/policy.d.ts +114 -0
- package/dist/policy.js +60 -0
- package/dist/policy.js.map +1 -0
- package/dist/resource.d.ts +378 -0
- package/dist/resource.js +430 -0
- package/dist/resource.js.map +1 -0
- package/dist/resources.d.ts +77 -0
- package/dist/resources.js +244 -0
- package/dist/resources.js.map +1 -0
- package/dist/run.d.ts +101 -0
- package/dist/run.js +7 -0
- package/dist/run.js.map +1 -0
- package/dist/sandbox.d.ts +33 -0
- package/dist/sandbox.js +127 -0
- package/dist/sandbox.js.map +1 -0
- package/dist/scenario.d.ts +221 -0
- package/dist/scenario.js +1104 -0
- package/dist/scenario.js.map +1 -0
- package/dist/scenarios.d.ts +55 -0
- package/dist/scenarios.js +71 -0
- package/dist/scenarios.js.map +1 -0
- package/dist/secret.d.ts +42 -0
- package/dist/secret.js +58 -0
- package/dist/secret.js.map +1 -0
- package/dist/shared.d.ts +69 -0
- package/dist/shared.js +84 -0
- package/dist/shared.js.map +1 -0
- package/dist/source.d.ts +58 -0
- package/dist/source.js +54 -0
- package/dist/source.js.map +1 -0
- package/dist/steps.d.ts +76 -0
- package/dist/steps.js +23 -0
- package/dist/steps.js.map +1 -0
- package/dist/version.d.ts +29 -0
- package/dist/version.js +76 -0
- package/dist/version.js.map +1 -0
- package/dist/worker.d.ts +37 -0
- package/dist/worker.js +228 -0
- package/dist/worker.js.map +1 -0
- package/dist/writer.d.ts +35 -0
- package/dist/writer.js +201 -0
- package/dist/writer.js.map +1 -0
- package/oxlint.json +128 -0
- package/package.json +96 -3
- package/src/apply-steps.ts +110 -0
- package/src/apply.ts +626 -0
- package/src/approvals.ts +157 -0
- package/src/ast.ts +115 -0
- package/src/call.ts +483 -0
- package/src/client.ts +604 -0
- package/src/config.ts +404 -0
- package/src/credentials.ts +296 -0
- package/src/cucumber.ts +230 -0
- package/src/datafile.ts +481 -0
- package/src/db.ts +197 -0
- package/src/define.ts +285 -0
- package/src/describe.ts +282 -0
- package/src/drift.ts +259 -0
- package/src/env.ts +122 -0
- package/src/errors.ts +202 -0
- package/src/expectations.ts +191 -0
- package/src/fake.ts +156 -0
- package/src/fill.ts +24 -0
- package/src/host.ts +96 -0
- package/src/index.ts +143 -0
- package/src/ledger.ts +419 -0
- package/src/lint.ts +208 -0
- package/src/lockfile.ts +95 -0
- package/src/log.ts +82 -0
- package/src/op.ts +402 -0
- package/src/outline.ts +620 -0
- package/src/paths.ts +32 -0
- package/src/plugin.ts +37 -0
- package/src/policy.ts +139 -0
- package/src/resource.ts +670 -0
- package/src/resources.ts +311 -0
- package/src/run.ts +106 -0
- package/src/sandbox.ts +161 -0
- package/src/scenario.ts +1365 -0
- package/src/scenarios.ts +111 -0
- package/src/secret.ts +92 -0
- package/src/shared.ts +126 -0
- package/src/source.ts +82 -0
- package/src/steps.ts +90 -0
- package/src/version.ts +86 -0
- package/src/worker.ts +264 -0
- package/src/writer.ts +225 -0
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import { readdirSync, readFileSync, statSync } from "node:fs";
|
|
2
|
+
import { dirname, join, relative, resolve, sep } from "node:path";
|
|
3
|
+
import { parsed } from "./ast.js";
|
|
4
|
+
import { rootOf } from "./config.js";
|
|
5
|
+
import { readDataFile, Reference } from "./datafile.js";
|
|
6
|
+
import { LOCKFILE, readLockfile } from "./lockfile.js";
|
|
7
|
+
import { VENDOR } from "./op.js";
|
|
8
|
+
import { resourceTypesOf } from "./resource.js";
|
|
9
|
+
import { problemLine } from "./shared.js";
|
|
10
|
+
/**
|
|
11
|
+
* The resources the config's data files declare, read without importing or running them; throws
|
|
12
|
+
* one error listing every problem, each at `file:line:column`, for a test or CI to fail on.
|
|
13
|
+
* `describeConfig` lists the same, with the problems beside them instead.
|
|
14
|
+
*/
|
|
15
|
+
export function readResources(config) {
|
|
16
|
+
const { resources, problems } = readDataFiles(rootOf(config), config.connectors);
|
|
17
|
+
if (problems.length) {
|
|
18
|
+
const lines = problems.map((p) => ` ${problemLine(p)}`);
|
|
19
|
+
throw new Error(`The resources' data files have problems:\n${lines.join("\n")}`);
|
|
20
|
+
}
|
|
21
|
+
return resources;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Reads `resources/` under `root`, the config's directory: each `.ts` file in it but
|
|
25
|
+
* `*.test.ts`, `*.d.ts` and `node_modules`, parsed with oxc and held to the data-file subset
|
|
26
|
+
* (`readDataFile`). A constructor import (`@sanoma-ai/connector-github/resources`) is matched to the
|
|
27
|
+
* connector whose `info.package` it names, never imported; each resource is checked by calling
|
|
28
|
+
* its type, as running the file would, with each resource it names given as that resource.
|
|
29
|
+
*
|
|
30
|
+
* Problems: anything outside the subset, a constructor or data file the config does not know, a
|
|
31
|
+
* type the connector does not declare, a value the type refuses (a reference where its type
|
|
32
|
+
* takes none among them), a reference cycle, and two resources of one type with one identity.
|
|
33
|
+
*
|
|
34
|
+
* Each declaration is joined to its binding in the lockfile (`readLockfile`) by its key,
|
|
35
|
+
* `<file>#<export>`; a binding no export declares is an orphan. Problems: the lockfile's, a
|
|
36
|
+
* binding of another type than its declaration's, and two declarations bound to one object.
|
|
37
|
+
*/
|
|
38
|
+
export function readDataFiles(root, connectors, types = resourceTypesOf(connectors)) {
|
|
39
|
+
const problems = [];
|
|
40
|
+
if (root === undefined) {
|
|
41
|
+
problems.push({
|
|
42
|
+
message: "The config has no root, so its data files cannot be found: make it with defineConfig, which records its file, or set its `root`",
|
|
43
|
+
});
|
|
44
|
+
return { resources: [], bindings: {}, orphans: [], problems };
|
|
45
|
+
}
|
|
46
|
+
const lock = readLockfile(root);
|
|
47
|
+
problems.push(...lock.problems);
|
|
48
|
+
const files = new Map();
|
|
49
|
+
for (const path of dataFilesUnder(join(root, "resources"))) {
|
|
50
|
+
const rel = relative(root, path).split(sep).join("/");
|
|
51
|
+
const source = readFileSync(path, "utf8");
|
|
52
|
+
const { program, problems: syntax, at } = parsed(source, path);
|
|
53
|
+
const data = readDataFile(program, path, join(root, "resources"));
|
|
54
|
+
const problem = (offset, message) => problems.push({ file: rel, ...at(offset), message });
|
|
55
|
+
for (const p of syntax)
|
|
56
|
+
problems.push({ file: rel, ...p });
|
|
57
|
+
for (const p of data.problems)
|
|
58
|
+
problem(p.start, p.message);
|
|
59
|
+
files.set(path, { rel, data, problem });
|
|
60
|
+
}
|
|
61
|
+
// Each connector's constructors entry, `<info.package>/resources`, to its vendor.
|
|
62
|
+
const entries = new Map();
|
|
63
|
+
for (const connector of connectors) {
|
|
64
|
+
const { id, info } = connector[VENDOR];
|
|
65
|
+
if (info?.package)
|
|
66
|
+
entries.set(`${info.package}/resources`, id);
|
|
67
|
+
}
|
|
68
|
+
// What each file's names stand for, and every resource read by its id.
|
|
69
|
+
const vendors = new Map();
|
|
70
|
+
const named = new Map();
|
|
71
|
+
const declarations = new Map();
|
|
72
|
+
for (const [path, file] of files) {
|
|
73
|
+
const fileVendors = new Map();
|
|
74
|
+
const fileNamed = new Map();
|
|
75
|
+
for (const imp of file.data.imports) {
|
|
76
|
+
if (imp.kind === "constructors") {
|
|
77
|
+
const vendor = entries.get(imp.source);
|
|
78
|
+
if (vendor === undefined) {
|
|
79
|
+
file.problem(imp.start, `"${imp.source}" is not the resources entry of a connector in the config's \`connectors\`: add the connector, and import from its package's \`/resources\``);
|
|
80
|
+
}
|
|
81
|
+
else if (imp.imported !== vendor) {
|
|
82
|
+
file.problem(imp.start, `"${imp.source}" exports its constructors as ${vendor}: \`import { ${vendor} } from "${imp.source}"\``);
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
fileVendors.set(imp.local, vendor);
|
|
86
|
+
}
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
const other = files.get(resolve(dirname(path), imp.source));
|
|
90
|
+
if (!other) {
|
|
91
|
+
file.problem(imp.start, `"${imp.source}" is not a data file under resources/`);
|
|
92
|
+
}
|
|
93
|
+
else if (!other.data.declared.includes(imp.imported)) {
|
|
94
|
+
file.problem(imp.start, `${imp.imported} is not a resource ${other.rel} declares`);
|
|
95
|
+
}
|
|
96
|
+
else if (other.data.exports.some((e) => e.name === imp.imported)) {
|
|
97
|
+
fileNamed.set(imp.local, `${other.rel}#${imp.imported}`);
|
|
98
|
+
}
|
|
99
|
+
// Else its value was refused, and reported in its file: a reference to it fails quietly.
|
|
100
|
+
}
|
|
101
|
+
for (const exp of file.data.exports) {
|
|
102
|
+
const id = `${file.rel}#${exp.name}`;
|
|
103
|
+
fileNamed.set(exp.name, id);
|
|
104
|
+
declarations.set(id, { file, exp });
|
|
105
|
+
}
|
|
106
|
+
vendors.set(file, fileVendors);
|
|
107
|
+
named.set(file, fileNamed);
|
|
108
|
+
}
|
|
109
|
+
// Each resource after the ones it names, which it is given as they are declared.
|
|
110
|
+
const done = new Map();
|
|
111
|
+
const visiting = [];
|
|
112
|
+
const byName = new Map();
|
|
113
|
+
function declare(id) {
|
|
114
|
+
if (done.has(id))
|
|
115
|
+
return done.get(id);
|
|
116
|
+
const { file, exp } = declarations.get(id);
|
|
117
|
+
if (visiting.includes(id)) {
|
|
118
|
+
file.problem(exp.start, `${id} refers to itself: ${[...visiting.slice(visiting.indexOf(id)), id].join(" → ")}`);
|
|
119
|
+
return undefined;
|
|
120
|
+
}
|
|
121
|
+
visiting.push(id);
|
|
122
|
+
const result = build(file, exp);
|
|
123
|
+
visiting.pop();
|
|
124
|
+
if (result?.declared.name !== undefined) {
|
|
125
|
+
const { vendor, type, name } = result.declared;
|
|
126
|
+
const key = `${vendor}.${type} ${JSON.stringify(name)}`;
|
|
127
|
+
const first = byName.get(key);
|
|
128
|
+
if (first === undefined)
|
|
129
|
+
byName.set(key, id);
|
|
130
|
+
else {
|
|
131
|
+
file.problem(exp.start, `${key} is declared twice, also as ${first}: declare each resource once, and import it where it is used`);
|
|
132
|
+
done.set(id, undefined);
|
|
133
|
+
return undefined;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
done.set(id, result);
|
|
137
|
+
return result;
|
|
138
|
+
}
|
|
139
|
+
function build(file, exp) {
|
|
140
|
+
// An unknown constructors import was reported with the import.
|
|
141
|
+
const vendor = vendors.get(file).get(exp.vendor);
|
|
142
|
+
if (vendor === undefined)
|
|
143
|
+
return undefined;
|
|
144
|
+
const resource = types.get(`${vendor}.${exp.type}`);
|
|
145
|
+
if (!resource) {
|
|
146
|
+
const known = [...types.values()].filter((r) => r.vendor === vendor).map((r) => r.type);
|
|
147
|
+
file.problem(exp.start, `${vendor} has no resource type ${exp.type}: its types are ${known.join(", ")}`);
|
|
148
|
+
return undefined;
|
|
149
|
+
}
|
|
150
|
+
const refs = {};
|
|
151
|
+
let ok = true;
|
|
152
|
+
// The fields with each name of a resource as that resource, and where each is named.
|
|
153
|
+
const given = (v, at) => {
|
|
154
|
+
if (v instanceof Reference) {
|
|
155
|
+
// A name that did not resolve was reported where it is bound.
|
|
156
|
+
const target = named.get(file).get(v.name);
|
|
157
|
+
const declared = target === undefined ? undefined : declare(target)?.declared;
|
|
158
|
+
if (!declared)
|
|
159
|
+
ok = false;
|
|
160
|
+
else
|
|
161
|
+
refs[at] = target;
|
|
162
|
+
return declared;
|
|
163
|
+
}
|
|
164
|
+
if (Array.isArray(v))
|
|
165
|
+
return v.map((item, i) => given(item, `${at}.${i}`));
|
|
166
|
+
if (v === null || typeof v !== "object")
|
|
167
|
+
return v;
|
|
168
|
+
return Object.fromEntries(Object.entries(v).map(([k, item]) => [k, given(item, at ? `${at}.${k}` : k)]));
|
|
169
|
+
};
|
|
170
|
+
const fields = given(exp.desired, "");
|
|
171
|
+
if (!ok)
|
|
172
|
+
return undefined;
|
|
173
|
+
try {
|
|
174
|
+
// Checked as running the file would: by the resource type, which allows a resource only where its `fields.references` say.
|
|
175
|
+
return { declared: resource(fields), refs };
|
|
176
|
+
}
|
|
177
|
+
catch (e) {
|
|
178
|
+
// One line per problem: zod's own spans lines.
|
|
179
|
+
file.problem(exp.start, `export const ${exp.name}: ${e.message.replaceAll(/\s*\n\s*/g, " ")}`);
|
|
180
|
+
return undefined;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
// Each binding against its declaration: of its type, and the only one bound to its object.
|
|
184
|
+
const boundBy = new Map();
|
|
185
|
+
for (const [id, { file, exp }] of declarations) {
|
|
186
|
+
const binding = lock.bindings[id];
|
|
187
|
+
// An unknown constructors import was reported with the import.
|
|
188
|
+
const vendor = vendors.get(file).get(exp.vendor);
|
|
189
|
+
if (binding === undefined || vendor === undefined)
|
|
190
|
+
continue;
|
|
191
|
+
const type = `${vendor}.${exp.type}`;
|
|
192
|
+
const object = `${binding.type} ${binding.id}`;
|
|
193
|
+
const first = boundBy.get(object);
|
|
194
|
+
const why = binding.type !== type
|
|
195
|
+
? `${id} is bound to a ${binding.type} in ${LOCKFILE}, but declares a ${type}`
|
|
196
|
+
: first !== undefined
|
|
197
|
+
? `${id} is bound to the same ${object} as ${first} in ${LOCKFILE}: bind each object once`
|
|
198
|
+
: undefined;
|
|
199
|
+
if (why === undefined)
|
|
200
|
+
boundBy.set(object, id);
|
|
201
|
+
else {
|
|
202
|
+
// Left out, as any declaration with a problem, and so is any that names it.
|
|
203
|
+
file.problem(exp.start, why);
|
|
204
|
+
done.set(id, undefined);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
const keys = new Set([...files.values()].flatMap((f) => f.data.declared.map((name) => `${f.rel}#${name}`)));
|
|
208
|
+
const orphans = Object.entries(lock.bindings)
|
|
209
|
+
.filter(([key]) => !keys.has(key))
|
|
210
|
+
.map(([key, binding]) => ({ key, ...binding }));
|
|
211
|
+
const resources = [];
|
|
212
|
+
for (const [id, { file, exp }] of declarations) {
|
|
213
|
+
const result = declare(id);
|
|
214
|
+
if (!result)
|
|
215
|
+
continue;
|
|
216
|
+
const { vendor, type, name: identity, desired } = result.declared;
|
|
217
|
+
const binding = lock.bindings[id]?.id;
|
|
218
|
+
resources.push({
|
|
219
|
+
id,
|
|
220
|
+
file: file.rel,
|
|
221
|
+
vendor,
|
|
222
|
+
type,
|
|
223
|
+
name: identity ?? exp.name,
|
|
224
|
+
...(identity !== undefined && { identity }),
|
|
225
|
+
...(binding !== undefined && { binding }),
|
|
226
|
+
span: [exp.start, exp.end],
|
|
227
|
+
desired,
|
|
228
|
+
refs: result.refs,
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
problems.sort((a, b) => (a.file ?? "").localeCompare(b.file ?? "") || (a.line ?? 0) - (b.line ?? 0) || (a.column ?? 0) - (b.column ?? 0));
|
|
232
|
+
return { resources, bindings: lock.bindings, orphans, problems };
|
|
233
|
+
}
|
|
234
|
+
/** The data files under `dir`, sorted: regular `.ts` files, less tests, declarations and `node_modules`; none when `dir` is not a directory. */
|
|
235
|
+
function dataFilesUnder(dir) {
|
|
236
|
+
if (!statSync(dir, { throwIfNoEntry: false })?.isDirectory())
|
|
237
|
+
return [];
|
|
238
|
+
return readdirSync(dir, { recursive: true, withFileTypes: true })
|
|
239
|
+
.filter((d) => d.isFile() && d.name.endsWith(".ts") && !d.name.endsWith(".test.ts") && !d.name.endsWith(".d.ts"))
|
|
240
|
+
.map((d) => join(d.parentPath, d.name))
|
|
241
|
+
.filter((path) => !relative(dir, path).split(sep).includes("node_modules"))
|
|
242
|
+
.toSorted();
|
|
243
|
+
}
|
|
244
|
+
//# sourceMappingURL=resources.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resources.js","sourceRoot":"","sources":["../src/resources.ts"],"names":[],"mappings":"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"}
|
package/dist/run.d.ts
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2
|
+
import type { ApprovalState, Principal, WorkflowDefinition } from "./define.ts";
|
|
3
|
+
import type { Fake } from "./fake.ts";
|
|
4
|
+
import type { LedgerStore } from "./ledger.ts";
|
|
5
|
+
import type { DriverFn, Op } from "./op.ts";
|
|
6
|
+
import type { CallNode } from "./outline.ts";
|
|
7
|
+
import type { Policy } from "./policy.ts";
|
|
8
|
+
import type { Resource } from "./resource.ts";
|
|
9
|
+
import type { Secrets } from "./secret.ts";
|
|
10
|
+
import type { Source } from "./source.ts";
|
|
11
|
+
import type { Steps } from "./steps.ts";
|
|
12
|
+
/** What the DBOS workflow receives: the workflow's input, who started the run, and for a sandbox run its scenario. */
|
|
13
|
+
export interface RunArgs {
|
|
14
|
+
input: unknown;
|
|
15
|
+
startedBy: Principal;
|
|
16
|
+
/** The scenario a sandbox run is seeded from; the run calls the fakes instead of the drivers. */
|
|
17
|
+
sandbox?: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* What one `startWorker` call runs with. DBOS registrations are process-wide and outlive a
|
|
21
|
+
* shutdown, so each run takes the state current when it starts and keeps it: a run left over
|
|
22
|
+
* from a stopped worker never reads a newer worker's drivers or policy.
|
|
23
|
+
*/
|
|
24
|
+
export interface WorkerState {
|
|
25
|
+
/** The config's `appName`, recorded on every ledger record. */
|
|
26
|
+
app: string;
|
|
27
|
+
/** The operations as the config's connectors declare them, by id. */
|
|
28
|
+
ops: Map<string, Op>;
|
|
29
|
+
/** The drivers' functions, by operation id, each guarded by its driver's `env` (`indexDrivers` in config.ts). */
|
|
30
|
+
drivers: Map<string, DriverFn>;
|
|
31
|
+
/** The makers of the config's fake vendors, by vendor id: a sandbox run makes its own of each when it is seeded. */
|
|
32
|
+
fakes: Map<string, () => Fake<any, any>>;
|
|
33
|
+
/** Where sandbox runs' scenarios are, the resource types their steps may name, and the steps the connectors ship. */
|
|
34
|
+
scenarios?: URL;
|
|
35
|
+
/** The worker's `source`, when it was given one. */
|
|
36
|
+
source?: Source;
|
|
37
|
+
types: ReadonlyMap<string, Resource>;
|
|
38
|
+
steps: readonly Steps[];
|
|
39
|
+
/** Its `version`, when it has one, is recorded with each of its decisions. */
|
|
40
|
+
policy: Policy;
|
|
41
|
+
ledger: LedgerStore;
|
|
42
|
+
/** The stored secrets, for a live run's drivers (`CallContext.secrets`). */
|
|
43
|
+
secrets: Secrets;
|
|
44
|
+
/**
|
|
45
|
+
* The config's workflows by name, the built-in `drift` among them. A run takes its definition
|
|
46
|
+
* from here, by the name it was registered under: a process registers each name with DBOS once,
|
|
47
|
+
* and each worker's config says what it runs. Scenarios name them too.
|
|
48
|
+
*/
|
|
49
|
+
workflows: Map<string, WorkflowDefinition<any, any>>;
|
|
50
|
+
/** Each workflow's outline, by name: read once when the worker starts, every run is held to it (`call_not_in_outline`). */
|
|
51
|
+
outlines: Map<string, WorkflowOutline>;
|
|
52
|
+
/**
|
|
53
|
+
* Set when the worker stops, before DBOS shuts down. DBOS abandons a stopped worker's run
|
|
54
|
+
* functions, which then fail as their next DBOS call finds the database closed. Such a failure,
|
|
55
|
+
* one with none of our codes, is not recorded: the run recovered on the next worker records
|
|
56
|
+
* how it really ends (see `isInfrastructureError`).
|
|
57
|
+
*/
|
|
58
|
+
stopped: boolean;
|
|
59
|
+
}
|
|
60
|
+
/** What a run keeps in memory. Rebuilt the same way when DBOS replays the run. */
|
|
61
|
+
export interface Run {
|
|
62
|
+
id: string;
|
|
63
|
+
workflow: string;
|
|
64
|
+
actor: Principal;
|
|
65
|
+
/** The scenario a sandbox run is seeded from; unset for a live run. */
|
|
66
|
+
sandbox?: string;
|
|
67
|
+
/** A sandbox run's own fakes' functions, by operation id, from `seedSandbox`; unset for a live run. */
|
|
68
|
+
fakeDrivers?: Map<string, DriverFn>;
|
|
69
|
+
/** A sandbox run's own secrets, in memory, from `seedSandbox`; unset for a live run. */
|
|
70
|
+
fakeSecrets?: Secrets;
|
|
71
|
+
approvals: ApprovalState[];
|
|
72
|
+
/** The next ledger `seq`. Advanced only outside steps, so a replay counts the same way. */
|
|
73
|
+
seq: number;
|
|
74
|
+
/**
|
|
75
|
+
* The last `ctx` call queued. Each call waits for the one before it, so a run's calls run one
|
|
76
|
+
* at a time, in program order, even under `Promise.all`. Never rejects.
|
|
77
|
+
*/
|
|
78
|
+
tail: Promise<unknown>;
|
|
79
|
+
/**
|
|
80
|
+
* Set while a `ctx.all` runs, so a second one started before it settles is refused. The
|
|
81
|
+
* member a call belongs to travels with the call (`currentGroup` in ledger.ts), not here.
|
|
82
|
+
*/
|
|
83
|
+
inAll: boolean;
|
|
84
|
+
/** Set when the workflow body has returned or thrown. A call still queued then is refused. */
|
|
85
|
+
ended: boolean;
|
|
86
|
+
/** The workflow's outline, which every `ctx` call is placed in (`placeCall`). */
|
|
87
|
+
outline: WorkflowOutline;
|
|
88
|
+
state: WorkerState;
|
|
89
|
+
}
|
|
90
|
+
/** What `placeCall` holds a run's `ctx` calls to: the file's lines, so a frame's line and column become an offset, and the outline's call nodes. */
|
|
91
|
+
export interface WorkflowOutline {
|
|
92
|
+
file: string;
|
|
93
|
+
/** `lineStartsOf` the file's text, `\n` line endings. */
|
|
94
|
+
lineStarts: readonly number[];
|
|
95
|
+
calls: readonly CallNode[];
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* The run whose workflow body is running: what a built-in's own steps read of it (who started
|
|
99
|
+
* it, whether it is a sandbox run, the worker's source and policy), as no `ctx` member gives them.
|
|
100
|
+
*/
|
|
101
|
+
export declare const currentRun: AsyncLocalStorage<Run>;
|
package/dist/run.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2
|
+
/**
|
|
3
|
+
* The run whose workflow body is running: what a built-in's own steps read of it (who started
|
|
4
|
+
* it, whether it is a sandbox run, the worker's source and policy), as no `ctx` member gives them.
|
|
5
|
+
*/
|
|
6
|
+
export const currentRun = new AsyncLocalStorage();
|
|
7
|
+
//# sourceMappingURL=run.js.map
|
package/dist/run.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAqGrD;;;GAGG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,iBAAiB,EAAO,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { SanomaError } from "./errors.ts";
|
|
2
|
+
import type { Fake, ResourceFake } from "./fake.ts";
|
|
3
|
+
import { type LedgerRecord } from "./ledger.ts";
|
|
4
|
+
import type { Run } from "./run.ts";
|
|
5
|
+
import { type Given, type Scenario } from "./scenario.ts";
|
|
6
|
+
/**
|
|
7
|
+
* The error a sandbox run of the scenario fails with when it seeds a resource of a vendor whose
|
|
8
|
+
* fake (one of `fakes`, by vendor) holds none, or whose connector attaches no fake; undefined
|
|
9
|
+
* when every vendor it seeds a resource of has a `ResourceFake`. Pure.
|
|
10
|
+
*/
|
|
11
|
+
export declare function missingResourceFake(scenario: Pick<Scenario, "name" | "given">, fakes: ReadonlyMap<string, Fake<unknown>>): SanomaError | undefined;
|
|
12
|
+
/**
|
|
13
|
+
* Seeds one resource into the run's own fake of its vendor: put with its fields, or removed.
|
|
14
|
+
* A seed the fake refuses (a field the provider's shape lacks, say) fails the scenario, naming
|
|
15
|
+
* the step, as the other seed-time refusals do.
|
|
16
|
+
*/
|
|
17
|
+
export declare function seedResource(scenario: string, copy: ResourceFake, given: Extract<Given, {
|
|
18
|
+
resource: string;
|
|
19
|
+
}>): Extract<LedgerRecord, {
|
|
20
|
+
type: "scenario.seeded";
|
|
21
|
+
}>["seeds"][number];
|
|
22
|
+
/**
|
|
23
|
+
* Seeds a sandbox run of the scenario `name`, from the worker, in one step: reads the scenario,
|
|
24
|
+
* checks that it runs this workflow, makes the run's own fakes (each vendor's maker, called once
|
|
25
|
+
* for the run), checks that every operation the workflow uses or the scenario seeds has one and
|
|
26
|
+
* that every resource it seeds has a fake holding resources, calls each `Given` operation
|
|
27
|
+
* through them, puts or removes each `Given` resource in them, injects the faults into them,
|
|
28
|
+
* then puts their functions on the run. The run then calls those only, so sandbox runs share no
|
|
29
|
+
* state when the makers make a new fake each. The step's checkpoint never stands in for them: a
|
|
30
|
+
* run whose seeding is replayed from it has none, and fails, since a sandbox run does not
|
|
31
|
+
* survive a worker restart.
|
|
32
|
+
*/
|
|
33
|
+
export declare function seedSandbox(run: Run, name: string): Promise<void>;
|
package/dist/sandbox.js
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { DBOS } from "@dbos-inc/dbos-sdk";
|
|
2
|
+
import { indexDrivers } from "./config.js";
|
|
3
|
+
import { opIdsOf } from "./define.js";
|
|
4
|
+
import { SanomaError } from "./errors.js";
|
|
5
|
+
import { entry, write } from "./ledger.js";
|
|
6
|
+
import { memorySecrets } from "./secret.js";
|
|
7
|
+
import { loadScenarios } from "./scenario.js";
|
|
8
|
+
import { errorMessage } from "./shared.js";
|
|
9
|
+
/*
|
|
10
|
+
* What a worker does for a sandbox run, imported only when it starts one: kept apart from
|
|
11
|
+
* `scenario.ts`, which the app reads too, because it needs DBOS and the ledger.
|
|
12
|
+
*/
|
|
13
|
+
/** True for a fake that holds resources (`ResourceFake`, as `@sanoma-ai/bridge`'s `tfFake` is). */
|
|
14
|
+
const holdsResources = (fake) => "override" in fake && "put" in fake && "remove" in fake;
|
|
15
|
+
/**
|
|
16
|
+
* The error a sandbox run of the scenario fails with when it seeds a resource of a vendor whose
|
|
17
|
+
* fake (one of `fakes`, by vendor) holds none, or whose connector attaches no fake; undefined
|
|
18
|
+
* when every vendor it seeds a resource of has a `ResourceFake`. Pure.
|
|
19
|
+
*/
|
|
20
|
+
export function missingResourceFake(scenario, fakes) {
|
|
21
|
+
const plain = scenario.given.filter((g) => {
|
|
22
|
+
if (!("resource" in g))
|
|
23
|
+
return false;
|
|
24
|
+
const fake = fakes.get(g.vendor);
|
|
25
|
+
return !fake || !holdsResources(fake);
|
|
26
|
+
});
|
|
27
|
+
if (plain.length === 0)
|
|
28
|
+
return undefined;
|
|
29
|
+
const resources = [...new Set(plain.map((g) => g.resource))];
|
|
30
|
+
const vendors = [...new Set(plain.map((g) => g.vendor))];
|
|
31
|
+
const why = vendors.map((v) => fakes.has(v) ? `${v}'s fake holds no resources (it is not a tfFake)` : `${v}'s connector attaches no fake`);
|
|
32
|
+
return new SanomaError("invalid_input", `Scenario "${scenario.name}" seeds ${resources.join(", ")}, but ${why.join("; ")}`, {
|
|
33
|
+
scenario: scenario.name,
|
|
34
|
+
resources,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Seeds one resource into the run's own fake of its vendor: put with its fields, or removed.
|
|
39
|
+
* A seed the fake refuses (a field the provider's shape lacks, say) fails the scenario, naming
|
|
40
|
+
* the step, as the other seed-time refusals do.
|
|
41
|
+
*/
|
|
42
|
+
export function seedResource(scenario, copy, given) {
|
|
43
|
+
const { resource, type, name } = given;
|
|
44
|
+
try {
|
|
45
|
+
if ("gone" in given) {
|
|
46
|
+
copy.remove(type, name);
|
|
47
|
+
return { resource, name, gone: true };
|
|
48
|
+
}
|
|
49
|
+
copy.put(type, name, given.fields);
|
|
50
|
+
return { resource, name, fields: given.fields };
|
|
51
|
+
}
|
|
52
|
+
catch (err) {
|
|
53
|
+
throw new SanomaError("invalid_input", `Scenario "${scenario}" cannot seed ${resource} "${name}" ("${given.step}"): ${errorMessage(err)}`, { scenario, step: given.step, resource, name }, { cause: err });
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Seeds a sandbox run of the scenario `name`, from the worker, in one step: reads the scenario,
|
|
58
|
+
* checks that it runs this workflow, makes the run's own fakes (each vendor's maker, called once
|
|
59
|
+
* for the run), checks that every operation the workflow uses or the scenario seeds has one and
|
|
60
|
+
* that every resource it seeds has a fake holding resources, calls each `Given` operation
|
|
61
|
+
* through them, puts or removes each `Given` resource in them, injects the faults into them,
|
|
62
|
+
* then puts their functions on the run. The run then calls those only, so sandbox runs share no
|
|
63
|
+
* state when the makers make a new fake each. The step's checkpoint never stands in for them: a
|
|
64
|
+
* run whose seeding is replayed from it has none, and fails, since a sandbox run does not
|
|
65
|
+
* survive a worker restart.
|
|
66
|
+
*/
|
|
67
|
+
export async function seedSandbox(run, name) {
|
|
68
|
+
const { state } = run;
|
|
69
|
+
let copies;
|
|
70
|
+
// The run's secrets, in memory as its fakes are: seeding and its calls share them.
|
|
71
|
+
const secrets = memorySecrets();
|
|
72
|
+
const { seeds } = await DBOS.runStep(async () => {
|
|
73
|
+
// Read in the step, so a recovered run never reads a feature file edited or renamed since.
|
|
74
|
+
const { scenarios, errors } = await loadScenarios(state);
|
|
75
|
+
const scenario = scenarios.find((s) => s.name === name);
|
|
76
|
+
if (!scenario) {
|
|
77
|
+
const why = errors.length ? `; these files did not load: ${errors.map((e) => e.message).join("; ")}` : "";
|
|
78
|
+
throw new SanomaError("invalid_input", `No scenario named "${name}"${why}`, { scenario: name });
|
|
79
|
+
}
|
|
80
|
+
if (scenario.workflow !== run.workflow) {
|
|
81
|
+
throw new SanomaError("invalid_input", `Scenario "${name}" runs ${scenario.workflow}, not ${run.workflow}`, {
|
|
82
|
+
scenario: name,
|
|
83
|
+
workflow: scenario.workflow,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
const fakes = new Map([...state.fakes].map(([vendor, make]) => [vendor, make()]));
|
|
87
|
+
const drivers = indexDrivers([...fakes.values()].map((f) => f.driver), state.ops);
|
|
88
|
+
const uses = opIdsOf(state.workflows.get(run.workflow));
|
|
89
|
+
const seeding = scenario.given.flatMap((g) => ("op" in g ? [g.op] : []));
|
|
90
|
+
const missing = [...new Set([...uses, ...seeding])].filter((id) => !drivers.has(id));
|
|
91
|
+
if (missing.length) {
|
|
92
|
+
throw new SanomaError("invalid_input", `A sandbox run of ${run.workflow} has no fake for ${missing.join(", ")}: no fake its connectors attach implements ${missing.length > 1 ? "them" : "it"}`, { scenario: name, missing });
|
|
93
|
+
}
|
|
94
|
+
const plain = missingResourceFake(scenario, fakes);
|
|
95
|
+
if (plain)
|
|
96
|
+
throw plain;
|
|
97
|
+
const seeded = [];
|
|
98
|
+
for (const [i, given] of scenario.given.entries()) {
|
|
99
|
+
if ("fault" in given)
|
|
100
|
+
continue;
|
|
101
|
+
if ("op" in given) {
|
|
102
|
+
const call = { idempotencyKey: `${run.id}:seed:${i}`, runId: run.id, opId: given.op, attempt: 1, secrets };
|
|
103
|
+
const output = await drivers.get(given.op)(given.input, call);
|
|
104
|
+
seeded.push({ op: given.op, input: given.input, output });
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
// Checked above: the vendor's fake holds resources.
|
|
108
|
+
seeded.push(seedResource(name, fakes.get(given.vendor), given));
|
|
109
|
+
}
|
|
110
|
+
for (const given of scenario.given) {
|
|
111
|
+
if ("fault" in given)
|
|
112
|
+
fakes.get(state.ops.get(given.op).vendor)[given.fault](given.op);
|
|
113
|
+
}
|
|
114
|
+
copies = drivers;
|
|
115
|
+
return { seeds: seeded };
|
|
116
|
+
}, { name: "sandbox:seed" });
|
|
117
|
+
if (!copies) {
|
|
118
|
+
// Replayed from its checkpoint (after a worker restart, or in a fork), so the run has no fakes.
|
|
119
|
+
// The records written before the restart hold the seqs from here on: the failure goes after them.
|
|
120
|
+
run.seq = Math.max(run.seq, ...(await state.ledger.read(run.id)).map((r) => r.seq + 1));
|
|
121
|
+
throw new SanomaError("invalid_input", `Sandbox run ${run.id} was interrupted by a worker restart and the fakes' state is gone; start the scenario again`, { runId: run.id, scenario: name });
|
|
122
|
+
}
|
|
123
|
+
run.fakeDrivers = copies;
|
|
124
|
+
run.fakeSecrets = secrets;
|
|
125
|
+
await write(run, entry(run, { type: "scenario.seeded", scenario: name, seeds }));
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=sandbox.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sandbox.js","sourceRoot":"","sources":["../src/sandbox.ts"],"names":[],"mappings":"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"}
|