@tailor-platform/sdk 0.23.4 → 0.24.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.
@@ -1,10 +1,10 @@
1
1
  /// <reference path="./user-defined.d.ts" />
2
- import * as zod0 from "zod";
2
+ import * as zod34 from "zod";
3
3
  import { z } from "zod";
4
4
  import * as type_fest0 from "type-fest";
5
5
  import { IsAny, NonEmptyObject } from "type-fest";
6
6
  import { StandardSchemaV1 } from "@standard-schema/spec";
7
- import * as zod_v4_core0 from "zod/v4/core";
7
+ import * as zod_v4_core50 from "zod/v4/core";
8
8
 
9
9
  //#region src/configure/types/helpers.d.ts
10
10
  type Prettify<T$1> = { [K in keyof T$1 as string extends K ? never : K]: T$1[K] } & {};
@@ -1394,7 +1394,7 @@ interface AppConfig<Auth extends AuthConfig = AuthConfig, Idp extends IdPConfig[
1394
1394
  name: string;
1395
1395
  env?: Env;
1396
1396
  cors?: string[];
1397
- allowedIPAddresses?: string[];
1397
+ allowedIpAddresses?: string[];
1398
1398
  disableIntrospection?: boolean;
1399
1399
  db?: TailorDBServiceInput;
1400
1400
  resolver?: ResolverServiceInput;
@@ -1417,12 +1417,12 @@ declare function defineGenerators(...configs: GeneratorConfig[]): (["@tailor-pla
1417
1417
  }] | {
1418
1418
  id: string;
1419
1419
  description: string;
1420
- processType: zod_v4_core0.$InferInnerFunctionType<zod_v4_core0.$ZodFunctionArgs, zod_v4_core0.$ZodFunctionOut>;
1421
- processResolver: zod_v4_core0.$InferInnerFunctionType<zod_v4_core0.$ZodFunctionArgs, zod_v4_core0.$ZodFunctionOut>;
1422
- processExecutor: zod_v4_core0.$InferInnerFunctionType<zod_v4_core0.$ZodFunctionArgs, zod_v4_core0.$ZodFunctionOut>;
1423
- aggregate: zod_v4_core0.$InferInnerFunctionType<zod_v4_core0.$ZodFunctionArgs, zod0.ZodAny>;
1424
- processTailorDBNamespace?: zod_v4_core0.$InferInnerFunctionType<zod_v4_core0.$ZodFunctionArgs, zod_v4_core0.$ZodFunctionOut> | undefined;
1425
- processResolverNamespace?: zod_v4_core0.$InferInnerFunctionType<zod_v4_core0.$ZodFunctionArgs, zod_v4_core0.$ZodFunctionOut> | undefined;
1420
+ processType: zod_v4_core50.$InferInnerFunctionType<zod_v4_core50.$ZodFunctionArgs, zod_v4_core50.$ZodFunctionOut>;
1421
+ processResolver: zod_v4_core50.$InferInnerFunctionType<zod_v4_core50.$ZodFunctionArgs, zod_v4_core50.$ZodFunctionOut>;
1422
+ processExecutor: zod_v4_core50.$InferInnerFunctionType<zod_v4_core50.$ZodFunctionArgs, zod_v4_core50.$ZodFunctionOut>;
1423
+ aggregate: zod_v4_core50.$InferInnerFunctionType<zod_v4_core50.$ZodFunctionArgs, zod34.ZodAny>;
1424
+ processTailorDBNamespace?: zod_v4_core50.$InferInnerFunctionType<zod_v4_core50.$ZodFunctionArgs, zod_v4_core50.$ZodFunctionOut> | undefined;
1425
+ processResolverNamespace?: zod_v4_core50.$InferInnerFunctionType<zod_v4_core50.$ZodFunctionArgs, zod_v4_core50.$ZodFunctionOut> | undefined;
1426
1426
  })[];
1427
1427
  //#endregion
1428
1428
  //#region src/parser/service/executor/schema.d.ts
@@ -1561,4 +1561,4 @@ type Executor = z.infer<typeof ExecutorSchema>;
1561
1561
  type ExecutorInput = z.input<typeof ExecutorSchema>;
1562
1562
  //#endregion
