@tailor-platform/sdk 2.14.2 → 2.16.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 +108 -0
- package/bin/tailor.mjs +2 -2
- package/dist/application-Dw3t9p2f.mjs +1 -0
- package/dist/{application-BAqZFMWP.mjs → application-wYQ-ivDg.mjs} +27 -27
- package/dist/application-wYQ-ivDg.mjs.map +1 -0
- package/dist/cli/commands/deploy/app-id-lock.d.mts +97 -0
- package/dist/cli/commands/executor/jobs.d.mts +1 -0
- package/dist/cli/commands/generate/seed/bundler.d.mts +18 -0
- package/dist/cli/commands/tailordb/migrate/config.d.mts +1 -0
- package/dist/cli/commands/tailordb/migrate/diff-calculator.d.mts +15 -1
- package/dist/cli/commands/tailordb/migrate/generate.d.mts +5 -2
- package/dist/cli/commands/tailordb/migrate/rename-detection.d.mts +13 -0
- package/dist/cli/commands/tailordb/migrate/snapshot-comparison.d.mts +7 -1
- package/dist/cli/commands/workflow/executions.d.mts +2 -0
- package/dist/cli/commands/workflow/waiter.d.mts +1 -0
- package/dist/cli/commands/workspace/create.d.mts +16 -1
- package/dist/cli/commands/workspace/expiry.d.mts +5 -0
- package/dist/cli/commands/workspace/get.d.mts +6 -1
- package/dist/cli/commands/workspace/list.d.mts +1 -0
- package/dist/cli/lib.d.mts +6 -3
- package/dist/cli/lib.mjs +1 -1
- package/dist/cli/lib.mjs.map +1 -1
- package/dist/cli/main.d.mts +8 -8
- package/dist/cli/main.mjs +56 -60
- package/dist/cli/main.mjs.map +1 -1
- package/dist/cli/shared/command.d.mts +1 -1
- package/dist/cli/shared/error-json.d.mts +2 -1
- package/dist/cli/shared/errors.d.mts +1 -0
- package/dist/cli/shared/function-execution.d.mts +14 -0
- package/dist/cli/shared/github-actions.d.mts +13 -0
- package/dist/completion/zsh-worker.zsh +98 -5
- package/dist/configure/config/types.d.mts +23 -6
- package/dist/configure/index.mjs +1 -1
- package/dist/configure/index.mjs.map +1 -1
- package/dist/configure/services/executor/trigger/event.d.mts +5 -2
- package/dist/crashreport-DF8YMIE5.mjs +1 -0
- package/dist/{crashreport-BN28xp5B.mjs → crashreport-Doz2Kuuq.mjs} +2 -2
- package/dist/{crashreport-BN28xp5B.mjs.map → crashreport-Doz2Kuuq.mjs.map} +1 -1
- package/dist/date-CGBZbMW5.mjs +2 -0
- package/dist/date-CGBZbMW5.mjs.map +1 -0
- package/dist/errors-BtTxkzgy.mjs +7 -0
- package/dist/errors-BtTxkzgy.mjs.map +1 -0
- package/dist/file-DKBOj5q4.mjs +2 -0
- package/dist/file-DKBOj5q4.mjs.map +1 -0
- package/dist/guards-ForsrxnH.mjs +2 -0
- package/dist/guards-ForsrxnH.mjs.map +1 -0
- package/dist/{logger-CCjs1DuH.mjs → logger-CEAxByN5.mjs} +3 -3
- package/dist/{logger-CCjs1DuH.mjs.map → logger-CEAxByN5.mjs.map} +1 -1
- package/dist/manager-E3ffRcCt.mjs +2 -0
- package/dist/manager-E3ffRcCt.mjs.map +1 -0
- package/dist/node-builtins-DYfhPBnz.mjs +2 -0
- package/dist/node-builtins-DYfhPBnz.mjs.map +1 -0
- package/dist/plugin/builtin/file-utils/index.mjs +27 -1
- package/dist/plugin/builtin/file-utils/index.mjs.map +1 -1
- package/dist/plugin/builtin/seed/index.mjs +1 -1
- package/dist/plugin/builtin/seed/seed-type-processor.d.mts +17 -0
- package/dist/plugin/get-generated-table.d.mts +13 -0
- package/dist/plugin/index.d.mts +2 -2
- package/dist/plugin/index.mjs +1 -1
- package/dist/plugin/index.mjs.map +1 -1
- package/dist/register-ts-hook-DrHS-J1k.mjs +878 -0
- package/dist/register-ts-hook-DrHS-J1k.mjs.map +1 -0
- package/dist/runtime/file.d.mts +46 -2
- package/dist/runtime/file.mjs +1 -1
- package/dist/runtime/index.mjs +1 -1
- package/dist/{schema-DMlLMsWA.mjs → schema-BTioi2dP.mjs} +2 -2
- package/dist/{schema-DMlLMsWA.mjs.map → schema-BTioi2dP.mjs.map} +1 -1
- package/dist/{seed-CCc9Xk66.mjs → seed-C3P_T_Eh.mjs} +28 -9
- package/dist/seed-C3P_T_Eh.mjs.map +1 -0
- package/dist/service-Cw7hb5HK.mjs +2 -0
- package/dist/service-Cw7hb5HK.mjs.map +1 -0
- package/dist/service-DaoW0kzo.mjs +7 -0
- package/dist/service-DaoW0kzo.mjs.map +1 -0
- package/dist/service-dn9jxC8c.mjs +1 -0
- package/dist/service_pb-DKrsO1_u.mjs +1 -0
- package/dist/service_pb-DprmLNsq.mjs +2 -0
- package/dist/{service_pb-BdzjiHfC.mjs.map → service_pb-DprmLNsq.mjs.map} +1 -1
- package/dist/types/auth.generated.d.mts +1 -19
- package/dist/types/executor.generated.d.mts +5 -3
- package/dist/types/field.generated.d.mts +40 -0
- package/dist/types/helpers.d.mts +9 -1
- package/dist/types/resolver.generated.d.mts +5 -40
- package/dist/utils/test/index.d.mts +7 -5
- package/dist/utils/test/index.mjs +1 -1
- package/dist/utils/test/index.mjs.map +1 -1
- package/dist/vitest/index.d.mts +2 -3
- package/dist/vitest/index.mjs +1 -1
- package/dist/vitest/index.mjs.map +1 -1
- package/dist/vitest/mocks/file.d.mts +2 -2
- package/dist/vitest/setup.d.mts +0 -37
- package/dist/vitest/setup.mjs +1 -1
- package/dist/vitest/setup.mjs.map +1 -1
- package/dist/{workspace_resource_pb-C4EY-Gns.mjs → workspace_resource_pb-BOoRts_z.mjs} +2 -2
- package/dist/{workspace_resource_pb-C4EY-Gns.mjs.map → workspace_resource_pb-BOoRts_z.mjs.map} +1 -1
- package/docs/cli/application.md +1 -1
- package/docs/cli/function.md +19 -6
- package/docs/cli/tailordb.md +11 -11
- package/docs/cli/workspace.md +133 -20
- package/docs/cli-reference.md +94 -25
- package/docs/configuration.md +20 -3
- package/docs/github-actions.md +45 -13
- package/docs/migration/v3.md +38 -0
- package/docs/plugin/custom.md +36 -4
- package/docs/runtime.md +39 -0
- package/docs/services/resolver.md +3 -1
- package/docs/services/tailordb-migration.md +31 -9
- package/docs/testing.md +3 -7
- package/package.json +10 -10
- package/dist/application-BAqZFMWP.mjs.map +0 -1
- package/dist/application-BKlOiD1x.mjs +0 -1
- package/dist/crashreport-By23O2k-.mjs +0 -1
- package/dist/date-DrUO8rOJ.mjs +0 -2
- package/dist/date-DrUO8rOJ.mjs.map +0 -1
- package/dist/errors-BlX4gUw5.mjs +0 -4
- package/dist/errors-BlX4gUw5.mjs.map +0 -1
- package/dist/file-COPYfju_.mjs +0 -2
- package/dist/file-COPYfju_.mjs.map +0 -1
- package/dist/node-builtins-TQHhwNzG.mjs +0 -2
- package/dist/node-builtins-TQHhwNzG.mjs.map +0 -1
- package/dist/register-ts-hook-Cphn4r8s.mjs +0 -642
- package/dist/register-ts-hook-Cphn4r8s.mjs.map +0 -1
- package/dist/seed-CCc9Xk66.mjs.map +0 -1
- package/dist/service-7SCy2bhm.mjs +0 -7
- package/dist/service-7SCy2bhm.mjs.map +0 -1
- package/dist/service-CWFQ8EVo.mjs +0 -1
- package/dist/service-CqbQXFDp.mjs +0 -2
- package/dist/service-CqbQXFDp.mjs.map +0 -1
- package/dist/service_pb-BdzjiHfC.mjs +0 -2
- package/dist/service_pb-p68oLtp9.mjs +0 -1
package/docs/cli/application.md
CHANGED
|
@@ -118,7 +118,7 @@ create one explicitly before requesting a deployment plan.
|
|
|
118
118
|
|
|
119
119
|
**Config File Modification:**
|
|
120
120
|
|
|
121
|
-
On first run, `deploy`
|
|
121
|
+
On the first local run, `deploy` assigns your application a stable id (a UUID) so the SDK can recognize ownership across renames. Projects that use `tailor setup` get it recorded in `.github/tailor.lock` under `appIds`; other projects get an `id: "<uuid>"` field written into the `defineConfig({...})` call in `tailor.config.ts`. Commit the file that received the id. See [Configuration](../configuration.md#application-settings) for details.
|
|
122
122
|
|
|
123
123
|
**Multiple Config Deploys:**
|
|
124
124
|
|
package/docs/cli/function.md
CHANGED
|
@@ -83,12 +83,15 @@ tailor function logs [options] [execution-id]
|
|
|
83
83
|
|
|
84
84
|
**Options**
|
|
85
85
|
|
|
86
|
-
| Option | Alias | Description
|
|
87
|
-
| ------------------------------- | ----- |
|
|
88
|
-
| `--workspace-id <WORKSPACE_ID>` | `-w` | Workspace ID
|
|
89
|
-
| `--profile <PROFILE>` | `-p` | Workspace profile
|
|
90
|
-
| `--order <ORDER>` | - | Sort order (asc or desc)
|
|
91
|
-
| `--limit <LIMIT>` | `-l` | Maximum number of items to return (0: unlimited)
|
|
86
|
+
| Option | Alias | Description | Required | Default | Env |
|
|
87
|
+
| ------------------------------- | ----- | -------------------------------------------------------------------------------------------- | -------- | -------- | ------------------------------ |
|
|
88
|
+
| `--workspace-id <WORKSPACE_ID>` | `-w` | Workspace ID | No | - | `TAILOR_PLATFORM_WORKSPACE_ID` |
|
|
89
|
+
| `--profile <PROFILE>` | `-p` | Workspace profile | No | - | `TAILOR_PLATFORM_PROFILE` |
|
|
90
|
+
| `--order <ORDER>` | - | Sort order (asc or desc) | No | `"desc"` | - |
|
|
91
|
+
| `--limit <LIMIT>` | `-l` | Maximum number of items to return (0: unlimited) | No | `50` | - |
|
|
92
|
+
| `--follow` | `-f` | Keep polling a running execution and print new log entries as they arrive (detail mode only) | No | `false` | - |
|
|
93
|
+
| `--interval <INTERVAL>` | `-i` | Polling interval for --follow (e.g., '3s', '500ms', '1m') | No | `"3s"` | - |
|
|
94
|
+
| `--timeout <TIMEOUT>` | `-t` | Maximum time to keep following (e.g., '30s', '10m'); unbounded by default | No | - | - |
|
|
92
95
|
|
|
93
96
|
See [Global Options](../cli-reference.md#global-options) for options available to all commands.
|
|
94
97
|
|
|
@@ -118,8 +121,18 @@ $ tailor function logs --json
|
|
|
118
121
|
$ tailor function logs <execution-id> --json
|
|
119
122
|
```
|
|
120
123
|
|
|
124
|
+
**Stream log entries of a running execution until it completes**
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
$ tailor function logs <execution-id> --follow
|
|
128
|
+
```
|
|
129
|
+
|
|
121
130
|
**Notes**
|
|
122
131
|
|
|
132
|
+
Execution details include `logEntries`, the structured log lines (message, severity, timestamp) recorded while the function ran. They are available while the execution is still running, whereas the flat `logs` string is filled in only after completion. The human-readable view shows the structured entries when present and falls back to `logs` otherwise.
|
|
133
|
+
|
|
134
|
+
Use `--follow` to keep polling a running execution and print new log entries as they arrive until it completes. Polling continues while the execution is suspended at a wait point, and indefinitely unless `--timeout` is set. On environments where no structured entries are returned, `--follow` shows the flat `logs` string once the execution completes. With `--json`, `--follow` waits for completion and then emits the final execution details once.
|
|
135
|
+
|
|
123
136
|
When viewing a specific execution that failed, the command displays error details with the stack trace mapped back to your original source files (clickable file links and code snippets, matching `function run` output).
|
|
124
137
|
|
|
125
138
|
Stack traces are mapped only when the execution includes a content hash for the exact build that ran. If the content hash is missing or the build is no longer available, the command falls back to a plain-text error display.
|
package/docs/cli/tailordb.md
CHANGED
|
@@ -119,17 +119,17 @@ tailor tailordb migration generate [options]
|
|
|
119
119
|
|
|
120
120
|
**Options**
|
|
121
121
|
|
|
122
|
-
| Option | Alias | Description
|
|
123
|
-
| ------------------------------------- | ----- |
|
|
124
|
-
| `--yes` | `-y` | Skip confirmation prompts
|
|
125
|
-
| `--config <CONFIG>` | `-c` | Path to Tailor config file
|
|
126
|
-
| `--name <NAME>` | `-n` | Optional description for the migration
|
|
127
|
-
| `--init` | - | Delete existing migrations and start fresh
|
|
128
|
-
| `--data-only` | - | Create a migration with no schema changes whose migration script runs a standalone data transformation
|
|
129
|
-
| `--namespace <NAMESPACE>` | - | Target TailorDB namespace for --data-only (required if multiple namespaces exist)
|
|
130
|
-
| `--rename <RENAME>` | - | Record a field or
|
|
131
|
-
| `--drop <DROP>` | - | Confirm that a removed field or
|
|
132
|
-
| `--expand-contract <EXPAND_CONTRACT>` | - | Convert a field type through a temporary field (format: "Table.field"; repeatable). Generates two migrations.
|
|
122
|
+
| Option | Alias | Description | Required | Default | Env |
|
|
123
|
+
| ------------------------------------- | ----- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | -------------------- | -------------------- |
|
|
124
|
+
| `--yes` | `-y` | Skip confirmation prompts | No | `false` | - |
|
|
125
|
+
| `--config <CONFIG>` | `-c` | Path to Tailor config file | No | `"tailor.config.ts"` | `TAILOR_CONFIG_PATH` |
|
|
126
|
+
| `--name <NAME>` | `-n` | Optional description for the migration | No | - | - |
|
|
127
|
+
| `--init` | - | Delete existing migrations and start fresh | No | `false` | - |
|
|
128
|
+
| `--data-only` | - | Create a migration with no schema changes whose migration script runs a standalone data transformation | No | `false` | - |
|
|
129
|
+
| `--namespace <NAMESPACE>` | - | Target TailorDB namespace for --data-only (required if multiple namespaces exist) | No | - | - |
|
|
130
|
+
| `--rename <RENAME>` | - | Record a field, table, or nested member rename instead of remove + add (format: "Table.oldField:newField", "OldTable:NewTable", or "Table.field.oldMember:newMember"; repeatable). Renames require a migration script that copies the data. | No | - | - |
|
|
131
|
+
| `--drop <DROP>` | - | Confirm that a removed field, table, or nested member is a genuine removal, not a rename (format: "Table.field", "Table", or "Table.field.member"; repeatable). Required in non-interactive runs for a removal with rename candidates. | No | - | - |
|
|
132
|
+
| `--expand-contract <EXPAND_CONTRACT>` | - | Convert a field type, or a single value into an array, through a temporary field (format: "Table.field"; repeatable). Generates two migrations. | No | - | - |
|
|
133
133
|
|
|
134
134
|
See [Global Options](../cli-reference.md#global-options) for options available to all commands.
|
|
135
135
|
|
package/docs/cli/workspace.md
CHANGED
|
@@ -16,15 +16,17 @@ See [Global Options](../cli-reference.md#global-options) for options available t
|
|
|
16
16
|
|
|
17
17
|
**Commands**
|
|
18
18
|
|
|
19
|
-
| Command | Description
|
|
20
|
-
| ----------------------------------------- |
|
|
21
|
-
| [`workspace app`](#workspace-app) | Manage workspace applications
|
|
22
|
-
| [`workspace create`](#workspace-create) | Create a new Tailor Platform workspace.
|
|
23
|
-
| [`workspace delete`](#workspace-delete) | Delete a Tailor Platform workspace.
|
|
24
|
-
| [`workspace get`](#workspace-get) | Show detailed information about a workspace
|
|
25
|
-
| [`workspace list`](#workspace-list) | List all Tailor Platform workspaces.
|
|
26
|
-
| [`workspace
|
|
27
|
-
| [`workspace
|
|
19
|
+
| Command | Description |
|
|
20
|
+
| ----------------------------------------- | ---------------------------------------------------------------------------------------------- |
|
|
21
|
+
| [`workspace app`](#workspace-app) | Manage workspace applications |
|
|
22
|
+
| [`workspace create`](#workspace-create) | Create a new Tailor Platform workspace. |
|
|
23
|
+
| [`workspace delete`](#workspace-delete) | Delete a Tailor Platform workspace. |
|
|
24
|
+
| [`workspace get`](#workspace-get) | Show detailed information about a workspace |
|
|
25
|
+
| [`workspace list`](#workspace-list) | List all Tailor Platform workspaces. |
|
|
26
|
+
| [`workspace prune`](#workspace-prune) | Delete stale temporary workspaces, by name and age or by the expiry each recorded at creation. |
|
|
27
|
+
| [`workspace restore`](#workspace-restore) | Restore a deleted workspace |
|
|
28
|
+
| [`workspace ttl`](#workspace-ttl) | Manage when a workspace becomes prunable. |
|
|
29
|
+
| [`workspace user`](#workspace-user) | Manage workspace users |
|
|
28
30
|
|
|
29
31
|
### workspace app
|
|
30
32
|
|
|
@@ -98,17 +100,18 @@ tailor workspace create [options]
|
|
|
98
100
|
|
|
99
101
|
**Options**
|
|
100
102
|
|
|
101
|
-
| Option | Alias | Description
|
|
102
|
-
| ------------------------------------- | ----- |
|
|
103
|
-
| `--name <NAME>` | `-n` | Workspace name
|
|
104
|
-
| `--region <REGION>` | `-r` | Workspace region (us-west, asia-northeast)
|
|
105
|
-
| `--delete-protection` | `-d` | Enable delete protection
|
|
106
|
-
| `--organization-id <ORGANIZATION_ID>` | `-o` | Organization ID to workspace associate with
|
|
107
|
-
| `--folder-id <FOLDER_ID>` | `-f` | Folder ID to workspace associate with
|
|
108
|
-
| `--
|
|
109
|
-
| `--profile <
|
|
110
|
-
| `--profile
|
|
111
|
-
| `--
|
|
103
|
+
| Option | Alias | Description | Required | Default | Env |
|
|
104
|
+
| ------------------------------------- | ----- | --------------------------------------------------------------------------------------------------------------------------------------------- | -------- | --------- | --------------------------------- |
|
|
105
|
+
| `--name <NAME>` | `-n` | Workspace name | Yes | - | - |
|
|
106
|
+
| `--region <REGION>` | `-r` | Workspace region (us-west, asia-northeast) | Yes | - | - |
|
|
107
|
+
| `--delete-protection` | `-d` | Enable delete protection | No | `false` | - |
|
|
108
|
+
| `--organization-id <ORGANIZATION_ID>` | `-o` | Organization ID to workspace associate with | No | - | `TAILOR_PLATFORM_ORGANIZATION_ID` |
|
|
109
|
+
| `--folder-id <FOLDER_ID>` | `-f` | Folder ID to workspace associate with | No | - | `TAILOR_PLATFORM_FOLDER_ID` |
|
|
110
|
+
| `--ttl <TTL>` | - | Record on the workspace itself when it becomes prunable, such as 30m, 24h, or 7d. `workspace prune --expired` deletes it once that has passed | No | - | - |
|
|
111
|
+
| `--profile-name <PROFILE_NAME>` | `-p` | Profile name to create | No | - | - |
|
|
112
|
+
| `--profile <PROFILE>` | - | Workspace profile used for authentication and Platform selection | No | - | `TAILOR_PLATFORM_PROFILE` |
|
|
113
|
+
| `--profile-user <PROFILE_USER>` | - | User email address or machine user client ID for the profile (defaults to current user) | No | - | - |
|
|
114
|
+
| `--permission <PERMISSION>` | - | Profile permission (requires --profile-name). 'read' blocks all write commands while the profile is active. | No | `"write"` | - |
|
|
112
115
|
|
|
113
116
|
See [Global Options](../cli-reference.md#global-options) for options available to all commands.
|
|
114
117
|
|
|
@@ -170,6 +173,48 @@ tailor workspace list [options]
|
|
|
170
173
|
|
|
171
174
|
See [Global Options](../cli-reference.md#global-options) for options available to all commands.
|
|
172
175
|
|
|
176
|
+
### workspace prune
|
|
177
|
+
|
|
178
|
+
Delete stale temporary workspaces, by name and age or by the expiry each recorded at creation.
|
|
179
|
+
|
|
180
|
+
**Usage**
|
|
181
|
+
|
|
182
|
+
```
|
|
183
|
+
tailor workspace prune [options]
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
**Options**
|
|
187
|
+
|
|
188
|
+
| Option | Alias | Description | Required | Default | Env |
|
|
189
|
+
| --------------------------------------- | ----- | ------------------------------------------------------------------------------------------------------------------------------------------ | -------- | ------- | ------------------------- |
|
|
190
|
+
| `--name <NAME>` | - | Select workspaces whose whole name matches this regular expression (repeatable) | No | - | - |
|
|
191
|
+
| `--older-than <OLDER_THAN>` | - | Minimum age since creation, such as 30m, 24h, or 7d. 0s disables the age check and requires a location. Required unless --expired is given | No | - | - |
|
|
192
|
+
| `--expired` | - | Select workspaces whose own --ttl expiry has passed, instead of by name and age. Requires --organization-root, --folder-id, or --personal | No | `false` | - |
|
|
193
|
+
| `--organization-root <ORGANIZATION_ID>` | - | Consider the workspaces directly under this organization, excluding those in its folders (repeatable) | No | - | - |
|
|
194
|
+
| `--folder-id <FOLDER_ID>` | - | Consider the workspaces in this folder (repeatable) | No | - | - |
|
|
195
|
+
| `--personal` | - | Consider the workspaces belonging to no organization and no folder | No | `false` | - |
|
|
196
|
+
| `--exclude <EXCLUDE>` | - | Keep a workspace with this exact name even when it matches (repeatable) | No | - | - |
|
|
197
|
+
| `--limit <LIMIT>` | - | Abort when more workspaces match than this, without deleting anything. 0 removes the cap | No | `20` | - |
|
|
198
|
+
| `--dry-run` | - | List the workspaces that would be deleted without deleting them | No | `false` | - |
|
|
199
|
+
| `--profile <PROFILE>` | - | Workspace profile used for authentication and Platform selection | No | - | `TAILOR_PLATFORM_PROFILE` |
|
|
200
|
+
| `--yes` | `-y` | Skip confirmation prompts | No | `false` | - |
|
|
201
|
+
|
|
202
|
+
See [Global Options](../cli-reference.md#global-options) for options available to all commands.
|
|
203
|
+
|
|
204
|
+
**Notes**
|
|
205
|
+
|
|
206
|
+
Use this to reclaim workspaces left behind by CI runs, preview deployments, or interrupted local test runs. A workspace is deleted only when its whole name matches a --name pattern, it was created at least --older-than ago, and it is not excluded, delete-protected, or outside the requested locations. Run with --dry-run first to see what would be deleted.
|
|
207
|
+
|
|
208
|
+
With --expired the workspaces select themselves instead: each one is deleted only once the --ttl expiry it recorded at creation has passed, so callers need no --name or --older-than. A workspace that records no expiry is never deleted this way, and neither is one whose recorded expiry cannot be read. Because that expiry is recorded on the workspace rather than derived from its name, anything able to write the workspace's metadata can bring its deletion forward -- and writing a workspace's metadata is a lesser permission than deleting it. --expired therefore requires at least one location, and --name still applies on top.
|
|
209
|
+
|
|
210
|
+
Every workspace lives in exactly one location, and the location options name them explicitly: --organization-root selects the workspaces directly under an organization and none inside its folders, --folder-id selects the workspaces in one folder, and --personal selects the workspaces belonging to no organization and no folder. Each option can be given more than once, they combine as a union, and none of them is read from the environment -- a sweep covers exactly the locations spelled out on the command line. Selecting --personal is a deliberate choice to accept, for every organization-less workspace visible to this login, the expiry that anyone able to write a workspace's metadata may have recorded. Without any location option, a --name / --older-than sweep considers every visible workspace.
|
|
211
|
+
|
|
212
|
+
Restoring a workspace does not clear its recorded expiry, so a workspace restored after expiring is deleted again by the next --expired run. Restore it, then run `workspace ttl set` or `workspace ttl clear` before the next run — or keep it out of that run with --exclude.
|
|
213
|
+
|
|
214
|
+
Safety guards: the command aborts without deleting anything when more workspaces match than --limit allows (--dry-run still lists them all), both --expired and --older-than 0s (no age check) are only accepted together with at least one location option, and a location option that resolves to an empty value (an unset CI secret) is rejected instead of silently widening the sweep -- even when another location is given alongside it. Each workspace is re-read immediately before it is deleted and skipped when it no longer matches the name, location, exclusion, or delete-protection criteria that selected it. Unlike `workspace delete`, a single confirmation covers every listed candidate; pass --yes to skip it in CI. Deleted workspaces can be restored with `workspace restore` for a limited time.
|
|
215
|
+
|
|
216
|
+
Only workspaces visible to the current login (or the machine user in CI) are considered.
|
|
217
|
+
|
|
173
218
|
### workspace restore
|
|
174
219
|
|
|
175
220
|
Restore a deleted workspace
|
|
@@ -189,6 +234,74 @@ tailor workspace restore [options]
|
|
|
189
234
|
|
|
190
235
|
See [Global Options](../cli-reference.md#global-options) for options available to all commands.
|
|
191
236
|
|
|
237
|
+
### workspace ttl
|
|
238
|
+
|
|
239
|
+
Manage when a workspace becomes prunable.
|
|
240
|
+
|
|
241
|
+
**Usage**
|
|
242
|
+
|
|
243
|
+
```
|
|
244
|
+
tailor workspace ttl [command]
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
See [Global Options](../cli-reference.md#global-options) for options available to all commands.
|
|
248
|
+
|
|
249
|
+
**Commands**
|
|
250
|
+
|
|
251
|
+
| Command | Description |
|
|
252
|
+
| --------------------------------------------- | ---------------------------------------------------------------------------------- |
|
|
253
|
+
| [`workspace ttl set`](#workspace-ttl-set) | Record when a workspace becomes prunable, replacing any expiry it already records. |
|
|
254
|
+
| [`workspace ttl clear`](#workspace-ttl-clear) | Drop a workspace's recorded prune expiry. |
|
|
255
|
+
|
|
256
|
+
#### workspace ttl clear
|
|
257
|
+
|
|
258
|
+
Drop a workspace's recorded prune expiry.
|
|
259
|
+
|
|
260
|
+
**Usage**
|
|
261
|
+
|
|
262
|
+
```
|
|
263
|
+
tailor workspace ttl clear [options]
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
**Options**
|
|
267
|
+
|
|
268
|
+
| Option | Alias | Description | Required | Default | Env |
|
|
269
|
+
| ------------------------------- | ----- | ----------------- | -------- | ------- | ------------------------------ |
|
|
270
|
+
| `--workspace-id <WORKSPACE_ID>` | `-w` | Workspace ID | No | - | `TAILOR_PLATFORM_WORKSPACE_ID` |
|
|
271
|
+
| `--profile <PROFILE>` | `-p` | Workspace profile | No | - | `TAILOR_PLATFORM_PROFILE` |
|
|
272
|
+
|
|
273
|
+
See [Global Options](../cli-reference.md#global-options) for options available to all commands.
|
|
274
|
+
|
|
275
|
+
**Notes**
|
|
276
|
+
|
|
277
|
+
A workspace recording no expiry is never deleted by `workspace prune --expired`. Clearing an expiry the workspace does not record succeeds without changing anything.
|
|
278
|
+
|
|
279
|
+
#### workspace ttl set
|
|
280
|
+
|
|
281
|
+
Record when a workspace becomes prunable, replacing any expiry it already records.
|
|
282
|
+
|
|
283
|
+
**Usage**
|
|
284
|
+
|
|
285
|
+
```
|
|
286
|
+
tailor workspace ttl set [options]
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
**Options**
|
|
290
|
+
|
|
291
|
+
| Option | Alias | Description | Required | Default | Env |
|
|
292
|
+
| ------------------------------- | ----- | --------------------------------------------------------------------------- | -------- | ------- | ------------------------------ |
|
|
293
|
+
| `--workspace-id <WORKSPACE_ID>` | `-w` | Workspace ID | No | - | `TAILOR_PLATFORM_WORKSPACE_ID` |
|
|
294
|
+
| `--profile <PROFILE>` | `-p` | Workspace profile | No | - | `TAILOR_PLATFORM_PROFILE` |
|
|
295
|
+
| `--ttl <TTL>` | - | Time from now until the workspace becomes prunable, such as 30m, 24h, or 7d | Yes | - | - |
|
|
296
|
+
|
|
297
|
+
See [Global Options](../cli-reference.md#global-options) for options available to all commands.
|
|
298
|
+
|
|
299
|
+
**Notes**
|
|
300
|
+
|
|
301
|
+
The expiry runs from now, not from when the workspace was created, so `--ttl 24h` always leaves a full day regardless of the workspace's age. Use this to give a restored workspace a new expiry, or to record one after `workspace create --ttl` failed to.
|
|
302
|
+
|
|
303
|
+
This is not an auto-delete timer: it only makes the workspace eligible for `workspace prune --expired`, which still honors delete protection and its own filters.
|
|
304
|
+
|
|
192
305
|
### workspace user
|
|
193
306
|
|
|
194
307
|
Manage workspace users
|
package/docs/cli-reference.md
CHANGED
|
@@ -19,6 +19,12 @@ tailor <command> [options]
|
|
|
19
19
|
| `--verbose` | - | Enable verbose logging | No | `false` |
|
|
20
20
|
| `--json` | `-j` | Output as JSON | No | `false` |
|
|
21
21
|
|
|
22
|
+
### Progress and Detailed Logs
|
|
23
|
+
|
|
24
|
+
`generate` and `deploy` show service progress and failures on stderr. Pass `--verbose`
|
|
25
|
+
to include individual loaded files, plugin table changes, and generated file paths.
|
|
26
|
+
Generation reports completion for each plugin that finishes processing its output files.
|
|
27
|
+
|
|
22
28
|
### JSON Output
|
|
23
29
|
|
|
24
30
|
For commands that return structured results, passing `--json` writes one parseable JSON document
|
|
@@ -29,10 +35,68 @@ Commands that only perform side effects and do not define a structured result ma
|
|
|
29
35
|
even when `--json` is passed.
|
|
30
36
|
|
|
31
37
|
Errors, warnings, progress, and diagnostic messages are written to stderr. After argument parsing,
|
|
32
|
-
a command failure under `--json` emits a JSON error envelope to stderr.
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
38
|
+
a command failure under `--json` emits a JSON error envelope to stderr. Failures you can act on — an
|
|
39
|
+
invalid or missing option, a resource that does not exist, an invalid configuration, or an unmet
|
|
40
|
+
precondition — carry a stable `error.code` such as `PROFILE_NOT_FOUND`, `TAILORDB_NAMESPACE_NOT_FOUND`,
|
|
41
|
+
or `MIGRATION_SCRIPT_REQUIRED`. Where a remediation exists, the envelope also includes
|
|
42
|
+
`error.suggestion`, `error.help` (the `--help` invocation for the failing command), `error.next` (a
|
|
43
|
+
runnable command), or `error.context`. `UNEXPECTED_ERROR` marks failures without a dedicated code,
|
|
44
|
+
including SDK-internal errors. Diagnostic lines may precede the error envelope, and stdout is not
|
|
45
|
+
guaranteed to contain an error object.
|
|
46
|
+
|
|
47
|
+
Authentication failures distinguish missing credentials (`AUTH_TOKEN_NOT_FOUND`), a missing saved
|
|
48
|
+
user (`AUTH_USER_NOT_FOUND`), an expired token (`AUTH_TOKEN_EXPIRED`), and a failed token refresh
|
|
49
|
+
(`AUTH_TOKEN_REFRESH_FAILED`). Login recovery preserves the selected profile. For saved identities,
|
|
50
|
+
the next step opens login help so you can reuse the original browser or machine-user login method. Permission and
|
|
51
|
+
connection failures include guidance in `error.suggestion`; API failures also identify the operation
|
|
52
|
+
and affected resources in `error.context`.
|
|
53
|
+
|
|
54
|
+
If deployment fails and saving recovery metadata also fails, `DEPLOY_METADATA_RECOVERY_FAILED`
|
|
55
|
+
includes separate `error.context.apply` and `error.context.recovery` errors, each retaining its code
|
|
56
|
+
and available recovery information. Inspect the current resource state before retrying: some writes
|
|
57
|
+
may have completed. `--verbose --json` additionally includes stack traces for both causes.
|
|
58
|
+
|
|
59
|
+
Generation hook failures use `PLUGIN_GENERATION_FAILED`. The error includes the failed hook
|
|
60
|
+
and each failing plugin's ID and error in `error.context.failures`; successful plugins are
|
|
61
|
+
excluded from that list.
|
|
62
|
+
|
|
63
|
+
### Verbose Output
|
|
64
|
+
|
|
65
|
+
Use `--verbose` to include debug diagnostics and error stack traces. `DEBUG=true` or
|
|
66
|
+
`RUNNER_DEBUG=1` also enables verbose output, including stacks in JSON errors. GitHub Actions
|
|
67
|
+
sets `RUNNER_DEBUG=1` when debug logging is enabled, so the same command automatically includes
|
|
68
|
+
these details in a debug run. These settings do not enable JSON output; pass `--json` separately.
|
|
69
|
+
|
|
70
|
+
Capture the original failure's stderr and exit code before retrying. Argument parsing and failures
|
|
71
|
+
before the CLI starts may produce plain text even with `--json`. A failed deployment may have
|
|
72
|
+
already applied changes, so inspect its output before deciding to run it again.
|
|
73
|
+
|
|
74
|
+
### GitHub Actions Annotations
|
|
75
|
+
|
|
76
|
+
When `GITHUB_ACTIONS` is exactly `true`, a command that ends in failure also writes one
|
|
77
|
+
`::error::` workflow command to stderr, so the failure appears as an annotation on the run
|
|
78
|
+
instead of only inside the scrolled log. The annotation repeats what the CLI already prints:
|
|
79
|
+
its `title` is the error code (`AUTH_TOKEN_NOT_FOUND`, `PLUGIN_GENERATION_FAILED`, ...), and its
|
|
80
|
+
body carries the same details, suggestion, and next action. Colors are stripped and newlines are
|
|
81
|
+
encoded, so the annotation is a single line.
|
|
82
|
+
|
|
83
|
+
Exactly one annotation is written per failed command, and only for the failure that ends it.
|
|
84
|
+
Warnings and individually reported problems stay plain stderr output. The bundled CLI plugins
|
|
85
|
+
(`seed`, `setup`, `tailordb-erd`) annotate their failures the same way. A command that exits
|
|
86
|
+
without reporting through the CLI's error path, such as one relaying a failed remote execution,
|
|
87
|
+
writes no annotation.
|
|
88
|
+
|
|
89
|
+
Set `TAILOR_GITHUB_ACTIONS_ANNOTATIONS=false` (also `off`, `no`, or `0`) to turn annotations off.
|
|
90
|
+
Passing `--json` also suppresses them, so a workflow step that parses `--json` output gets only the
|
|
91
|
+
error envelope on stderr. The flag is honored even when the command fails during argument parsing,
|
|
92
|
+
before the envelope itself becomes available.
|
|
93
|
+
|
|
94
|
+
An annotation does not by itself fail a step: the step still fails on the CLI's exit code, which
|
|
95
|
+
is unchanged. Workflows that already echo their own `::error::` around the CLI keep working;
|
|
96
|
+
those messages describe the workflow's own checks, which can fail even when the CLI succeeds.
|
|
97
|
+
|
|
98
|
+
Annotations do not yet carry `file=`/`line=` source locations, and `generate` and `deploy` do not
|
|
99
|
+
group their per-service progress.
|
|
36
100
|
|
|
37
101
|
## Common Options
|
|
38
102
|
|
|
@@ -83,6 +147,7 @@ You can use environment variables to configure workspace and authentication:
|
|
|
83
147
|
| `TAILOR_BUNDLE_CONCURRENCY` | Max concurrent bundle workers for `deploy` (resolvers/executors/workflows). Defaults to CPU count |
|
|
84
148
|
| `TAILOR_APPLY_CONCURRENCY` | Max concurrent platform RPCs during `apply`/`deploy`. Defaults to 16 |
|
|
85
149
|
| `VISUAL` / `EDITOR` | Preferred editor for commands that open files (e.g., `vim`, `code`, `nano`) |
|
|
150
|
+
| `TAILOR_GITHUB_ACTIONS_ANNOTATIONS` | GitHub Actions failure annotations: `on` (default) or `off` |
|
|
86
151
|
| `TAILOR_CRASH_REPORTS_LOCAL` | Local crash log writing: `on` (default) or `off` |
|
|
87
152
|
| `TAILOR_CRASH_REPORTS_REMOTE` | Automatic crash report submission: `off` (default) or `on` |
|
|
88
153
|
|
|
@@ -265,27 +330,31 @@ Commands for managing organizations and folders.
|
|
|
265
330
|
|
|
266
331
|
Commands for managing workspaces and profiles.
|
|
267
332
|
|
|
268
|
-
| Command | Description
|
|
269
|
-
| ----------------------------------------------------------------- |
|
|
270
|
-
| [workspace](./cli/workspace.md#workspace) | Manage Tailor Platform workspaces.
|
|
271
|
-
| [workspace app](./cli/workspace.md#workspace-app) | Manage workspace applications
|
|
272
|
-
| [workspace app health](./cli/workspace.md#workspace-app-health) | Check application schema health
|
|
273
|
-
| [workspace app list](./cli/workspace.md#workspace-app-list) | List applications in a workspace
|
|
274
|
-
| [workspace create](./cli/workspace.md#workspace-create) | Create a new Tailor Platform workspace.
|
|
275
|
-
| [workspace delete](./cli/workspace.md#workspace-delete) | Delete a Tailor Platform workspace.
|
|
276
|
-
| [workspace get](./cli/workspace.md#workspace-get) | Show detailed information about a workspace
|
|
277
|
-
| [workspace list](./cli/workspace.md#workspace-list) | List all Tailor Platform workspaces.
|
|
278
|
-
| [workspace
|
|
279
|
-
| [workspace
|
|
280
|
-
| [workspace
|
|
281
|
-
| [workspace
|
|
282
|
-
| [workspace
|
|
283
|
-
| [workspace user
|
|
284
|
-
| [
|
|
285
|
-
| [
|
|
286
|
-
| [
|
|
287
|
-
| [
|
|
288
|
-
| [profile
|
|
333
|
+
| Command | Description |
|
|
334
|
+
| ----------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
|
|
335
|
+
| [workspace](./cli/workspace.md#workspace) | Manage Tailor Platform workspaces. |
|
|
336
|
+
| [workspace app](./cli/workspace.md#workspace-app) | Manage workspace applications |
|
|
337
|
+
| [workspace app health](./cli/workspace.md#workspace-app-health) | Check application schema health |
|
|
338
|
+
| [workspace app list](./cli/workspace.md#workspace-app-list) | List applications in a workspace |
|
|
339
|
+
| [workspace create](./cli/workspace.md#workspace-create) | Create a new Tailor Platform workspace. |
|
|
340
|
+
| [workspace delete](./cli/workspace.md#workspace-delete) | Delete a Tailor Platform workspace. |
|
|
341
|
+
| [workspace get](./cli/workspace.md#workspace-get) | Show detailed information about a workspace |
|
|
342
|
+
| [workspace list](./cli/workspace.md#workspace-list) | List all Tailor Platform workspaces. |
|
|
343
|
+
| [workspace prune](./cli/workspace.md#workspace-prune) | Delete stale temporary workspaces, by name and age or by the expiry each recorded at creation. |
|
|
344
|
+
| [workspace restore](./cli/workspace.md#workspace-restore) | Restore a deleted workspace |
|
|
345
|
+
| [workspace ttl](./cli/workspace.md#workspace-ttl) | Manage when a workspace becomes prunable. |
|
|
346
|
+
| [workspace ttl clear](./cli/workspace.md#workspace-ttl-clear) | Drop a workspace's recorded prune expiry. |
|
|
347
|
+
| [workspace ttl set](./cli/workspace.md#workspace-ttl-set) | Record when a workspace becomes prunable, replacing any expiry it already records. |
|
|
348
|
+
| [workspace user](./cli/workspace.md#workspace-user) | Manage workspace users |
|
|
349
|
+
| [workspace user invite](./cli/workspace.md#workspace-user-invite) | Invite a user to a workspace |
|
|
350
|
+
| [workspace user list](./cli/workspace.md#workspace-user-list) | List users in a workspace |
|
|
351
|
+
| [workspace user remove](./cli/workspace.md#workspace-user-remove) | Remove a user from a workspace |
|
|
352
|
+
| [workspace user update](./cli/workspace.md#workspace-user-update) | Update a user's role in a workspace |
|
|
353
|
+
| [profile](./cli/workspace.md#profile) | Manage workspace profiles (user + workspace combinations). |
|
|
354
|
+
| [profile create](./cli/workspace.md#profile-create) | Create a new profile. |
|
|
355
|
+
| [profile delete](./cli/workspace.md#profile-delete) | Delete a profile. |
|
|
356
|
+
| [profile list](./cli/workspace.md#profile-list) | List all profiles. |
|
|
357
|
+
| [profile update](./cli/workspace.md#profile-update) | Update profile properties. |
|
|
289
358
|
|
|
290
359
|
### [Auth Resource Commands](./cli/auth.md)
|
|
291
360
|
|
package/docs/configuration.md
CHANGED
|
@@ -21,19 +21,23 @@ To deploy the same config to multiple workspaces with per-environment values, se
|
|
|
21
21
|
import { defineConfig } from "@tailor-platform/sdk";
|
|
22
22
|
|
|
23
23
|
export default defineConfig({
|
|
24
|
-
// SDK-managed app id — do not edit, except when copying this config to a separate app.
|
|
25
|
-
// id: "<uuid>" — written here automatically on first run
|
|
26
24
|
name: "my-app",
|
|
27
25
|
cors: ["https://example.com"],
|
|
28
26
|
allowedIpAddresses: ["192.168.1.0/24"],
|
|
29
27
|
disableIntrospection: false,
|
|
30
28
|
logLevel: process.env.TAILOR_APP_LOG_LEVEL ?? "DEBUG",
|
|
29
|
+
metadata: { "erp-kit-version": "v1-2-3" },
|
|
31
30
|
});
|
|
32
31
|
```
|
|
33
32
|
|
|
34
33
|
**Name**: Set the application name.
|
|
35
34
|
|
|
36
|
-
**Id (auto-managed)**: A stable identifier used to recognize resources managed by the SDK across renames.
|
|
35
|
+
**Id (auto-managed)**: A stable identifier used to recognize resources managed by the SDK across renames. The SDK assigns it on the first local `deploy` and keeps it under version control for you; do not edit it by hand.
|
|
36
|
+
|
|
37
|
+
- Projects that use [`tailor setup`](./github-actions.md#app-id) keep the id in `.github/tailor.lock`, under `appIds`, keyed by the config file's path. `tailor.config.ts` itself carries no id, so a config copied inside the repository gets its own id, and configs that re-export another file work as well.
|
|
38
|
+
- Other projects get an `id: "<uuid>"` field written into the `defineConfig({...})` call. Delete it only if you want the SDK to assign a new id on the next `deploy` — typically when `tailor.config.ts` was copied from another project and the new application should not share the original's id. Writing the field requires `defineConfig({...})` to be called with an inline object literal: if the argument is a separate variable (e.g. `defineConfig(config)`), or if `tailor.config.ts` re-exports a config from another file, add the `id` field manually to the file that contains the actual `defineConfig({...})` object literal.
|
|
39
|
+
|
|
40
|
+
When a project starts using `tailor setup`, the next local `deploy` or `setup` moves the id from `tailor.config.ts` into the lock and removes it from the config. `AppConfig.id` stays supported: a config `id` that agrees with the lock is accepted (a local `deploy` moves it into the lock; `deploy --dry-run`, `remove`, and CI remind you to remove it), and one that disagrees stops the command so you can decide which value to keep.
|
|
37
41
|
|
|
38
42
|
**CORS**: Specify CORS settings as an array. You can also include Static Website URL references (e.g. `website.url`) in this array; see [Static Website](./services/staticwebsite.md).
|
|
39
43
|
|
|
@@ -41,6 +45,19 @@ export default defineConfig({
|
|
|
41
45
|
|
|
42
46
|
**Disable Introspection**: Disable GraphQL introspection. Default is `false`.
|
|
43
47
|
|
|
48
|
+
**Metadata**: Extra labels written to the deployed application's metadata on `deploy`, alongside the labels the SDK writes itself. Use it to record information that tooling reads back from the platform, such as the version of a framework the config is generated from. Keys must match `^[a-z][a-z0-9_-]{0,62}$` and must not start with `sdk-`; values must be empty or match the same pattern, so a version like `1.2.3` is written as `v1-2-3`. At most 17 entries can be set:
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
const erpKitVersion = "1.2.3";
|
|
52
|
+
|
|
53
|
+
export default defineConfig({
|
|
54
|
+
name: "my-app",
|
|
55
|
+
metadata: { "erp-kit-version": `v${erpKitVersion.replace(/\./g, "-")}` },
|
|
56
|
+
});
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Entries are only added or overwritten. An entry removed from the config keeps its last deployed value on the platform, and labels the config does not name are left untouched. Because those retained labels count towards the platform's limit of 20 labels per resource, `deploy` reports the overflow and stops before changing the application when the labels it would leave behind exceed that limit. The labels are written when the application itself is deployed, so a config with no TailorDB, Resolver, IdP, or Auth service has no application to carry them.
|
|
60
|
+
|
|
44
61
|
**Log Level**: Controls which `console.*` and `logger.*` (from `@tailor-platform/sdk/runtime`) calls are kept when deployment functions are bundled. Supported values are `"DEBUG"`, `"INFO"`, `"WARN"`, `"ERROR"`, and `"SILENT"`. The default is `"DEBUG"` and keeps all calls. `console.log` is treated as a DEBUG-level call (matching the platform's OpenTelemetry severity mapping), so it is dropped at `"INFO"` and above, alongside `console.debug` and `logger.debug`. `logger.setAttributes` has no severity and is never dropped, regardless of `logLevel`. For production deployments, use `"WARN"` to keep warn/error calls while dropping debug, log, and info calls:
|
|
45
62
|
|
|
46
63
|
```typescript
|
package/docs/github-actions.md
CHANGED
|
@@ -208,22 +208,54 @@ planned.)
|
|
|
208
208
|
### `.github/tailor.lock`
|
|
209
209
|
|
|
210
210
|
A machine-owned JSON file that tracks which files the SDK manages, the inputs
|
|
211
|
-
they were generated from, and their content hashes
|
|
212
|
-
|
|
213
|
-
detect hand edits.
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
211
|
+
they were generated from, and their content hashes, plus the id of every app in
|
|
212
|
+
the repository (see [App id](#app-id)). **Commit this file.** The SDK uses it to
|
|
213
|
+
recognize its own files on re-runs and to detect hand edits. The only part
|
|
214
|
+
meant for hand editing is `appIds`, and only to re-key an entry after moving an
|
|
215
|
+
app directory or to delete the entry of a removed app.
|
|
216
|
+
|
|
217
|
+
### App id
|
|
218
|
+
|
|
219
|
+
Every application has a stable id (a UUID) that the SDK uses to recognize the
|
|
220
|
+
resources it owns across renames. In a repository set up with `tailor setup`,
|
|
221
|
+
the id lives in `.github/tailor.lock` under `appIds`, keyed by the config
|
|
222
|
+
file's repository-relative path:
|
|
223
|
+
|
|
224
|
+
```jsonc
|
|
225
|
+
{
|
|
226
|
+
"version": 2,
|
|
227
|
+
"targets": [/* generated workflows */],
|
|
228
|
+
"appIds": {
|
|
229
|
+
"apps/order/tailor.config.ts": "d0a3398a-…",
|
|
230
|
+
"apps/billing/tailor.config.ts": "7f21c4e0-…",
|
|
231
|
+
},
|
|
232
|
+
}
|
|
233
|
+
```
|
|
222
234
|
|
|
235
|
+
`setup` records the id when it generates a workflow, and a local `tailor
|
|
236
|
+
deploy` records one for any config that has none yet. Because the key is the
|
|
237
|
+
config path, renaming the app keeps its id, and copying a config to a new
|
|
238
|
+
directory gives the copy a fresh id instead of the original's. If
|
|
239
|
+
`tailor.config.ts` still has an `id` field from before, `setup` or a local
|
|
240
|
+
`deploy` moves it into the lock and removes it from the config; a config `id`
|
|
241
|
+
that disagrees with the lock stops the command so you can decide which value
|
|
242
|
+
to keep.
|
|
243
|
+
|
|
244
|
+
In CI, `tailor deploy` never assigns an id — if one were assigned fresh on
|
|
245
|
+
each run, every deploy would create a brand-new application and lose ownership
|
|
246
|
+
of previously deployed resources. A config without a recorded id fails the
|
|
247
|
+
plan job with instructions to run `tailor deploy` locally and commit the lock.
|
|
223
248
|
If your pipeline intentionally deploys a fresh, throwaway application on every
|
|
224
249
|
run (for example an end-to-end test harness that creates and deletes its own
|
|
225
|
-
workspace), set `TAILOR_CI_ALLOW_ID_INJECTION=true` to
|
|
226
|
-
|
|
250
|
+
workspace), set `TAILOR_CI_ALLOW_ID_INJECTION=true` to let CI assign one.
|
|
251
|
+
|
|
252
|
+
When you move an app directory, its `appIds` entry still points at the old
|
|
253
|
+
path. Locally, `deploy` and `setup` notice the single unmatched entry and ask
|
|
254
|
+
whether the app was moved; answering yes re-keys the entry so the app keeps
|
|
255
|
+
its id. In CI, or when more than one entry is unmatched, the command stops and
|
|
256
|
+
asks you to re-key the entry (or delete entries of removed apps) by hand.
|
|
257
|
+
Re-run the relevant `setup` subcommand as well so the workflow's paths follow
|
|
258
|
+
the move.
|
|
227
259
|
|
|
228
260
|
## Secrets
|
|
229
261
|
|
package/docs/migration/v3.md
CHANGED
|
@@ -160,3 +160,41 @@ property, which is the relation's cardinality (e.g. "n-1", "1-1",
|
|
|
160
160
|
```
|
|
161
161
|
|
|
162
162
|
</details>
|
|
163
|
+
|
|
164
|
+
## String file uploads → explicit encoding
|
|
165
|
+
|
|
166
|
+
**Migration:** Manual
|
|
167
|
+
|
|
168
|
+
String inputs to the SDK `file.upload` and generated `uploadFile` require an explicit `encoding` in v3. Add `encoding: "utf8"` to preserve the previous behavior; use `"base64"` only when decoding the input is intended. Byte inputs are unchanged. This migration requires checking the input type and regenerating file helpers, so it provides review guidance instead of rewriting calls automatically.
|
|
169
|
+
|
|
170
|
+
Before:
|
|
171
|
+
|
|
172
|
+
```ts
|
|
173
|
+
await file.upload(ns, table, field, id, text, { contentType: "text/plain" });
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
After:
|
|
177
|
+
|
|
178
|
+
```ts
|
|
179
|
+
await file.upload(ns, table, field, id, text, { contentType: "text/plain", encoding: "utf8" });
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
<details>
|
|
183
|
+
<summary>Prompt for an AI agent (to perform this migration)</summary>
|
|
184
|
+
|
|
185
|
+
```text
|
|
186
|
+
Inspect calls to the imported SDK file.upload (including aliases and destructured upload)
|
|
187
|
+
and generated uploadFile helpers, including shared wrappers and option objects.
|
|
188
|
+
For string inputs, add encoding: utf8 to preserve existing text storage behavior.
|
|
189
|
+
Choose encoding: base64 only if decoding is explicitly intended; never infer it from
|
|
190
|
+
the string contents or contentType. Preserve all existing upload options.
|
|
191
|
+
Leave byte-only inputs unchanged. For string | byte unions, supplying encoding: utf8
|
|
192
|
+
preserves behavior because byte input ignores encoding. Narrow shared options types
|
|
193
|
+
so TypeScript can see that encoding is present for strings.
|
|
194
|
+
Run tailor generate to regenerate uploadFile helpers instead of editing generated files.
|
|
195
|
+
The global tailordb.file.upload does not support this encoding option; switch to the
|
|
196
|
+
file import from @tailor-platform/sdk/runtime before using it.
|
|
197
|
+
Do not change unrelated upload APIs or already explicit encodings.
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
</details>
|