@tailor-platform/sdk 1.35.1 → 1.36.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +52 -0
- package/dist/application-BB5TqXWY.mjs +4 -0
- package/dist/{application-BnJRroGX.mjs → application-BwboBFcU.mjs} +102 -17
- package/dist/application-BwboBFcU.mjs.map +1 -0
- package/dist/cli/index.mjs +303 -17
- package/dist/cli/index.mjs.map +1 -1
- package/dist/cli/lib.d.mts +190 -6
- package/dist/cli/lib.mjs +3 -3
- package/dist/{client-BmQP4kKS.mjs → client-B6icVEv4.mjs} +1 -1
- package/dist/{client-CA2NM_4R.mjs → client-CN15WgW2.mjs} +25 -8
- package/dist/client-CN15WgW2.mjs.map +1 -0
- package/dist/configure/index.d.mts +5 -5
- package/dist/configure/index.mjs +38 -9
- package/dist/configure/index.mjs.map +1 -1
- package/dist/{crash-report-Bd2T8BhU.mjs → crash-report-CB1UtT3O.mjs} +1 -1
- package/dist/{crash-report-CPkI2-cp.mjs → crash-report-CdxPj_SW.mjs} +2 -2
- package/dist/{crash-report-CPkI2-cp.mjs.map → crash-report-CdxPj_SW.mjs.map} +1 -1
- package/dist/{env-MSlwZt8l.d.mts → env-_ce3IYbl.d.mts} +2 -2
- package/dist/{index-B1Fgxi8D.d.mts → index-C7vIBAg8.d.mts} +2 -2
- package/dist/{index-wCoQup4y.d.mts → index-CYaunQeL.d.mts} +76 -6
- package/dist/{index-D-tMAFVp.d.mts → index-CxSLivW7.d.mts} +2 -2
- package/dist/{index-BG7YCyXF.d.mts → index-DDCyefuU.d.mts} +2 -2
- package/dist/{index-BBlE_vQF.d.mts → index-DZN1QFLM.d.mts} +2 -2
- package/dist/plugin/builtin/enum-constants/index.d.mts +1 -1
- package/dist/plugin/builtin/file-utils/index.d.mts +1 -1
- package/dist/plugin/builtin/kysely-type/index.d.mts +1 -1
- package/dist/plugin/builtin/seed/index.d.mts +1 -1
- package/dist/plugin/index.d.mts +2 -2
- package/dist/{plugin-CZaJ3_QR.d.mts → plugin-CiPUxkyN.d.mts} +3 -2
- package/dist/{runtime-D4O-RfcH.mjs → runtime-C7RRDaB3.mjs} +230 -22
- package/dist/runtime-C7RRDaB3.mjs.map +1 -0
- package/dist/utils/test/index.d.mts +2 -2
- package/dist/{workflow.generated-IZ3kLjC_.d.mts → workflow.generated-8BeGQsVU.d.mts} +212 -4
- package/docs/cli/function.md +2 -2
- package/docs/services/idp.md +50 -0
- package/docs/services/resolver.md +1 -1
- package/docs/services/secret.md +25 -0
- package/docs/services/workflow.md +48 -0
- package/package.json +9 -8
- package/dist/application-BnJRroGX.mjs.map +0 -1
- package/dist/application-mGasp_EX.mjs +0 -4
- package/dist/client-CA2NM_4R.mjs.map +0 -1
- package/dist/runtime-D4O-RfcH.mjs.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="@tailor-platform/function-types" />
|
|
2
|
-
import { U as TailorDBType, rt as TailorField } from "../../plugin-
|
|
3
|
-
import {
|
|
2
|
+
import { U as TailorDBType, rt as TailorField } from "../../plugin-CiPUxkyN.mjs";
|
|
3
|
+
import { n as output, rt as WORKFLOW_TEST_ENV_KEY } from "../../index-CYaunQeL.mjs";
|
|
4
4
|
import { StandardSchemaV1 } from "@standard-schema/spec";
|
|
5
5
|
|
|
6
6
|
//#region src/utils/test/mock.d.ts
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference types="@tailor-platform/function-types" />
|
|
2
|
-
import { Nt as BuiltinIdP, S as TailorDBServiceInput, T as AuthConfig } from "./plugin-
|
|
2
|
+
import { Nt as BuiltinIdP, S as TailorDBServiceInput, T as AuthConfig } from "./plugin-CiPUxkyN.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/types/idp.generated.d.ts
|
|
5
5
|
/**
|
|
@@ -59,6 +59,193 @@ type IdPInput = {
|
|
|
59
59
|
emailConfig?: {
|
|
60
60
|
fromName?: string | undefined;
|
|
61
61
|
passwordResetSubject?: string | undefined;
|
|
62
|
+
} | undefined; /** Per-operation permission policies for IdP users */
|
|
63
|
+
permission?: {
|
|
64
|
+
create: readonly (readonly (string | boolean | readonly string[] | readonly boolean[] | {
|
|
65
|
+
user: string;
|
|
66
|
+
} | {
|
|
67
|
+
idpUser: "name" | "id" | "disabled";
|
|
68
|
+
} | {
|
|
69
|
+
oldIdpUser: "name" | "id" | "disabled";
|
|
70
|
+
} | {
|
|
71
|
+
newIdpUser: "name" | "id" | "disabled";
|
|
72
|
+
})[] | readonly (boolean | readonly (string | boolean | readonly string[] | readonly boolean[] | {
|
|
73
|
+
user: string;
|
|
74
|
+
} | {
|
|
75
|
+
idpUser: "name" | "id" | "disabled";
|
|
76
|
+
} | {
|
|
77
|
+
oldIdpUser: "name" | "id" | "disabled";
|
|
78
|
+
} | {
|
|
79
|
+
newIdpUser: "name" | "id" | "disabled";
|
|
80
|
+
})[])[] | {
|
|
81
|
+
conditions: readonly (string | boolean | readonly string[] | readonly boolean[] | {
|
|
82
|
+
user: string;
|
|
83
|
+
} | {
|
|
84
|
+
idpUser: "name" | "id" | "disabled";
|
|
85
|
+
} | {
|
|
86
|
+
oldIdpUser: "name" | "id" | "disabled";
|
|
87
|
+
} | {
|
|
88
|
+
newIdpUser: "name" | "id" | "disabled";
|
|
89
|
+
})[] | readonly (readonly (string | boolean | readonly string[] | readonly boolean[] | {
|
|
90
|
+
user: string;
|
|
91
|
+
} | {
|
|
92
|
+
idpUser: "name" | "id" | "disabled";
|
|
93
|
+
} | {
|
|
94
|
+
oldIdpUser: "name" | "id" | "disabled";
|
|
95
|
+
} | {
|
|
96
|
+
newIdpUser: "name" | "id" | "disabled";
|
|
97
|
+
})[])[];
|
|
98
|
+
description?: string | undefined;
|
|
99
|
+
permit?: boolean | undefined;
|
|
100
|
+
})[];
|
|
101
|
+
read: readonly (readonly (string | boolean | readonly string[] | readonly boolean[] | {
|
|
102
|
+
user: string;
|
|
103
|
+
} | {
|
|
104
|
+
idpUser: "name" | "id" | "disabled";
|
|
105
|
+
} | {
|
|
106
|
+
oldIdpUser: "name" | "id" | "disabled";
|
|
107
|
+
} | {
|
|
108
|
+
newIdpUser: "name" | "id" | "disabled";
|
|
109
|
+
})[] | readonly (boolean | readonly (string | boolean | readonly string[] | readonly boolean[] | {
|
|
110
|
+
user: string;
|
|
111
|
+
} | {
|
|
112
|
+
idpUser: "name" | "id" | "disabled";
|
|
113
|
+
} | {
|
|
114
|
+
oldIdpUser: "name" | "id" | "disabled";
|
|
115
|
+
} | {
|
|
116
|
+
newIdpUser: "name" | "id" | "disabled";
|
|
117
|
+
})[])[] | {
|
|
118
|
+
conditions: readonly (string | boolean | readonly string[] | readonly boolean[] | {
|
|
119
|
+
user: string;
|
|
120
|
+
} | {
|
|
121
|
+
idpUser: "name" | "id" | "disabled";
|
|
122
|
+
} | {
|
|
123
|
+
oldIdpUser: "name" | "id" | "disabled";
|
|
124
|
+
} | {
|
|
125
|
+
newIdpUser: "name" | "id" | "disabled";
|
|
126
|
+
})[] | readonly (readonly (string | boolean | readonly string[] | readonly boolean[] | {
|
|
127
|
+
user: string;
|
|
128
|
+
} | {
|
|
129
|
+
idpUser: "name" | "id" | "disabled";
|
|
130
|
+
} | {
|
|
131
|
+
oldIdpUser: "name" | "id" | "disabled";
|
|
132
|
+
} | {
|
|
133
|
+
newIdpUser: "name" | "id" | "disabled";
|
|
134
|
+
})[])[];
|
|
135
|
+
description?: string | undefined;
|
|
136
|
+
permit?: boolean | undefined;
|
|
137
|
+
})[];
|
|
138
|
+
update: readonly (readonly (string | boolean | readonly string[] | readonly boolean[] | {
|
|
139
|
+
user: string;
|
|
140
|
+
} | {
|
|
141
|
+
idpUser: "name" | "id" | "disabled";
|
|
142
|
+
} | {
|
|
143
|
+
oldIdpUser: "name" | "id" | "disabled";
|
|
144
|
+
} | {
|
|
145
|
+
newIdpUser: "name" | "id" | "disabled";
|
|
146
|
+
})[] | readonly (boolean | readonly (string | boolean | readonly string[] | readonly boolean[] | {
|
|
147
|
+
user: string;
|
|
148
|
+
} | {
|
|
149
|
+
idpUser: "name" | "id" | "disabled";
|
|
150
|
+
} | {
|
|
151
|
+
oldIdpUser: "name" | "id" | "disabled";
|
|
152
|
+
} | {
|
|
153
|
+
newIdpUser: "name" | "id" | "disabled";
|
|
154
|
+
})[])[] | {
|
|
155
|
+
conditions: readonly (string | boolean | readonly string[] | readonly boolean[] | {
|
|
156
|
+
user: string;
|
|
157
|
+
} | {
|
|
158
|
+
idpUser: "name" | "id" | "disabled";
|
|
159
|
+
} | {
|
|
160
|
+
oldIdpUser: "name" | "id" | "disabled";
|
|
161
|
+
} | {
|
|
162
|
+
newIdpUser: "name" | "id" | "disabled";
|
|
163
|
+
})[] | readonly (readonly (string | boolean | readonly string[] | readonly boolean[] | {
|
|
164
|
+
user: string;
|
|
165
|
+
} | {
|
|
166
|
+
idpUser: "name" | "id" | "disabled";
|
|
167
|
+
} | {
|
|
168
|
+
oldIdpUser: "name" | "id" | "disabled";
|
|
169
|
+
} | {
|
|
170
|
+
newIdpUser: "name" | "id" | "disabled";
|
|
171
|
+
})[])[];
|
|
172
|
+
description?: string | undefined;
|
|
173
|
+
permit?: boolean | undefined;
|
|
174
|
+
})[];
|
|
175
|
+
delete: readonly (readonly (string | boolean | readonly string[] | readonly boolean[] | {
|
|
176
|
+
user: string;
|
|
177
|
+
} | {
|
|
178
|
+
idpUser: "name" | "id" | "disabled";
|
|
179
|
+
} | {
|
|
180
|
+
oldIdpUser: "name" | "id" | "disabled";
|
|
181
|
+
} | {
|
|
182
|
+
newIdpUser: "name" | "id" | "disabled";
|
|
183
|
+
})[] | readonly (boolean | readonly (string | boolean | readonly string[] | readonly boolean[] | {
|
|
184
|
+
user: string;
|
|
185
|
+
} | {
|
|
186
|
+
idpUser: "name" | "id" | "disabled";
|
|
187
|
+
} | {
|
|
188
|
+
oldIdpUser: "name" | "id" | "disabled";
|
|
189
|
+
} | {
|
|
190
|
+
newIdpUser: "name" | "id" | "disabled";
|
|
191
|
+
})[])[] | {
|
|
192
|
+
conditions: readonly (string | boolean | readonly string[] | readonly boolean[] | {
|
|
193
|
+
user: string;
|
|
194
|
+
} | {
|
|
195
|
+
idpUser: "name" | "id" | "disabled";
|
|
196
|
+
} | {
|
|
197
|
+
oldIdpUser: "name" | "id" | "disabled";
|
|
198
|
+
} | {
|
|
199
|
+
newIdpUser: "name" | "id" | "disabled";
|
|
200
|
+
})[] | readonly (readonly (string | boolean | readonly string[] | readonly boolean[] | {
|
|
201
|
+
user: string;
|
|
202
|
+
} | {
|
|
203
|
+
idpUser: "name" | "id" | "disabled";
|
|
204
|
+
} | {
|
|
205
|
+
oldIdpUser: "name" | "id" | "disabled";
|
|
206
|
+
} | {
|
|
207
|
+
newIdpUser: "name" | "id" | "disabled";
|
|
208
|
+
})[])[];
|
|
209
|
+
description?: string | undefined;
|
|
210
|
+
permit?: boolean | undefined;
|
|
211
|
+
})[];
|
|
212
|
+
sendPasswordResetEmail: readonly (readonly (string | boolean | readonly string[] | readonly boolean[] | {
|
|
213
|
+
user: string;
|
|
214
|
+
} | {
|
|
215
|
+
idpUser: "name" | "id" | "disabled";
|
|
216
|
+
} | {
|
|
217
|
+
oldIdpUser: "name" | "id" | "disabled";
|
|
218
|
+
} | {
|
|
219
|
+
newIdpUser: "name" | "id" | "disabled";
|
|
220
|
+
})[] | readonly (boolean | readonly (string | boolean | readonly string[] | readonly boolean[] | {
|
|
221
|
+
user: string;
|
|
222
|
+
} | {
|
|
223
|
+
idpUser: "name" | "id" | "disabled";
|
|
224
|
+
} | {
|
|
225
|
+
oldIdpUser: "name" | "id" | "disabled";
|
|
226
|
+
} | {
|
|
227
|
+
newIdpUser: "name" | "id" | "disabled";
|
|
228
|
+
})[])[] | {
|
|
229
|
+
conditions: readonly (string | boolean | readonly string[] | readonly boolean[] | {
|
|
230
|
+
user: string;
|
|
231
|
+
} | {
|
|
232
|
+
idpUser: "name" | "id" | "disabled";
|
|
233
|
+
} | {
|
|
234
|
+
oldIdpUser: "name" | "id" | "disabled";
|
|
235
|
+
} | {
|
|
236
|
+
newIdpUser: "name" | "id" | "disabled";
|
|
237
|
+
})[] | readonly (readonly (string | boolean | readonly string[] | readonly boolean[] | {
|
|
238
|
+
user: string;
|
|
239
|
+
} | {
|
|
240
|
+
idpUser: "name" | "id" | "disabled";
|
|
241
|
+
} | {
|
|
242
|
+
oldIdpUser: "name" | "id" | "disabled";
|
|
243
|
+
} | {
|
|
244
|
+
newIdpUser: "name" | "id" | "disabled";
|
|
245
|
+
})[])[];
|
|
246
|
+
description?: string | undefined;
|
|
247
|
+
permit?: boolean | undefined;
|
|
248
|
+
})[];
|
|
62
249
|
} | undefined;
|
|
63
250
|
};
|
|
64
251
|
//#endregion
|
|
@@ -77,6 +264,7 @@ type IdPExternalConfig = {
|
|
|
77
264
|
};
|
|
78
265
|
type IdPOwnConfig = Omit<DefinedIdp<string, IdPInput, string>, "provider">;
|
|
79
266
|
type IdPConfig = IdPOwnConfig | IdPExternalConfig;
|
|
267
|
+
type IdPUserField = "id" | "name" | "disabled";
|
|
80
268
|
//#endregion
|
|
81
269
|
//#region src/configure/services/secrets/index.d.ts
|
|
82
270
|
declare const secretsDefinitionBrand: unique symbol;
|
|
@@ -84,8 +272,15 @@ type SecretsDefinitionBrand = {
|
|
|
84
272
|
readonly [secretsDefinitionBrand]: true;
|
|
85
273
|
};
|
|
86
274
|
type SecretsVaultInput = Record<string, string>;
|
|
275
|
+
type SecretsVaultInputNullish = Record<string, string | undefined | null>;
|
|
87
276
|
type SecretsInput = Record<string, SecretsVaultInput>;
|
|
88
|
-
type
|
|
277
|
+
type SecretsInputNullish = Record<string, SecretsVaultInputNullish>;
|
|
278
|
+
type SecretsOptions = {
|
|
279
|
+
readonly ignoreNullishValues: boolean;
|
|
280
|
+
};
|
|
281
|
+
type DefinedSecrets<T extends SecretsInputNullish> = {
|
|
282
|
+
readonly vaults: T;
|
|
283
|
+
readonly options: SecretsOptions;
|
|
89
284
|
get<V extends Extract<keyof T, string>, S extends Extract<keyof T[V], string>>(vault: V, secret: S): Promise<string | undefined>;
|
|
90
285
|
getAll<V extends Extract<keyof T, string>, S extends Extract<keyof T[V], string>>(vault: V, secrets: readonly S[]): Promise<(string | undefined)[]>;
|
|
91
286
|
} & SecretsDefinitionBrand;
|
|
@@ -98,6 +293,19 @@ type SecretsConfig = Omit<ReturnType<typeof defineSecretManager>, "get" | "getAl
|
|
|
98
293
|
* @returns Defined secrets with typed runtime access methods
|
|
99
294
|
*/
|
|
100
295
|
declare function defineSecretManager<const T extends SecretsInput>(config: T): DefinedSecrets<T>;
|
|
296
|
+
/**
|
|
297
|
+
* Define secrets configuration for the Tailor SDK with ignoreNullishValues option.
|
|
298
|
+
* When `ignoreNullishValues` is true, secrets with nullish values are skipped during deploy
|
|
299
|
+
* instead of causing an error. This is useful for CI environments where not all
|
|
300
|
+
* secret values are available.
|
|
301
|
+
* @param config - Secrets configuration mapping vault names to their secrets
|
|
302
|
+
* @param options - Options for secret management behavior
|
|
303
|
+
* @param options.ignoreNullishValues - When true, secrets with nullish values are skipped during deploy
|
|
304
|
+
* @returns Defined secrets with typed runtime access methods
|
|
305
|
+
*/
|
|
306
|
+
declare function defineSecretManager<const T extends SecretsInputNullish>(config: T, options: {
|
|
307
|
+
ignoreNullishValues: true;
|
|
308
|
+
}): DefinedSecrets<T>;
|
|
101
309
|
//#endregion
|
|
102
310
|
//#region src/types/staticwebsite.generated.d.ts
|
|
103
311
|
type StaticWebsite = {
|
|
@@ -202,5 +410,5 @@ type RetryPolicy = {
|
|
|
202
410
|
backoffMultiplier: number;
|
|
203
411
|
};
|
|
204
412
|
//#endregion
|
|
205
|
-
export {
|
|
206
|
-
//# sourceMappingURL=workflow.generated-
|
|
413
|
+
export { IdpDefinitionBrand as _, ResolverExternalConfig as a, IdPGqlOperationsInput as b, WorkflowServiceConfig as c, defineStaticWebSite as d, SecretsConfig as f, IdPUserField as g, IdPExternalConfig as h, ExecutorServiceInput as i, WorkflowServiceInput as l, IdPConfig as m, AppConfig as n, ResolverServiceConfig as o, defineSecretManager as p, ExecutorServiceConfig as r, ResolverServiceInput as s, RetryPolicy as t, StaticWebsiteConfig as u, IdPEmailConfig as v, IdPInput as x, IdPGqlOperations as y };
|
|
414
|
+
//# sourceMappingURL=workflow.generated-8BeGQsVU.d.mts.map
|
package/docs/cli/function.md
CHANGED
|
@@ -152,7 +152,7 @@ tailor-sdk function test-run [options] <file>
|
|
|
152
152
|
**Run a resolver with input arguments**
|
|
153
153
|
|
|
154
154
|
```bash
|
|
155
|
-
$ tailor-sdk function test-run resolvers/add.ts --arg '{"
|
|
155
|
+
$ tailor-sdk function test-run resolvers/add.ts --arg '{"a":1,"b":2}'
|
|
156
156
|
```
|
|
157
157
|
|
|
158
158
|
**Run a specific workflow job by name**
|
|
@@ -164,7 +164,7 @@ $ tailor-sdk function test-run workflows/sample.ts --name validate-order
|
|
|
164
164
|
**Run a pre-bundled .js file directly**
|
|
165
165
|
|
|
166
166
|
```bash
|
|
167
|
-
$ tailor-sdk function test-run build/resolvers/add.js --arg '{"
|
|
167
|
+
$ tailor-sdk function test-run build/resolvers/add.js --arg '{"a":1,"b":2}'
|
|
168
168
|
```
|
|
169
169
|
|
|
170
170
|
<!-- politty:command:function test-run:examples:end -->
|
package/docs/services/idp.md
CHANGED
|
@@ -99,6 +99,56 @@ defineIdp("my-idp", {
|
|
|
99
99
|
|
|
100
100
|
**Validation:** Each field must be 200 characters or less and must not contain newline characters.
|
|
101
101
|
|
|
102
|
+
### permission
|
|
103
|
+
|
|
104
|
+
Per-operation permission policies for IdP user management. Controls who can create, read, update, delete users, and send password reset emails.
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
defineIdp("my-idp", {
|
|
108
|
+
authorization: "loggedIn",
|
|
109
|
+
clients: ["my-client"],
|
|
110
|
+
permission: {
|
|
111
|
+
create: [{ conditions: [[{ user: "role" }, "=", "ADMIN"]], permit: true }],
|
|
112
|
+
read: [{ conditions: [[{ user: "_loggedIn" }, "=", true]], permit: true }],
|
|
113
|
+
update: [
|
|
114
|
+
{ conditions: [[{ newIdpUser: "name" }, "!=", { oldIdpUser: "name" }]], permit: true },
|
|
115
|
+
],
|
|
116
|
+
delete: [{ conditions: [[{ user: "role" }, "=", "ADMIN"]], permit: true }],
|
|
117
|
+
sendPasswordResetEmail: [{ conditions: [], permit: true }],
|
|
118
|
+
},
|
|
119
|
+
});
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
**Operations:**
|
|
123
|
+
|
|
124
|
+
- `create` - Controls who can create IdP users
|
|
125
|
+
- `read` - Controls who can read IdP users
|
|
126
|
+
- `update` - Controls who can update IdP users
|
|
127
|
+
- `delete` - Controls who can delete IdP users
|
|
128
|
+
- `sendPasswordResetEmail` - Controls who can send password reset emails
|
|
129
|
+
|
|
130
|
+
**Operands:**
|
|
131
|
+
|
|
132
|
+
- `{ user: "field" }` - Authenticated user's attribute
|
|
133
|
+
- `{ idpUser: "field" }` - IdP user field (for create/read/delete). Allowed values: `"id"`, `"name"`, `"disabled"`
|
|
134
|
+
- `{ oldIdpUser: "field" }` - Previous IdP user field value (for update only). Allowed values: `"id"`, `"name"`, `"disabled"`
|
|
135
|
+
- `{ newIdpUser: "field" }` - New IdP user field value (for update only). Allowed values: `"id"`, `"name"`, `"disabled"`
|
|
136
|
+
- Literal values: `string`, `boolean`, `string[]`, `boolean[]`
|
|
137
|
+
|
|
138
|
+
**Operators:** `"="`, `"!="`, `"in"`, `"not in"`
|
|
139
|
+
|
|
140
|
+
**Helper:** `unsafeAllowAllIdPPermission` grants full access without conditions. Intended only for development and testing.
|
|
141
|
+
|
|
142
|
+
```typescript
|
|
143
|
+
import { unsafeAllowAllIdPPermission } from "@tailor-platform/sdk";
|
|
144
|
+
|
|
145
|
+
defineIdp("my-idp", {
|
|
146
|
+
authorization: "loggedIn",
|
|
147
|
+
clients: ["my-client"],
|
|
148
|
+
permission: unsafeAllowAllIdPPermission,
|
|
149
|
+
});
|
|
150
|
+
```
|
|
151
|
+
|
|
102
152
|
## Using idp.provider()
|
|
103
153
|
|
|
104
154
|
The `idp.provider()` method creates a type-safe reference to the IdP for use in Auth configuration. The client name is validated at compile time against the clients defined in the IdP.
|
|
@@ -13,7 +13,7 @@ Resolvers provide:
|
|
|
13
13
|
|
|
14
14
|
## Comparison with Tailor Platform Pipeline Resolver
|
|
15
15
|
|
|
16
|
-
The SDK's Resolver is a simplified version of Tailor Platform's [Pipeline Resolver](https://docs.tailor.tech/guides/
|
|
16
|
+
The SDK's Resolver is a simplified version of Tailor Platform's [Pipeline Resolver](https://docs.tailor.tech/guides/resolver).
|
|
17
17
|
|
|
18
18
|
| Pipeline Resolver | SDK Resolver |
|
|
19
19
|
| ---------------------------------------- | --------------------------------- |
|
package/docs/services/secret.md
CHANGED
|
@@ -64,6 +64,31 @@ export default defineConfig({
|
|
|
64
64
|
|
|
65
65
|
The exported `secrets` object provides type-safe `get()` and `getAll()` methods for runtime access from resolvers, executors, and workflows.
|
|
66
66
|
|
|
67
|
+
### Skipping Secrets with Missing Values
|
|
68
|
+
|
|
69
|
+
In CI environments, you may not have all secret values available (e.g., secrets are already set on the platform and you don't want to duplicate them in CI environment variables). Use the `ignoreNullishValues` option to skip secrets whose values are `undefined` or `null`:
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
export const secrets = defineSecretManager(
|
|
73
|
+
{
|
|
74
|
+
"api-keys": {
|
|
75
|
+
"stripe-secret-key": process.env.STRIPE_SECRET_KEY,
|
|
76
|
+
"sendgrid-api-key": process.env.SENDGRID_API_KEY,
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
{ ignoreNullishValues: true },
|
|
80
|
+
);
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
When `ignoreNullishValues: true`:
|
|
84
|
+
|
|
85
|
+
- Secrets with a string value are created or updated as normal
|
|
86
|
+
- Secrets with `undefined` or `null` values are **skipped** — they are not created, updated, or deleted
|
|
87
|
+
- Skipped secrets are shown in the deploy output for visibility
|
|
88
|
+
- Secrets removed from the config entirely are still deleted (orphan cleanup)
|
|
89
|
+
|
|
90
|
+
This allows you to set secret values once (e.g., via local `tailor-sdk apply` or the CLI) and then deploy from CI without needing the actual values in CI environment variables.
|
|
91
|
+
|
|
67
92
|
## Using Secrets
|
|
68
93
|
|
|
69
94
|
### Runtime Access with `get()` / `getAll()`
|
|
@@ -115,6 +115,54 @@ export const mainJob = createWorkflowJob({
|
|
|
115
115
|
|
|
116
116
|
**Important:** On the Tailor runtime, job triggers are executed synchronously. This means `Promise.all([jobA.trigger(), jobB.trigger()])` will not run jobs in parallel.
|
|
117
117
|
|
|
118
|
+
### Deterministic Execution Requirement
|
|
119
|
+
|
|
120
|
+
Workflow jobs use a **suspend/resume execution model**. When a job calls `.trigger()`, the runtime suspends the current job, executes the triggered job, and then **re-executes the calling job from the beginning** with cached results from previous triggers.
|
|
121
|
+
|
|
122
|
+
This means that **job code must be deterministic** — every re-execution must produce the same sequence of `.trigger()` calls with the same arguments in the same order.
|
|
123
|
+
|
|
124
|
+
Using `.trigger()` inside a loop works correctly, as long as the loop is deterministic:
|
|
125
|
+
|
|
126
|
+
```typescript
|
|
127
|
+
// ✅ OK: deterministic loop — same calls in the same order on every execution
|
|
128
|
+
const regions = ["us", "eu", "ap"];
|
|
129
|
+
for (const region of regions) {
|
|
130
|
+
const result = await fetchData.trigger({ region });
|
|
131
|
+
results.push(result);
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
```typescript
|
|
136
|
+
// ❌ Bad: non-deterministic — argument changes between executions
|
|
137
|
+
await processJob.trigger({ timestamp: Date.now() });
|
|
138
|
+
|
|
139
|
+
// ✅ OK: call Date.now() in separated job
|
|
140
|
+
const timestamp = await timestampJob.trigger();
|
|
141
|
+
await processJob.trigger({ timestamp });
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
```typescript
|
|
145
|
+
// ❌ Bad: non-deterministic — external data may change between executions
|
|
146
|
+
const items = await fetch("https://api.example.com/items").then((r) => r.json());
|
|
147
|
+
for (const item of items) {
|
|
148
|
+
await processItem.trigger({ id: item.id });
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// ✅ OK: call fetch("https://api.example.com/items").then((r) => r.json()); in separated job
|
|
152
|
+
const items = await fetchItemsJob.trigger();
|
|
153
|
+
for (const item of items) {
|
|
154
|
+
await processItem.trigger({ id: item.id });
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
If the runtime detects that a `.trigger()` call at the same position has different arguments than the previous execution, it will throw an **argument hash mismatch error**.
|
|
159
|
+
|
|
160
|
+
**Guidelines:**
|
|
161
|
+
|
|
162
|
+
- Do not use non-deterministic values (random numbers, timestamps, external API responses) as `.trigger()` arguments.
|
|
163
|
+
- Do not use conditions that may change between executions to decide whether to call `.trigger()`.
|
|
164
|
+
- Any data that varies between executions should be fetched **inside the triggered job**, not passed as an argument from the calling job.
|
|
165
|
+
|
|
118
166
|
## Workflow Definition
|
|
119
167
|
|
|
120
168
|
Define a workflow using `createWorkflow` and export it as default:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tailor-platform/sdk",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.36.0",
|
|
4
4
|
"description": "Tailor Platform SDK - The SDK to work with Tailor Platform",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -81,8 +81,9 @@
|
|
|
81
81
|
"@bufbuild/protobuf": "2.11.0",
|
|
82
82
|
"@connectrpc/connect": "2.1.1",
|
|
83
83
|
"@connectrpc/connect-node": "2.1.1",
|
|
84
|
-
"@inquirer/core": "11.1.
|
|
85
|
-
"@inquirer/prompts": "8.
|
|
84
|
+
"@inquirer/core": "11.1.8",
|
|
85
|
+
"@inquirer/prompts": "8.4.0",
|
|
86
|
+
"@jridgewell/trace-mapping": "0.3.31",
|
|
86
87
|
"@liam-hq/cli": "0.7.24",
|
|
87
88
|
"@napi-rs/keyring": "1.2.0",
|
|
88
89
|
"@opentelemetry/api": "1.9.1",
|
|
@@ -110,7 +111,7 @@
|
|
|
110
111
|
"multiline-ts": "4.0.1",
|
|
111
112
|
"open": "11.0.0",
|
|
112
113
|
"ora": "9.3.0",
|
|
113
|
-
"oxc-parser": "0.
|
|
114
|
+
"oxc-parser": "0.124.0",
|
|
114
115
|
"p-limit": "7.3.0",
|
|
115
116
|
"pathe": "2.0.3",
|
|
116
117
|
"pgsql-ast-parser": "12.0.2",
|
|
@@ -134,13 +135,13 @@
|
|
|
134
135
|
"@types/mime-types": "3.0.1",
|
|
135
136
|
"@types/node": "24.12.2",
|
|
136
137
|
"@types/semver": "7.7.1",
|
|
137
|
-
"@typescript/native-preview": "7.0.0-dev.
|
|
138
|
+
"@typescript/native-preview": "7.0.0-dev.20260406.1",
|
|
138
139
|
"@vitest/coverage-v8": "4.1.2",
|
|
139
140
|
"eslint": "10.2.0",
|
|
140
141
|
"eslint-plugin-jsdoc": "62.9.0",
|
|
141
|
-
"eslint-plugin-oxlint": "1.
|
|
142
|
-
"oxfmt": "0.
|
|
143
|
-
"oxlint": "1.
|
|
142
|
+
"eslint-plugin-oxlint": "1.59.0",
|
|
143
|
+
"oxfmt": "0.44.0",
|
|
144
|
+
"oxlint": "1.59.0",
|
|
144
145
|
"oxlint-tsgolint": "0.20.0",
|
|
145
146
|
"sonda": "0.11.1",
|
|
146
147
|
"tsdown": "0.21.7",
|