1563
1563
  export { SCIMAttribute as $, TailorDBType as A, AuthConfig as B, ResolverExternalConfig as C, InferFieldsOutput as Ct, ExecutorServiceInput as D, ExecutorServiceConfig as E, PermissionCondition as F, AuthServiceInput as G, AuthInvoker as H, TailorTypeGqlPermission as I, IdProviderConfig as J, BuiltinIdP as K, TailorTypePermission as L, AllowedValues as M, AllowedValuesOutput as N, TailorDBField as O, ParsedTailorDBType as P, SAML as Q, unsafeAllowAllGqlPermission as R, defineIdp as S, FieldOutput$1 as St, ResolverServiceInput as T, output as Tt, AuthOwnConfig as U, AuthExternalConfig as V, defineAuth as W, OAuth2ClientInput as X, OAuth2ClientGrantType as Y, OIDC as Z, WorkflowServiceInput as _, Resolver as _t, IncomingWebhookTrigger as a, TenantProviderConfig as at, IdPConfig as b, FieldMetadata as bt, ScheduleTriggerInput as c, UserAttributeMap as ct, AppConfig as d, AttributeList as dt, SCIMAttributeMapping as et, defineConfig as f, AttributeMap as ft, WorkflowServiceConfig as g, QueryType as gt, Generator as h, TailorField as ht, GqlOperation as i, SCIMResource as it, db as j, TailorDBInstance as k, WebhookOperation as l, UsernameFieldKey as lt, CodeGeneratorBase as m, unauthenticatedTailorUser as mt, ExecutorInput as n, SCIMAuthorization as nt, RecordTrigger as o, UserAttributeKey as ot, defineGenerators as p, TailorUser as pt, IDToken as q, FunctionOperation as r, SCIMConfig as rt, ResolverExecutedTrigger as s, UserAttributeListKey as st, Executor as t, SCIMAttributeType as tt, WorkflowOperation as u, ValueOperand as ut, StaticWebsiteConfig as v, ResolverInput as vt, ResolverServiceConfig as w, JsonCompatible as wt, IdPExternalConfig as x, FieldOptions as xt, defineStaticWebSite as y, ArrayFieldOutput as yt, unsafeAllowAllTypePermission as z };
1564
- //# sourceMappingURL=types-CgO-wV9v.d.mts.map
1564
+ //# sourceMappingURL=types-CbL5qnOl.d.mts.map
@@ -1,6 +1,6 @@
1
1
  /// <reference path="./../../user-defined.d.ts" />
2
- import { A as TailorDBType, ht as TailorField } from "../../types-CgO-wV9v.mjs";
3
- import { n as output } from "../../index-CANeLBB6.mjs";
2
+ import { A as TailorDBType, ht as TailorField } from "../../types-CbL5qnOl.mjs";
3
+ import { n as output } from "../../index-D_6mOKf-.mjs";
4
4
  import { StandardSchemaV1 } from "@standard-schema/spec";
5
5
 
6
6
  //#region src/utils/test/index.d.ts
@@ -16,17 +16,19 @@ For service-specific documentation, see:
16
16
  ### Application Settings
17
17
 
18
18
  ```typescript
19
+ import { defineConfig } from "@tailor-platform/sdk";
20
+
19
21
  export default defineConfig({
20
22
  name: "my-app",
21
- cors: ["https://example.com", website.url],
22
- allowedIPAddresses: ["192.168.1.0/24"],
23
+ cors: ["https://example.com"],
24
+ allowedIpAddresses: ["192.168.1.0/24"],
23
25
  disableIntrospection: false,
24
26
  });
25
27
  ```
26
28
 
27
29
  **Name**: Set the application name.
28
30
 
29
- **CORS**: Specify CORS settings as an array.
31
+ **CORS**: Specify CORS settings as an array. You can also include Static Website URL references (e.g. `website.url`) in this array; see [Static Website](./services/staticwebsite.md).
30
32
 
31
33
  **Allowed IP Addresses**: Specify IP addresses allowed to access the application in CIDR format.
32
34
 
@@ -74,7 +74,12 @@ scheduleTrigger({ cron: "0 * * * *", timezone: "Asia/Tokyo" });
74
74
  Fires when an external webhook is received:
75
75
 
76
76
  ```typescript
77
- incomingWebhookTrigger<WebhookPayload>();
77
+ type WebhookRequest = {
78
+ body: WebhookPayload;
79
+ headers: Record<string, string>;
80
+ };
81
+
82
+ incomingWebhookTrigger<WebhookRequest>();
78
83
  ```
79
84
 
80
85
  ### Resolver Executed Trigger
