@tailor-platform/sdk 2.20.0 → 2.22.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 +69 -0
- package/agent-skills/tailor/SKILL.md +3 -1
- package/dist/application-BE4vehXW.mjs +1 -0
- package/dist/application-BzO9ywXQ.mjs +199 -0
- package/dist/application-BzO9ywXQ.mjs.map +1 -0
- package/dist/cli/commands/deploy/app-id-lock.d.mts +31 -0
- package/dist/cli/lib.d.mts +2 -2
- package/dist/cli/lib.mjs +1 -1
- package/dist/cli/lib.mjs.map +1 -1
- package/dist/cli/main.d.mts +1 -0
- package/dist/cli/main.mjs +42 -42
- package/dist/cli/main.mjs.map +1 -1
- package/dist/cli/shared/logger.d.mts +9 -0
- package/dist/cli/shared/tailordb-namespaces.d.mts +1 -1
- package/dist/completion/zsh-worker.zsh +654 -131
- package/dist/configure/config/index.d.mts +2 -0
- package/dist/configure/index.d.mts +2 -1
- package/dist/configure/index.mjs +12 -1
- package/dist/configure/index.mjs.map +1 -1
- package/dist/configure/services/secrets/index.d.mts +14 -0
- package/dist/configure/services/tailordb/schema.d.mts +3 -2
- package/dist/configure/types/secret-vault-name.d.mts +32 -0
- package/dist/crashreport-CBaRJl5h.mjs +1 -0
- package/dist/{crashreport-Cyuz1qiu.mjs → crashreport-DFpRn-LS.mjs} +4 -4
- package/dist/{crashreport-Cyuz1qiu.mjs.map → crashreport-DFpRn-LS.mjs.map} +1 -1
- package/dist/{date-B7-oyTGE.mjs → date-Dri6Yas-.mjs} +2 -2
- package/dist/date-Dri6Yas-.mjs.map +1 -0
- package/dist/{errors-BjJnpXkK.mjs → errors-C9zGf4nz.mjs} +2 -2
- package/dist/{errors-BjJnpXkK.mjs.map → errors-C9zGf4nz.mjs.map} +1 -1
- package/dist/es-builtins-SfvXRVoG.mjs +2 -0
- package/dist/{es-builtins-BHCXINQp.mjs.map → es-builtins-SfvXRVoG.mjs.map} +1 -1
- package/dist/field-parse-DhnFs9WG.mjs +2 -0
- package/dist/field-parse-DhnFs9WG.mjs.map +1 -0
- package/dist/{globals-CMHSnj4w.mjs → globals-BCmGX05J.mjs} +2 -2
- package/dist/{globals-CMHSnj4w.mjs.map → globals-BCmGX05J.mjs.map} +1 -1
- package/dist/guards-yDXyKC9F.mjs +2 -0
- package/dist/{guards-ForsrxnH.mjs.map → guards-yDXyKC9F.mjs.map} +1 -1
- package/dist/{kysely-type-B_oA8D1k.mjs → kysely-type-C-iyFFH7.mjs} +2 -2
- package/dist/{kysely-type-B_oA8D1k.mjs.map → kysely-type-C-iyFFH7.mjs.map} +1 -1
- package/dist/logger-Db-YRTwK.mjs +9 -0
- package/dist/logger-Db-YRTwK.mjs.map +1 -0
- package/dist/manager-8-JOvuLl.mjs +2 -0
- package/dist/{manager-qfbUL7ru.mjs.map → manager-8-JOvuLl.mjs.map} +1 -1
- package/dist/plugin/builtin/enum-constants/index.mjs +1 -1
- package/dist/plugin/builtin/enum-constants/index.mjs.map +1 -1
- package/dist/plugin/builtin/file-utils/index.mjs +1 -1
- package/dist/plugin/builtin/file-utils/index.mjs.map +1 -1
- package/dist/plugin/builtin/kysely-type/index.mjs +1 -1
- package/dist/plugin/index.mjs +1 -1
- package/dist/plugin/index.mjs.map +1 -1
- package/dist/register-ts-hook-z7ggXQy4.mjs +922 -0
- package/dist/register-ts-hook-z7ggXQy4.mjs.map +1 -0
- package/dist/registry-BijIDRVA.mjs +2 -0
- package/dist/{registry-HlEaGvl5.mjs.map → registry-BijIDRVA.mjs.map} +1 -1
- package/dist/repl-editor-DGJBfIt1.mjs +2 -0
- package/dist/{repl-editor-BG1aDOfH.mjs.map → repl-editor-DGJBfIt1.mjs.map} +1 -1
- package/dist/runtime/field-parse.d.mts +17 -1
- package/dist/runtime/index.d.mts +2 -1
- package/dist/runtime/index.mjs +1 -1
- package/dist/runtime/secretmanager.d.mts +8 -20
- package/dist/schema-CRtAmDcl.mjs +2 -0
- package/dist/{schema-BKvcWdVf.mjs.map → schema-CRtAmDcl.mjs.map} +1 -1
- package/dist/secretmanager-vHQoXdQz.mjs.map +1 -1
- package/dist/seed/index.mjs +7 -6
- package/dist/seed/index.mjs.map +1 -1
- package/dist/service-Bx-7Lz06.mjs +1 -0
- package/dist/{service-CuqkHP1r.mjs → service-CL1Bp4It.mjs} +3 -3
- package/dist/{service-CuqkHP1r.mjs.map → service-CL1Bp4It.mjs.map} +1 -1
- package/dist/{service-B4Gh_bbL.mjs → service-DHVuH7-X.mjs} +2 -2
- package/dist/{service-B4Gh_bbL.mjs.map → service-DHVuH7-X.mjs.map} +1 -1
- package/dist/service_pb-DNskuJQC.mjs +1 -0
- package/dist/service_pb-y2GYIgfs.mjs +2 -0
- package/dist/{service_pb-DprmLNsq.mjs.map → service_pb-y2GYIgfs.mjs.map} +1 -1
- package/dist/tailordb-ddl-DqInYupv.mjs +7 -0
- package/dist/{tailordb-ddl-Fgm2cNvT.mjs.map → tailordb-ddl-DqInYupv.mjs.map} +1 -1
- package/dist/utils/test/index.mjs +1 -1
- package/dist/utils/test/index.mjs.map +1 -1
- package/dist/vitest/environment.mjs +1 -1
- package/dist/vitest/environment.mjs.map +1 -1
- package/dist/vitest/index.mjs +1 -1
- package/dist/vitest/index.mjs.map +1 -1
- package/dist/vitest/mocks/file.d.mts +1 -1
- package/dist/vitest/setup.mjs +1 -1
- package/dist/workspace_resource_pb-D2njwgsE.mjs +2 -0
- package/dist/{workspace_resource_pb-BOoRts_z.mjs.map → workspace_resource_pb-D2njwgsE.mjs.map} +1 -1
- package/docs/cli-reference.md +22 -12
- package/docs/configuration.md +1 -1
- package/docs/github-actions.md +90 -24
- package/docs/migration/v2.md +70 -5
- package/docs/migration/v3.md +64 -0
- package/docs/plugin/index.md +1 -1
- package/docs/services/resolver.md +21 -0
- package/docs/services/secret.md +20 -15
- package/package.json +19 -19
- package/dist/application-B6NYnrhv.mjs +0 -199
- package/dist/application-B6NYnrhv.mjs.map +0 -1
- package/dist/application-BlbyGJsd.mjs +0 -1
- package/dist/crashreport-CgymxQDu.mjs +0 -1
- package/dist/date-B7-oyTGE.mjs.map +0 -1
- package/dist/es-builtins-BHCXINQp.mjs +0 -2
- package/dist/field-parse-BbNyotv5.mjs +0 -2
- package/dist/field-parse-BbNyotv5.mjs.map +0 -1
- package/dist/guards-ForsrxnH.mjs +0 -2
- package/dist/logger-72hM4JWZ.mjs +0 -9
- package/dist/logger-72hM4JWZ.mjs.map +0 -1
- package/dist/manager-qfbUL7ru.mjs +0 -2
- package/dist/register-ts-hook-FsCX38LQ.mjs +0 -917
- package/dist/register-ts-hook-FsCX38LQ.mjs.map +0 -1
- package/dist/registry-HlEaGvl5.mjs +0 -2
- package/dist/repl-editor-BG1aDOfH.mjs +0 -2
- package/dist/schema-BKvcWdVf.mjs +0 -2
- package/dist/service-BgrEteZ2.mjs +0 -1
- package/dist/service_pb-DKrsO1_u.mjs +0 -1
- package/dist/service_pb-DprmLNsq.mjs +0 -2
- package/dist/tailordb-ddl-Fgm2cNvT.mjs +0 -7
- package/dist/workspace_resource_pb-BOoRts_z.mjs +0 -2
package/docs/cli-reference.md
CHANGED
|
@@ -12,12 +12,12 @@ tailor <command> [options]
|
|
|
12
12
|
|
|
13
13
|
<a id="global-options"></a>
|
|
14
14
|
|
|
15
|
-
| Option | Alias | Description | Required | Default |
|
|
16
|
-
| ------------------------------------------- | ----- | --------------------------------------------------- | -------- | ------- |
|
|
17
|
-
| `--env-file <ENV_FILE>` | `-e` | Path to the environment file (error if not found) | No | - |
|
|
18
|
-
| `--env-file-if-exists <ENV_FILE_IF_EXISTS>` | - | Path to the environment file (ignored if not found) | No | - |
|
|
19
|
-
| `--verbose` | - | Enable verbose logging | No | `false` |
|
|
20
|
-
| `--json` | `-j` | Output as JSON | No | `false` |
|
|
15
|
+
| Option | Alias | Description | Required | Default | Env |
|
|
16
|
+
| ------------------------------------------- | ----- | --------------------------------------------------- | -------- | ------- | -------------------- |
|
|
17
|
+
| `--env-file <ENV_FILE>` | `-e` | Path to the environment file (error if not found) | No | - | - |
|
|
18
|
+
| `--env-file-if-exists <ENV_FILE_IF_EXISTS>` | - | Path to the environment file (ignored if not found) | No | - | - |
|
|
19
|
+
| `--verbose` | - | Enable verbose logging | No | `false` | - |
|
|
20
|
+
| `--json` | `-j` | Output as JSON | No | `false` | `TAILOR_JSON_OUTPUT` |
|
|
21
21
|
|
|
22
22
|
### Progress and Detailed Logs
|
|
23
23
|
|
|
@@ -34,6 +34,14 @@ human-readable text or empty stdout.
|
|
|
34
34
|
Commands that only perform side effects and do not define a structured result may leave stdout empty
|
|
35
35
|
even when `--json` is passed.
|
|
36
36
|
|
|
37
|
+
Set `TAILOR_JSON_OUTPUT=true` (or `1`) to default every command to JSON without passing `--json`
|
|
38
|
+
each time. This is intended for agents, scripts, and CI steps that parse CLI output. An explicit
|
|
39
|
+
flag always wins, so `--json=false` forces table output even when the variable is enabled. The values
|
|
40
|
+
`true`, `True`, `TRUE`, `t`, `T`, and `1` enable JSON; `false`, `False`, `FALSE`, `f`, `F`, and `0`
|
|
41
|
+
keep table output. Other values are rejected. JSON mode also disables interactive prompts, so set the
|
|
42
|
+
variable per invocation or per job rather than exporting it from a shell profile; a command that
|
|
43
|
+
needed a prompt names what selected JSON when it refuses.
|
|
44
|
+
|
|
37
45
|
Errors, warnings, progress, and diagnostic messages are written to stderr. After argument parsing,
|
|
38
46
|
a command failure under `--json` emits a JSON error envelope to stderr. Failures you can act on — an
|
|
39
47
|
invalid or missing option, a resource that does not exist, an invalid configuration, or an unmet
|
|
@@ -96,14 +104,15 @@ is unchanged. Workflows that already echo their own `::error::` around the CLI k
|
|
|
96
104
|
those messages describe the workflow's own checks, which can fail even when the CLI succeeds.
|
|
97
105
|
|
|
98
106
|
When the failure has a known source, the annotation carries it: `seed validate` reports the
|
|
99
|
-
offending JSONL file and line,
|
|
100
|
-
file it imports cannot be parsed, that file and the line
|
|
101
|
-
relative to `GITHUB_WORKSPACE`; a file outside it is annotated
|
|
102
|
-
a path the runner cannot resolve.
|
|
107
|
+
offending JSONL file and line, including a line that is not valid JSON, and a rejected config
|
|
108
|
+
reports its file — or, when the config or a file it imports cannot be parsed, that file and the line
|
|
109
|
+
it failed on. Locations are written relative to `GITHUB_WORKSPACE`; a file outside it is annotated
|
|
110
|
+
without a location rather than with a path the runner cannot resolve.
|
|
103
111
|
|
|
104
112
|
For a JSONL file containing a blank line, the annotation's line and the line printed in the report
|
|
105
113
|
text differ: the annotation counts every line in the file, while the printed line counts only the
|
|
106
|
-
records. The annotation points at the row as an editor numbers it.
|
|
114
|
+
records. The annotation points at the row as an editor numbers it. A line that is not valid JSON is
|
|
115
|
+
printed with the line an editor shows, so both agree.
|
|
107
116
|
|
|
108
117
|
`generate` and `deploy` do not group their per-service progress.
|
|
109
118
|
|
|
@@ -225,7 +234,8 @@ Resolution rules:
|
|
|
225
234
|
then forwarded, so when the same flag appears on both sides the later one wins. A flag the host
|
|
226
235
|
does not define — including one only some commands declare, such as `--profile` — still has to be
|
|
227
236
|
typed after the plugin's own subcommand. `--help` and `--version` are answered by the host CLI and
|
|
228
|
-
never dispatch a plugin.
|
|
237
|
+
never dispatch a plugin. Setting `TAILOR_JSON_OUTPUT=true` also works, which plugins inherit from
|
|
238
|
+
the environment.
|
|
229
239
|
|
|
230
240
|
Because resolution is based on `node_modules/.bin` and `PATH`, any package manager that populates
|
|
231
241
|
`node_modules/.bin` works for project-local plugins — npm, pnpm (its content-addressable store is
|
package/docs/configuration.md
CHANGED
|
@@ -403,7 +403,7 @@ export default defineConfig({
|
|
|
403
403
|
|
|
404
404
|
### Plugins
|
|
405
405
|
|
|
406
|
-
Configure plugins using `definePlugins()
|
|
406
|
+
Configure plugins using `definePlugins()`, exported as `export const plugins`.
|
|
407
407
|
|
|
408
408
|
```typescript
|
|
409
409
|
import { definePlugins } from "@tailor-platform/sdk";
|
package/docs/github-actions.md
CHANGED
|
@@ -68,7 +68,9 @@ What it does:
|
|
|
68
68
|
applies the config; it does not re-run the PR plan.
|
|
69
69
|
- On **`workflow_dispatch`** with `dry-run: true`: runs plan only (useful for
|
|
70
70
|
rollback verification — see [Rollback](#rollback)). With `dry-run: false`
|
|
71
|
-
(default) it deploys, like a push.
|
|
71
|
+
(default) it deploys the selected branch, like a push. Pass
|
|
72
|
+
`--restrict-dispatch` to deploy only the target branch this way (see
|
|
73
|
+
[Restricting manual deploys](#restricting-manual-deploys)).
|
|
72
74
|
|
|
73
75
|
Fork pull requests cannot read repository secrets. For forks, the plan step is
|
|
74
76
|
automatically skipped; `generate-check` and other non-secret checks still run.
|
|
@@ -129,7 +131,9 @@ What it does:
|
|
|
129
131
|
before the deploy job starts.
|
|
130
132
|
- On **`workflow_dispatch`**: the `tailor-tag-guard` result is ignored — the
|
|
131
133
|
plan job runs regardless of branch reachability (useful for rolling back to
|
|
132
|
-
any tag). `dry-run: true` stops before the deploy job.
|
|
134
|
+
any tag). `dry-run: true` stops before the deploy job. With
|
|
135
|
+
`--restrict-dispatch`, the deploy job runs only for a tag that passes the
|
|
136
|
+
guard (see [Restricting manual deploys](#restricting-manual-deploys)).
|
|
133
137
|
|
|
134
138
|
### Choosing `--branch` for the tag target
|
|
135
139
|
|
|
@@ -190,20 +194,53 @@ Running a workflow setup subcommand creates or updates:
|
|
|
190
194
|
The workflow file. The `name:` field is set to `Tailor (<workspace-name>)` so
|
|
191
195
|
you can distinguish multiple workspaces in the Actions UI.
|
|
192
196
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
197
|
+
See [Customizing the generated workflow](#customizing-the-generated-workflow)
|
|
198
|
+
for what you can edit.
|
|
199
|
+
|
|
200
|
+
### Customizing the generated workflow
|
|
201
|
+
|
|
202
|
+
The SDK owns the jobs and steps whose `id` starts with `tailor-`, and the
|
|
203
|
+
top-level keys it writes (`name:`, `on:`, and `permissions:` in a workflow; the
|
|
204
|
+
metadata, inputs, and outputs of a composite action). Do not edit or rename
|
|
205
|
+
them. Everything else is yours, and re-running `setup` keeps it:
|
|
206
|
+
|
|
207
|
+
- **Your own jobs and steps.** Add them anywhere, without the `tailor-` prefix.
|
|
208
|
+
A step you add inside a managed job stays right after the managed step it
|
|
209
|
+
followed. For example, add private registry authentication or a system
|
|
210
|
+
dependency _before_ the managed `tailor-setup` step, and post-install extras
|
|
211
|
+
(such as `playwright install`) _after_ it. A job of your own can depend on a
|
|
212
|
+
managed job with `needs: tailor-deploy`.
|
|
213
|
+
- **Your own top-level keys**, such as a workflow-level `env:` or `defaults:`.
|
|
214
|
+
- **Runtime settings of managed jobs:** `runs-on`, `timeout-minutes`,
|
|
215
|
+
`container`, and `env`.
|
|
216
|
+
- **These inputs of managed steps:** `ignore` on `tailor-generate-check` and
|
|
217
|
+
`tailor-drift-check`, `fail-on-drift` on `tailor-drift-check`,
|
|
218
|
+
`install-command` on `tailor-install`, `node-version-file` on
|
|
219
|
+
`tailor-setup`, `label` on `tailor-plan`, and `user-mapping` on
|
|
220
|
+
`tailor-notify` and on a coordinator's steps that call an app action.
|
|
221
|
+
- **The `run:` command of the `build-site` step** in a composite action.
|
|
222
|
+
|
|
223
|
+
Comments above your own jobs and steps and at the end of the file are kept too.
|
|
224
|
+
Comments inside managed jobs and steps, and edits to the header comment, are
|
|
225
|
+
not kept.
|
|
226
|
+
|
|
227
|
+
`setup check` reports an edit to a managed part, and re-running `setup` stops
|
|
228
|
+
on it. Revert the edit, or pass `--force` to reset the managed parts to the
|
|
229
|
+
current template; `--force` still keeps your own jobs, steps, and settings.
|
|
230
|
+
A managed job or step you renamed counts as your own, so `--force` adds the
|
|
231
|
+
managed one back next to it; rename it back instead of forcing. To start over
|
|
232
|
+
from a clean template, delete the file and re-run `setup`.
|
|
233
|
+
|
|
234
|
+
When a template update removes a managed job that contains steps of yours, or
|
|
235
|
+
a job of yours `needs` a removed job, `setup` stops and names them. Move those
|
|
236
|
+
steps into a job of your own (or update the `needs`) and re-run. `--force` drops
|
|
237
|
+
steps left inside a removed job. It also stops when a new template version adds
|
|
238
|
+
a managed job or step whose id you already use; rename yours, or pass `--force`
|
|
239
|
+
to let the managed one replace it.
|
|
240
|
+
|
|
241
|
+
Files generated by an older SDK version are compared as a whole, so the first
|
|
242
|
+
re-run after upgrading stops if you edited the file in any way. Re-run once with
|
|
243
|
+
`--force` to switch it to this model; your own jobs and steps are kept.
|
|
207
244
|
|
|
208
245
|
### `.github/tailor.lock`
|
|
209
246
|
|
|
@@ -277,7 +314,8 @@ gh secret set TAILOR_PLATFORM_MACHINE_USER_CLIENT_SECRET --env my-app-stg
|
|
|
277
314
|
Setting them at the environment level isolates each target's credentials and
|
|
278
315
|
keeps them alongside that environment's `TAILOR_PLATFORM_WORKSPACE_ID`
|
|
279
316
|
variable. You can also set them as repository-level secrets if every target
|
|
280
|
-
shares one machine user
|
|
317
|
+
shares one machine user, but then any workflow on any branch can read them, so
|
|
318
|
+
the environment's protection rules no longer guard your deploys.
|
|
281
319
|
|
|
282
320
|
## GitHub Environments (approval gate)
|
|
283
321
|
|
|
@@ -309,8 +347,32 @@ or an out-of-band deploy. With `dry-run` off, a branch-target dispatch goes
|
|
|
309
347
|
straight to deploy (like a push), while a tag-target dispatch runs plan first
|
|
310
348
|
and then deploys.
|
|
311
349
|
|
|
312
|
-
|
|
313
|
-
|
|
350
|
+
By default you can select any branch or tag when dispatching manually, and it
|
|
351
|
+
deploys that ref. For tag targets, the tag-guard check is skipped for manual
|
|
352
|
+
dispatches, so you can deploy any commit regardless of branch membership.
|
|
353
|
+
|
|
354
|
+
### Restricting manual deploys
|
|
355
|
+
|
|
356
|
+
Pass `--restrict-dispatch` to `setup ci branch`, `setup ci tag`, or
|
|
357
|
+
`setup ci coordinate` to limit what a manual dispatch with `dry-run` off can
|
|
358
|
+
deploy:
|
|
359
|
+
|
|
360
|
+
- **Branch target:** only the target branch. Dispatching another branch skips
|
|
361
|
+
the deploy job.
|
|
362
|
+
- **Tag target:** only a tag. With `--branch`, the tag must also pass the
|
|
363
|
+
reachability guard. The tag does not have to match `--tag-pattern`.
|
|
364
|
+
|
|
365
|
+
Dry runs stay available from any ref. Re-run `setup` with the flag each time you
|
|
366
|
+
regenerate the workflow; it is not carried over from the previous run.
|
|
367
|
+
|
|
368
|
+
The flag guards against deploying the wrong ref by mistake. It is not an access
|
|
369
|
+
control: a manual dispatch runs the workflow file from the selected ref, so
|
|
370
|
+
anyone who can push a branch can remove the check there. To enforce which refs
|
|
371
|
+
can deploy, configure **Deployment branches and tags** on the target's GitHub
|
|
372
|
+
Environment and keep the machine-user secrets on that environment. Because the
|
|
373
|
+
plan job also enters the environment, allow `refs/pull/*/merge` as well so pull
|
|
374
|
+
request plans keep running, and note that dry runs from other branches are then
|
|
375
|
+
rejected too.
|
|
314
376
|
|
|
315
377
|
## Monorepo setup
|
|
316
378
|
|
|
@@ -365,6 +427,8 @@ git push origin v1.2.4
|
|
|
365
427
|
|
|
366
428
|
For tag targets, the tag-guard step is bypassed on manual dispatch, so you can
|
|
367
429
|
dispatch from any ref. Environment approval (if configured) applies as usual.
|
|
430
|
+
With `--restrict-dispatch`, step 4 deploys only a tag that passes the guard, and
|
|
431
|
+
a branch target deploys only its target branch, so use Option 1 there.
|
|
368
432
|
|
|
369
433
|
### Rollback limitations
|
|
370
434
|
|
|
@@ -445,7 +509,8 @@ subcommand.
|
|
|
445
509
|
|
|
446
510
|
`tailor setup check` audits the workflows recorded in
|
|
447
511
|
`.github/tailor.lock` against your current config and repository, without
|
|
448
|
-
writing anything. It reports when a workflow file is missing or
|
|
512
|
+
writing anything. It reports when a workflow file is missing or its SDK-managed
|
|
513
|
+
parts were edited by hand, a
|
|
449
514
|
newer template is available, `tailor.config.ts` is no longer under the recorded
|
|
450
515
|
`--dir`, or the repository default branch no longer matches a branch target's
|
|
451
516
|
trigger. It exits non-zero when it finds drift, so you can run it in CI. Each
|
|
@@ -474,10 +539,11 @@ itself at runtime.
|
|
|
474
539
|
## Updating the generated workflow
|
|
475
540
|
|
|
476
541
|
When you upgrade the SDK, re-run the relevant workflow setup subcommand with
|
|
477
|
-
the same flags to pick up template improvements.
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
542
|
+
the same flags to pick up template improvements. Your own jobs, steps, and
|
|
543
|
+
settings are kept (see
|
|
544
|
+
[Customizing the generated workflow](#customizing-the-generated-workflow)). If
|
|
545
|
+
you edited a managed part, the command stops; revert the edit or pass `--force`
|
|
546
|
+
to reset it.
|
|
481
547
|
|
|
482
548
|
The `.github/tailor.lock` file records the flags used at generation time,
|
|
483
549
|
so you can check what arguments were used previously.
|
package/docs/migration/v2.md
CHANGED
|
@@ -84,18 +84,83 @@ After:
|
|
|
84
84
|
import { definePlugins } from "@tailor-platform/sdk";
|
|
85
85
|
import { kyselyTypePlugin } from "@tailor-platform/sdk/plugin/kysely-type";
|
|
86
86
|
|
|
87
|
-
export const
|
|
87
|
+
export const plugins = definePlugins(kyselyTypePlugin({ distPath: "db.ts" }));
|
|
88
88
|
```
|
|
89
89
|
|
|
90
90
|
<details>
|
|
91
91
|
<summary>Prompt for an AI agent (to finish the cases the codemod could not migrate)</summary>
|
|
92
92
|
|
|
93
93
|
```text
|
|
94
|
-
defineGenerators() is replaced by definePlugins() in v2
|
|
95
|
-
|
|
96
|
-
|
|
94
|
+
defineGenerators() is replaced by definePlugins() in v2, exported as `plugins` — the
|
|
95
|
+
only export name the SDK reads plugins from. The codemod rewrites the known plugin
|
|
96
|
+
tuples (kysely-type, enum-constants, file-utils, seed) and renames the export variable
|
|
97
|
+
to `plugins` (left alone when the file already binds `plugins` to something else). For
|
|
98
|
+
any remaining defineGenerators([...]) the codemod left in place — a plugin it does not
|
|
97
99
|
know, or a non-tuple/spread form — convert it to definePlugins(pluginFn(config)),
|
|
98
|
-
importing the matching plugin from its @tailor-platform/sdk/plugin/<name> subpath
|
|
100
|
+
importing the matching plugin from its @tailor-platform/sdk/plugin/<name> subpath, and
|
|
101
|
+
assign the result to `export const plugins`.
|
|
102
|
+
Merge any remaining exported plugin arrays into `plugins`, including bindings
|
|
103
|
+
exported separately with `export { ... }`, and update their importing files.
|
|
104
|
+
Only tailor.config module exports are renamed automatically; preserve helper-module
|
|
105
|
+
exports and expose their plugins under the canonical config export manually.
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
</details>
|
|
109
|
+
|
|
110
|
+
## generator/generators → plugins export rename
|
|
111
|
+
|
|
112
|
+
**Migration:** Partially automatic
|
|
113
|
+
|
|
114
|
+
Rename the plugin config export (and its imports) from generator/generators to plugins
|
|
115
|
+
|
|
116
|
+
Before:
|
|
117
|
+
|
|
118
|
+
```ts
|
|
119
|
+
import { definePlugins } from "@tailor-platform/sdk";
|
|
120
|
+
import myPlugin from "./plugins/my-plugin";
|
|
121
|
+
|
|
122
|
+
export const generators = definePlugins(myPlugin());
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
After:
|
|
126
|
+
|
|
127
|
+
```ts
|
|
128
|
+
import { definePlugins } from "@tailor-platform/sdk";
|
|
129
|
+
import myPlugin from "./plugins/my-plugin";
|
|
130
|
+
|
|
131
|
+
export const plugins = definePlugins(myPlugin());
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Also updates other files that import the export by its old name.
|
|
135
|
+
|
|
136
|
+
Before:
|
|
137
|
+
|
|
138
|
+
```ts
|
|
139
|
+
import { generator } from "./tailor.config";
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
After:
|
|
143
|
+
|
|
144
|
+
```ts
|
|
145
|
+
import { plugins } from "./tailor.config";
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
<details>
|
|
149
|
+
<summary>Prompt for an AI agent (to finish the cases the codemod could not migrate)</summary>
|
|
150
|
+
|
|
151
|
+
```text
|
|
152
|
+
The SDK only reads plugins from an export named `plugins`; `generator`/`generators` is
|
|
153
|
+
already `definePlugins()` but under the old name. This codemod renames the export (and
|
|
154
|
+
any `import { generator[s] } from ".../tailor.config"` elsewhere) to `plugins`. It
|
|
155
|
+
leaves a file untouched when it already binds `plugins` to something else, or when a
|
|
156
|
+
bare (unaliased) import's local usages cannot be safely told apart from an unrelated
|
|
157
|
+
same-named binding in that file — rename those by hand to `plugins`.
|
|
158
|
+
Multiple arrays or bindings exported separately with `export { ... }` need manual
|
|
159
|
+
consolidation into the `plugins` export; update their importing files as well.
|
|
160
|
+
Only tailor.config module exports are renamed automatically. Review aliased SDK
|
|
161
|
+
factory calls and helper-module re-exports manually, preserving the helper API.
|
|
162
|
+
Indirect config exports, namespace/dynamic imports, and wildcard re-exports are
|
|
163
|
+
conservatively reported for review; keep unrelated values and canonical references unchanged.
|
|
99
164
|
```
|
|
100
165
|
|
|
101
166
|
</details>
|
package/docs/migration/v3.md
CHANGED
|
@@ -165,3 +165,67 @@ Do not change unrelated upload APIs or already explicit encodings.
|
|
|
165
165
|
```
|
|
166
166
|
|
|
167
167
|
</details>
|
|
168
|
+
|
|
169
|
+
## secrets.get()/getAll() (defineSecretManager) removed — use secretmanager from @tailor-platform/sdk/runtime
|
|
170
|
+
|
|
171
|
+
**Migration:** Manual
|
|
172
|
+
|
|
173
|
+
The `get()`/`getAll()` methods on the object `defineSecretManager()` returns are removed in v3. Importing that object into a resolver, executor, or workflow file bundles the raw values passed to `defineSecretManager()` into that function's deployed code, which fails to build once any value comes from `process.env`. `secretmanager.getSecret()`/`getSecrets()` from `@tailor-platform/sdk/runtime` read the same secrets without importing the config object.
|
|
174
|
+
|
|
175
|
+
Before:
|
|
176
|
+
|
|
177
|
+
```ts
|
|
178
|
+
import { secrets } from "../tailor.config";
|
|
179
|
+
|
|
180
|
+
const apiKey = await secrets.get("api-keys", "stripe-secret-key");
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
After:
|
|
184
|
+
|
|
185
|
+
```ts
|
|
186
|
+
import { secretmanager } from "@tailor-platform/sdk/runtime";
|
|
187
|
+
|
|
188
|
+
const apiKey = await secretmanager.getSecret("api-keys", "stripe-secret-key");
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
Before:
|
|
192
|
+
|
|
193
|
+
```ts
|
|
194
|
+
import { secrets } from "../tailor.config";
|
|
195
|
+
|
|
196
|
+
const [apiKey, webhookSecret] = await secrets.getAll("api-keys", [
|
|
197
|
+
"sendgrid-api-key",
|
|
198
|
+
"stripe-secret-key",
|
|
199
|
+
]);
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
After:
|
|
203
|
+
|
|
204
|
+
```ts
|
|
205
|
+
import { secretmanager } from "@tailor-platform/sdk/runtime";
|
|
206
|
+
|
|
207
|
+
const { "sendgrid-api-key": apiKey, "stripe-secret-key": webhookSecret } =
|
|
208
|
+
await secretmanager.getSecrets("api-keys", ["sendgrid-api-key", "stripe-secret-key"]);
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
<details>
|
|
212
|
+
<summary>Prompt for an AI agent (to perform this migration)</summary>
|
|
213
|
+
|
|
214
|
+
```text
|
|
215
|
+
`secrets.get()`/`getAll()` on the object `defineSecretManager()` returns are removed in v3.
|
|
216
|
+
Replace the import with `import { secretmanager } from "@tailor-platform/sdk/runtime";` and
|
|
217
|
+
call `secretmanager.getSecret(vault, name)` in place of `secrets.get(vault, name)`.
|
|
218
|
+
|
|
219
|
+
`getAll()` needs more than a rename: `secrets.getAll(vault, names)` returned an array of
|
|
220
|
+
values in the same order as `names`, while `secretmanager.getSecrets(vault, names)` returns
|
|
221
|
+
a partial record keyed by each requested name (a name with no value is omitted instead of
|
|
222
|
+
being `undefined` at its index). Rewrite positional destructuring (`const [a, b] = await
|
|
223
|
+
secrets.getAll(v, ["A", "B"])`) into keyed destructuring (`const { A: a, B: b } = await
|
|
224
|
+
secretmanager.getSecrets(v, ["A", "B"])`).
|
|
225
|
+
|
|
226
|
+
Also review: a `secrets` object re-exported or re-assigned to another name before use, and a
|
|
227
|
+
file that already imports something else named `secretmanager` (rename one of the two on
|
|
228
|
+
conflict).
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
</details>
|
package/docs/plugin/index.md
CHANGED
|
@@ -33,7 +33,7 @@ export default defineConfig({
|
|
|
33
33
|
});
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
-
**Important**:
|
|
36
|
+
**Important**: `definePlugins()` must be assigned to a named export called exactly `plugins` (not default, and not any other name).
|
|
37
37
|
|
|
38
38
|
### Attaching Plugins to Tables
|
|
39
39
|
|
|
@@ -141,6 +141,27 @@ GraphQL still accepts and returns `YYYY-MM-DD` strings. The SDK converts input t
|
|
|
141
141
|
|
|
142
142
|
This option also works in nested objects and with `array: true` or `optional: true`. Input must be a valid calendar date, and output must be a valid `Date` with a 4-digit UTC year (0000-9999). Both deployed resolvers and `tailor function run` perform these conversions.
|
|
143
143
|
|
|
144
|
+
A resolver bundle only includes the conversion code for the representations (`as: "date"` or `as: "temporal"`) its `input` and `output` use. To parse other values with such fields inside `body`, for example an external API response, use `parseDateFields` instead of `.parse()`. It takes the same arguments and returns the same result as `.parse()`. Calling `.parse()` on a field whose representation the bundle leaves out throws an error that points to `parseDateFields`.
|
|
145
|
+
|
|
146
|
+
```typescript
|
|
147
|
+
import { parseDateFields } from "@tailor-platform/sdk/runtime";
|
|
148
|
+
|
|
149
|
+
const payload = t.object({ due: t.date({ as: "date" }) });
|
|
150
|
+
|
|
151
|
+
createResolver({
|
|
152
|
+
name: "importDueDate",
|
|
153
|
+
operation: "mutation",
|
|
154
|
+
input: { id: t.string() },
|
|
155
|
+
body: async ({ input }) => {
|
|
156
|
+
const response = await fetchDueDate(input.id);
|
|
157
|
+
const result = parseDateFields(payload, { value: response, data: response, invoker: null });
|
|
158
|
+
if (result.issues) throw new Error(result.issues[0].message);
|
|
159
|
+
return result.value.due.toISOString();
|
|
160
|
+
},
|
|
161
|
+
output: t.string(),
|
|
162
|
+
});
|
|
163
|
+
```
|
|
164
|
+
|
|
144
165
|
An executor subscribing to the resolver with `resolverExecutedTrigger` receives the event as JSON, so `result` holds the `YYYY-MM-DD` string rather than a `Date`.
|
|
145
166
|
|
|
146
167
|
Use `t.date({ as: "temporal" })` to work with the [`Temporal.PlainDate`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainDate) value instead:
|
package/docs/services/secret.md
CHANGED
|
@@ -62,7 +62,7 @@ export default defineConfig({
|
|
|
62
62
|
});
|
|
63
63
|
```
|
|
64
64
|
|
|
65
|
-
The exported `secrets` object
|
|
65
|
+
The exported `secrets` object also carries the values you passed in, so import it only where you build your `tailor.config.ts` config (the file itself, or a helper module you import into it) — never from a resolver, executor, or workflow file. This `secrets` object's `get()`/`getAll()` methods are deprecated for the same reason and will be removed in a future major version; to read a secret at runtime, use the `secretmanager` API described below instead.
|
|
66
66
|
|
|
67
67
|
### Skipping Secrets with Missing Values
|
|
68
68
|
|
|
@@ -91,50 +91,55 @@ This allows you to set secret values once (e.g., via local `tailor deploy` or th
|
|
|
91
91
|
|
|
92
92
|
## Using Secrets
|
|
93
93
|
|
|
94
|
-
### Runtime Access with `
|
|
94
|
+
### Runtime Access with `secretmanager`
|
|
95
95
|
|
|
96
|
-
|
|
96
|
+
Read secret values at runtime with the `secretmanager` API from `@tailor-platform/sdk/runtime`, the same module you use for other platform runtime APIs (`idp`, `workflow`, `authconnection`, etc.). Pass the vault and secret names as strings. Once `tailor generate`/`tailor deploy` has run, vault names are autocompleted from `defineSecretManager()` (any other string still works, since vaults can also be managed imperatively via the CLI — see [Managing Secrets](#managing-secrets)), and inside a declared vault, secret names are checked against that vault's configuration.
|
|
97
97
|
|
|
98
|
-
#### `
|
|
98
|
+
#### `getSecret(vault, name)`
|
|
99
99
|
|
|
100
100
|
Retrieves a single secret value.
|
|
101
101
|
|
|
102
102
|
```typescript
|
|
103
103
|
import { createResolver } from "@tailor-platform/sdk";
|
|
104
|
-
import {
|
|
104
|
+
import { secretmanager } from "@tailor-platform/sdk/runtime";
|
|
105
105
|
|
|
106
106
|
export default createResolver({
|
|
107
107
|
name: "call-stripe",
|
|
108
|
+
operation: "query",
|
|
108
109
|
// ...
|
|
109
|
-
|
|
110
|
-
const apiKey = await
|
|
110
|
+
body: async ({ input }) => {
|
|
111
|
+
const apiKey = await secretmanager.getSecret("api-keys", "stripe-secret-key");
|
|
111
112
|
// Use apiKey to call the Stripe API
|
|
113
|
+
|
|
114
|
+
// await secretmanager.getSecret("api-keys", "unknown-key"); // Type error — "api-keys" only has "stripe-secret-key" and "sendgrid-api-key"
|
|
115
|
+
// await secretmanager.getSecret("cli-managed-vault", "anything"); // Fine — "cli-managed-vault" isn't declared in defineSecretManager(), so its secret names aren't checked
|
|
112
116
|
},
|
|
113
117
|
});
|
|
114
118
|
```
|
|
115
119
|
|
|
116
|
-
#### `
|
|
120
|
+
#### `getSecrets(vault, names)`
|
|
117
121
|
|
|
118
122
|
Retrieves multiple secret values at once from the same vault.
|
|
119
123
|
|
|
120
124
|
```typescript
|
|
121
125
|
import { createResolver } from "@tailor-platform/sdk";
|
|
122
|
-
import {
|
|
126
|
+
import { secretmanager } from "@tailor-platform/sdk/runtime";
|
|
123
127
|
|
|
124
128
|
export default createResolver({
|
|
125
129
|
name: "send-notification",
|
|
130
|
+
operation: "query",
|
|
126
131
|
// ...
|
|
127
|
-
|
|
128
|
-
const
|
|
129
|
-
"sendgrid-api-key",
|
|
130
|
-
"stripe-secret-key",
|
|
131
|
-
]);
|
|
132
|
+
body: async ({ input }) => {
|
|
133
|
+
const { "sendgrid-api-key": apiKey, "stripe-secret-key": webhookSecret } =
|
|
134
|
+
await secretmanager.getSecrets("api-keys", ["sendgrid-api-key", "stripe-secret-key"]);
|
|
132
135
|
// Use the retrieved secrets
|
|
133
136
|
},
|
|
134
137
|
});
|
|
135
138
|
```
|
|
136
139
|
|
|
137
|
-
|
|
140
|
+
`getSecret` returns `Promise<string | undefined>`; `getSecrets` returns a `Promise` of a partial record keyed by the requested names, omitting any name that has no value.
|
|
141
|
+
|
|
142
|
+
Import `secretmanager` directly in resolver, executor, and workflow files — never the `secrets` object from `tailor.config.ts` (see [Declarative Configuration](#declarative-configuration) above).
|
|
138
143
|
|
|
139
144
|
### In Webhook Operations
|
|
140
145
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tailor-platform/sdk",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.22.0",
|
|
4
4
|
"description": "Tailor Platform SDK - The SDK to work with Tailor Platform",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -152,7 +152,7 @@
|
|
|
152
152
|
"@0no-co/graphql.web": "1.3.4",
|
|
153
153
|
"@badgateway/oauth2-client": "3.3.1",
|
|
154
154
|
"@bufbuild/protobuf": "2.15.0",
|
|
155
|
-
"@bufbuild/protovalidate": "1.
|
|
155
|
+
"@bufbuild/protovalidate": "1.3.0",
|
|
156
156
|
"@connectrpc/connect": "2.2.0",
|
|
157
157
|
"@connectrpc/connect-node": "2.2.0",
|
|
158
158
|
"@inquirer/core": "12.0.3",
|
|
@@ -164,41 +164,41 @@
|
|
|
164
164
|
"@opentelemetry/resources": "2.11.0",
|
|
165
165
|
"@opentelemetry/sdk-trace-node": "2.11.0",
|
|
166
166
|
"@opentelemetry/semantic-conventions": "1.43.0",
|
|
167
|
-
"@oxc-project/types": "0.
|
|
168
|
-
"@politty/zod": "0.
|
|
167
|
+
"@oxc-project/types": "0.151.0",
|
|
168
|
+
"@politty/zod": "0.3.0",
|
|
169
169
|
"@secretlint/core": "13.0.5",
|
|
170
170
|
"@secretlint/secretlint-rule-preset-recommend": "13.0.5",
|
|
171
171
|
"@standard-schema/spec": "1.1.0",
|
|
172
172
|
"@tailor-platform/function-kysely-tailordb": "0.1.3",
|
|
173
|
-
"@toiroakr/lines-db": "0.
|
|
173
|
+
"@toiroakr/lines-db": "0.13.0",
|
|
174
174
|
"@toiroakr/read-multiline": "0.4.1",
|
|
175
175
|
"@urql/core": "6.0.3",
|
|
176
|
-
"amaro": "1.1
|
|
176
|
+
"amaro": "1.2.1",
|
|
177
177
|
"confbox": "0.3.1",
|
|
178
178
|
"date-fns": "4.4.0",
|
|
179
179
|
"es-toolkit": "1.52.0",
|
|
180
180
|
"find-up-simple": "1.0.1",
|
|
181
|
-
"get-east-asian-width": "1.
|
|
181
|
+
"get-east-asian-width": "1.7.0",
|
|
182
182
|
"get-tsconfig": "4.14.3",
|
|
183
183
|
"globals": "17.12.0",
|
|
184
184
|
"graphql": "17.0.2",
|
|
185
185
|
"inflection": "3.0.2",
|
|
186
|
-
"kysely": "0.29.
|
|
186
|
+
"kysely": "0.29.6",
|
|
187
187
|
"mime-types": "3.0.2",
|
|
188
188
|
"open": "11.0.4",
|
|
189
|
-
"oxc-parser": "0.
|
|
190
|
-
"p-limit": "7.3.
|
|
189
|
+
"oxc-parser": "0.151.0",
|
|
190
|
+
"p-limit": "7.3.3",
|
|
191
191
|
"pathe": "2.0.3",
|
|
192
192
|
"pgsql-ast-parser": "12.0.2",
|
|
193
193
|
"pkg-types": "2.3.3",
|
|
194
|
-
"rolldown": "1.2.
|
|
194
|
+
"rolldown": "1.2.9",
|
|
195
195
|
"semver": "7.8.5",
|
|
196
196
|
"sql-highlight": "6.1.0",
|
|
197
197
|
"std-env": "4.2.0",
|
|
198
198
|
"temporal-polyfill": "1.0.5",
|
|
199
199
|
"temporal-spec": "1.0.1",
|
|
200
200
|
"ts-cron-validator": "1.1.5",
|
|
201
|
-
"type-fest": "5.
|
|
201
|
+
"type-fest": "5.10.0",
|
|
202
202
|
"xdg-basedir": "5.1.0",
|
|
203
203
|
"zod": "4.6.5"
|
|
204
204
|
},
|
|
@@ -208,18 +208,18 @@
|
|
|
208
208
|
"@tailor-platform/shared": "^0.0.0",
|
|
209
209
|
"@tailor-platform/tailor-proto": "^0.0.1",
|
|
210
210
|
"@types/mime-types": "3.0.1",
|
|
211
|
-
"@types/node": "24.13.
|
|
211
|
+
"@types/node": "24.13.6",
|
|
212
212
|
"@types/semver": "7.8.0",
|
|
213
213
|
"@typescript/native-preview": "7.0.0-dev.20260707.2",
|
|
214
|
-
"@vitest/coverage-v8": "5.0.
|
|
215
|
-
"eslint-plugin-zod": "4.
|
|
216
|
-
"oxfmt": "0.
|
|
217
|
-
"oxlint": "1.
|
|
218
|
-
"oxlint-tsgolint": "7.0.
|
|
214
|
+
"@vitest/coverage-v8": "5.0.1",
|
|
215
|
+
"eslint-plugin-zod": "4.14.2",
|
|
216
|
+
"oxfmt": "0.70.0",
|
|
217
|
+
"oxlint": "1.85.0",
|
|
218
|
+
"oxlint-tsgolint": "7.0.2002",
|
|
219
219
|
"sonda": "0.14.0",
|
|
220
220
|
"tsdown": "0.23.0",
|
|
221
221
|
"typescript": "6.0.3",
|
|
222
|
-
"vitest": "5.0.
|
|
222
|
+
"vitest": "5.0.1",
|
|
223
223
|
"zinfer": "0.4.7"
|
|
224
224
|
},
|
|
225
225
|
"peerDependencies": {
|