@tailor-platform/sdk 1.62.0 → 1.65.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/dist/{actor-J2gJ0eK5.d.mts → actor-D_2aJjYO.d.mts} +2 -2
- package/dist/{application-BezXGbrU.mjs → application-76hhIhnJ.mjs} +42 -5
- package/dist/application-76hhIhnJ.mjs.map +1 -0
- package/dist/application-av2raLs6.mjs +4 -0
- package/dist/cli/index.mjs +505 -121
- package/dist/cli/index.mjs.map +1 -1
- package/dist/cli/lib.d.mts +24 -31
- package/dist/cli/lib.mjs +2 -2
- package/dist/configure/index.d.mts +5 -5
- package/dist/configure/index.mjs.map +1 -1
- package/dist/{index-CfRFkXIO.d.mts → index-Bhjep8cS.d.mts} +2 -2
- package/dist/{index-DUupuPhZ.d.mts → index-CZ2r3qiO.d.mts} +2 -2
- package/dist/{index-CPRnOjjt.d.mts → index-Db2RvnEH.d.mts} +2 -2
- package/dist/{index-CLxubakC.d.mts → index-DcXIjt9F.d.mts} +5 -5
- package/dist/{index-CQZVJ5SX.d.mts → index-QpC0TNbH.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-C_FyVSdl.d.mts → plugin-DylAsA4Z.d.mts} +2 -2
- package/dist/{runtime-C6o4hiYq.mjs → runtime-C7qTBDD2.mjs} +565 -99
- package/dist/runtime-C7qTBDD2.mjs.map +1 -0
- package/dist/{tailordb-BlBGmQK-.d.mts → tailordb-C-ar4XCX.d.mts} +4 -4
- package/dist/utils/test/index.d.mts +3 -3
- package/dist/{workflow.generated-Bf1tWylx.d.mts → workflow.generated-CCDsY0ce.d.mts} +42 -6
- package/docs/cli/auth.md +4 -4
- package/docs/cli/function.md +8 -8
- package/docs/cli/query.md +1 -1
- package/docs/cli/setup.md +18 -12
- package/docs/cli/workflow.md +10 -10
- package/docs/cli/workspace.md +14 -10
- package/docs/cli-reference.md +4 -4
- package/docs/github-actions.md +337 -0
- package/docs/services/auth.md +19 -0
- package/docs/services/idp.md +96 -0
- package/docs/services/tailordb-migration.md +17 -6
- package/package.json +12 -12
- package/dist/application-BezXGbrU.mjs.map +0 -1
- package/dist/application-DSXntqnV.mjs +0 -4
- package/dist/runtime-C6o4hiYq.mjs.map +0 -1
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
# GitHub Actions Integration
|
|
2
|
+
|
|
3
|
+
`tailor-sdk setup github` generates a GitHub Actions workflow that deploys your
|
|
4
|
+
Tailor Platform application automatically on push or tag.
|
|
5
|
+
|
|
6
|
+
> **Beta:** This command is under active development. CLI flags, the generated
|
|
7
|
+
> workflow, and the `.github/tailor-sdk.lock` schema may change before general
|
|
8
|
+
> availability.
|
|
9
|
+
|
|
10
|
+
## Quick start
|
|
11
|
+
|
|
12
|
+
Run the command from the root of your SDK project (where `tailor.config.ts`
|
|
13
|
+
lives):
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# Branch target: deploy to stg on every push to main
|
|
17
|
+
tailor-sdk setup github -n my-app-stg
|
|
18
|
+
|
|
19
|
+
# Tag target: deploy to production when a tag is pushed, with an approval gate
|
|
20
|
+
tailor-sdk setup github -n my-app-prod \
|
|
21
|
+
--tag --branch main --environment production
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
After running the command, follow the **Next steps** printed to the terminal to
|
|
25
|
+
set the required secrets, set the `TAILOR_PLATFORM_WORKSPACE_ID` variable, and
|
|
26
|
+
commit the generated files.
|
|
27
|
+
|
|
28
|
+
The generated workflow deploys to whichever workspace its
|
|
29
|
+
`TAILOR_PLATFORM_WORKSPACE_ID` Environment variable points at — it never
|
|
30
|
+
creates or renames a workspace. Provision the workspace and set that variable
|
|
31
|
+
before the first deploy (see [Targeting a workspace](#targeting-a-workspace)).
|
|
32
|
+
|
|
33
|
+
## Targets
|
|
34
|
+
|
|
35
|
+
A _target_ is one workflow file that handles one deployment destination.
|
|
36
|
+
Run `setup github` once per target.
|
|
37
|
+
|
|
38
|
+
### Branch target (recommended for staging)
|
|
39
|
+
|
|
40
|
+
The branch target fires on pull requests and pushes to the branch you specify
|
|
41
|
+
(defaulting to the repository's default branch when `--branch` is omitted):
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
tailor-sdk setup github -n my-app-stg
|
|
45
|
+
# Equivalent to:
|
|
46
|
+
tailor-sdk setup github -n my-app-stg --branch main
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
What it does:
|
|
50
|
+
|
|
51
|
+
- On **pull request**: runs `generate`, checks that generated files are
|
|
52
|
+
committed (`generate-check`), and posts a deployment plan as a PR comment.
|
|
53
|
+
(The plan and deploy jobs are independent; pull requests run plan only.)
|
|
54
|
+
- On **push to the branch**: deploys. The deploy action runs `generate` and
|
|
55
|
+
applies the config; it does not re-run the PR plan.
|
|
56
|
+
- On **`workflow_dispatch`** with `dry-run: true`: runs plan only (useful for
|
|
57
|
+
rollback verification — see [Rollback](#rollback)). With `dry-run: false`
|
|
58
|
+
(default) it deploys, like a push.
|
|
59
|
+
|
|
60
|
+
Fork pull requests cannot read repository secrets. For forks, the plan step is
|
|
61
|
+
automatically skipped; `generate-check` and other non-secret checks still run.
|
|
62
|
+
|
|
63
|
+
### Tag target (recommended for production)
|
|
64
|
+
|
|
65
|
+
The tag target fires when a tag matching `--tag-pattern` (default `v*`) is
|
|
66
|
+
pushed:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
tailor-sdk setup github -n my-app-prod \
|
|
70
|
+
--tag --tag-pattern "v*" --branch main --environment production
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
What it does:
|
|
74
|
+
|
|
75
|
+
- **`tailor-tag-guard`** (generated when `--branch` is supplied): checks that
|
|
76
|
+
the tagged commit is reachable from `main`. A tag on an unrelated commit is
|
|
77
|
+
silently skipped, not an error.
|
|
78
|
+
- **`tailor-plan`**: runs `generate`, `generate-check`, and posts a plan
|
|
79
|
+
summary to the Actions step summary (no PR comment, because there is no PR).
|
|
80
|
+
- **`tailor-deploy`**: waits for `tailor-plan`, then deploys. If the target
|
|
81
|
+
environment has required reviewers configured, GitHub requires their approval
|
|
82
|
+
before the deploy job starts.
|
|
83
|
+
- On **`workflow_dispatch`**: the `tailor-tag-guard` result is ignored — the
|
|
84
|
+
plan job runs regardless of branch reachability (useful for rolling back to
|
|
85
|
+
any tag). `dry-run: true` stops before the deploy job.
|
|
86
|
+
|
|
87
|
+
### Choosing `--branch` for the tag target
|
|
88
|
+
|
|
89
|
+
`--branch` has two different roles depending on the target kind:
|
|
90
|
+
|
|
91
|
+
| Target | Role of `--branch` |
|
|
92
|
+
| ------ | ---------------------------------------------------------------------------------------------- |
|
|
93
|
+
| Branch | The branch that triggers the workflow (push + PR base). Defaults to the repo's default branch. |
|
|
94
|
+
| Tag | The branch whose history the tag must be reachable from. Omit to disable the guard entirely. |
|
|
95
|
+
|
|
96
|
+
The workspace name (`--workspace-name`, or the config `name` when omitted) must
|
|
97
|
+
be 3–63 characters of lowercase letters, numbers, and hyphens, and cannot start
|
|
98
|
+
or end with a hyphen. It is used for the generated file name, the workflow
|
|
99
|
+
`name:`, the plan label, and the default GitHub Environment name; it does not
|
|
100
|
+
select which workspace gets deployed (see
|
|
101
|
+
[Targeting a workspace](#targeting-a-workspace)).
|
|
102
|
+
|
|
103
|
+
## Targeting a workspace
|
|
104
|
+
|
|
105
|
+
The generated `plan` and `deploy` jobs target a workspace by **id**, read from
|
|
106
|
+
the `TAILOR_PLATFORM_WORKSPACE_ID` GitHub Environment variable. They never
|
|
107
|
+
resolve a workspace by name and never create one. Set this variable per
|
|
108
|
+
environment before the first deploy.
|
|
109
|
+
|
|
110
|
+
Because the variable is scoped to a GitHub Environment, both the `plan` and
|
|
111
|
+
`deploy` jobs declare `environment:` so the value resolves. When you omit
|
|
112
|
+
`--environment`, the environment name defaults to the workspace name.
|
|
113
|
+
|
|
114
|
+
1. Provision the workspace (once per environment) and obtain its id. For now
|
|
115
|
+
this is a manual step:
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
tailor-sdk workspace create # copy the printed workspace id
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
2. Set the id as the Environment variable (the environment name is your
|
|
122
|
+
`--environment` value, or the workspace name when omitted):
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
gh variable set TAILOR_PLATFORM_WORKSPACE_ID --env my-app-stg
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
If `TAILOR_PLATFORM_WORKSPACE_ID` is unset, `deploy` fails because the target
|
|
129
|
+
workspace is not provisioned, and `plan` reports that the workspace is not
|
|
130
|
+
provisioned yet instead of running a dry-run.
|
|
131
|
+
|
|
132
|
+
If the target environment has required reviewers, that approval gate applies to
|
|
133
|
+
the `plan` job as well as `deploy`, because `plan` must enter the environment to
|
|
134
|
+
read the variable. (A token-based read that lets `plan` run without entering the
|
|
135
|
+
environment is planned.)
|
|
136
|
+
|
|
137
|
+
## Generated files
|
|
138
|
+
|
|
139
|
+
Running `setup github` creates or updates:
|
|
140
|
+
|
|
141
|
+
### `.github/workflows/tailor-<workspace-name>.yml`
|
|
142
|
+
|
|
143
|
+
The workflow file. The `name:` field is set to `Tailor (<workspace-name>)` so
|
|
144
|
+
you can distinguish multiple workspaces in the Actions UI.
|
|
145
|
+
|
|
146
|
+
Jobs and steps whose `id` starts with `tailor-` are managed by the SDK. Do not
|
|
147
|
+
edit or rename them — the SDK tracks them by id.
|
|
148
|
+
|
|
149
|
+
You can add your own jobs and steps around the managed ones. To add
|
|
150
|
+
project-specific setup (such as private registry authentication or a system
|
|
151
|
+
dependency), add a step _before_ the managed setup steps. For post-install
|
|
152
|
+
extras (such as `playwright install`), add a step _after_ them.
|
|
153
|
+
|
|
154
|
+
Note that re-running `setup github` currently regenerates the whole file: if
|
|
155
|
+
the file differs from what the SDK last wrote — whether you edited a managed
|
|
156
|
+
step or added your own — the command stops and reports the conflict. Pass
|
|
157
|
+
`--force` to discard your edits and regenerate from the current template, then
|
|
158
|
+
re-apply your own steps. (Preserving user-added steps across regeneration is
|
|
159
|
+
planned.)
|
|
160
|
+
|
|
161
|
+
### `.github/tailor-sdk.lock`
|
|
162
|
+
|
|
163
|
+
A machine-owned JSON file that tracks which files the SDK manages, the inputs
|
|
164
|
+
they were generated from, and their content hashes. **Commit this file. Never
|
|
165
|
+
edit it by hand.** The SDK uses it to recognize its own files on re-runs and to
|
|
166
|
+
detect hand edits.
|
|
167
|
+
|
|
168
|
+
### `tailor.config.ts` (id injection)
|
|
169
|
+
|
|
170
|
+
If your config does not already have an `id` field, `setup github` injects one.
|
|
171
|
+
This `id` must be committed alongside the workflow file. In CI, `tailor-sdk
|
|
172
|
+
deploy` refuses to inject a new id — if the id were assigned fresh on each CI
|
|
173
|
+
run, every deploy would create a brand-new application and lose ownership of
|
|
174
|
+
previously deployed resources.
|
|
175
|
+
|
|
176
|
+
If your pipeline intentionally deploys a fresh, throwaway application on every
|
|
177
|
+
run (for example an end-to-end test harness that creates and deletes its own
|
|
178
|
+
workspace), set `TAILOR_PLATFORM_SDK_ALLOW_CI_ID_INJECTION=true` to opt back
|
|
179
|
+
into automatic id injection for that pipeline.
|
|
180
|
+
|
|
181
|
+
## Secrets
|
|
182
|
+
|
|
183
|
+
The generated workflow reads two secrets:
|
|
184
|
+
|
|
185
|
+
| Secret | Description |
|
|
186
|
+
| -------------------------------------------- | -------------------------- |
|
|
187
|
+
| `TAILOR_PLATFORM_MACHINE_USER_CLIENT_ID` | Machine user client ID |
|
|
188
|
+
| `TAILOR_PLATFORM_MACHINE_USER_CLIENT_SECRET` | Machine user client secret |
|
|
189
|
+
|
|
190
|
+
Set them on the target GitHub Environment (the `--environment` value, or the
|
|
191
|
+
workspace name when omitted) with the GitHub CLI:
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
gh secret set TAILOR_PLATFORM_MACHINE_USER_CLIENT_ID --env my-app-stg
|
|
195
|
+
gh secret set TAILOR_PLATFORM_MACHINE_USER_CLIENT_SECRET --env my-app-stg
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
Setting them at the environment level isolates each target's credentials and
|
|
199
|
+
keeps them alongside that environment's `TAILOR_PLATFORM_WORKSPACE_ID`
|
|
200
|
+
variable. You can also set them as repository-level secrets if every target
|
|
201
|
+
shares one machine user.
|
|
202
|
+
|
|
203
|
+
## GitHub Environments (approval gate)
|
|
204
|
+
|
|
205
|
+
Both the `plan` and `deploy` jobs are associated with a GitHub Environment — the
|
|
206
|
+
`--environment` value, or the workspace name when omitted. The environment holds
|
|
207
|
+
that target's `TAILOR_PLATFORM_WORKSPACE_ID` variable and machine-user secrets,
|
|
208
|
+
and lets you:
|
|
209
|
+
|
|
210
|
+
- **Require reviewer approval** before the jobs run (suitable for production).
|
|
211
|
+
- **Scope secrets and the workspace-id variable** to specific environments so
|
|
212
|
+
staging and production deploy to separate workspaces with separate machine
|
|
213
|
+
users.
|
|
214
|
+
|
|
215
|
+
To configure the environment, go to your repository's **Settings → Environments**
|
|
216
|
+
and create an environment whose name matches the target's environment. Add
|
|
217
|
+
required reviewers, the `TAILOR_PLATFORM_WORKSPACE_ID` variable, and the
|
|
218
|
+
environment-scoped secrets there.
|
|
219
|
+
|
|
220
|
+
Required reviewers gate the `plan` job as well, because `plan` must enter the
|
|
221
|
+
environment to read `TAILOR_PLATFORM_WORKSPACE_ID`. (A token-based read that
|
|
222
|
+
lets `plan` run without entering the environment is planned.)
|
|
223
|
+
|
|
224
|
+
## Manual runs and dry-run
|
|
225
|
+
|
|
226
|
+
You can trigger the workflow manually from **Actions → Run workflow**. The
|
|
227
|
+
`dry-run` input (boolean, default `false`) runs the plan job without
|
|
228
|
+
deploying. Use this to preview what would change before executing a rollback
|
|
229
|
+
or an out-of-band deploy. With `dry-run` off, a branch-target dispatch goes
|
|
230
|
+
straight to deploy (like a push), while a tag-target dispatch runs plan first
|
|
231
|
+
and then deploys.
|
|
232
|
+
|
|
233
|
+
For tag targets, you can select any branch or tag when dispatching manually. The tag-guard check is skipped for manual dispatches, so
|
|
234
|
+
you can deploy any commit regardless of branch membership.
|
|
235
|
+
|
|
236
|
+
## Monorepo setup
|
|
237
|
+
|
|
238
|
+
For a monorepo where your SDK app lives in a subdirectory, pass `--dir`:
|
|
239
|
+
|
|
240
|
+
```bash
|
|
241
|
+
tailor-sdk setup github -n my-app --dir apps/backend
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
The generated workflow adds a `paths` filter on `apps/backend/**` so the
|
|
245
|
+
workflow only runs when that subdirectory changes. The `working-directory` for
|
|
246
|
+
SDK commands is set accordingly.
|
|
247
|
+
|
|
248
|
+
## Rollback
|
|
249
|
+
|
|
250
|
+
`tailor-sdk deploy` is declarative: redeploying a past configuration returns
|
|
251
|
+
the platform to that state. The recommended rollback approaches are:
|
|
252
|
+
|
|
253
|
+
### Option 1 — Revert the commit (branch target)
|
|
254
|
+
|
|
255
|
+
```bash
|
|
256
|
+
git revert <commit-sha>
|
|
257
|
+
git push
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
The push triggers the deploy job, which applies the reverted configuration. To
|
|
261
|
+
preview the diff first, open the revert as a pull request (the plan job comments
|
|
262
|
+
the diff) or use a `dry-run: true` manual dispatch before merging.
|
|
263
|
+
|
|
264
|
+
### Option 2 — Advance the tag (tag target)
|
|
265
|
+
|
|
266
|
+
Move the production tag to an earlier commit:
|
|
267
|
+
|
|
268
|
+
```bash
|
|
269
|
+
git tag -f v1.2.3 <earlier-commit-sha>
|
|
270
|
+
git push --force-with-lease origin v1.2.3
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
Or create a new tag that points to the earlier commit:
|
|
274
|
+
|
|
275
|
+
```bash
|
|
276
|
+
git tag v1.2.4 <earlier-commit-sha>
|
|
277
|
+
git push origin v1.2.4
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
### Option 3 — Manual dispatch with dry-run verification
|
|
281
|
+
|
|
282
|
+
1. Go to **Actions → `Tailor (<workspace-name>)` → Run workflow**.
|
|
283
|
+
2. Enter the tag or ref you want to redeploy.
|
|
284
|
+
3. Set `dry-run` to `true` and run. Inspect the plan output.
|
|
285
|
+
4. Run again with `dry-run` set to `false`.
|
|
286
|
+
|
|
287
|
+
For tag targets, the tag-guard step is bypassed on manual dispatch, so you can
|
|
288
|
+
dispatch from any ref. Environment approval (if configured) applies as usual.
|
|
289
|
+
|
|
290
|
+
### Rollback limitations
|
|
291
|
+
|
|
292
|
+
- **Schema and data are not rolled back.** If the older config expects a schema
|
|
293
|
+
state that no longer exists, the plan may show errors. In that case, review
|
|
294
|
+
the diff carefully before proceeding.
|
|
295
|
+
- **Seed data** is not part of the deployment pipeline and is unaffected by
|
|
296
|
+
rollbacks.
|
|
297
|
+
- **Static websites** are not yet integrated into the generated pipeline.
|
|
298
|
+
Static asset rollbacks must be performed manually.
|
|
299
|
+
|
|
300
|
+
## Multi-environment example
|
|
301
|
+
|
|
302
|
+
A typical setup with staging and production:
|
|
303
|
+
|
|
304
|
+
```bash
|
|
305
|
+
# Staging: main → stg (deploy on every push to main)
|
|
306
|
+
tailor-sdk setup github -n my-app-stg
|
|
307
|
+
|
|
308
|
+
# Production: tagged commits → prod, with approval gate and branch guard
|
|
309
|
+
tailor-sdk setup github -n my-app-prod \
|
|
310
|
+
--tag --branch main --environment production
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
Then provision each workspace and set its id on the matching environment (the
|
|
314
|
+
staging target's environment defaults to `my-app-stg`; production uses
|
|
315
|
+
`production`):
|
|
316
|
+
|
|
317
|
+
```bash
|
|
318
|
+
gh variable set TAILOR_PLATFORM_WORKSPACE_ID --env my-app-stg
|
|
319
|
+
gh secret set TAILOR_PLATFORM_MACHINE_USER_CLIENT_ID --env my-app-stg
|
|
320
|
+
gh secret set TAILOR_PLATFORM_MACHINE_USER_CLIENT_SECRET --env my-app-stg
|
|
321
|
+
|
|
322
|
+
gh variable set TAILOR_PLATFORM_WORKSPACE_ID --env production
|
|
323
|
+
gh secret set TAILOR_PLATFORM_MACHINE_USER_CLIENT_ID --env production
|
|
324
|
+
gh secret set TAILOR_PLATFORM_MACHINE_USER_CLIENT_SECRET --env production
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
Commit both workflow files and `.github/tailor-sdk.lock`.
|
|
328
|
+
|
|
329
|
+
## Updating the generated workflow
|
|
330
|
+
|
|
331
|
+
When you upgrade the SDK, re-run `setup github` with the same flags to pick up
|
|
332
|
+
template improvements. If the SDK detects that you have hand-edited a managed
|
|
333
|
+
section, it stops and asks you to use `--force` to overwrite your edits, or to
|
|
334
|
+
move your customizations into your own steps before regenerating.
|
|
335
|
+
|
|
336
|
+
The `.github/tailor-sdk.lock` file records the flags used at generation time,
|
|
337
|
+
so you can check what arguments were used previously.
|
package/docs/services/auth.md
CHANGED
|
@@ -515,6 +515,25 @@ export const auth = defineAuth("my-auth", {
|
|
|
515
515
|
|
|
516
516
|
**invoker**: The machine user whose permissions are used to execute the hook. Must reference a machine user defined in the same auth configuration.
|
|
517
517
|
|
|
518
|
+
### Federated identity claims
|
|
519
|
+
|
|
520
|
+
When a user signs in through a Built-in IdP OAuth provider (Google or Microsoft), the upstream provider's profile is available on `claims.federated_identity`. It is `undefined` for password logins, so guard before reading it. Commonly present claims (`name`, `given_name`, `family_name`, `picture`, `locale`) are typed; any other claim the provider issues is forwarded as-is. Availability varies by provider (for example, Microsoft does not issue `picture`).
|
|
521
|
+
|
|
522
|
+
```typescript
|
|
523
|
+
hooks: {
|
|
524
|
+
beforeLogin: {
|
|
525
|
+
handler: async ({ claims }) => {
|
|
526
|
+
const federated = claims.federated_identity;
|
|
527
|
+
if (federated?.provider === "google") {
|
|
528
|
+
// Populate the user record from the upstream profile
|
|
529
|
+
const avatarUrl = federated.claims.picture;
|
|
530
|
+
}
|
|
531
|
+
},
|
|
532
|
+
invoker: "hook-invoker",
|
|
533
|
+
},
|
|
534
|
+
}
|
|
535
|
+
```
|
|
536
|
+
|
|
518
537
|
## CLI Commands
|
|
519
538
|
|
|
520
539
|
Manage Auth resources using the CLI:
|
package/docs/services/idp.md
CHANGED
|
@@ -125,6 +125,89 @@ defineIdp("my-idp", {
|
|
|
125
125
|
});
|
|
126
126
|
```
|
|
127
127
|
|
|
128
|
+
### userAuthPolicy
|
|
129
|
+
|
|
130
|
+
User authentication policy. Controls password requirements, the identifier used for login, allowed email domains, and social login providers. Every field is optional. The boolean options default to disabled, and the password length fields default to a minimum of 6 and a maximum of 4096.
|
|
131
|
+
|
|
132
|
+
```typescript
|
|
133
|
+
defineIdp("my-idp", {
|
|
134
|
+
clients: ["my-client"],
|
|
135
|
+
userAuthPolicy: {
|
|
136
|
+
useNonEmailIdentifier: false,
|
|
137
|
+
allowSelfPasswordReset: true,
|
|
138
|
+
passwordRequireUppercase: true,
|
|
139
|
+
passwordRequireLowercase: true,
|
|
140
|
+
passwordRequireNonAlphanumeric: true,
|
|
141
|
+
passwordRequireNumeric: true,
|
|
142
|
+
passwordMinLength: 8,
|
|
143
|
+
passwordMaxLength: 128,
|
|
144
|
+
},
|
|
145
|
+
});
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
**Login behavior:**
|
|
149
|
+
|
|
150
|
+
- `useNonEmailIdentifier` - Allow a non-email identifier (username) instead of requiring an email address. Default `false`.
|
|
151
|
+
- `allowSelfPasswordReset` - Show the "Forgot password?" flow so users can reset their own password. Default `false`.
|
|
152
|
+
- `disablePasswordAuth` - Remove password authentication entirely. Default `false`. Requires at least one social login provider to be enabled.
|
|
153
|
+
|
|
154
|
+
**Password requirements:**
|
|
155
|
+
|
|
156
|
+
- `passwordRequireUppercase` - Require at least one uppercase letter. Default `false`.
|
|
157
|
+
- `passwordRequireLowercase` - Require at least one lowercase letter. Default `false`.
|
|
158
|
+
- `passwordRequireNumeric` - Require at least one numeric character. Default `false`.
|
|
159
|
+
- `passwordRequireNonAlphanumeric` - Require at least one non-alphanumeric character. Default `false`.
|
|
160
|
+
- `passwordMinLength` - Minimum password length. Must be between 6 and 30. Default `6`.
|
|
161
|
+
- `passwordMaxLength` - Maximum password length. Must be between 6 and 4096. Default `4096`.
|
|
162
|
+
|
|
163
|
+
**Email domains and social login:**
|
|
164
|
+
|
|
165
|
+
- `allowedEmailDomains` - Restrict registration to these email domains. An empty list (the default) allows all domains, but a non-empty list is required when `allowGoogleOauth` or `allowMicrosoftOauth` is enabled.
|
|
166
|
+
- `allowGoogleOauth` - Enable the "Sign in with Google" button. Default `false`.
|
|
167
|
+
- `allowMicrosoftOauth` - Enable the "Sign in with Microsoft" button. Default `false`.
|
|
168
|
+
|
|
169
|
+
**Constraints:** the following combinations are rejected at parse time.
|
|
170
|
+
|
|
171
|
+
- `passwordMinLength` must be less than or equal to `passwordMaxLength`.
|
|
172
|
+
- A non-empty `allowedEmailDomains` cannot be combined with `useNonEmailIdentifier: true` (an empty list is allowed). Enabling `allowGoogleOauth` or `allowMicrosoftOauth` is likewise rejected with `useNonEmailIdentifier: true` (leaving them `false` or unset is fine).
|
|
173
|
+
- `allowGoogleOauth` requires a non-empty `allowedEmailDomains`.
|
|
174
|
+
- `allowMicrosoftOauth` requires both a non-empty `allowedEmailDomains` and `disablePasswordAuth: true`.
|
|
175
|
+
- `disablePasswordAuth` requires `allowGoogleOauth` or `allowMicrosoftOauth`, and cannot be combined with `allowSelfPasswordReset`.
|
|
176
|
+
|
|
177
|
+
### gqlOperations
|
|
178
|
+
|
|
179
|
+
Controls which GraphQL user-management operations the IdP exposes. All operations are enabled by default. Use this to turn operations off entirely, independent of the `permission` policies that decide who may call them.
|
|
180
|
+
|
|
181
|
+
```typescript
|
|
182
|
+
defineIdp("my-idp", {
|
|
183
|
+
clients: ["my-client"],
|
|
184
|
+
gqlOperations: {
|
|
185
|
+
create: true,
|
|
186
|
+
read: true,
|
|
187
|
+
update: true,
|
|
188
|
+
delete: false,
|
|
189
|
+
sendPasswordResetEmail: false,
|
|
190
|
+
},
|
|
191
|
+
});
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
**Fields:** each field defaults to `true` (enabled). Set a field to `false` to disable that operation.
|
|
195
|
+
|
|
196
|
+
- `create` - The `_createUser` mutation.
|
|
197
|
+
- `read` - The `_users` and `_user` query operations.
|
|
198
|
+
- `update` - The `_updateUser` mutation.
|
|
199
|
+
- `delete` - The `_deleteUser` mutation.
|
|
200
|
+
- `sendPasswordResetEmail` - The `_sendPasswordResetEmail` mutation.
|
|
201
|
+
|
|
202
|
+
**Shortcut:** pass the string `"query"` to expose a read-only IdP. It enables `read` and disables every mutation.
|
|
203
|
+
|
|
204
|
+
```typescript
|
|
205
|
+
defineIdp("my-idp", {
|
|
206
|
+
clients: ["my-client"],
|
|
207
|
+
gqlOperations: "query",
|
|
208
|
+
});
|
|
209
|
+
```
|
|
210
|
+
|
|
128
211
|
### authorization (optional, legacy)
|
|
129
212
|
|
|
130
213
|
Legacy access control field. Use `permission` instead for fine-grained per-operation control. This field is kept for backward compatibility.
|
|
@@ -170,6 +253,19 @@ defineIdp("my-idp", {
|
|
|
170
253
|
|
|
171
254
|
**Validation:** Each field must be 200 characters or less and must not contain newline characters.
|
|
172
255
|
|
|
256
|
+
### lang
|
|
257
|
+
|
|
258
|
+
UI language for the IdP-hosted pages such as the login and password reset screens.
|
|
259
|
+
|
|
260
|
+
```typescript
|
|
261
|
+
defineIdp("my-idp", {
|
|
262
|
+
clients: ["my-client"],
|
|
263
|
+
lang: "ja",
|
|
264
|
+
});
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
**Values:** `"en"` or `"ja"`.
|
|
268
|
+
|
|
173
269
|
### publishUserEvents
|
|
174
270
|
|
|
175
271
|
Publish IdP user lifecycle events (`idp.user.created`, `idp.user.updated`, `idp.user.deleted`). These events are consumed by executors that use `idpUserCreatedTrigger`, `idpUserUpdatedTrigger`, `idpUserDeletedTrigger`, or `idpUserTrigger`.
|
|
@@ -355,20 +355,21 @@ Coordinate this with your team because everyone else's local migrations will be
|
|
|
355
355
|
|
|
356
356
|
## Failure Recovery
|
|
357
357
|
|
|
358
|
-
If
|
|
358
|
+
If the pre-migration phase or `migrate.ts` fails:
|
|
359
359
|
|
|
360
360
|
- **The transaction rolls back** for that migration's script. Database changes the script made are undone.
|
|
361
|
-
- **The pre-migration
|
|
362
|
-
- The whole `apply` aborts. Subsequent migrations in the same run do not execute.
|
|
361
|
+
- **The pre-migration schema changes are rolled back** to the prior checkpoint: types that already existed are restored to their previous shape, and types the migration newly introduced are dropped. The workspace is left at its prior checkpoint and prior schema — not half-applied.
|
|
362
|
+
- The whole `apply` aborts and the checkpoint label is not bumped. Subsequent migrations in the same run do not execute.
|
|
363
|
+
|
|
364
|
+
The rollback is best-effort per type; if reverting a type fails, a warning is logged and the original migration error is still reported.
|
|
363
365
|
|
|
364
366
|
After a failure:
|
|
365
367
|
|
|
366
368
|
1. Read the `Logs:` block in the apply output to find the cause.
|
|
367
369
|
2. Fix `migrate.ts` (or the data it depends on).
|
|
368
|
-
3. Re-run `tailor-sdk deploy`. The same migration runs again because its label was never bumped.
|
|
369
|
-
4. If the pre-migration relaxation is causing problems for application code in the meantime, accept the temporary optionality or roll forward with a fix; do not try to manually re-tighten the schema, or you'll create remote drift.
|
|
370
|
+
3. Re-run `tailor-sdk deploy`. The same migration runs again because its label was never bumped, and the prior-checkpoint schema is a clean baseline to retry against.
|
|
370
371
|
|
|
371
|
-
If a migration **succeeds in script** but the post-migration phase fails (rare; usually
|
|
372
|
+
If a migration **succeeds in script** but the **post-migration phase** fails (rare; usually a constraint violation the script should have prevented), the pre-migration changes are **not** rolled back: the script's data changes are already committed and the post-migration phase may have dropped removed columns or types, which cannot be reverted without data loss. Investigate, fix, and re-run.
|
|
372
373
|
|
|
373
374
|
## Rollback Strategy
|
|
374
375
|
|
|
@@ -444,6 +445,16 @@ For genuinely different schemas across environments, prefer separate workspaces
|
|
|
444
445
|
4. To force the remote schema back to a known snapshot, use `migration sync <N>` (see [`migration sync` Semantics](#migration-sync-semantics)).
|
|
445
446
|
5. As a last resort in non-production environments, `--no-schema-check` skips both checks. Do not use this as a routine workaround.
|
|
446
447
|
|
|
448
|
+
### "Invalid schema snapshot" or "Invalid migration diff" error
|
|
449
|
+
|
|
450
|
+
**Cause:** A `schema.json` or `diff.json` file in the `migrations/` directory is corrupted or does not match the expected structure. Merge conflicts left in these files are a common cause.
|
|
451
|
+
|
|
452
|
+
**Resolution:**
|
|
453
|
+
|
|
454
|
+
1. Read the error message — it includes the file path and the offending field.
|
|
455
|
+
2. Restore the file from version control (`git checkout -- <path>`), or regenerate migration files with `migration generate` / `migration script`.
|
|
456
|
+
3. Do not hand-edit `schema.json` or `diff.json`; they are managed by the CLI.
|
|
457
|
+
|
|
447
458
|
### "No machine user available for migration execution"
|
|
448
459
|
|
|
449
460
|
**Cause:** Neither `migration.machineUser` is set nor are there any machine users in `auth.machineUsers`.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tailor-platform/sdk",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.65.0",
|
|
4
4
|
"description": "Tailor Platform SDK - The SDK to work with Tailor Platform",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -146,11 +146,11 @@
|
|
|
146
146
|
"@jridgewell/trace-mapping": "0.3.31",
|
|
147
147
|
"@napi-rs/keyring": "1.3.0",
|
|
148
148
|
"@opentelemetry/api": "1.9.1",
|
|
149
|
-
"@opentelemetry/exporter-trace-otlp-proto": "0.
|
|
150
|
-
"@opentelemetry/resources": "2.
|
|
151
|
-
"@opentelemetry/sdk-trace-node": "2.
|
|
149
|
+
"@opentelemetry/exporter-trace-otlp-proto": "0.219.0",
|
|
150
|
+
"@opentelemetry/resources": "2.8.0",
|
|
151
|
+
"@opentelemetry/sdk-trace-node": "2.8.0",
|
|
152
152
|
"@opentelemetry/semantic-conventions": "1.41.1",
|
|
153
|
-
"@oxc-project/types": "0.
|
|
153
|
+
"@oxc-project/types": "0.135.0",
|
|
154
154
|
"@standard-schema/spec": "1.1.0",
|
|
155
155
|
"@tailor-platform/function-kysely-tailordb": "0.1.3",
|
|
156
156
|
"@toiroakr/lines-db": "0.9.2",
|
|
@@ -169,34 +169,34 @@
|
|
|
169
169
|
"madge": "8.0.0",
|
|
170
170
|
"mime-types": "3.0.2",
|
|
171
171
|
"open": "11.0.0",
|
|
172
|
-
"oxc-parser": "0.
|
|
172
|
+
"oxc-parser": "0.135.0",
|
|
173
173
|
"p-limit": "7.3.0",
|
|
174
174
|
"pathe": "2.0.3",
|
|
175
175
|
"pgsql-ast-parser": "12.0.2",
|
|
176
176
|
"pkg-types": "2.3.1",
|
|
177
177
|
"politty": "0.5.1",
|
|
178
178
|
"rolldown": "1.1.0",
|
|
179
|
-
"semver": "7.8.
|
|
179
|
+
"semver": "7.8.3",
|
|
180
180
|
"sql-highlight": "6.1.0",
|
|
181
181
|
"std-env": "4.1.0",
|
|
182
182
|
"table": "6.9.0",
|
|
183
183
|
"ts-cron-validator": "1.1.5",
|
|
184
184
|
"tsx": "4.22.4",
|
|
185
185
|
"type-fest": "5.7.0",
|
|
186
|
-
"undici": "8.4.
|
|
186
|
+
"undici": "8.4.1",
|
|
187
187
|
"xdg-basedir": "5.1.0",
|
|
188
188
|
"zod": "4.4.3"
|
|
189
189
|
},
|
|
190
190
|
"devDependencies": {
|
|
191
|
-
"@opentelemetry/sdk-trace-base": "2.
|
|
191
|
+
"@opentelemetry/sdk-trace-base": "2.8.0",
|
|
192
192
|
"@types/madge": "5.0.3",
|
|
193
193
|
"@types/mime-types": "3.0.1",
|
|
194
194
|
"@types/node": "24.13.1",
|
|
195
195
|
"@types/semver": "7.7.1",
|
|
196
|
-
"@typescript/native-preview": "7.0.0-dev.
|
|
196
|
+
"@typescript/native-preview": "7.0.0-dev.20260612.1",
|
|
197
197
|
"@vitest/coverage-v8": "4.1.8",
|
|
198
|
-
"oxfmt": "0.
|
|
199
|
-
"oxlint": "1.
|
|
198
|
+
"oxfmt": "0.54.0",
|
|
199
|
+
"oxlint": "1.69.0",
|
|
200
200
|
"oxlint-tsgolint": "0.23.0",
|
|
201
201
|
"sonda": "0.11.1",
|
|
202
202
|
"tsdown": "0.22.2",
|