@@ -113,8 +118,7 @@ Call external webhooks with dynamic data:
113
118
  createExecutor({
114
119
  operation: {
115
120
  kind: "webhook",
116
- url: ({ newRecord }) =>
117
- `https://api.example.com/webhooks/${newRecord.type}`,
121
+ url: ({ typeName }) => `https://api.example.com/webhooks/${typeName}`,
118
122
  headers: {
119
123
  "Content-Type": "application/json",
120
124
  "X-API-Key": { vault: "api-keys", key: "external-api" },
@@ -133,13 +137,11 @@ createExecutor({
133
137
  Execute GraphQL queries and mutations:
134
138
 
135
139
  ```typescript
136
- import { gql } from "@tailor-platform/sdk";
137
-
138
140
  createExecutor({
139
141
  operation: {
140
142
  kind: "graphql",
141
143
  appName: "my-app",
142
- query: gql`
144
+ query: `
143
145
  mutation UpdateUserStatus($id: ID!, $status: String!) {
144
146
  updateUser(id: $id, input: { status: $status }) {
145
147
  id
@@ -169,7 +171,7 @@ Record triggers receive context based on the operation type:
169
171
  ```typescript
170
172
  interface RecordCreatedContext<T> {
171
173
  workspaceId: string; // Workspace identifier
172
- namespaceName: string; // Application/namespace name
174
+ appNamespace: string; // Application/namespace name
173
175
  typeName: string; // TailorDB type name
174
176
  newRecord: T; // The newly created record
175
177
  }
@@ -180,7 +182,7 @@ interface RecordCreatedContext<T> {
180
182
  ```typescript
181
183
  interface RecordUpdatedContext<T> {
182
184
  workspaceId: string;
183
- namespaceName: string;
185
+ appNamespace: string;
184
186
  typeName: string;
185
187
  oldRecord: T; // Previous record state
186
188
  newRecord: T; // Current record state
@@ -192,7 +194,7 @@ interface RecordUpdatedContext<T> {
192
194
  ```typescript
193
195
  interface RecordDeletedContext<T> {
194
196
  workspaceId: string;
195
- namespaceName: string;
197
+ appNamespace: string;
196
198
  typeName: string;
197
199
  oldRecord: T; // The deleted record
198
200
  }
@@ -240,7 +242,7 @@ Webhook triggers receive HTTP request data:
240
242
  interface WebhookContext<T = unknown> {
241
243
  body: T; // Parsed request body
242
244
  headers: Record<string, string>; // Request headers
243
- method: string; // HTTP method (POST, etc.)
245
+ method: "POST" | "GET" | "PUT" | "DELETE"; // HTTP method
244
246
  rawBody: string; // Raw request body as string
245
247
  }
246
248
  ```
@@ -257,7 +259,10 @@ interface StripeWebhook {
257
259
 
258
260
  export default createExecutor({
259
261
  name: "stripe-webhook",
260
- trigger: incomingWebhookTrigger<StripeWebhook>(),
262
+ trigger: incomingWebhookTrigger<{
263
+ body: StripeWebhook;
264
+ headers: { "stripe-signature": string };
265
+ }>(),
261
266
  operation: {
262
267
  kind: "function",
263
268
  body: async ({ body, headers }) => {
@@ -275,9 +280,11 @@ Resolver triggers receive the resolver's result or error:
275
280
 
276
281
  ```typescript
277
282
  interface ResolverExecutedContext<TResult> {
283
+ workspaceId: string; // Workspace identifier
284
+ appNamespace: string; // Application/namespace name
278
285
  resolverName: string; // Name of the executed resolver
279
286
  result?: TResult; // Return value (on success)
280
- error?: Error; // Error object (on failure)
287
+ error?: string; // Error message (on failure)
281
288
  }
282
289
  ```
283
290
 
@@ -40,13 +40,13 @@ defineStaticWebSite("my-website", {
40
40
  });
41
41
  ```
42
42
 
43
- ### allowedIPAddresses
43
+ ### allowedIpAddresses
44
44
 
45
45
  Restrict access to specific IP addresses in CIDR format:
46
46
 
47
47
  ```typescript
48
48
  defineStaticWebSite("my-website", {
49
- allowedIPAddresses: ["192.168.0.0/24", "10.0.0.0/8"],
49
+ allowedIpAddresses: ["192.168.0.0/24", "10.0.0.0/8"],
50
50
  });
51
51
  ```
52
52
 
@@ -10,7 +10,7 @@ Workflows provide:
10
10
  - Durable execution with automatic state management
11
11
  - Resume capabilities from failure points
12
12
  - Access to TailorDB via Kysely query builder
13
- - Job triggering for parallel or sequential execution
13
+ - Job triggering to compose multi-step logic
14
14
 
15
15
  For the official Tailor Platform documentation, see [Workflow Guide](https://docs.tailor.tech/guides/workflow).
16
16
 
@@ -18,13 +18,12 @@ For the official Tailor Platform documentation, see [Workflow Guide](https://doc
18
18
 
19
19
  All workflow components must follow these rules:
20
20
 
21
- | Rule | Description |
22
- | ---------------------------------------------- | --------------------------------------------------- |
23
- | `createWorkflow` result must be default export | Workflow files must export the workflow as default |
24
- | All jobs must be named exports | Every job used in a workflow must be a named export |
25
- | Job names must be unique | Job names must be unique across the entire project |
26
- | `mainJob` is required | Every workflow must specify a `mainJob` |
27
- | Jobs in `deps` must be job objects | Pass job objects, not strings |
21
+ | Rule | Description |
22
+ | ---------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
23
+ | `createWorkflow` result must be default export | Workflow files must export the workflow as default |
24
+ | All jobs must be named exports | Includes `mainJob` and any job triggered via `.trigger()` (even if referenced only within the same file) |
25
+ | Job `name` values must be unique | Job names must be unique across the entire project |
26
+ | `mainJob` is required | Every workflow must specify a `mainJob` |
28
27
 
29
28
  ## Creating a Workflow Job
30
29
 
@@ -49,56 +48,27 @@ export const fetchCustomer = createWorkflowJob({
49
48
  });
50
49
  ```
51
50
 
52
- ## Job Dependencies
51
+ ## Triggering Jobs
52
+
53
+ Use `.trigger()` to start other jobs from within a job.
53
54
 
54
- Jobs can depend on other jobs using the `deps` array. Dependent jobs are accessible via the second argument of `body` function with hyphens replaced by underscores:
55
+ Jobs are triggered by calling `.trigger()` on the other job object (no `deps` and no `jobs` object in the context).
55
56
 
56
57
  ```typescript
57
58
  import { createWorkflowJob } from "@tailor-platform/sdk";
58
59
  import { fetchCustomer } from "./jobs/fetch-customer";
59
60
  import { sendNotification } from "./jobs/send-notification";
60
61
 
61
- // All jobs must be named exports - including jobs with dependencies
62
- export const processOrder = createWorkflowJob({
63
- name: "process-order",
64
- deps: [fetchCustomer, sendNotification],
65
- body: async (input: { orderId: string; customerId: string }, { jobs }) => {
66
- // Access dependent jobs with hyphens replaced by underscores
67
- // "fetch-customer" -> jobs.fetch_customer()
68
- // "send-notification" -> jobs.send_notification()
69
- const customer = await jobs.fetch_customer({
70
- customerId: input.customerId,
71
- });
72
-
73
- const notification = await jobs.send_notification({
74
- message: `Order ${input.orderId} is being processed`,
75
- recipient: customer.email,
76
- });
77
-
78
- return {
79
- orderId: input.orderId,
80
- customerEmail: customer.email,
81
- notificationSent: notification.sent,
82
- };
83
- },
84
- });
85
- ```
86
-
87
- ## Triggering Jobs
88
-
89
- Use `.trigger()` to start other jobs from within a job:
90
-
91
- ```typescript
92
62
  export const mainJob = createWorkflowJob({
93
63
  name: "main-job",
94
- deps: [fetchCustomer, sendNotification],
95
- body: (input: { customerId: string }, { jobs }) => {
96
- // .trigger() is synchronous on server - do NOT use await
97
- // "fetch-customer" -> jobs.fetch_customer
98
- const customer = jobs.fetch_customer.trigger({
64
+ body: async (input: { customerId: string }) => {
65
+ // You can write `await` for type-safety in your source.
66
+ // During deployment bundling, job.trigger() calls are transformed to a synchronous
67
+ // runtime call and `await` is removed.
68
+ const customer = await fetchCustomer.trigger({
99
69
  customerId: input.customerId,
100
70
  });
101
- const notification = jobs.send_notification.trigger({
71
+ const notification = await sendNotification.trigger({
102
72
  message: "Order processed",
103
73
  recipient: customer.email,
104
74
  });
@@ -107,7 +77,7 @@ export const mainJob = createWorkflowJob({
107
77
  });
108
78
  ```
109
79
 
110
- **Important:** `.trigger()` is synchronous on the server. Do NOT use `await` with it.
80
+ **Important:** On the Tailor runtime, job triggers are executed synchronously. This means `Promise.all([jobA.trigger(), jobB.trigger()])` will not run jobs in parallel.
111
81
 
112
82
  ## Workflow Definition
113
83
 
@@ -121,9 +91,17 @@ import { sendNotification } from "./jobs/send-notification";
121
91
  // Jobs must be named exports
122
92
  export const processOrder = createWorkflowJob({
123
93
  name: "process-order",
124
- deps: [fetchCustomer, sendNotification],
125
- body: async (input, { jobs }) => {
126
- // ... job logic
94
+ body: async (input: { customerId: string }, { env }) => {
95
+ // `env` contains values from `tailor.config.ts` -> `env`.
96
+ // Trigger other jobs by calling .trigger() on the job object.
97
+ const customer = await fetchCustomer.trigger({
98
+ customerId: input.customerId,
99
+ });
100
+ await sendNotification.trigger({
101
+ message: "Order processed",
102
+ recipient: customer.email,
103
+ });
104
+ return { customerId: input.customerId };
127
105
  },
128
106
  });
129
107
 
@@ -134,6 +112,41 @@ export default createWorkflow({
134
112
  });
135
113
  ```
136
114
 
115
+ ## Triggering a Workflow from a Resolver
116
+
117
+ You can start a workflow execution from a resolver using `workflow.trigger()`.
118
+
119
+ - `workflow.trigger(args, options?)` returns a workflow run ID (`Promise<string>`).
120
+ - To run with machine-user permissions, pass `{ authInvoker: auth.invoker("<machine-user>") }`.
121
+
122
+ ```typescript
123
+ import { createResolver, t } from "@tailor-platform/sdk";
124
+ import { auth } from "../tailor.config";
125
+ import orderProcessingWorkflow from "../workflows/order-processing";
126
+
127
+ export default createResolver({
128
+ name: "triggerOrderProcessing",
129
+ operation: "mutation",
130
+ input: {
131
+ orderId: t.string(),
132
+ customerId: t.string(),
133
+ },
134
+ body: async ({ input }) => {
135
+ const workflowRunId = await orderProcessingWorkflow.trigger(
136
+ { orderId: input.orderId, customerId: input.customerId },
137
+ { authInvoker: auth.invoker("manager-machine-user") },
138
+ );
139
+
140
+ return { workflowRunId };
141
+ },
142
+ output: t.object({
143
+ workflowRunId: t.string(),
144
+ }),
145
+ });
146
+ ```
147
+
148
+ See the full working example in the repository: [example/resolvers/triggerWorkflow.ts](../../../../example/resolvers/triggerWorkflow.ts).
149
+
137
150
  ## File Organization
138
151
 
139
152
  Recommended file structure for workflows:
package/docs/testing.md CHANGED
@@ -189,6 +189,12 @@ E2E tests verify your application works correctly when deployed to Tailor Platfo
189
189
 
190
190
  ### Setting Up E2E Tests
191
191
 
192
+ The examples below use `graphql-request` as a lightweight GraphQL client.
193
+
194
+ ```bash
195
+ pnpm add -D graphql-request
196
+ ```
197
+
192
198
  **1. Global Setup**
193
199
 
194
200
  Create a global setup file that retrieves deployment information before running tests:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tailor-platform/sdk",
3
- "version": "0.23.4",
3
+ "version": "0.24.0",
4
4
  "description": "Tailor Platform SDK - The SDK to work with Tailor Platform",
5
5
  "license": "MIT",
6
6
  "main": "./dist/configure/index.mjs",
@@ -83,7 +83,7 @@
83
83
  "eslint-plugin-jsdoc": "61.5.0",
84
84
  "globals": "16.5.0",
85
85
  "sonda": "0.10.1",
86
- "tsdown": "0.18.1",
86
+ "tsdown": "0.18.2",
87
87
  "typescript": "5.9.3",
88
88
  "typescript-eslint": "8.50.0",
89
89
  "vitest": "4.0.16"
@@ -97,6 +97,7 @@
97
97
  "lint": "eslint --cache .",
98
98
  "lint:fix": "eslint --cache . --fix",
99
99
  "typecheck": "tsc --noEmit",
100
+ "perf:typecheck": "bash scripts/perf/exec.sh",
100
101
  "prepublish": "pnpm run build",
101
102
  "postinstall": "node postinstall.mjs",
102
103
  "measure:bundle": "node ../../scripts/measure-bundle-size-sonda.js"