@sanoma-ai/workflows 0.2.0 → 0.4.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/README.md +146 -85
- package/dist/approvals.d.ts +11 -6
- package/dist/approvals.js +38 -10
- package/dist/approvals.js.map +1 -1
- package/dist/call-workflow.d.ts +16 -0
- package/dist/call-workflow.js +35 -0
- package/dist/call-workflow.js.map +1 -0
- package/dist/call.d.ts +33 -4
- package/dist/call.js +107 -42
- package/dist/call.js.map +1 -1
- package/dist/cedar.d.ts +87 -0
- package/dist/cedar.js +365 -0
- package/dist/cedar.js.map +1 -0
- package/dist/client.d.ts +85 -7
- package/dist/client.js +289 -25
- package/dist/client.js.map +1 -1
- package/dist/collection.d.ts +107 -0
- package/dist/collection.js +306 -0
- package/dist/collection.js.map +1 -0
- package/dist/config.d.ts +42 -14
- package/dist/config.js +82 -18
- package/dist/config.js.map +1 -1
- package/dist/constructors.d.ts +2 -0
- package/dist/constructors.js +5 -0
- package/dist/constructors.js.map +1 -0
- package/dist/data.d.ts +2 -0
- package/dist/data.js +3 -0
- package/dist/data.js.map +1 -0
- package/dist/datafile.d.ts +28 -2
- package/dist/datafile.js +118 -19
- package/dist/datafile.js.map +1 -1
- package/dist/db.d.ts +5 -3
- package/dist/db.js +88 -21
- package/dist/db.js.map +1 -1
- package/dist/define.d.ts +14 -5
- package/dist/define.js +1 -5
- package/dist/define.js.map +1 -1
- package/dist/describe.d.ts +45 -5
- package/dist/describe.js +72 -7
- package/dist/describe.js.map +1 -1
- package/dist/direct.d.ts +9 -0
- package/dist/direct.js +11 -0
- package/dist/direct.js.map +1 -0
- package/dist/errors.d.ts +16 -1
- package/dist/errors.js +30 -1
- package/dist/errors.js.map +1 -1
- package/dist/expectations.d.ts +3 -3
- package/dist/expectations.js +16 -7
- package/dist/expectations.js.map +1 -1
- package/dist/fill.d.ts +4 -0
- package/dist/fill.js +13 -0
- package/dist/fill.js.map +1 -1
- package/dist/index.d.ts +8 -4
- package/dist/index.js +10 -4
- package/dist/index.js.map +1 -1
- package/dist/ledger.d.ts +12 -1
- package/dist/ledger.js +18 -11
- package/dist/ledger.js.map +1 -1
- package/dist/lint.d.ts +5 -4
- package/dist/lint.js +24 -7
- package/dist/lint.js.map +1 -1
- package/dist/op.d.ts +6 -0
- package/dist/op.js.map +1 -1
- package/dist/outline.d.ts +2 -0
- package/dist/outline.js +1 -1
- package/dist/outline.js.map +1 -1
- package/dist/paths.d.ts +4 -0
- package/dist/paths.js +17 -3
- package/dist/paths.js.map +1 -1
- package/dist/person.d.ts +61 -0
- package/dist/person.js +69 -0
- package/dist/person.js.map +1 -0
- package/dist/plugin.d.ts +28 -0
- package/dist/plugin.js +52 -1
- package/dist/plugin.js.map +1 -1
- package/dist/policy.d.ts +51 -55
- package/dist/policy.js +14 -36
- package/dist/policy.js.map +1 -1
- package/dist/resource.d.ts +21 -5
- package/dist/resource.js +12 -3
- package/dist/resource.js.map +1 -1
- package/dist/resources.d.ts +58 -6
- package/dist/resources.js +119 -26
- package/dist/resources.js.map +1 -1
- package/dist/run.d.ts +17 -1
- package/dist/run.js.map +1 -1
- package/dist/scenario.d.ts +16 -9
- package/dist/scenario.js +149 -44
- package/dist/scenario.js.map +1 -1
- package/dist/scenarios.d.ts +10 -6
- package/dist/scenarios.js +8 -4
- package/dist/scenarios.js.map +1 -1
- package/dist/schema.d.ts +32 -0
- package/dist/schema.js +225 -0
- package/dist/schema.js.map +1 -0
- package/dist/sdk.d.ts +34 -0
- package/dist/sdk.js +168 -0
- package/dist/sdk.js.map +1 -0
- package/dist/shared.d.ts +181 -5
- package/dist/shared.js +160 -7
- package/dist/shared.js.map +1 -1
- package/dist/sites.d.ts +52 -0
- package/dist/sites.js +174 -0
- package/dist/sites.js.map +1 -0
- package/dist/version.d.ts +3 -2
- package/dist/version.js +3 -2
- package/dist/version.js.map +1 -1
- package/dist/worker.d.ts +3 -2
- package/dist/worker.js +24 -4
- package/dist/worker.js.map +1 -1
- package/oxlint.json +7 -20
- package/package.json +8 -3
- package/src/approvals.ts +49 -13
- package/src/call-workflow.ts +44 -0
- package/src/call.ts +157 -45
- package/src/cedar.ts +493 -0
- package/src/client.ts +368 -37
- package/src/collection.ts +431 -0
- package/src/config.ts +131 -34
- package/src/constructors.ts +4 -0
- package/src/data.ts +10 -0
- package/src/datafile.ts +141 -21
- package/src/db.ts +90 -22
- package/src/define.ts +15 -10
- package/src/describe.ts +113 -10
- package/src/direct.ts +15 -0
- package/src/errors.ts +36 -1
- package/src/expectations.ts +17 -8
- package/src/fill.ts +15 -0
- package/src/index.ts +33 -2
- package/src/ledger.ts +35 -17
- package/src/lint.ts +29 -12
- package/src/op.ts +6 -0
- package/src/outline.ts +1 -1
- package/src/paths.ts +18 -3
- package/src/person.ts +75 -0
- package/src/plugin.ts +74 -5
- package/src/policy.ts +59 -63
- package/src/resource.ts +35 -8
- package/src/resources.ts +165 -24
- package/src/run.ts +18 -1
- package/src/scenario.ts +186 -57
- package/src/scenarios.ts +15 -8
- package/src/schema.ts +261 -0
- package/src/sdk.ts +211 -0
- package/src/shared.ts +271 -8
- package/src/sites.ts +220 -0
- package/src/version.ts +3 -2
- package/src/worker.ts +29 -6
package/dist/sites.js
ADDED
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { existsSync, readdirSync } from "node:fs";
|
|
2
|
+
import { join, relative, sep } from "node:path";
|
|
3
|
+
import { childrenOf, readSource } from "./ast.js";
|
|
4
|
+
import { keyName } from "./datafile.js";
|
|
5
|
+
import { stringValue, unwrap } from "./outline.js";
|
|
6
|
+
import { filesUnder, isDirectory } from "./paths.js";
|
|
7
|
+
import { apiNameOf, DATA_VENDOR, SITE_NAME } from "./shared.js";
|
|
8
|
+
/** Where a site's code is: its pages and its components. */
|
|
9
|
+
const SITE_DIRS = ["routes", "components"];
|
|
10
|
+
/** Where `api` and `defineSite` come from: `sanoma/site`, which re-exports the app's. */
|
|
11
|
+
const SITE_SOURCES = new Set(["sanoma/site", "@sanoma-ai/app/site"]);
|
|
12
|
+
const UI_SOURCES = new Set(["@sanoma-ai/app/ui"]);
|
|
13
|
+
const KIND_NAMES = { workflow: "workflow", collection: "collection", op: "operation" };
|
|
14
|
+
/** What makes a route from its id, whose first argument is the id. */
|
|
15
|
+
const ROUTE_MAKERS = new Set(["createFileRoute", "createLazyFileRoute"]);
|
|
16
|
+
/**
|
|
17
|
+
* The sites under `root`: each folder of `sites/` with a `routes/` whose name is a URL segment,
|
|
18
|
+
* by name (as `@sanoma-ai/app/build`'s `sitesOf` mounts them). Reads `routes/**` and
|
|
19
|
+
* `components/**` (`.ts` and `.tsx`, less tests and declarations) of each with oxc, never running
|
|
20
|
+
* them: each `<RunForm workflow="…" />` whose `RunForm` is imported from `@sanoma-ai/app/ui`, and
|
|
21
|
+
* each use of `api` imported from `sanoma/site`, called or passed on (`queryFn: api.data.leads.list`):
|
|
22
|
+
* `api.<name>` and `api.<name>.<method>` are a workflow, `api.data.<collection>.<op>` a collection,
|
|
23
|
+
* and `api.<vendor>.<resource>.<op>` an operation. A name that is not written out (a variable, a
|
|
24
|
+
* template with holes, a computed member) is skipped, as is a use through a namespace import or a
|
|
25
|
+
* destructured `api`. A call to what `description` does not have, or to an operation a page may
|
|
26
|
+
* not call directly, is a problem.
|
|
27
|
+
*/
|
|
28
|
+
export function readSites(root, description) {
|
|
29
|
+
if (root === undefined)
|
|
30
|
+
return [];
|
|
31
|
+
const dir = join(root, "sites");
|
|
32
|
+
if (!isDirectory(dir))
|
|
33
|
+
return [];
|
|
34
|
+
const workflows = new Set(description.workflows.map((wf) => wf.name));
|
|
35
|
+
const collections = new Set(description.collections.map((c) => c.name));
|
|
36
|
+
const ops = new Map(description.ops.map((op) => [op.id, op]));
|
|
37
|
+
// A workflow's api name to its name: two of one api name are a problem on the workflows.
|
|
38
|
+
const byApiName = new Map(description.workflows.map((wf) => [apiNameOf(wf.name), wf.name]));
|
|
39
|
+
/** A call as written, resolved as the app's `callApi` resolves it, with why it would fail. */
|
|
40
|
+
const resolve = ({ kind, name, via, ...at }) => {
|
|
41
|
+
const target = kind === "workflow" && via === "api" ? (byApiName.get(name) ?? name) : name;
|
|
42
|
+
const found = kind === "workflow"
|
|
43
|
+
? via === "api"
|
|
44
|
+
? byApiName.has(name)
|
|
45
|
+
: workflows.has(name)
|
|
46
|
+
: kind === "collection"
|
|
47
|
+
? collections.has(name)
|
|
48
|
+
: ops.has(name);
|
|
49
|
+
const problem = !found
|
|
50
|
+
? `calls ${KIND_NAMES[kind]} "${target}", which does not exist`
|
|
51
|
+
: kind === "op" && !ops.get(name).direct
|
|
52
|
+
? `calls operation "${target}", which a page may not call directly: start a workflow that calls it`
|
|
53
|
+
: undefined;
|
|
54
|
+
return { call: { kind, target, via, ...at }, ...(problem && { problem }) };
|
|
55
|
+
};
|
|
56
|
+
return readdirSync(dir, { withFileTypes: true })
|
|
57
|
+
.filter((d) => d.isDirectory() && SITE_NAME.test(d.name) && existsSync(join(dir, d.name, "routes")))
|
|
58
|
+
.map((d) => d.name)
|
|
59
|
+
.toSorted()
|
|
60
|
+
.map((name) => {
|
|
61
|
+
const files = SITE_DIRS.flatMap((sub) => filesUnder(join(dir, name, sub), isSource)).toSorted();
|
|
62
|
+
const resolved = files.flatMap((path) => {
|
|
63
|
+
const file = readSource(path);
|
|
64
|
+
return typeof file === "string" ? [] : usesIn(file, relative(root, path).split(sep).join("/")).map(resolve);
|
|
65
|
+
});
|
|
66
|
+
const title = titleOf(join(dir, name, "site.ts"));
|
|
67
|
+
const calls = resolved.map((r) => r.call);
|
|
68
|
+
const problems = resolved.flatMap(({ call: { file, line, column }, problem }) => problem === undefined ? [] : [{ file, line, column, message: problem }]);
|
|
69
|
+
return { name, ...(title !== undefined && { title }), calls, problems };
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
/** The uses in one file, in its order. */
|
|
73
|
+
function usesIn({ program, at }, file) {
|
|
74
|
+
const api = importedAs(program, SITE_SOURCES, "api");
|
|
75
|
+
const runForm = importedAs(program, UI_SOURCES, "RunForm");
|
|
76
|
+
if (!api.size && !runForm.size)
|
|
77
|
+
return [];
|
|
78
|
+
const found = [];
|
|
79
|
+
let page;
|
|
80
|
+
const visit = (node) => {
|
|
81
|
+
if (!node)
|
|
82
|
+
return;
|
|
83
|
+
if (node.type === "MemberExpression") {
|
|
84
|
+
const named = apiPath(node, api);
|
|
85
|
+
// The outermost member of a path on `api`: what it names, called or not; its inner members are not visited.
|
|
86
|
+
if (named)
|
|
87
|
+
return void found.push({ ...named, via: "api", file, ...at(node.start) });
|
|
88
|
+
}
|
|
89
|
+
else if (node.type === "CallExpression" && page === undefined) {
|
|
90
|
+
const callee = unwrap(node.callee);
|
|
91
|
+
if (callee?.type === "Identifier" && ROUTE_MAKERS.has(callee.name)) {
|
|
92
|
+
const id = stringValue(node.arguments[0]);
|
|
93
|
+
if (id !== undefined)
|
|
94
|
+
page = pageOf(id);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
else if (node.type === "JSXOpeningElement" && node.name.type === "JSXIdentifier" && runForm.has(node.name.name)) {
|
|
98
|
+
const attribute = node.attributes.find((a) => a.type === "JSXAttribute" && a.name.type === "JSXIdentifier" && a.name.name === "workflow");
|
|
99
|
+
const value = attribute?.value?.type === "JSXExpressionContainer" ? attribute.value.expression : attribute?.value;
|
|
100
|
+
const name = stringValue(value);
|
|
101
|
+
if (name !== undefined)
|
|
102
|
+
found.push({ kind: "workflow", name, via: "RunForm", file, ...at(node.start) });
|
|
103
|
+
}
|
|
104
|
+
for (const child of childrenOf(node))
|
|
105
|
+
visit(child);
|
|
106
|
+
};
|
|
107
|
+
visit(program);
|
|
108
|
+
return found.map((use) => (page === undefined ? use : { ...use, page }));
|
|
109
|
+
}
|
|
110
|
+
/** What a member path on `api` names; undefined for a path on anything else, a name not written out, or no name. */
|
|
111
|
+
function apiPath(member, api) {
|
|
112
|
+
const path = [];
|
|
113
|
+
let node = member;
|
|
114
|
+
while (node?.type === "MemberExpression") {
|
|
115
|
+
const key = node.computed ? stringValue(node.property) : node.property.name;
|
|
116
|
+
if (key === undefined)
|
|
117
|
+
return undefined;
|
|
118
|
+
path.unshift(key);
|
|
119
|
+
node = unwrap(node.object);
|
|
120
|
+
}
|
|
121
|
+
if (node?.type !== "Identifier" || !api.has(node.name))
|
|
122
|
+
return undefined;
|
|
123
|
+
const [first, second] = path;
|
|
124
|
+
if (first === DATA_VENDOR)
|
|
125
|
+
return path.length === 3 ? { kind: "collection", name: second } : undefined;
|
|
126
|
+
if (path.length === 3)
|
|
127
|
+
return { kind: "op", name: path.join(".") };
|
|
128
|
+
return path.length <= 2 ? { kind: "workflow", name: first } : undefined;
|
|
129
|
+
}
|
|
130
|
+
/** The local names `imported` has in the file, imported as a value from one of `sources`. */
|
|
131
|
+
function importedAs(program, sources, imported) {
|
|
132
|
+
const names = new Set();
|
|
133
|
+
for (const statement of program.body) {
|
|
134
|
+
if (statement.type !== "ImportDeclaration" || statement.importKind === "type")
|
|
135
|
+
continue;
|
|
136
|
+
if (!sources.has(statement.source.value))
|
|
137
|
+
continue;
|
|
138
|
+
for (const s of statement.specifiers) {
|
|
139
|
+
if (s.type === "ImportSpecifier" && s.importKind !== "type" && keyName(s.imported) === imported) {
|
|
140
|
+
names.add(s.local.name);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return names;
|
|
145
|
+
}
|
|
146
|
+
/** A site's title: the string `title` its `site.ts` exports by default through `defineSite`. */
|
|
147
|
+
function titleOf(path) {
|
|
148
|
+
const file = readSource(path);
|
|
149
|
+
if (typeof file === "string")
|
|
150
|
+
return undefined;
|
|
151
|
+
const defineSite = importedAs(file.program, SITE_SOURCES, "defineSite");
|
|
152
|
+
const exported = file.program.body.find((s) => s.type === "ExportDefaultDeclaration")?.declaration;
|
|
153
|
+
const call = unwrap(exported);
|
|
154
|
+
const callee = unwrap(call?.callee);
|
|
155
|
+
const options = unwrap(call?.arguments?.[0]);
|
|
156
|
+
if (call?.type !== "CallExpression" || callee?.type !== "Identifier" || !defineSite.has(callee.name))
|
|
157
|
+
return undefined;
|
|
158
|
+
if (options?.type !== "ObjectExpression")
|
|
159
|
+
return undefined;
|
|
160
|
+
const title = options.properties.find((p) => p.type === "Property" && !p.computed && keyName(p.key) === "title");
|
|
161
|
+
return stringValue(title?.value);
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* A route's path from its id, as the router serves it: `(group)` and `_pathless` segments left
|
|
165
|
+
* out, a `_` that ends a segment dropped, and no trailing slash.
|
|
166
|
+
*/
|
|
167
|
+
const pageOf = (id) => `/${id
|
|
168
|
+
.split("/")
|
|
169
|
+
.filter((s) => s && !/^\(.*\)$/.test(s) && !s.startsWith("_"))
|
|
170
|
+
.map((s) => s.replace(/_$/, ""))
|
|
171
|
+
.join("/")}`;
|
|
172
|
+
/** A site's source file: `.ts` or `.tsx`, but a test or a declaration. */
|
|
173
|
+
const isSource = (name) => /\.tsx?$/.test(name) && !/\.(test|d)\.tsx?$/.test(name);
|
|
174
|
+
//# sourceMappingURL=sites.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sites.js","sourceRoot":"","sources":["../src/sites.ts"],"names":[],"mappings":"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"}
|
package/dist/version.d.ts
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { type WorkflowDefinition } from "./define.ts";
|
|
2
2
|
/** This package's version. A unit test keeps it equal to package.json. */
|
|
3
|
-
export declare const RUNTIME_VERSION = "0.
|
|
3
|
+
export declare const RUNTIME_VERSION = "0.4.1";
|
|
4
4
|
/**
|
|
5
5
|
* The sequence of DBOS calls the runtime makes around each `ctx` call: policy step, approval
|
|
6
6
|
* events and messages, the driver step. Bump it whenever that sequence changes, even without a
|
|
7
7
|
* package release, so a run in flight on the old layout is not replayed against the new one.
|
|
8
8
|
* 2: calls run in program order; a decision event per approval (2026-10-07).
|
|
9
|
+
* 3: a start the policy holds waits on its approval before the body (2026-10-21).
|
|
9
10
|
*/
|
|
10
|
-
export declare const STEP_LAYOUT =
|
|
11
|
+
export declare const STEP_LAYOUT = 3;
|
|
11
12
|
/**
|
|
12
13
|
* The application version DBOS stamps on every run, always `<appName>@…`: DBOS version names
|
|
13
14
|
* are unique per system database across apps. A worker recovers and dequeues only runs of its
|
package/dist/version.js
CHANGED
|
@@ -5,14 +5,15 @@ import { dirname, join } from "node:path";
|
|
|
5
5
|
import { jsonSchemaOf, opIdsOf } from "./define.js";
|
|
6
6
|
import { upFrom } from "./paths.js";
|
|
7
7
|
/** This package's version. A unit test keeps it equal to package.json. */
|
|
8
|
-
export const RUNTIME_VERSION = "0.
|
|
8
|
+
export const RUNTIME_VERSION = "0.4.1";
|
|
9
9
|
/**
|
|
10
10
|
* The sequence of DBOS calls the runtime makes around each `ctx` call: policy step, approval
|
|
11
11
|
* events and messages, the driver step. Bump it whenever that sequence changes, even without a
|
|
12
12
|
* package release, so a run in flight on the old layout is not replayed against the new one.
|
|
13
13
|
* 2: calls run in program order; a decision event per approval (2026-10-07).
|
|
14
|
+
* 3: a start the policy holds waits on its approval before the body (2026-10-21).
|
|
14
15
|
*/
|
|
15
|
-
export const STEP_LAYOUT =
|
|
16
|
+
export const STEP_LAYOUT = 3;
|
|
16
17
|
let dbosVersion;
|
|
17
18
|
/** The installed DBOS SDK's version, read from its package.json (which its exports don't expose). */
|
|
18
19
|
function installedDbosVersion() {
|
package/dist/version.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,OAAO,EAA2B,MAAM,aAAa,CAAC;AAC7E,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEpC,0EAA0E;AAC1E,MAAM,CAAC,MAAM,eAAe,GAAG,OAAO,CAAC;AAEvC
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"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"}
|
package/dist/worker.d.ts
CHANGED
|
@@ -13,8 +13,9 @@ export interface WorkerOptions {
|
|
|
13
13
|
/** The least severe level of the runtime's and DBOS's messages to show, for the whole process: `warn` by default. */
|
|
14
14
|
logLevel?: string;
|
|
15
15
|
/**
|
|
16
|
-
* Start without naming the vendors not configured yet (`unconfigured` still does)
|
|
17
|
-
* whose runs use the fakes alone, as `runScenarios`'s
|
|
16
|
+
* Start without naming the vendors not configured yet (`unconfigured` still does), or the
|
|
17
|
+
* policies' problems: for a worker whose runs use the fakes alone, as `runScenarios`'s, which
|
|
18
|
+
* `sanoma check` reports them beside.
|
|
18
19
|
*/
|
|
19
20
|
quiet?: boolean;
|
|
20
21
|
/**
|
package/dist/worker.js
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import { DBOS } from "@dbos-inc/dbos-sdk";
|
|
2
|
-
import {
|
|
2
|
+
import { awaitApproval } from "./approvals.js";
|
|
3
|
+
import { buildCtx, decideStart, isInfrastructureError, startHoldOf } from "./call.js";
|
|
3
4
|
import { dbosStatusesOf } from "./client.js";
|
|
4
5
|
import { resolveConfig } from "./config.js";
|
|
5
6
|
import { storedSecrets, watchCredentials } from "./credentials.js";
|
|
6
7
|
import { DBOS_DATABASE_OPTIONS, lazyPool, prepareDatabase } from "./db.js";
|
|
7
8
|
import { credentialsOf, unconfigured, unconfiguredSummary } from "./env.js";
|
|
8
|
-
import { errorInfo, parseOrThrow } from "./errors.js";
|
|
9
|
+
import { errorInfo, parseOrThrow, PolicyDeniedError } from "./errors.js";
|
|
9
10
|
import { entry, ownedLedger, skipped, write, writeFailure } from "./ledger.js";
|
|
10
11
|
import { dbosLogger, quietIfSandbox, setLogLevel, warn } from "./log.js";
|
|
11
12
|
import { lineStartsOf, readSource } from "./ast.js";
|
|
12
13
|
import { callsOf, outlineWithSource } from "./outline.js";
|
|
13
14
|
import { currentRun } from "./run.js";
|
|
14
|
-
import { errorMessage } from "./shared.js";
|
|
15
|
+
import { errorMessage, WORKFLOW_ACTION } from "./shared.js";
|
|
15
16
|
// DBOS registrations are process-wide and survive shutdown, so a name is registered once, and
|
|
16
17
|
// its function reads the state of the worker running when a run starts, definition and all; the
|
|
17
18
|
// run keeps that state.
|
|
@@ -39,8 +40,10 @@ export async function startWorker(config, options = {}) {
|
|
|
39
40
|
...(resolved.scenarios && { scenarios: resolved.scenarios }),
|
|
40
41
|
...(options.source && { source: options.source }),
|
|
41
42
|
types: resolved.types,
|
|
43
|
+
collections: resolved.collections,
|
|
42
44
|
steps: resolved.steps,
|
|
43
45
|
policy: resolved.policy,
|
|
46
|
+
...(resolved.root !== undefined && { root: resolved.root }),
|
|
44
47
|
ledger: ledger.store,
|
|
45
48
|
secrets: storedSecrets(() => secrets.db(), "sanoma"),
|
|
46
49
|
workflows: resolved.workflows,
|
|
@@ -61,6 +64,7 @@ export async function startWorker(config, options = {}) {
|
|
|
61
64
|
() => credentials.close(),
|
|
62
65
|
() => secrets.close(),
|
|
63
66
|
() => ledger.close(),
|
|
67
|
+
async () => resolved.dataStore?.close(),
|
|
64
68
|
]) {
|
|
65
69
|
await close().catch((error) => (failed ??= { error }));
|
|
66
70
|
}
|
|
@@ -111,6 +115,9 @@ export async function startWorker(config, options = {}) {
|
|
|
111
115
|
const summary = unconfiguredSummary(worker.unconfigured, resolved.driversByVendor.size);
|
|
112
116
|
if (summary && !options.quiet)
|
|
113
117
|
warn(summary);
|
|
118
|
+
if (resolved.policyProblems.length && !options.quiet) {
|
|
119
|
+
warn(`the policies do not hold, so every call and start is refused:\n ${resolved.policyProblems.join("\n ")}`);
|
|
120
|
+
}
|
|
114
121
|
}
|
|
115
122
|
catch (err) {
|
|
116
123
|
// Once DBOS is launched, the caller gets no worker to stop: stop it here, so no run goes on
|
|
@@ -173,7 +180,7 @@ function register(name) {
|
|
|
173
180
|
});
|
|
174
181
|
}
|
|
175
182
|
/** One run of the workflow registered as `name`, on the state of the worker running when it starts. */
|
|
176
|
-
async function runWorkflow(name, { input, startedBy, sandbox }) {
|
|
183
|
+
async function runWorkflow(name, { input, startedBy, sandbox, hold }) {
|
|
177
184
|
const state = current;
|
|
178
185
|
// A stopped worker's state stays current while DBOS shuts down.
|
|
179
186
|
if (!state || state.stopped)
|
|
@@ -202,6 +209,19 @@ async function runWorkflow(name, { input, startedBy, sandbox }) {
|
|
|
202
209
|
try {
|
|
203
210
|
// The one parse of the input: the client checked it, but sent it as given.
|
|
204
211
|
const parsed = parseOrThrow(wf.input, input, `The input does not match ${wf.name}'s schema`);
|
|
212
|
+
// The policy held the start: the body waits for each hold's approval in turn, the policy
|
|
213
|
+
// asked again once one is approved, and a rejection or a deny fails the run.
|
|
214
|
+
const action = `${WORKFLOW_ACTION}${wf.name}`;
|
|
215
|
+
for (let next = hold; next;) {
|
|
216
|
+
const held = { op: action, input, reasons: next.reasons };
|
|
217
|
+
await awaitApproval(run, next.title, { approver: next.approver, covers: [action] }, undefined, held);
|
|
218
|
+
const decision = await DBOS.runStep(async () => decideStart(state.policy, wf.name, parsed, startedBy, run.approvals), {
|
|
219
|
+
name: `policy:${action}`,
|
|
220
|
+
});
|
|
221
|
+
if (decision.kind === "deny")
|
|
222
|
+
throw new PolicyDeniedError(action, decision.reason);
|
|
223
|
+
next = decision.kind === "approve" ? startHoldOf(wf.name, decision) : undefined;
|
|
224
|
+
}
|
|
205
225
|
if (sandbox !== undefined) {
|
|
206
226
|
// Imported here, so a live worker never loads the Gherkin parser or faker.
|
|
207
227
|
const { seedSandbox } = await import("./sandbox.js");
|
package/dist/worker.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker.js","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"worker.js","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":"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"}
|
package/oxlint.json
CHANGED
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"overrides": [
|
|
3
3
|
{
|
|
4
|
-
"files": ["workflows/**"
|
|
4
|
+
"files": ["workflows/**"],
|
|
5
|
+
"jsPlugins": ["./dist/plugin.js"],
|
|
5
6
|
"rules": {
|
|
7
|
+
"sanoma/date": "error",
|
|
6
8
|
"no-restricted-globals": [
|
|
7
9
|
"error",
|
|
8
|
-
{
|
|
9
|
-
"name": "Date",
|
|
10
|
-
"message": "Workflows are replayed: use `await ctx.now()` for the time and `ctx.sleep({ until })` to wait for a date."
|
|
11
|
-
},
|
|
12
10
|
{
|
|
13
11
|
"name": "fetch",
|
|
14
12
|
"message": "A workflow must call vendors through ctx, so the policy sees every call: use a connector operation listed in `uses`."
|
|
@@ -35,8 +33,8 @@
|
|
|
35
33
|
"name": "require",
|
|
36
34
|
"message": "Import from `@sanoma-ai/workflows`, a `@sanoma-ai/connector-*` package, zod or a file in this directory."
|
|
37
35
|
},
|
|
38
|
-
{ "name": "eval", "message": "Not allowed in a workflow
|
|
39
|
-
{ "name": "Function", "message": "Not allowed in a workflow
|
|
36
|
+
{ "name": "eval", "message": "Not allowed in a workflow." },
|
|
37
|
+
{ "name": "Function", "message": "Not allowed in a workflow." },
|
|
40
38
|
{
|
|
41
39
|
"name": "globalThis",
|
|
42
40
|
"message": "Reaching globals through globalThis would bypass these rules: use `ctx`."
|
|
@@ -85,20 +83,9 @@
|
|
|
85
83
|
},
|
|
86
84
|
{
|
|
87
85
|
"name": "@sanoma-ai/workflows",
|
|
88
|
-
"allowImportNames": [
|
|
89
|
-
"defineWorkflow",
|
|
90
|
-
"definePolicy",
|
|
91
|
-
"allow",
|
|
92
|
-
"deny",
|
|
93
|
-
"approve",
|
|
94
|
-
"approvedFor",
|
|
95
|
-
"allowAll",
|
|
96
|
-
"mayDecide",
|
|
97
|
-
"errorCode",
|
|
98
|
-
"z"
|
|
99
|
-
],
|
|
86
|
+
"allowImportNames": ["defineWorkflow", "mayDecide", "errorCode", "z"],
|
|
100
87
|
"allowTypeImports": true,
|
|
101
|
-
"message": "A workflow
|
|
88
|
+
"message": "A workflow imports only these and types from @sanoma-ai/workflows: the rest (SanomaClient, startWorker, the ledger stores, config helpers) could start runs, approve its own approvals, forge the ledger or read credentials. Ask for approval with `ctx.approval`."
|
|
102
89
|
}
|
|
103
90
|
],
|
|
104
91
|
"patterns": [
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sanoma-ai/workflows",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "Business processes as TypeScript functions, run durably on DBOS",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"approvals",
|
|
@@ -35,6 +35,10 @@
|
|
|
35
35
|
"types": "./dist/index.d.ts",
|
|
36
36
|
"default": "./dist/index.js"
|
|
37
37
|
},
|
|
38
|
+
"./data": {
|
|
39
|
+
"types": "./dist/data.d.ts",
|
|
40
|
+
"default": "./dist/data.js"
|
|
41
|
+
},
|
|
38
42
|
"./describe": {
|
|
39
43
|
"types": "./dist/describe.d.ts",
|
|
40
44
|
"default": "./dist/describe.js"
|
|
@@ -48,8 +52,8 @@
|
|
|
48
52
|
"default": "./dist/plugin.js"
|
|
49
53
|
},
|
|
50
54
|
"./resources": {
|
|
51
|
-
"types": "./dist/
|
|
52
|
-
"default": "./dist/
|
|
55
|
+
"types": "./dist/constructors.d.ts",
|
|
56
|
+
"default": "./dist/constructors.js"
|
|
53
57
|
},
|
|
54
58
|
"./scenario": {
|
|
55
59
|
"types": "./dist/scenario.d.ts",
|
|
@@ -68,6 +72,7 @@
|
|
|
68
72
|
"access": "public"
|
|
69
73
|
},
|
|
70
74
|
"dependencies": {
|
|
75
|
+
"@cedar-policy/cedar-wasm": "4.14.0",
|
|
71
76
|
"@cucumber/cucumber": "13.3.0",
|
|
72
77
|
"@cucumber/cucumber-expressions": "^20.1.0",
|
|
73
78
|
"@cucumber/messages": "^34.2.1",
|
package/src/approvals.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { DBOS } from "@dbos-inc/dbos-sdk";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
-
import { type ApprovalRequest, type ApprovalResult, type ApprovalState,
|
|
3
|
+
import { type ApprovalRequest, type ApprovalResult, type ApprovalState, Principal } from "./define.ts";
|
|
4
4
|
import { RejectedError } from "./errors.ts";
|
|
5
5
|
import { entry, write } from "./ledger.ts";
|
|
6
6
|
import { warn } from "./log.ts";
|
|
7
7
|
import type { Placed } from "./call.ts";
|
|
8
8
|
import type { Run } from "./run.ts";
|
|
9
|
-
import {
|
|
9
|
+
import { readPeople } from "./resources.ts";
|
|
10
|
+
import { approverLabel, OWN_CHANGE, refusalOf } from "./shared.ts";
|
|
10
11
|
|
|
11
12
|
// The wire contract between a run waiting on approvals and whoever decides them. The client
|
|
12
13
|
// imports this file and never the worker's.
|
|
@@ -50,23 +51,28 @@ export interface CheckedApproval extends Omit<ApprovalRequest, "covers"> {
|
|
|
50
51
|
covers: string[];
|
|
51
52
|
}
|
|
52
53
|
|
|
53
|
-
/**
|
|
54
|
+
/**
|
|
55
|
+
* A policy's hold: the call held (an operation, or `workflow:<name>` for a run's start), the
|
|
56
|
+
* ledger `seq` its `op.called` record takes (a start has none), and the rules that held it.
|
|
57
|
+
*/
|
|
54
58
|
export interface HeldCall {
|
|
55
59
|
op: string;
|
|
56
|
-
seq
|
|
60
|
+
seq?: number;
|
|
57
61
|
input: unknown;
|
|
62
|
+
reasons?: string[] | undefined;
|
|
58
63
|
}
|
|
59
64
|
|
|
60
65
|
/**
|
|
61
|
-
* Waits, durably, for a decision from someone who may make it
|
|
62
|
-
* rejection. Without `held`, the workflow asked
|
|
63
|
-
* `place` is the held call's outline node and name
|
|
66
|
+
* Waits, durably, for a decision from someone who may make it (`mayDecide`: the run's own actor
|
|
67
|
+
* only while nobody else could). Throws `RejectedError` on a rejection. Without `held`, the workflow asked
|
|
68
|
+
* (`ctx.approval`); with it, the policy did, and `place` is the held call's outline node and name
|
|
69
|
+
* (none for a run's start, which is no call in the outline).
|
|
64
70
|
*/
|
|
65
71
|
export async function awaitApproval(
|
|
66
72
|
run: Run,
|
|
67
73
|
title: string,
|
|
68
74
|
req: CheckedApproval,
|
|
69
|
-
place: Placed,
|
|
75
|
+
place: Placed | undefined,
|
|
70
76
|
held?: HeldCall,
|
|
71
77
|
): Promise<ApprovalResult> {
|
|
72
78
|
const { covers } = req;
|
|
@@ -79,7 +85,7 @@ export async function awaitApproval(
|
|
|
79
85
|
...(req.details === undefined ? {} : { details: req.details }),
|
|
80
86
|
requestedBy: held ? "policy" : "workflow",
|
|
81
87
|
covers,
|
|
82
|
-
...(held
|
|
88
|
+
...(held && { op: held.op, ...heldOf(held), input: held.input }),
|
|
83
89
|
status: "pending",
|
|
84
90
|
requestedAt: 0,
|
|
85
91
|
refused: [],
|
|
@@ -99,7 +105,7 @@ export async function awaitApproval(
|
|
|
99
105
|
approver: state.approver,
|
|
100
106
|
requestedBy: state.requestedBy,
|
|
101
107
|
covers,
|
|
102
|
-
...(held
|
|
108
|
+
...(held && { op: held.op, ...heldOf(held) }),
|
|
103
109
|
},
|
|
104
110
|
{ key: state.id, at: state.requestedAt },
|
|
105
111
|
),
|
|
@@ -113,9 +119,23 @@ export async function awaitApproval(
|
|
|
113
119
|
const at = await DBOS.now();
|
|
114
120
|
const parsed = ApprovalMessage.safeParse(raw);
|
|
115
121
|
const msg = parsed.success ? parsed.data : undefined;
|
|
116
|
-
|
|
122
|
+
// The people matter only when the run's own actor decides (`refusalOf`): then they are read as
|
|
123
|
+
// the data files declare them now, in a step, so a replay decides the same. While those files
|
|
124
|
+
// have problems, someone else may be missing from them, so the starter is refused.
|
|
125
|
+
const refusal = !msg
|
|
126
|
+
? null
|
|
127
|
+
: msg.by.id === run.actor.id
|
|
128
|
+
? await DBOS.runStep(
|
|
129
|
+
async () => {
|
|
130
|
+
const { people, problems } = readPeople(run.state.root);
|
|
131
|
+
return refusalOf(state, msg.by, run, people) ?? (problems.length ? OWN_CHANGE : null);
|
|
132
|
+
},
|
|
133
|
+
{ name: `decider:${state.id}` },
|
|
134
|
+
)
|
|
135
|
+
: (refusalOf(state, msg.by, run, []) ?? null);
|
|
136
|
+
if (!msg || refusal !== null) {
|
|
117
137
|
const by = msg?.by.id ?? senderOf(raw);
|
|
118
|
-
const reason =
|
|
138
|
+
const reason = refusal ?? "not a valid decision message";
|
|
119
139
|
state.refused.push({
|
|
120
140
|
...(by === undefined ? {} : { by }),
|
|
121
141
|
...(msg?.id === undefined ? {} : { id: msg.id }),
|
|
@@ -133,12 +153,15 @@ export async function awaitApproval(
|
|
|
133
153
|
);
|
|
134
154
|
continue;
|
|
135
155
|
}
|
|
156
|
+
// The run's own actor decides only when nobody else could, which the record says.
|
|
157
|
+
const alone = msg.by.id === run.actor.id ? { alone: true as const } : {};
|
|
136
158
|
Object.assign(state, {
|
|
137
159
|
status: statusOf(msg.decision),
|
|
138
160
|
decidedBy: msg.by.id,
|
|
139
161
|
decidedAt: at,
|
|
140
162
|
note: msg.note,
|
|
141
163
|
decidedWith: msg.id,
|
|
164
|
+
...alone,
|
|
142
165
|
});
|
|
143
166
|
// The list first, then the ledger, then the decision event: whoever sees the event sees both.
|
|
144
167
|
await DBOS.setEvent(APPROVALS_EVENT, all);
|
|
@@ -146,7 +169,14 @@ export async function awaitApproval(
|
|
|
146
169
|
run,
|
|
147
170
|
entry(
|
|
148
171
|
run,
|
|
149
|
-
{
|
|
172
|
+
{
|
|
173
|
+
type: "approval.decided",
|
|
174
|
+
approval: state.id,
|
|
175
|
+
decision: msg.decision,
|
|
176
|
+
by: msg.by.id,
|
|
177
|
+
note: msg.note,
|
|
178
|
+
...alone,
|
|
179
|
+
},
|
|
150
180
|
{ key: state.id, at },
|
|
151
181
|
),
|
|
152
182
|
);
|
|
@@ -155,3 +185,9 @@ export async function awaitApproval(
|
|
|
155
185
|
return { approvedBy: msg.by.id, at, note: msg.note };
|
|
156
186
|
}
|
|
157
187
|
}
|
|
188
|
+
|
|
189
|
+
/** What an approval and its request record keep of a hold besides the operation: its `seq` and rules, when it has them. */
|
|
190
|
+
const heldOf = ({ seq, reasons }: HeldCall) => ({
|
|
191
|
+
...(seq !== undefined && { opSeq: seq }),
|
|
192
|
+
...(reasons !== undefined && { reasons }),
|
|
193
|
+
});
|