@tailor-platform/sdk 2.0.0-next.6 → 2.0.0-next.7
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/CHANGELOG.md +47 -0
- package/dist/{application-BJXRpQj5.mjs → application-GzW98_Xr.mjs} +199 -172
- package/dist/application-GzW98_Xr.mjs.map +1 -0
- package/dist/application-OM0taSPn.mjs +3 -0
- package/dist/cli/index.mjs +12 -9
- package/dist/cli/index.mjs.map +1 -1
- package/dist/cli/lib.mjs +2 -2
- package/dist/completion/zsh-worker.zsh +1 -1
- package/dist/configure/config/types.d.mts +5 -1
- package/dist/configure/index.mjs +16 -16
- package/dist/configure/index.mjs.map +1 -1
- package/dist/configure/services/auth/types.d.mts +18 -23
- package/dist/configure/services/executor/operation.d.mts +1 -1
- package/dist/configure/services/workflow/job.d.mts +10 -10
- package/dist/configure/services/workflow/workflow.d.mts +6 -4
- package/dist/{globals-D-YbJKW-.mjs → globals-CBZ0egXT.mjs} +3 -6
- package/dist/globals-CBZ0egXT.mjs.map +1 -0
- package/dist/{register-ts-hook-DL31O2W9.mjs → register-ts-hook-DvEs6YsL.mjs} +35 -78
- package/dist/register-ts-hook-DvEs6YsL.mjs.map +1 -0
- package/dist/{registry-CC3CbQiF.mjs → registry-i7EdJ-D5.mjs} +10 -10
- package/dist/registry-i7EdJ-D5.mjs.map +1 -0
- package/dist/runtime/globals.d.mts +1 -4
- package/dist/runtime/index.mjs +1 -1
- package/dist/runtime/workflow.d.mts +1 -76
- package/dist/runtime/workflow.mjs +1 -1
- package/dist/service-BJAQ70e5.mjs +3 -0
- package/dist/{service-CnHz9rwz.mjs → service-Dmxa2I4i.mjs} +31 -17
- package/dist/service-Dmxa2I4i.mjs.map +1 -0
- package/dist/utils/test/index.mjs +11 -11
- package/dist/utils/test/index.mjs.map +1 -1
- package/dist/utils/test/mock.d.mts +6 -6
- package/dist/vitest/environment.mjs +1 -1
- package/dist/vitest/index.mjs +67 -99
- package/dist/vitest/index.mjs.map +1 -1
- package/dist/vitest/mocks/workflow.d.mts +21 -41
- package/dist/vitest/setup.mjs +1 -1
- package/dist/vitest/workflow-local.d.mts +2 -2
- package/dist/workflow-CsBvRE3g.mjs +34 -0
- package/dist/workflow-CsBvRE3g.mjs.map +1 -0
- package/docs/cli/application.md +2 -0
- package/docs/cli/function.md +2 -2
- package/docs/cli/tailordb.md +2 -2
- package/docs/cli-reference.md +1 -1
- package/docs/configuration.md +2 -0
- package/docs/github-actions.md +2 -2
- package/docs/migration/v2.md +128 -11
- package/docs/runtime.md +1 -1
- package/docs/services/auth.md +7 -7
- package/docs/services/workflow.md +43 -43
- package/docs/testing.md +9 -9
- package/package.json +2 -2
- package/dist/application-BJXRpQj5.mjs.map +0 -1
- package/dist/application-BV-AXawv.mjs +0 -3
- package/dist/globals-D-YbJKW-.mjs.map +0 -1
- package/dist/register-ts-hook-DL31O2W9.mjs.map +0 -1
- package/dist/registry-CC3CbQiF.mjs.map +0 -1
- package/dist/service-CnHz9rwz.mjs.map +0 -1
- package/dist/service-nU6ITOHL.mjs +0 -3
- package/dist/workflow-9kHGKxF2.mjs +0 -64
- package/dist/workflow-9kHGKxF2.mjs.map +0 -1
|
@@ -6,7 +6,7 @@ import { WaitPointInstance } from "../../configure/services/workflow/wait-point.
|
|
|
6
6
|
import { Mock } from "vitest";
|
|
7
7
|
//#region src/vitest/mocks/workflow.d.ts
|
|
8
8
|
type JobHandler = (jobName: string, args: unknown, options?: StartJobFunctionOptions) => unknown;
|
|
9
|
-
type
|
|
9
|
+
type StartHandlerFn = (workflowName: string, args: unknown, options?: StartWorkflowOptions) => string;
|
|
10
10
|
type ResumeHandlerFn = (executionId: string) => string;
|
|
11
11
|
type WaitHandlerFn = (key: string, payload: unknown) => unknown;
|
|
12
12
|
type ResolveHandler = (executionId: string, key: string, callback: (payload: unknown) => unknown) => unknown | Promise<unknown>;
|
|
@@ -14,7 +14,7 @@ type SetWaitHandler = {
|
|
|
14
14
|
(handler: WaitHandlerFn): void;
|
|
15
15
|
(handler: unknown): void;
|
|
16
16
|
};
|
|
17
|
-
interface
|
|
17
|
+
interface StartedJob {
|
|
18
18
|
jobName: string;
|
|
19
19
|
args: unknown;
|
|
20
20
|
options?: StartJobFunctionOptions;
|
|
@@ -23,17 +23,12 @@ type WaitPayload<Payload> = [Payload] extends [undefined] ? undefined : Payload;
|
|
|
23
23
|
/**
|
|
24
24
|
* Acquire a disposable mock for workflow operations (`tailor.workflow`).
|
|
25
25
|
* Restored on dispose.
|
|
26
|
-
*
|
|
27
|
-
* Canonical names (`startWorkflow`, `startJobFunction`, `resumeWorkflowExecution`)
|
|
28
|
-
* and their frozen aliases (`triggerWorkflow`, `triggerJobFunction`, `resumeWorkflow`)
|
|
29
|
-
* share the same underlying `vi.fn`, so calls through either name are recorded
|
|
30
|
-
* once and handlers configured on either name apply to both.
|
|
31
26
|
* @returns Disposable workflow mock control object
|
|
32
27
|
* @example
|
|
33
28
|
* ```typescript
|
|
34
29
|
* import { mockWorkflow } from "@tailor-platform/sdk/vitest";
|
|
35
30
|
*
|
|
36
|
-
* test("job
|
|
31
|
+
* test("job start", async () => {
|
|
37
32
|
* using wf = mockWorkflow();
|
|
38
33
|
* const job = wf.job(validateOrder);
|
|
39
34
|
* job.mockResolvedValue({ valid: true });
|
|
@@ -45,43 +40,28 @@ type WaitPayload<Payload> = [Payload] extends [undefined] ? undefined : Payload;
|
|
|
45
40
|
declare function mockWorkflow(): {
|
|
46
41
|
/** The `startJobFunction` `vi.fn`. */
|
|
47
42
|
startJobFunction: Mock<(jobName: string, _args?: unknown, _options?: StartJobFunctionOptions) => unknown>;
|
|
48
|
-
/**
|
|
49
|
-
* Frozen alias of `startJobFunction` (same `vi.fn` reference).
|
|
50
|
-
* @deprecated Use `startJobFunction` instead.
|
|
51
|
-
*/
|
|
52
|
-
triggerJobFunction: Mock<(jobName: string, _args?: unknown, _options?: StartJobFunctionOptions) => unknown>;
|
|
53
43
|
/** The `startWorkflow` `vi.fn`. */
|
|
54
44
|
startWorkflow: Mock<(_workflowName: string, _args?: unknown, _options?: StartWorkflowOptions) => Promise<string>>;
|
|
55
|
-
/**
|
|
56
|
-
* Frozen alias of `startWorkflow` (same `vi.fn` reference).
|
|
57
|
-
* @deprecated Use `startWorkflow` instead.
|
|
58
|
-
*/
|
|
59
|
-
triggerWorkflow: Mock<(_workflowName: string, _args?: unknown, _options?: StartWorkflowOptions) => Promise<string>>;
|
|
60
45
|
/** The `resumeWorkflowExecution` `vi.fn`. */
|
|
61
46
|
resumeWorkflowExecution: Mock<(executionId: string) => Promise<string>>;
|
|
62
|
-
/**
|
|
63
|
-
* Frozen alias of `resumeWorkflowExecution` (same `vi.fn` reference).
|
|
64
|
-
* @deprecated Use `resumeWorkflowExecution` instead.
|
|
65
|
-
*/
|
|
66
|
-
resumeWorkflow: Mock<(executionId: string) => Promise<string>>;
|
|
67
47
|
/** The `wait` `vi.fn`. */
|
|
68
48
|
wait: Mock<(_key: string, _payload?: unknown) => unknown>;
|
|
69
49
|
/** The `resolve` `vi.fn`. */
|
|
70
50
|
resolve: Mock<(_executionId: string, _key: string, _callback: (payload: unknown) => unknown) => Promise<void>>;
|
|
71
51
|
/**
|
|
72
|
-
* Get a stable, typed mock for a workflow job's `
|
|
73
|
-
* The real
|
|
52
|
+
* Get a stable, typed mock for a workflow job's `start` method.
|
|
53
|
+
* The real start behavior is used until an implementation or result is configured.
|
|
74
54
|
* @param definition - Workflow job definition to mock
|
|
75
|
-
* @returns Typed `
|
|
55
|
+
* @returns Typed `start` mock for the definition
|
|
76
56
|
*/
|
|
77
|
-
job<Name extends string, Input, Output>(definition: WorkflowJob<Name, Input, Output>): Mock<WorkflowJob<Name, Input, Output>["
|
|
57
|
+
job<Name extends string, Input, Output>(definition: WorkflowJob<Name, Input, Output>): Mock<WorkflowJob<Name, Input, Output>["start"]>;
|
|
78
58
|
/**
|
|
79
|
-
* Get a stable, typed mock for a workflow definition's `
|
|
80
|
-
* The real
|
|
59
|
+
* Get a stable, typed mock for a workflow definition's `start` method.
|
|
60
|
+
* The real start behavior is used until an implementation or result is configured.
|
|
81
61
|
* @param definition - Workflow definition to mock
|
|
82
|
-
* @returns Typed `
|
|
62
|
+
* @returns Typed `start` mock for the definition
|
|
83
63
|
*/
|
|
84
|
-
workflow<Definition extends Workflow>(definition: Definition): Mock<Definition["
|
|
64
|
+
workflow<Definition extends Workflow>(definition: Definition): Mock<Definition["start"]>;
|
|
85
65
|
/**
|
|
86
66
|
* Get stable, typed mocks for a wait point's `wait` and `resolve` methods.
|
|
87
67
|
* @param definition - Wait point definition to mock
|
|
@@ -98,30 +78,30 @@ declare function mockWorkflow(): {
|
|
|
98
78
|
*/
|
|
99
79
|
setJobHandler(handler: JobHandler): void;
|
|
100
80
|
/**
|
|
101
|
-
* Enqueue a single result for the next `
|
|
81
|
+
* Enqueue a single result for the next `startJobFunction` call (FIFO;
|
|
102
82
|
* takes priority over `setJobHandler`).
|
|
103
83
|
* @param result - Result to return from the next call
|
|
104
84
|
*/
|
|
105
85
|
enqueueResult(result: unknown): void;
|
|
106
86
|
/**
|
|
107
|
-
* Enqueue results for multiple subsequent `
|
|
87
|
+
* Enqueue results for multiple subsequent `startJobFunction` calls (FIFO).
|
|
108
88
|
* @param results - Results to enqueue, one per upcoming call
|
|
109
89
|
*/
|
|
110
90
|
enqueueResults(...results: unknown[]): void;
|
|
111
91
|
/**
|
|
112
|
-
* All jobs
|
|
113
|
-
* @returns
|
|
92
|
+
* All jobs started via `startJobFunction`, in order.
|
|
93
|
+
* @returns Started jobs array
|
|
114
94
|
*/
|
|
115
|
-
readonly
|
|
95
|
+
readonly startedJobs: StartedJob[];
|
|
116
96
|
/**
|
|
117
|
-
* Configure what `
|
|
97
|
+
* Configure what `startWorkflow` returns. Pass a string (same id every
|
|
118
98
|
* call) or `(name, args, options) => string`. Default: a placeholder UUID.
|
|
119
99
|
* @param handler - Static execution ID or a function returning one
|
|
120
100
|
*/
|
|
121
|
-
|
|
101
|
+
setStartHandler(handler: string | StartHandlerFn): void;
|
|
122
102
|
/**
|
|
123
|
-
* Configure what `
|
|
124
|
-
* call) or `(executionId) => string`. Default: echoes the input executionId.
|
|
103
|
+
* Configure what `resumeWorkflowExecution` returns. Pass a string (same id
|
|
104
|
+
* every call) or `(executionId) => string`. Default: echoes the input executionId.
|
|
125
105
|
* @param handler - Static execution ID or a function returning one
|
|
126
106
|
*/
|
|
127
107
|
setResumeHandler(handler: string | ResumeHandlerFn): void;
|
|
@@ -132,7 +112,7 @@ declare function mockWorkflow(): {
|
|
|
132
112
|
*/
|
|
133
113
|
setWaitHandler: SetWaitHandler;
|
|
134
114
|
/**
|
|
135
|
-
* Set the `env` passed to job bodies invoked via `createWorkflowJob().
|
|
115
|
+
* Set the `env` passed to job bodies invoked via `createWorkflowJob().start()`.
|
|
136
116
|
* Cleared on dispose / reset.
|
|
137
117
|
* @param env - Env passed to job bodies.
|
|
138
118
|
*/
|
package/dist/vitest/setup.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as RUNTIME_FLAG_KEY } from "../globals-
|
|
1
|
+
import { t as RUNTIME_FLAG_KEY } from "../globals-CBZ0egXT.mjs";
|
|
2
2
|
import { t as mockSecretmanager } from "../secretmanager-IY4UvinW.mjs";
|
|
3
3
|
import { pathToFileURL } from "node:url";
|
|
4
4
|
import { afterEach, beforeAll, beforeEach } from "vitest";
|
|
@@ -12,9 +12,9 @@ interface RunWorkflowLocallyOptions {
|
|
|
12
12
|
env?: TailorEnv;
|
|
13
13
|
}
|
|
14
14
|
/**
|
|
15
|
-
* Run a workflow's main job and dependent job
|
|
15
|
+
* Run a workflow's main job and dependent job starts locally with real job bodies.
|
|
16
16
|
*
|
|
17
|
-
* Use this for local full-chain workflow tests. Regular `.
|
|
17
|
+
* Use this for local full-chain workflow tests. Regular `.start()` calls
|
|
18
18
|
* delegate to the platform workflow runtime and should be mocked with
|
|
19
19
|
* `mockWorkflow()` when you are not intentionally running the local chain.
|
|
20
20
|
* @param workflow - Workflow definition to run
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
//#region src/runtime/workflow.ts
|
|
2
|
+
const api = () => globalThis.tailor.workflow;
|
|
3
|
+
/**
|
|
4
|
+
* See {@link PlatformWorkflowAPI.startWorkflow}.
|
|
5
|
+
* @param args - Forwarded to {@link PlatformWorkflowAPI.startWorkflow}
|
|
6
|
+
* @returns The execution ID of the started workflow
|
|
7
|
+
*/
|
|
8
|
+
const startWorkflow = (...args) => api().startWorkflow(...args);
|
|
9
|
+
/**
|
|
10
|
+
* See {@link PlatformWorkflowAPI.resumeWorkflowExecution}.
|
|
11
|
+
* @param args - Forwarded to {@link PlatformWorkflowAPI.resumeWorkflowExecution}
|
|
12
|
+
* @returns The execution ID of the resumed workflow
|
|
13
|
+
*/
|
|
14
|
+
const resumeWorkflowExecution = (...args) => api().resumeWorkflowExecution(...args);
|
|
15
|
+
/**
|
|
16
|
+
* See {@link PlatformWorkflowAPI.startJobFunction}.
|
|
17
|
+
* @param args - Forwarded to {@link PlatformWorkflowAPI.startJobFunction}
|
|
18
|
+
* @returns The job's return value
|
|
19
|
+
*/
|
|
20
|
+
const startJobFunction = (...args) => api().startJobFunction(...args);
|
|
21
|
+
const wait = (...args) => api().wait(...args);
|
|
22
|
+
const resolve = (...args) => api().resolve(...args);
|
|
23
|
+
/** Runtime wrapper namespace for `tailor.workflow`. */
|
|
24
|
+
const workflow = {
|
|
25
|
+
startWorkflow,
|
|
26
|
+
resumeWorkflowExecution,
|
|
27
|
+
startJobFunction,
|
|
28
|
+
wait,
|
|
29
|
+
resolve
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
//#endregion
|
|
33
|
+
export { workflow as t };
|
|
34
|
+
//# sourceMappingURL=workflow-CsBvRE3g.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow-CsBvRE3g.mjs","names":[],"sources":["../src/runtime/workflow.ts"],"sourcesContent":["/**\n * Workflow utilities.\n *\n * Thin typed wrapper around the platform-provided `tailor.workflow` runtime API.\n * At runtime this delegates to `globalThis.tailor.workflow`. Use `mockWorkflow`\n * from `@tailor-platform/sdk/vitest` to mock these calls in unit tests.\n * @example\n * import { workflow } from \"@tailor-platform/sdk/runtime\";\n *\n * const executionId = await workflow.startWorkflow(\"myWorkflow\", { data: \"value\" });\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\n/**\n * Specifies the machine user that should be used to execute the workflow.\n * This allows workflows to run with specific authentication context.\n */\nexport interface Invoker {\n /** The namespace where the machine user is defined */\n namespace: string;\n /** The name of the machine user to use for workflow execution */\n machineUserName: string;\n}\n\n/** Options for {@link startWorkflow}. */\nexport interface StartWorkflowOptions {\n /** Optional authentication invoker to specify which machine user should execute the workflow */\n authInvoker?: Invoker;\n}\n\ndeclare const executionPolicyKeyBrand: unique symbol;\n\n/**\n * A concrete runtime key produced by an execution policy instance — either an\n * exact-match policy's `.key`, or a wildcard policy's `.keyFor(suffix)` (see\n * `defineWorkflowExecutionPolicies`). Branded so an arbitrary string that\n * wasn't derived from a declared policy can't be passed as `executionPolicyKey`.\n */\nexport type ExecutionPolicyKey = string & { readonly [executionPolicyKeyBrand]: never };\n\n/** Options for {@link startJobFunction}. */\nexport interface StartJobFunctionOptions {\n /**\n * Execution policy key matched by the platform against the policies\n * declared with `defineWorkflowExecutionPolicies` in `tailor.config.ts`.\n */\n executionPolicyKey?: ExecutionPolicyKey;\n}\n\n/**\n * Platform API surface for `tailor.workflow`. Describes the shape the platform\n * runtime injects on `globalThis.tailor.workflow`.\n */\nexport interface PlatformWorkflowAPI {\n /**\n * Starts a workflow and returns its execution ID.\n * @param workflowName - Workflow name as defined in tailor.config\n * @param args - Arguments forwarded to the workflow's main job\n * @param options - Optional start options (e.g. `authInvoker`)\n * @returns The execution ID of the started workflow\n */\n startWorkflow(workflowName: string, args?: any, options?: StartWorkflowOptions): Promise<string>;\n\n /**\n * Resumes a failed or pending-retry workflow execution and returns its execution ID.\n * @param executionId - The execution to resume\n * @returns The execution ID of the resumed workflow\n */\n resumeWorkflowExecution(executionId: string): Promise<string>;\n\n /**\n * Starts a job function and returns its result.\n * @param jobName - Job name as defined in the workflow\n * @param args - Arguments forwarded to the job\n * @param options - Optional start options (e.g. `executionPolicyKey`)\n * @returns The job's return value\n */\n startJobFunction(jobName: string, args?: any, options?: StartJobFunctionOptions): any;\n\n /**\n * Suspends the current workflow execution and waits for an external signal to resume.\n * @param key - Wait point key\n * @param payload - Optional payload to record with the wait point\n * @returns The payload supplied by the corresponding `resolve` call\n */\n wait(key: string, payload?: any): any;\n\n /**\n * Resolves a waiting workflow execution, causing it to resume.\n * @param executionId - The execution to resume\n * @param key - Wait point key to resolve\n * @param callback - Callback receiving the wait payload; its return value is forwarded to `wait`\n * @returns A promise that resolves once the resolve has been recorded\n */\n resolve(executionId: string, key: string, callback: (waitPayload: any) => any): Promise<void>;\n}\n\nconst api = (): PlatformWorkflowAPI =>\n (globalThis as unknown as { tailor: { workflow: PlatformWorkflowAPI } }).tailor.workflow;\n\n/**\n * See {@link PlatformWorkflowAPI.startWorkflow}.\n * @param args - Forwarded to {@link PlatformWorkflowAPI.startWorkflow}\n * @returns The execution ID of the started workflow\n */\nconst startWorkflow: PlatformWorkflowAPI[\"startWorkflow\"] = (...args) =>\n api().startWorkflow(...args);\n\n/**\n * See {@link PlatformWorkflowAPI.resumeWorkflowExecution}.\n * @param args - Forwarded to {@link PlatformWorkflowAPI.resumeWorkflowExecution}\n * @returns The execution ID of the resumed workflow\n */\nconst resumeWorkflowExecution: PlatformWorkflowAPI[\"resumeWorkflowExecution\"] = (...args) =>\n api().resumeWorkflowExecution(...args);\n\n/**\n * See {@link PlatformWorkflowAPI.startJobFunction}.\n * @param args - Forwarded to {@link PlatformWorkflowAPI.startJobFunction}\n * @returns The job's return value\n */\nconst startJobFunction: PlatformWorkflowAPI[\"startJobFunction\"] = (...args) =>\n api().startJobFunction(...args);\n\nconst wait: PlatformWorkflowAPI[\"wait\"] = (...args) => api().wait(...args);\n\nconst resolve: PlatformWorkflowAPI[\"resolve\"] = (...args) => api().resolve(...args);\n\n/** Runtime wrapper namespace for `tailor.workflow`. */\nexport const workflow = {\n startWorkflow,\n resumeWorkflowExecution,\n startJobFunction,\n wait,\n resolve,\n} as const satisfies PlatformWorkflowAPI;\n"],"mappings":";AAkGA,MAAM,YACH,WAAwE,OAAO;;;;;;AAOlF,MAAM,iBAAuD,GAAG,SAC9D,IAAI,CAAC,CAAC,cAAc,GAAG,IAAI;;;;;;AAO7B,MAAM,2BAA2E,GAAG,SAClF,IAAI,CAAC,CAAC,wBAAwB,GAAG,IAAI;;;;;;AAOvC,MAAM,oBAA6D,GAAG,SACpE,IAAI,CAAC,CAAC,iBAAiB,GAAG,IAAI;AAEhC,MAAM,QAAqC,GAAG,SAAS,IAAI,CAAC,CAAC,KAAK,GAAG,IAAI;AAEzE,MAAM,WAA2C,GAAG,SAAS,IAAI,CAAC,CAAC,QAAQ,GAAG,IAAI;;AAGlF,MAAa,WAAW;CACtB;CACA;CACA;CACA;CACA;AACF"}
|
package/docs/cli/application.md
CHANGED
|
@@ -130,6 +130,8 @@ tailor deploy --config apps/buyer/tailor.config.ts,apps/supplier/tailor.config.t
|
|
|
130
130
|
|
|
131
131
|
When multiple configs are provided, `deploy` creates or updates all configured services first, then updates the applications. This lets one application reference resources owned by another config with `external: true` during the same deploy.
|
|
132
132
|
|
|
133
|
+
Each config's `files` and `ignores` patterns (see [Service Configuration](../configuration.md#service-configuration)) resolve relative to that config's own directory, not the directory you ran `deploy` from. For example, `apps/buyer/tailor.config.ts` declaring `files: ["db/**/*.ts"]` loads files from `apps/buyer/db/`, independent of where `apps/supplier/tailor.config.ts`'s patterns resolve. If a config's relative patterns match nothing under its own directory, the SDK falls back to the invocation directory and logs a warning (see [Service Configuration](../configuration.md#service-configuration) for details).
|
|
134
|
+
|
|
133
135
|
**Migration Handling:**
|
|
134
136
|
|
|
135
137
|
When migrations are configured (`db.tailordb.migration` in config), the `deploy` command automatically:
|
package/docs/cli/function.md
CHANGED
|
@@ -178,5 +178,5 @@ You can pass either a source file (`.ts`) or a pre-bundled file (`.js`).
|
|
|
178
178
|
When a `.js` file is provided, detection and bundling are skipped and the file is executed as-is.
|
|
179
179
|
|
|
180
180
|
> [!WARNING]
|
|
181
|
-
> Workflow job `.
|
|
182
|
-
>
|
|
181
|
+
> Workflow job `.start()` calls do not work in test-run mode.
|
|
182
|
+
> Started jobs are not executed; only the target job's `body` function runs in isolation.
|
package/docs/cli/tailordb.md
CHANGED
|
@@ -231,10 +231,10 @@ See [Global Options](../cli-reference.md#global-options) for options available t
|
|
|
231
231
|
|
|
232
232
|
### tailordb erd
|
|
233
233
|
|
|
234
|
-
The `tailordb erd` commands (export, diff, serve, deploy) are provided by the `@tailor-platform/sdk-tailordb-erd
|
|
234
|
+
The `tailordb erd` commands (export, diff, serve, deploy) are provided by the `@tailor-platform/sdk-plugin-tailordb-erd` CLI plugin. Install it next to the SDK and keep running `tailor tailordb erd <command>` as before:
|
|
235
235
|
|
|
236
236
|
```bash
|
|
237
|
-
npm install -D @tailor-platform/sdk-tailordb-erd
|
|
237
|
+
npm install -D @tailor-platform/sdk-plugin-tailordb-erd@next
|
|
238
238
|
tailor tailordb erd export --namespace myNamespace
|
|
239
239
|
```
|
|
240
240
|
|
package/docs/cli-reference.md
CHANGED
|
@@ -121,7 +121,7 @@ tailor hello world --loud
|
|
|
121
121
|
|
|
122
122
|
This also works under a built-in command group. The command path is joined with hyphens, so a plugin
|
|
123
123
|
nested under `tailordb` is named `tailor-tailordb-erd`. This is how the
|
|
124
|
-
`@tailor-platform/sdk-tailordb-erd
|
|
124
|
+
`@tailor-platform/sdk-plugin-tailordb-erd`
|
|
125
125
|
package provides the `tailordb erd` commands:
|
|
126
126
|
|
|
127
127
|
```bash
|
package/docs/configuration.md
CHANGED
|
@@ -82,6 +82,8 @@ export default defineConfig({
|
|
|
82
82
|
|
|
83
83
|
**ignores**: Glob patterns to exclude files. Optional. By default, `**/*.test.ts` and `**/*.spec.ts` are automatically ignored. If you explicitly specify `ignores`, the default patterns will not be applied. Use `ignores: []` to include all files including test files.
|
|
84
84
|
|
|
85
|
+
**Pattern resolution**: `files` and `ignores` patterns are resolved relative to the directory of the `tailor.config.ts` file that declares them, not the directory you run the command from. This matters when deploying [multiple configs](./cli/application.md#deploy) together — each config's patterns only match files under its own directory. If a config's _relative_ patterns match nothing under its own directory, the SDK falls back to resolving them from the directory you ran the command from and logs a warning (this fallback doesn't apply to already-absolute patterns, since their resolution can't change). Update such patterns to be relative to the config's own directory — this fallback will be removed in v2.
|
|
86
|
+
|
|
85
87
|
### External Resources
|
|
86
88
|
|
|
87
89
|
You can reference resources managed by Terraform or other SDK projects to include them in your application's subgraph. External resources are not deployed by this project but can be used for shared access across multiple applications.
|
package/docs/github-actions.md
CHANGED
|
@@ -73,11 +73,11 @@ tailor setup -n my-app-stg --erd-preview
|
|
|
73
73
|
```
|
|
74
74
|
|
|
75
75
|
The generated workflow runs `tailor tailordb erd`, which is provided by the
|
|
76
|
-
`@tailor-platform/sdk-tailordb-erd
|
|
76
|
+
`@tailor-platform/sdk-plugin-tailordb-erd` CLI plugin — install it as a
|
|
77
77
|
dev-dependency in your project:
|
|
78
78
|
|
|
79
79
|
```bash
|
|
80
|
-
npm install -D @tailor-platform/sdk-tailordb-erd
|
|
80
|
+
npm install -D @tailor-platform/sdk-plugin-tailordb-erd@next
|
|
81
81
|
```
|
|
82
82
|
|
|
83
83
|
The generated workflow builds one self-contained ERD viewer HTML file for each
|
package/docs/migration/v2.md
CHANGED
|
@@ -350,7 +350,7 @@ Do not change behavior beyond the auth.invoker() removal.
|
|
|
350
350
|
|
|
351
351
|
**Migration:** Partially automatic
|
|
352
352
|
|
|
353
|
-
Rename statically identified SDK `authInvoker` options to `invoker`, replace `auth.invoker("name")` there with the bare `"name"` string, and drop the `auth` import when no other reference remains. Ambiguous workflow `.
|
|
353
|
+
Rename statically identified SDK `authInvoker` options to `invoker`, replace `auth.invoker("name")` there with the bare `"name"` string, and drop the `auth` import when no other reference remains. Ambiguous workflow `.start()` calls are left for manual review. The `auth.invoker()` helper is removed in v2 because importing `auth` from `tailor.config.ts` into runtime files pulls Node-only modules into the bundle.
|
|
354
354
|
|
|
355
355
|
Before:
|
|
356
356
|
|
|
@@ -378,8 +378,8 @@ For each remaining auth.invoker(<expr>) call:
|
|
|
378
378
|
machine user name string; platform/runtime authInvoker payloads still expect
|
|
379
379
|
the object form.
|
|
380
380
|
2. Rename remaining authInvoker option keys to invoker only for SDK resolver,
|
|
381
|
-
executor, workflow.
|
|
382
|
-
payload keys such as tailor.workflow.
|
|
381
|
+
executor, workflow.start(), or startWorkflow() options. Keep platform/runtime
|
|
382
|
+
payload keys such as tailor.workflow.startWorkflow(..., { authInvoker: ... }).
|
|
383
383
|
3. After removing every auth.invoker usage in a file, delete the now-unused auth
|
|
384
384
|
import (keeping it pulls Node-only config modules into runtime bundles); leave
|
|
385
385
|
the import if auth is still referenced elsewhere.
|
|
@@ -694,6 +694,73 @@ export const { approval } = createWaitPoints((define) => ({
|
|
|
694
694
|
}));
|
|
695
695
|
```
|
|
696
696
|
|
|
697
|
+
## workflow.triggerWorkflow/triggerJobFunction/resumeWorkflow → startWorkflow/startJobFunction/resumeWorkflowExecution
|
|
698
|
+
|
|
699
|
+
**Migration:** Partially automatic
|
|
700
|
+
|
|
701
|
+
Rename tailor.workflow call sites from the pre-alignment triggerWorkflow/triggerJobFunction/resumeWorkflow names to the canonical startWorkflow/startJobFunction/resumeWorkflowExecution names, on both the ambient tailor.workflow global and a workflow value imported from @tailor-platform/sdk/runtime(/workflow). For a renamed triggerWorkflow call, also renames a literal `invoker` option key to `authInvoker` — startWorkflow's options expect the platform shape directly, unlike the removed triggerWorkflow wrapper, which converted invoker to authInvoker internally.
|
|
702
|
+
|
|
703
|
+
Before:
|
|
704
|
+
|
|
705
|
+
```ts
|
|
706
|
+
import { workflow } from "@tailor-platform/sdk/runtime";
|
|
707
|
+
|
|
708
|
+
await workflow.triggerWorkflow("myWorkflow", { data: "value" });
|
|
709
|
+
```
|
|
710
|
+
|
|
711
|
+
After:
|
|
712
|
+
|
|
713
|
+
```ts
|
|
714
|
+
import { workflow } from "@tailor-platform/sdk/runtime";
|
|
715
|
+
|
|
716
|
+
await workflow.startWorkflow("myWorkflow", { data: "value" });
|
|
717
|
+
```
|
|
718
|
+
|
|
719
|
+
A literal invoker option is renamed to authInvoker:
|
|
720
|
+
|
|
721
|
+
Before:
|
|
722
|
+
|
|
723
|
+
```ts
|
|
724
|
+
await workflow.triggerWorkflow("myWorkflow", { data: "value" }, { invoker: myInvoker });
|
|
725
|
+
```
|
|
726
|
+
|
|
727
|
+
After:
|
|
728
|
+
|
|
729
|
+
```ts
|
|
730
|
+
await workflow.startWorkflow("myWorkflow", { data: "value" }, { authInvoker: myInvoker });
|
|
731
|
+
```
|
|
732
|
+
|
|
733
|
+
<details>
|
|
734
|
+
<summary>Prompt for an AI agent (to finish the cases the codemod could not migrate)</summary>
|
|
735
|
+
|
|
736
|
+
```text
|
|
737
|
+
The pre-alignment tailor.workflow names triggerWorkflow, triggerJobFunction, and
|
|
738
|
+
resumeWorkflow are removed from the SDK's type surface in v2; use the canonical
|
|
739
|
+
startWorkflow, startJobFunction, and resumeWorkflowExecution names instead. The
|
|
740
|
+
codemod rewrites direct member-access call sites on the ambient tailor.workflow
|
|
741
|
+
global and on a workflow value imported from @tailor-platform/sdk/runtime or
|
|
742
|
+
@tailor-platform/sdk/runtime/workflow (including aliased imports). It skips a
|
|
743
|
+
file entirely when a local declaration shadows the workflow import or the
|
|
744
|
+
ambient tailor name, to avoid rewriting an unrelated same-named value — review
|
|
745
|
+
those manually.
|
|
746
|
+
|
|
747
|
+
For a renamed triggerWorkflow call, the codemod also renames a literal invoker
|
|
748
|
+
option key (including shorthand { invoker }) to authInvoker, since startWorkflow
|
|
749
|
+
expects the platform's authInvoker shape directly while triggerWorkflow's removed
|
|
750
|
+
wrapper converted invoker to authInvoker internally.
|
|
751
|
+
|
|
752
|
+
Also review, and migrate by hand:
|
|
753
|
+
- Destructured references (e.g. const { triggerWorkflow } = workflow) — the
|
|
754
|
+
codemod only rewrites direct member-access calls.
|
|
755
|
+
- Imported TriggerWorkflowOptions / TriggerJobFunctionOptions types — rename
|
|
756
|
+
them to StartWorkflowOptions / StartJobFunctionOptions.
|
|
757
|
+
- An invoker option passed via a variable or spread (not a literal object) —
|
|
758
|
+
the codemod only inspects literal object arguments; rename the invoker key
|
|
759
|
+
to authInvoker in the options object's own definition.
|
|
760
|
+
```
|
|
761
|
+
|
|
762
|
+
</details>
|
|
763
|
+
|
|
697
764
|
## openDownloadStream → downloadStream
|
|
698
765
|
|
|
699
766
|
**Migration:** Manual
|
|
@@ -787,18 +854,18 @@ string literals.
|
|
|
787
854
|
|
|
788
855
|
</details>
|
|
789
856
|
|
|
790
|
-
## Workflow
|
|
857
|
+
## Workflow job start() and start tests
|
|
791
858
|
|
|
792
859
|
**Migration:** Manual
|
|
793
860
|
|
|
794
|
-
Workflow job `.trigger()` now aligns with the platform runtime: it returns the job result directly instead of a Promise wrapper, and tests no longer run job bodies locally. Mock
|
|
861
|
+
Workflow job `.start()` (previously `.trigger()`) now aligns with the platform runtime: it returns the job result directly instead of a Promise wrapper, and tests no longer run job bodies locally. Mock start responses with `mockWorkflow()` (`setJobHandler` / `enqueueResult`, assert via `startedJobs`), or use `runWorkflowLocally()` for a full-chain local run.
|
|
795
862
|
|
|
796
863
|
Tests must mock the workflow runtime instead of running bodies locally:
|
|
797
864
|
|
|
798
865
|
Before:
|
|
799
866
|
|
|
800
867
|
```ts
|
|
801
|
-
const result = await orderJob.
|
|
868
|
+
const result = await orderJob.start({ id });
|
|
802
869
|
expect(result.status).toBe("done");
|
|
803
870
|
```
|
|
804
871
|
|
|
@@ -807,7 +874,7 @@ After:
|
|
|
807
874
|
```ts
|
|
808
875
|
using wf = mockWorkflow();
|
|
809
876
|
wf.setJobHandler((jobName) => (jobName === "order-job" ? { status: "done" } : null));
|
|
810
|
-
const result = await orderJob.
|
|
877
|
+
const result = await orderJob.start({ id });
|
|
811
878
|
expect(result.status).toBe("done");
|
|
812
879
|
```
|
|
813
880
|
|
|
@@ -815,11 +882,57 @@ expect(result.status).toBe("done");
|
|
|
815
882
|
<summary>Prompt for an AI agent (to perform this migration)</summary>
|
|
816
883
|
|
|
817
884
|
```text
|
|
818
|
-
Workflow job .
|
|
885
|
+
Workflow job .start() now uses the platform workflow runtime instead of running
|
|
819
886
|
the job body locally. In tests, acquire `using wf = mockWorkflow()` and provide
|
|
820
|
-
|
|
821
|
-
full-chain local run; an unmocked
|
|
822
|
-
|
|
887
|
+
start responses (setJobHandler / enqueueResult), or use runWorkflowLocally() for a
|
|
888
|
+
full-chain local run; an unmocked start now throws. Outside tests, treat the
|
|
889
|
+
start result as the job output directly (no Promise wrapper to unwrap).
|
|
890
|
+
```
|
|
891
|
+
|
|
892
|
+
</details>
|
|
893
|
+
|
|
894
|
+
## Workflow.trigger()/WorkflowJob.trigger() → .start()
|
|
895
|
+
|
|
896
|
+
**Migration:** Manual
|
|
897
|
+
|
|
898
|
+
Rename `Workflow.trigger()` (returned by `createWorkflow()`) and `WorkflowJob.trigger()` (returned by `createWorkflowJob()`) to `.start()`, aligning the SDK's ergonomic verb with the platform's `start*` RPC vocabulary. No codemod ships for this rename: distinguishing a workflow/job `.trigger()` call from an unrelated object's own `.trigger()` method requires resolving the receiver back to a `createWorkflow`/`createWorkflowJob` result across files, which the SDK's own CLI bundler already does for build-time rewriting. Reusing that logic in a standalone script is a nontrivial lift, and — unlike the bundler, which fails loudly when it cannot rewrite a call — a codemod false positive would silently rewrite an unrelated `.trigger()` call with no error. For the call-site volume this rename typically involves, manual review guided by the prompt below is the safer trade-off.
|
|
899
|
+
|
|
900
|
+
Before:
|
|
901
|
+
|
|
902
|
+
```ts
|
|
903
|
+
const inventory = checkInventory.trigger({ orderId: input.orderId });
|
|
904
|
+
const workflowRunId = await orderProcessingWorkflow.trigger(args, { invoker: "manager" });
|
|
905
|
+
```
|
|
906
|
+
|
|
907
|
+
After:
|
|
908
|
+
|
|
909
|
+
```ts
|
|
910
|
+
const inventory = checkInventory.start({ orderId: input.orderId });
|
|
911
|
+
const workflowRunId = await orderProcessingWorkflow.start(args, { invoker: "manager" });
|
|
912
|
+
```
|
|
913
|
+
|
|
914
|
+
<details>
|
|
915
|
+
<summary>Prompt for an AI agent (to perform this migration)</summary>
|
|
916
|
+
|
|
917
|
+
```text
|
|
918
|
+
In Tailor SDK v2, the ergonomic .trigger() method on a createWorkflow() or
|
|
919
|
+
createWorkflowJob() result is renamed to .start(). This is unrelated to the
|
|
920
|
+
separate tailor.workflow.triggerWorkflow/triggerJobFunction/resumeWorkflow removal
|
|
921
|
+
(see the workflow-trigger-rename codemod) — this rename targets the SDK's own
|
|
922
|
+
ergonomic wrapper, not the low-level platform call.
|
|
923
|
+
|
|
924
|
+
For each flagged `.trigger(` call in these files:
|
|
925
|
+
1. Confirm the receiver is a workflow or job object — typically a local const
|
|
926
|
+
assigned from createWorkflow(...)/createWorkflowJob(...), a named import of one,
|
|
927
|
+
or the default import of a workflow module. Skip receivers that are unrelated
|
|
928
|
+
objects with their own .trigger() method (state machines, event emitters, etc.).
|
|
929
|
+
2. Rename the call from .trigger(...) to .start(...); the argument list is unchanged.
|
|
930
|
+
3. Update any mock/test code that reads WorkflowJob['trigger'] / Workflow['trigger']
|
|
931
|
+
as a type, or that mocks the ergonomic method via a wrapper — for example,
|
|
932
|
+
`wf.job(definition)` / `wf.workflow(definition)` from mockWorkflow() now return a
|
|
933
|
+
mock of the `.start` method.
|
|
934
|
+
4. Update prose/docs/comments that say "trigger the workflow/job" to "start" only
|
|
935
|
+
where they describe this SDK verb specifically, not unrelated event terminology.
|
|
823
936
|
```
|
|
824
937
|
|
|
825
938
|
</details>
|
|
@@ -1091,3 +1204,7 @@ The CLI stores human users by their stable subject ID instead of email (email is
|
|
|
1091
1204
|
### Node.js minimum version raised to 22.15.0
|
|
1092
1205
|
|
|
1093
1206
|
v2 requires Node.js **22.15.0** or later. This is the first version that includes `module.registerHooks()`, which the SDK uses to register its TypeScript loader hook synchronously in the main thread. No source change is required; ensure your environment runs Node.js 22.15.0+.
|
|
1207
|
+
|
|
1208
|
+
### Legacy bundle artifact cleanup removed from deploy
|
|
1209
|
+
|
|
1210
|
+
`tailor deploy` no longer deletes on-disk bundle artifacts (`.entry.js` files, workflow-job bundles, and the `hooks-validate-scripts/` directory) left in the SDK output directory (`.tailor` by default) by SDK versions that predate the current in-memory bundling approach. Current bundlers no longer write these files. No source change is required; if such stale files remain from a very old SDK version, delete only those specific files/directories manually — do not delete the output directory itself, since it also holds deploy state (e.g. `secrets-state/`, `*.context.json`) that existing secrets and Auth Connections depend on.
|
package/docs/runtime.md
CHANGED
|
@@ -81,7 +81,7 @@ The runtime entry re-exports the following namespaces. Detailed signatures, para
|
|
|
81
81
|
- `secretmanager` — secret-vault access (`getSecret`, `getSecrets`)
|
|
82
82
|
- `authconnection` — OAuth-style connection tokens (`getConnectionToken`)
|
|
83
83
|
- `idp` — IdP user management (`new Client({ namespace })`)
|
|
84
|
-
- `workflow` — workflow & job control (`startWorkflow`, `resumeWorkflowExecution`, `startJobFunction`, `wait`, `resolve
|
|
84
|
+
- `workflow` — workflow & job control (`startWorkflow`, `resumeWorkflowExecution`, `startJobFunction`, `wait`, `resolve`)
|
|
85
85
|
- `context` — execution context (`getInvoker`)
|
|
86
86
|
- `file` — `tailordb.file` BLOB API (`upload`, `download`, `downloadAsBase64`, `delete`, `getMetadata`, `downloadStream`, `uploadStream`)
|
|
87
87
|
- `aigateway` — AI Gateway URL resolution (`get`)
|
package/docs/services/auth.md
CHANGED
|
@@ -107,7 +107,7 @@ userProfile: {
|
|
|
107
107
|
|
|
108
108
|
**usernameField**: The field in the TailorDB type used as the username. This field must have a unique constraint (`.unique()`) since it is used to uniquely identify users.
|
|
109
109
|
|
|
110
|
-
**attributes**: Specifies which fields from the TailorDB type are used as user attributes. Set to `true` to enable a field.
|
|
110
|
+
**attributes**: Specifies which fields from the TailorDB type are used as user attributes. Set to `true` to enable a field. Machine user definitions must assign values to attributes derived from required fields; attributes derived from optional fields may be omitted (see [Machine Users](#machine-users)). Only fields with ValueOperand types (string, boolean, string[], boolean[]) can be used as attributes. The `id` field and datetime/date/time types are excluded.
|
|
111
111
|
|
|
112
112
|
## Attribute List
|
|
113
113
|
|
|
@@ -200,7 +200,7 @@ machineUsers: {
|
|
|
200
200
|
},
|
|
201
201
|
```
|
|
202
202
|
|
|
203
|
-
**attributes**: Values for attributes enabled in `userProfile.attributes` (or
|
|
203
|
+
**attributes**: Values for attributes enabled in `userProfile.attributes` (or fields defined in `machineUserAttributes` when `userProfile` is omitted). Attribute keys mirror the field's optionality: attributes derived from required fields must be set, while attributes derived from optional fields may be omitted. Setting an attribute to `null` or `undefined` is equivalent to omitting it — the attribute is deployed as unset. These values are accessible via the runtime principal's `attributes`:
|
|
204
204
|
|
|
205
205
|
```typescript
|
|
206
206
|
// In a resolver
|
|
@@ -269,7 +269,7 @@ tailor machineuser token <name>
|
|
|
269
269
|
|
|
270
270
|
### Specifying a machine user invoker
|
|
271
271
|
|
|
272
|
-
Resolvers, executors, and `workflow.
|
|
272
|
+
Resolvers, executors, and `workflow.start()` accept an `invoker` option that chooses which machine user runs the operation. Pass the machine user name as a plain string — it is type-narrowed to the names you registered in `machineUsers`.
|
|
273
273
|
|
|
274
274
|
```typescript
|
|
275
275
|
// tailor.config.ts
|
|
@@ -284,19 +284,19 @@ export const auth = defineAuth("my-auth", {
|
|
|
284
284
|
```
|
|
285
285
|
|
|
286
286
|
```typescript
|
|
287
|
-
// resolvers/
|
|
287
|
+
// resolvers/start-workflow.ts
|
|
288
288
|
import { createResolver, t } from "@tailor-platform/sdk";
|
|
289
289
|
import myWorkflow from "../workflows/my-workflow";
|
|
290
290
|
|
|
291
291
|
export default createResolver({
|
|
292
|
-
name: "
|
|
292
|
+
name: "startMyWorkflow",
|
|
293
293
|
operation: "mutation",
|
|
294
294
|
input: {
|
|
295
295
|
id: t.string(),
|
|
296
296
|
},
|
|
297
297
|
body: async ({ input }) => {
|
|
298
|
-
//
|
|
299
|
-
const workflowRunId = await myWorkflow.
|
|
298
|
+
// Start workflow with machine user permissions
|
|
299
|
+
const workflowRunId = await myWorkflow.start(
|
|
300
300
|
{ id: input.id },
|
|
301
301
|
{ invoker: "admin-machine-user" },
|
|
302
302
|
);
|