@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.
Files changed (176) hide show
  1. package/LICENSE +105 -0
  2. package/README.md +544 -2
  3. package/dist/apply-steps.d.ts +6 -0
  4. package/dist/apply-steps.js +93 -0
  5. package/dist/apply-steps.js.map +1 -0
  6. package/dist/apply.d.ts +197 -0
  7. package/dist/apply.js +470 -0
  8. package/dist/apply.js.map +1 -0
  9. package/dist/approvals.d.ts +46 -0
  10. package/dist/approvals.js +111 -0
  11. package/dist/approvals.js.map +1 -0
  12. package/dist/ast.d.ts +57 -0
  13. package/dist/ast.js +81 -0
  14. package/dist/ast.js.map +1 -0
  15. package/dist/call.d.ts +37 -0
  16. package/dist/call.js +417 -0
  17. package/dist/call.js.map +1 -0
  18. package/dist/client.d.ts +203 -0
  19. package/dist/client.js +457 -0
  20. package/dist/client.js.map +1 -0
  21. package/dist/config.d.ts +126 -0
  22. package/dist/config.js +264 -0
  23. package/dist/config.js.map +1 -0
  24. package/dist/credentials.d.ts +55 -0
  25. package/dist/credentials.js +261 -0
  26. package/dist/credentials.js.map +1 -0
  27. package/dist/cucumber.d.ts +64 -0
  28. package/dist/cucumber.js +158 -0
  29. package/dist/cucumber.js.map +1 -0
  30. package/dist/datafile.d.ts +71 -0
  31. package/dist/datafile.js +380 -0
  32. package/dist/datafile.js.map +1 -0
  33. package/dist/db.d.ts +58 -0
  34. package/dist/db.js +179 -0
  35. package/dist/db.js.map +1 -0
  36. package/dist/define.d.ts +205 -0
  37. package/dist/define.js +103 -0
  38. package/dist/define.js.map +1 -0
  39. package/dist/describe.d.ts +141 -0
  40. package/dist/describe.js +135 -0
  41. package/dist/describe.js.map +1 -0
  42. package/dist/drift.d.ts +127 -0
  43. package/dist/drift.js +167 -0
  44. package/dist/drift.js.map +1 -0
  45. package/dist/env.d.ts +49 -0
  46. package/dist/env.js +83 -0
  47. package/dist/env.js.map +1 -0
  48. package/dist/errors.d.ts +88 -0
  49. package/dist/errors.js +148 -0
  50. package/dist/errors.js.map +1 -0
  51. package/dist/expectations.d.ts +26 -0
  52. package/dist/expectations.js +162 -0
  53. package/dist/expectations.js.map +1 -0
  54. package/dist/fake.d.ts +55 -0
  55. package/dist/fake.js +87 -0
  56. package/dist/fake.js.map +1 -0
  57. package/dist/fill.d.ts +9 -0
  58. package/dist/fill.js +17 -0
  59. package/dist/fill.js.map +1 -0
  60. package/dist/host.d.ts +56 -0
  61. package/dist/host.js +45 -0
  62. package/dist/host.js.map +1 -0
  63. package/dist/index.d.ts +23 -0
  64. package/dist/index.js +29 -0
  65. package/dist/index.js.map +1 -0
  66. package/dist/ledger.d.ts +217 -0
  67. package/dist/ledger.js +251 -0
  68. package/dist/ledger.js.map +1 -0
  69. package/dist/lint.d.ts +32 -0
  70. package/dist/lint.js +168 -0
  71. package/dist/lint.js.map +1 -0
  72. package/dist/lockfile.d.ts +36 -0
  73. package/dist/lockfile.js +69 -0
  74. package/dist/lockfile.js.map +1 -0
  75. package/dist/log.d.ts +24 -0
  76. package/dist/log.js +83 -0
  77. package/dist/log.js.map +1 -0
  78. package/dist/op.d.ts +260 -0
  79. package/dist/op.js +188 -0
  80. package/dist/op.js.map +1 -0
  81. package/dist/outline.d.ts +179 -0
  82. package/dist/outline.js +506 -0
  83. package/dist/outline.js.map +1 -0
  84. package/dist/paths.d.ts +11 -0
  85. package/dist/paths.js +30 -0
  86. package/dist/paths.js.map +1 -0
  87. package/dist/plugin.d.ts +28 -0
  88. package/dist/plugin.js +25 -0
  89. package/dist/plugin.js.map +1 -0
  90. package/dist/policy.d.ts +114 -0
  91. package/dist/policy.js +60 -0
  92. package/dist/policy.js.map +1 -0
  93. package/dist/resource.d.ts +378 -0
  94. package/dist/resource.js +430 -0
  95. package/dist/resource.js.map +1 -0
  96. package/dist/resources.d.ts +77 -0
  97. package/dist/resources.js +244 -0
  98. package/dist/resources.js.map +1 -0
  99. package/dist/run.d.ts +101 -0
  100. package/dist/run.js +7 -0
  101. package/dist/run.js.map +1 -0
  102. package/dist/sandbox.d.ts +33 -0
  103. package/dist/sandbox.js +127 -0
  104. package/dist/sandbox.js.map +1 -0
  105. package/dist/scenario.d.ts +221 -0
  106. package/dist/scenario.js +1104 -0
  107. package/dist/scenario.js.map +1 -0
  108. package/dist/scenarios.d.ts +55 -0
  109. package/dist/scenarios.js +71 -0
  110. package/dist/scenarios.js.map +1 -0
  111. package/dist/secret.d.ts +42 -0
  112. package/dist/secret.js +58 -0
  113. package/dist/secret.js.map +1 -0
  114. package/dist/shared.d.ts +69 -0
  115. package/dist/shared.js +84 -0
  116. package/dist/shared.js.map +1 -0
  117. package/dist/source.d.ts +58 -0
  118. package/dist/source.js +54 -0
  119. package/dist/source.js.map +1 -0
  120. package/dist/steps.d.ts +76 -0
  121. package/dist/steps.js +23 -0
  122. package/dist/steps.js.map +1 -0
  123. package/dist/version.d.ts +29 -0
  124. package/dist/version.js +76 -0
  125. package/dist/version.js.map +1 -0
  126. package/dist/worker.d.ts +37 -0
  127. package/dist/worker.js +228 -0
  128. package/dist/worker.js.map +1 -0
  129. package/dist/writer.d.ts +35 -0
  130. package/dist/writer.js +201 -0
  131. package/dist/writer.js.map +1 -0
  132. package/oxlint.json +128 -0
  133. package/package.json +96 -3
  134. package/src/apply-steps.ts +110 -0
  135. package/src/apply.ts +626 -0
  136. package/src/approvals.ts +157 -0
  137. package/src/ast.ts +115 -0
  138. package/src/call.ts +483 -0
  139. package/src/client.ts +604 -0
  140. package/src/config.ts +404 -0
  141. package/src/credentials.ts +296 -0
  142. package/src/cucumber.ts +230 -0
  143. package/src/datafile.ts +481 -0
  144. package/src/db.ts +197 -0
  145. package/src/define.ts +285 -0
  146. package/src/describe.ts +282 -0
  147. package/src/drift.ts +259 -0
  148. package/src/env.ts +122 -0
  149. package/src/errors.ts +202 -0
  150. package/src/expectations.ts +191 -0
  151. package/src/fake.ts +156 -0
  152. package/src/fill.ts +24 -0
  153. package/src/host.ts +96 -0
  154. package/src/index.ts +143 -0
  155. package/src/ledger.ts +419 -0
  156. package/src/lint.ts +208 -0
  157. package/src/lockfile.ts +95 -0
  158. package/src/log.ts +82 -0
  159. package/src/op.ts +402 -0
  160. package/src/outline.ts +620 -0
  161. package/src/paths.ts +32 -0
  162. package/src/plugin.ts +37 -0
  163. package/src/policy.ts +139 -0
  164. package/src/resource.ts +670 -0
  165. package/src/resources.ts +311 -0
  166. package/src/run.ts +106 -0
  167. package/src/sandbox.ts +161 -0
  168. package/src/scenario.ts +1365 -0
  169. package/src/scenarios.ts +111 -0
  170. package/src/secret.ts +92 -0
  171. package/src/shared.ts +126 -0
  172. package/src/source.ts +82 -0
  173. package/src/steps.ts +90 -0
  174. package/src/version.ts +86 -0
  175. package/src/worker.ts +264 -0
  176. package/src/writer.ts +225 -0
@@ -0,0 +1,205 @@
1
+ import { z } from "zod";
2
+ import { type Op } from "./op.ts";
3
+ /**
4
+ * Who is acting: the person or service that starts a run or decides an approval. `id` is
5
+ * whatever the deployment identifies people by; `groups` are the roles it vouches for.
6
+ */
7
+ export interface Principal {
8
+ id: string;
9
+ groups?: string[];
10
+ }
11
+ export declare const Principal: z.ZodType<Principal>;
12
+ export type Builtin = "approval" | "sleep" | "all";
13
+ export type Use = Op | Builtin;
14
+ /** Who may decide an approval: one person, by `Principal.id`, or anyone in a group, by `Principal.groups`. */
15
+ export type Approver = string | {
16
+ group: string;
17
+ };
18
+ export declare const Approver: z.ZodType<Approver>;
19
+ /** Why `by` may not decide the approval, naming who may. */
20
+ export declare const notApprover: ({ approver }: Pick<ApprovalState, "approver">, by: Principal) => string;
21
+ /** True when the two name the same approver: the same id, or the same group. */
22
+ export declare const sameApprover: (a: Approver, b: Approver) => boolean;
23
+ /** `covers` as given (operations), parsed to their ids. */
24
+ export declare const Covers: z.ZodOptional<z.ZodArray<z.ZodPipe<z.ZodObject<{
25
+ id: z.ZodString;
26
+ }, z.core.$strip>, z.ZodTransform<string, {
27
+ id: string;
28
+ }>>>>;
29
+ export interface ApprovalRequest {
30
+ /** Who must approve: a person's id, or `{ group }` for anyone in it. Phase 4 replaces this with a Cedar decision. */
31
+ approver: Approver;
32
+ /**
33
+ * The operations the approval stands for, so a policy can let their calls through once it
34
+ * is approved (`a.covers.includes(op.id)`). None unless given.
35
+ */
36
+ covers?: Op[];
37
+ links?: string[];
38
+ details?: string;
39
+ }
40
+ /**
41
+ * Checks a `ctx.approval` request as a workflow may give it, so the UI and the ledger get what
42
+ * the types say, and turns `covers` into op ids.
43
+ */
44
+ export declare const ApprovalRequestSchema: z.ZodObject<{
45
+ approver: z.ZodType<Approver, unknown, z.core.$ZodTypeInternals<Approver, unknown>>;
46
+ covers: z.ZodOptional<z.ZodArray<z.ZodPipe<z.ZodObject<{
47
+ id: z.ZodString;
48
+ }, z.core.$strip>, z.ZodTransform<string, {
49
+ id: string;
50
+ }>>>>;
51
+ links: z.ZodOptional<z.ZodArray<z.ZodString>>;
52
+ details: z.ZodOptional<z.ZodString>;
53
+ }, z.core.$strip>;
54
+ /** One approval in a run, as the run sees it. Published as the run's "approvals" event. */
55
+ export interface ApprovalState extends Omit<ApprovalRequest, "covers"> {
56
+ id: string;
57
+ title: string;
58
+ /** Who asked: the workflow (`ctx.approval`), or the policy holding an operation call. */
59
+ requestedBy: "workflow" | "policy";
60
+ /**
61
+ * The operations the approval stands for, by id. A policy hold covers the call it held and
62
+ * any `covers` the policy added; a workflow's approval covers the `covers` it named, or none.
63
+ */
64
+ covers: string[];
65
+ /** For a policy request: the operation call held, by op id. */
66
+ op?: string;
67
+ /** For a policy request: the ledger `seq` of the call held, which its `op.called` record has. */
68
+ opSeq?: number;
69
+ /** For a policy request: the held call's input. */
70
+ input?: unknown;
71
+ status: "pending" | "approved" | "rejected";
72
+ requestedAt: number;
73
+ decidedBy?: string;
74
+ decidedAt?: number;
75
+ note?: string;
76
+ /** The `id` of the decision message the run decided with, when it had one. */
77
+ decidedWith?: string;
78
+ /**
79
+ * Messages that were ignored: decisions sent by someone who may not decide the approval,
80
+ * and messages that were not a decision. `by` is the sender, when the message named one, and
81
+ * `id` the decision message's own, when it had one.
82
+ */
83
+ refused: {
84
+ by?: string;
85
+ id?: string;
86
+ at: number;
87
+ reason: string;
88
+ }[];
89
+ }
90
+ export interface ApprovalResult {
91
+ approvedBy: string;
92
+ at: number;
93
+ note?: string;
94
+ }
95
+ /**
96
+ * How long `ctx.sleep` waits: until a time (an ISO 8601 date-time with an offset, such as
97
+ * `2026-10-07T09:00:00Z`, or epoch milliseconds), or for a duration whose parts add up. A time
98
+ * already past waits not at all.
99
+ */
100
+ export type SleepRequest = {
101
+ until: string | number;
102
+ } | {
103
+ ms?: number;
104
+ seconds?: number;
105
+ minutes?: number;
106
+ hours?: number;
107
+ days?: number;
108
+ };
109
+ /** Checks a `ctx.sleep` request that names a time. */
110
+ export declare const SleepUntil: z.ZodObject<{
111
+ until: z.ZodUnion<readonly [z.ZodISODateTime, z.ZodNumber]>;
112
+ }, z.core.$strict>;
113
+ /** Checks a `ctx.sleep` request that names a duration. */
114
+ export declare const SleepFor: z.ZodObject<{
115
+ ms: z.ZodOptional<z.ZodNumber>;
116
+ seconds: z.ZodOptional<z.ZodNumber>;
117
+ minutes: z.ZodOptional<z.ZodNumber>;
118
+ hours: z.ZodOptional<z.ZodNumber>;
119
+ days: z.ZodOptional<z.ZodNumber>;
120
+ }, z.core.$strict>;
121
+ /** Checks a `ctx.all` argument: a list of functions, each one member. */
122
+ export declare const AllMembers: z.ZodArray<z.ZodCustom<() => unknown, () => unknown>>;
123
+ /**
124
+ * What a step is called, beside its operation: `ctx.ghost.post.create(input, { name: "Draft" })`,
125
+ * `ctx.sleep({ days: 1 }, { name: "Wait a day" })`. A string literal, or a top-level `const` of
126
+ * the workflow's file holding one, so the outline reads it. Without one, a call is named by its
127
+ * operation's id, a sleep `Sleep`; an approval by its title. Names are unique in a workflow, so a
128
+ * workflow that calls one operation twice names the calls.
129
+ */
130
+ export interface StepOptions {
131
+ name?: string;
132
+ }
133
+ type OpsOf<U extends readonly Use[]> = Extract<U[number], Op>;
134
+ type CtxOps<O extends Op> = {
135
+ readonly [V in O["vendor"]]: {
136
+ readonly [R in Extract<O, {
137
+ vendor: V;
138
+ }>["resource"]]: {
139
+ readonly [N in Extract<O, {
140
+ vendor: V;
141
+ resource: R;
142
+ }>["name"]]: Extract<O, {
143
+ vendor: V;
144
+ resource: R;
145
+ name: N;
146
+ }> extends Op<any, any, any, infer I, infer Out> ? (input: I, options?: StepOptions) => Promise<Out> : never;
147
+ };
148
+ };
149
+ };
150
+ interface ApprovalCtx {
151
+ /** Waits, durably, until the approver (or someone in the approver group) approves. Throws `RejectedError` on a rejection. */
152
+ approval(title: string, request: ApprovalRequest): Promise<ApprovalResult>;
153
+ }
154
+ interface SleepCtx {
155
+ /** Waits, durably, until a time or for a duration. Survives worker restarts. */
156
+ sleep(request: SleepRequest, options?: StepOptions): Promise<void>;
157
+ }
158
+ interface AllCtx {
159
+ /**
160
+ * Runs the members one after another, in order, and returns their outputs in that order. It
161
+ * declares a fan-out for the ledger and the graph; it adds no concurrency. The first member
162
+ * that throws stops the group with its error, and later members never run. Not nestable.
163
+ */
164
+ all<const T extends readonly (() => Promise<unknown>)[]>(members: T): Promise<{
165
+ -readonly [K in keyof T]: Awaited<ReturnType<T[K]>>;
166
+ }>;
167
+ }
168
+ interface BaseCtx {
169
+ /** The current time, recorded so replays see the same value. Use instead of `Date.now()`. */
170
+ now(): Promise<number>;
171
+ readonly runId: string;
172
+ }
173
+ export type Ctx<U extends readonly Use[]> = BaseCtx & CtxOps<OpsOf<U>> & ("approval" extends U[number] ? ApprovalCtx : unknown) & ("sleep" extends U[number] ? SleepCtx : unknown) & ("all" extends U[number] ? AllCtx : unknown);
174
+ /**
175
+ * A schema as JSON Schema (draft 2020-12). By default it describes what a caller sends
176
+ * (`io: "input"`: defaults stay optional); `io: "output"` describes what parsing returns.
177
+ * What JSON Schema can't express is left open. Throws when zod can't convert the schema at all.
178
+ */
179
+ export declare function jsonSchemaOf(schema: z.ZodType, io?: "input" | "output", refs?: ReadonlyMap<unknown, string>): Record<string, unknown>;
180
+ export interface WorkflowDefinition<U extends readonly Use[] = readonly Use[], S extends z.ZodType = z.ZodType> {
181
+ readonly kind: "workflow";
182
+ readonly name: string;
183
+ readonly title?: string;
184
+ readonly trigger: "manual";
185
+ readonly input: S;
186
+ /** Every operation and built-in the workflow may call. `ctx` is built from this list and nothing else. */
187
+ readonly uses: U;
188
+ readonly run: (ctx: Ctx<U>, input: z.output<S>) => Promise<unknown>;
189
+ /**
190
+ * The file that defined it, absolute. Set by defineWorkflow from its call site: the outline is
191
+ * read from it, the worker holds each run to that outline, and the app shows it as the code view.
192
+ */
193
+ readonly file: string;
194
+ }
195
+ /** The ids of the operations a workflow `uses`, in the order declared. */
196
+ export declare const opIdsOf: (wf: Pick<WorkflowDefinition, "uses">) => string[];
197
+ export declare function defineWorkflow<const U extends readonly Use[], S extends z.ZodType>(def: Omit<WorkflowDefinition<U, S>, "kind" | "file">): WorkflowDefinition<U, S>;
198
+ /**
199
+ * The file of the code that called the function calling this one (`defineWorkflow`'s caller),
200
+ * from V8's call sites, as a path; undefined where there is none.
201
+ */
202
+ export declare function callerFile(): string | undefined;
203
+ /** A V8 script name (a `file:` URL for a module, a path for a script) as a path; undefined for none. */
204
+ export declare function scriptPath(script: string | undefined): string | undefined;
205
+ export {};
package/dist/define.js ADDED
@@ -0,0 +1,103 @@
1
+ import { fileURLToPath } from "node:url";
2
+ import { getCallSites } from "node:util";
3
+ import { z } from "zod";
4
+ import { isOp } from "./op.js";
5
+ import { approverLabel } from "./shared.js";
6
+ export const Principal = z.object({
7
+ id: z.string().regex(/\S/, "id must not be blank"),
8
+ groups: z.array(z.string()).optional(),
9
+ });
10
+ export const Approver = z.union([z.string().regex(/\S/), z.object({ group: z.string().regex(/\S/) })], { error: 'needs an approver: a name, or { group: "name" }' });
11
+ /** Why `by` may not decide the approval, naming who may. */
12
+ export const notApprover = ({ approver }, by) => typeof approver === "string"
13
+ ? `${by.id} is not the approver; ${approverLabel(approver)} is`
14
+ : `${by.id} is not in ${approverLabel(approver)}`;
15
+ /** True when the two name the same approver: the same id, or the same group. */
16
+ export const sameApprover = (a, b) => typeof a === "string" || typeof b === "string" ? a === b : a.group === b.group;
17
+ const notOps = "covers must be a list of operations";
18
+ /** `covers` as given (operations), parsed to their ids. */
19
+ export const Covers = z
20
+ .array(z.object({ id: z.string() }, { error: notOps }).transform((op) => op.id), { error: notOps })
21
+ .optional();
22
+ /**
23
+ * Checks a `ctx.approval` request as a workflow may give it, so the UI and the ledger get what
24
+ * the types say, and turns `covers` into op ids.
25
+ */
26
+ export const ApprovalRequestSchema = z.object({
27
+ approver: Approver,
28
+ covers: Covers,
29
+ links: z.array(z.string(), { error: "links must be a list of strings" }).optional(),
30
+ details: z.string({ error: "details must be a string" }).optional(),
31
+ }, { error: "needs a request: { approver, covers?, links?, details? }" });
32
+ const time = "must be an ISO 8601 date-time with an offset, such as 2026-10-07T09:00:00Z, or epoch milliseconds";
33
+ const duration = z.number({ error: "must be a number" }).nonnegative("must not be negative").optional();
34
+ /** Checks a `ctx.sleep` request that names a time. */
35
+ export const SleepUntil = z.strictObject({
36
+ until: z.union([z.iso.datetime({ offset: true, error: time }), z.number({ error: time })], { error: time }),
37
+ });
38
+ /** Checks a `ctx.sleep` request that names a duration. */
39
+ export const SleepFor = z.strictObject({
40
+ ms: duration,
41
+ seconds: duration,
42
+ minutes: duration,
43
+ hours: duration,
44
+ days: duration,
45
+ });
46
+ /** Checks a `ctx.all` argument: a list of functions, each one member. */
47
+ export const AllMembers = z.array(z.custom((m) => typeof m === "function", "each member must be a function, such as () => ctx.…"), { error: "needs a list of functions: ctx.all([() => …, () => …])" });
48
+ /**
49
+ * A schema as JSON Schema (draft 2020-12). By default it describes what a caller sends
50
+ * (`io: "input"`: defaults stay optional); `io: "output"` describes what parsing returns.
51
+ * What JSON Schema can't express is left open. Throws when zod can't convert the schema at all.
52
+ */
53
+ export function jsonSchemaOf(schema, io = "input", refs) {
54
+ return z.toJSONSchema(schema, {
55
+ io,
56
+ target: "draft-2020-12",
57
+ unrepresentable: "any",
58
+ // A schema `refs` names, inside another, becomes a `$ref` to it (a resource type's state).
59
+ ...(refs?.size && {
60
+ override: ({ zodSchema, jsonSchema, path }) => {
61
+ const ref = path.length > 0 ? refs.get(zodSchema) : undefined;
62
+ if (ref === undefined)
63
+ return;
64
+ for (const key of Object.keys(jsonSchema))
65
+ delete jsonSchema[key];
66
+ Object.assign(jsonSchema, { $ref: ref });
67
+ },
68
+ }),
69
+ });
70
+ }
71
+ /** The ids of the operations a workflow `uses`, in the order declared. */
72
+ export const opIdsOf = (wf) => wf.uses.filter(isOp).map((op) => op.id);
73
+ export function defineWorkflow(def) {
74
+ if (!/^[a-z][a-z0-9-]*$/.test(def.name)) {
75
+ throw new Error(`Workflow name "${def.name}" must be lowercase letters, digits and dashes`);
76
+ }
77
+ const file = callerFile();
78
+ if (file === undefined) {
79
+ throw new Error(`Workflow "${def.name}" was defined from code with no file (an eval, or a bundle without one): ` +
80
+ "its outline is read from the file, and a run is held to the outline");
81
+ }
82
+ return Object.freeze({ kind: "workflow", ...def, file });
83
+ }
84
+ /**
85
+ * The file of the code that called the function calling this one (`defineWorkflow`'s caller),
86
+ * from V8's call sites, as a path; undefined where there is none.
87
+ */
88
+ export function callerFile() {
89
+ // Frame 0 is this function, frame 1 its caller, frame 2 theirs: by index, since a bundle may hold all three.
90
+ return scriptPath(getCallSites(3)[2]?.scriptName);
91
+ }
92
+ /** A V8 script name (a `file:` URL for a module, a path for a script) as a path; undefined for none. */
93
+ export function scriptPath(script) {
94
+ if (!script?.startsWith("file:"))
95
+ return script || undefined;
96
+ try {
97
+ return fileURLToPath(script);
98
+ }
99
+ catch {
100
+ return undefined;
101
+ }
102
+ }
103
+ //# sourceMappingURL=define.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"define.js","sourceRoot":"","sources":["../src/define.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,141 @@
1
+ import { type LintProblem } from "./ast.ts";
2
+ import { type SanomaConfig } from "./config.ts";
3
+ import { type Builtin } from "./define.ts";
4
+ import { type Effect } from "./op.ts";
5
+ import { type Outline } from "./outline.ts";
6
+ import { type ResourceFields } from "./resource.ts";
7
+ import { type DataFiles, type DeclaredResource, type ResourceProblem } from "./resources.ts";
8
+ export { outlineWorkflow, type Outline, type OutlineNode, type Span } from "./outline.ts";
9
+ export type { LintProblem } from "./ast.ts";
10
+ export { readDataFiles, readResources, type DataFiles, type DeclaredResource, type ResourceProblem, } from "./resources.ts";
11
+ export { formatOptions, renderDataFile, setFields, type DataFileContent } from "./writer.ts";
12
+ export { Reference, type DataValue } from "./datafile.ts";
13
+ export { LOCKFILE, readLockfile, serializeLockfile, writeLockfile, diffLockfiles, type Binding, type Bindings, type Rebind, } from "./lockfile.ts";
14
+ export type { ApplyInput, ApplyPlan, ApplyReport, ApplyResult, PlanAnswer, PlanStep } from "./apply.ts";
15
+ /** What a workflow is, read from its definition: enough to draw a start form and show what it may call. */
16
+ export interface WorkflowEntry {
17
+ name: string;
18
+ title?: string;
19
+ trigger: "manual";
20
+ /**
21
+ * Set for a workflow the runtime adds itself, `drift` or `apply`, rather than the config: a label. It
22
+ * starts like any other.
23
+ */
24
+ builtin?: true;
25
+ /** The input, as JSON Schema (draft 2020-12), from the zod schema. */
26
+ input: Record<string, unknown>;
27
+ /** Operation ids the workflow may call, in the order declared. */
28
+ ops: string[];
29
+ /** Built-ins the workflow may call. */
30
+ builtins: Builtin[];
31
+ /** The file that defined it, absolute. */
32
+ file: string;
33
+ /** What its `run` calls, in order, read from its file (`outlineWorkflow`), which the worker holds its runs to. */
34
+ outline: Outline;
35
+ /**
36
+ * What is wrong in its file, by position: what `lintWorkflow` finds (syntax, an import a
37
+ * workflow may not make, `instanceof` against the runtime's error classes, what the outline
38
+ * cannot draw in each `run`), read the one way the outline is, so a check sees what the
39
+ * worker refuses; and, at 1:1, an outline error that is the file's (it cannot be read, or holds
40
+ * no workflow of this name). A file defining several workflows gives each its problems. Empty
41
+ * for the built-in `drift`, which the package's tests hold to the lint.
42
+ */
43
+ problems: LintProblem[];
44
+ /**
45
+ * The text the outline's spans index into: the workflow's file, with `\n` line endings.
46
+ * Absent only when the outline is `{ error }`. Whole files: a server may keep it from clients.
47
+ */
48
+ source?: string;
49
+ }
50
+ /** What an operation is, read from its connector: enough to badge it and show its contract. */
51
+ export interface OpEntry {
52
+ id: string;
53
+ vendor: string;
54
+ resource: string;
55
+ name: string;
56
+ effect: Effect;
57
+ idempotent: boolean;
58
+ description?: string;
59
+ /** How a scenario's steps name it: Cucumber expressions over its input's fields. */
60
+ phrases?: {
61
+ given?: string;
62
+ expect?: string;
63
+ };
64
+ /** What a call sends, as JSON Schema (`io: "input"`: fields with defaults are optional). */
65
+ input: Record<string, unknown>;
66
+ /** What a call returns once its schema has parsed the vendor's reply (`io: "output"`). */
67
+ output: Record<string, unknown>;
68
+ }
69
+ /** Who a vendor is, from its connector's `VendorInfo`: enough to name it, show its logo and link to its connector. */
70
+ export interface VendorEntry {
71
+ /** The connector's `title`, else the vendor's id. */
72
+ title: string;
73
+ /** The logo as `data:image/svg+xml` URLs, for an `<img>`: `dark` is for dark backgrounds. */
74
+ logo?: {
75
+ src: string;
76
+ dark?: string;
77
+ };
78
+ /** The connector's npm package name. */
79
+ package?: string;
80
+ /** The connector package's `homepage` from its package.json: where its code and README are, as an https URL. */
81
+ homepage?: string;
82
+ /** Whether the vendor's connector attaches a fake (`withSetup`), for sandbox runs. */
83
+ fake: boolean;
84
+ }
85
+ /** A resource type a connector declares with `defineResource`. */
86
+ export interface ResourceTypeEntry {
87
+ /** `<vendor>.<type>`, such as `github.repository`. */
88
+ id: string;
89
+ vendor: string;
90
+ type: string;
91
+ title: string;
92
+ /** How a declared resource's identity is made, such as `name` or `repository_id:pattern`; absent when it is found only by its binding. */
93
+ identity?: string;
94
+ /** Its flagged fields, by dotted path. */
95
+ fields: ResourceFields;
96
+ /**
97
+ * Its state, as a read returns it, as JSON Schema (`io: "output"`), with `$id`
98
+ * `sanoma:resource-type/<id>`: the operations' contracts `$ref` it instead of repeating it.
99
+ */
100
+ schema: Record<string, unknown>;
101
+ /** Its operations' ids, sorted: `<id>.import` and `<id>.read`, and for a writable type its change operations. */
102
+ ops: string[];
103
+ }
104
+ /**
105
+ * A plain-JSON description of what a config can do: its workflows, the operations they call,
106
+ * and whether a policy gates them. The app server builds it from the config and sends it to the
107
+ * browser, so the UI shows exactly what the worker enforces. Never written by hand.
108
+ */
109
+ export interface ConfigDescription {
110
+ appName: string;
111
+ /** The application version runs started now are stamped with. */
112
+ version: string;
113
+ workflows: WorkflowEntry[];
114
+ ops: OpEntry[];
115
+ /** Every vendor the operations are from, by its id (an `OpEntry`'s `vendor`). */
116
+ vendors: Record<string, VendorEntry>;
117
+ /** The resource types the connectors declare, by `id`. */
118
+ resourceTypes: ResourceTypeEntry[];
119
+ /**
120
+ * The resources the data files under `resources/` declare, by file and then in file order,
121
+ * less any with a problem and any that names one.
122
+ */
123
+ resources: DeclaredResource[];
124
+ /** Each binding in the lockfile (`LOCKFILE`) whose key no data file declares, as `readDataFiles` reports it. */
125
+ orphans: DataFiles["orphans"];
126
+ /** What is wrong in the data files (`readDataFiles`), each at its file, relative to the root, line and column. A workflow's are on its entry. */
127
+ problems: ResourceProblem[];
128
+ /** `defined` is false for `allowAll`. */
129
+ policy: {
130
+ defined: boolean;
131
+ version?: string;
132
+ };
133
+ }
134
+ /**
135
+ * Describes a config. Throws what `startWorker` would refuse (see `resolveConfig`), except missing
136
+ * credentials (`SanomaClient.credentials` gives their statuses) and what is wrong in a workflow's
137
+ * file, which the worker refuses when it reads the outline: that is data, on each workflow's
138
+ * entry, as the data files' problems are, `problems`, beside the resources read without any.
139
+ * Each workflow's file is read and parsed once, however many workflows it defines.
140
+ */
141
+ export declare function describeConfig(config: SanomaConfig): ConfigDescription;
@@ -0,0 +1,135 @@
1
+ import { readSource } from "./ast.js";
2
+ import { resolveConfig } from "./config.js";
3
+ import { jsonSchemaOf, opIdsOf } from "./define.js";
4
+ import { lintWorkflow } from "./lint.js";
5
+ import { VENDOR } from "./op.js";
6
+ import { outlineWithSource } from "./outline.js";
7
+ import { allowAll, policyOpOf } from "./policy.js";
8
+ import { resourceTypesOf } from "./resource.js";
9
+ import { readDataFiles } from "./resources.js";
10
+ import { BUILT_IN_WORKFLOWS } from "./shared.js";
11
+ // `@sanoma-ai/workflows/describe`: what a UI renders from, apart from the main entry.
12
+ export { outlineWorkflow } from "./outline.js";
13
+ export { readDataFiles, readResources, } from "./resources.js";
14
+ // The writer: setting a resource's fields in its data file, and rendering a new one.
15
+ export { formatOptions, renderDataFile, setFields } from "./writer.js";
16
+ export { Reference } from "./datafile.js";
17
+ export { LOCKFILE, readLockfile, serializeLockfile, writeLockfile, diffLockfiles, } from "./lockfile.js";
18
+ /**
19
+ * Describes a config. Throws what `startWorker` would refuse (see `resolveConfig`), except missing
20
+ * credentials (`SanomaClient.credentials` gives their statuses) and what is wrong in a workflow's
21
+ * file, which the worker refuses when it reads the outline: that is data, on each workflow's
22
+ * entry, as the data files' problems are, `problems`, beside the resources read without any.
23
+ * Each workflow's file is read and parsed once, however many workflows it defines.
24
+ */
25
+ export function describeConfig(config) {
26
+ const resolved = resolveConfig(config);
27
+ const vendors = {};
28
+ // A vendor whose operations are split over several connectors is named by the first; its
29
+ // resource types are every connector's.
30
+ for (const connector of config.connectors) {
31
+ const { id, info } = connector[VENDOR];
32
+ vendors[id] ??= vendorEntry(id, info, resolved.fakes.has(id));
33
+ }
34
+ const resources = resourceTypesOf(config.connectors);
35
+ // Each resource type's state is described once, on its entry, and referenced from its operations.
36
+ const refs = new Map([...resources].map(([id, r]) => [r.schema, resourceTypeUri(id)]));
37
+ const resourceTypes = [...resources]
38
+ .map(([id, { vendor, type, title, identity, fields, schema, ops }]) => ({
39
+ id,
40
+ vendor,
41
+ type,
42
+ title,
43
+ identity,
44
+ fields,
45
+ schema: { $id: resourceTypeUri(id), ...toJsonSchema(schema, `${id} state`, "output") },
46
+ ops: Object.keys(ops)
47
+ .map((name) => `${id}.${name}`)
48
+ .toSorted(),
49
+ }))
50
+ .toSorted((a, b) => a.id.localeCompare(b.id));
51
+ const ops = [...resolved.ops.values()].map((op) => ({
52
+ ...policyOpOf(op),
53
+ idempotent: op.idempotent,
54
+ description: op.description,
55
+ ...(op.phrases && { phrases: op.phrases }),
56
+ input: toJsonSchema(op.input, `${op.id} input`, "input", refs),
57
+ output: toJsonSchema(op.output, `${op.id} output`, "output", refs),
58
+ }));
59
+ ops.sort((a, b) => a.id.localeCompare(b.id));
60
+ const read = memoised(readSource);
61
+ const lint = memoised((file) => lintWorkflow(file));
62
+ const workflows = [...resolved.workflows.values()].map((wf) => {
63
+ const file = read(wf.file);
64
+ const { outline, source, found } = outlineWithSource(wf, file);
65
+ // What the lint does not report: the file unread, or no workflow of this name in it.
66
+ const own = "error" in outline && !found && (typeof file === "string" || !file.problems.length);
67
+ const builtin = BUILT_IN_WORKFLOWS.has(wf.name);
68
+ const problems = builtin
69
+ ? []
70
+ : [
71
+ ...(typeof file === "string" ? [] : lint(file)),
72
+ ...(own ? [{ line: 1, column: 1, message: outline.error }] : []),
73
+ ];
74
+ return {
75
+ name: wf.name,
76
+ title: wf.title,
77
+ trigger: wf.trigger,
78
+ ...(builtin && { builtin: true }),
79
+ input: toJsonSchema(wf.input, `${wf.name} input`, "input"),
80
+ ops: opIdsOf(wf),
81
+ builtins: wf.uses.filter((u) => typeof u === "string"),
82
+ file: wf.file,
83
+ outline,
84
+ problems,
85
+ ...(source === undefined ? {} : { source }),
86
+ };
87
+ });
88
+ workflows.sort((a, b) => a.name.localeCompare(b.name));
89
+ const dataFiles = readDataFiles(resolved.root, config.connectors, resources);
90
+ return {
91
+ appName: resolved.appName,
92
+ version: resolved.version,
93
+ workflows,
94
+ ops,
95
+ vendors,
96
+ resourceTypes,
97
+ resources: dataFiles.resources,
98
+ orphans: dataFiles.orphans,
99
+ problems: dataFiles.problems,
100
+ policy: {
101
+ defined: resolved.policy !== allowAll,
102
+ ...(resolved.policy.version === undefined ? {} : { version: resolved.policy.version }),
103
+ },
104
+ };
105
+ }
106
+ /** `fn`, called once per argument for as long as the returned function lives. */
107
+ function memoised(fn) {
108
+ const seen = new Map();
109
+ return (arg) => {
110
+ if (!seen.has(arg))
111
+ seen.set(arg, fn(arg));
112
+ return seen.get(arg);
113
+ };
114
+ }
115
+ const svgDataUrl = (svg) => `data:image/svg+xml,${encodeURIComponent(svg.trim())}`;
116
+ const vendorEntry = (id, info, fake) => ({
117
+ title: info?.title ?? id,
118
+ ...(info?.logo && {
119
+ logo: { src: svgDataUrl(info.logo.svg), ...(info.logo.dark && { dark: svgDataUrl(info.logo.dark) }) },
120
+ }),
121
+ ...(info?.package && { package: info.package }),
122
+ ...(info?.homepage && { homepage: info.homepage }),
123
+ fake,
124
+ });
125
+ /** Where a resource type's state schema is, for a `$ref`. */
126
+ const resourceTypeUri = (id) => `sanoma:resource-type/${id}`;
127
+ function toJsonSchema(schema, what, io, refs) {
128
+ try {
129
+ return jsonSchemaOf(schema, io, refs);
130
+ }
131
+ catch (e) {
132
+ throw new Error(`Cannot describe ${what} as JSON Schema: ${e.message}`, { cause: e });
133
+ }
134
+ }
135
+ //# sourceMappingURL=describe.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"describe.js","sourceRoot":"","sources":["../src/describe.ts"],"names":[],"mappings":"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"}