@tailor-platform/sdk 2.30.0 → 2.33.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 +92 -0
- package/dist/ai/index.d.mts +112 -0
- package/dist/ai/index.mjs +2 -0
- package/dist/ai/index.mjs.map +1 -0
- package/dist/aigateway-DsWDjzk4.mjs.map +1 -1
- package/dist/{application-D0xNJbag.mjs → application-B9_NHiUC.mjs} +40 -32
- package/dist/application-B9_NHiUC.mjs.map +1 -0
- package/dist/application-Bet1K5C4.mjs +1 -0
- package/dist/assert-WeXvmG4j.mjs.map +1 -1
- package/dist/authconnection-CynFBIv8.mjs.map +1 -1
- package/dist/brand-C8nMKhJC.mjs.map +1 -1
- package/dist/cli/commands/deploy/staticwebsite.d.mts +1 -0
- package/dist/cli/lib.mjs +1 -1
- package/dist/cli/lib.mjs.map +1 -1
- package/dist/cli/main.mjs +44 -33
- package/dist/cli/main.mjs.map +1 -1
- package/dist/cli/services/resolver/service.d.mts +1 -0
- package/dist/cli/shared/client.d.mts +52 -1
- package/dist/cli/ts-hook.d.mts +0 -2
- package/dist/cli/ts-hook.mjs +0 -113
- package/dist/completion/zsh-worker.zsh +30 -6
- package/dist/configure/index.mjs.map +1 -1
- package/dist/configure/services/staticwebsite/index.d.mts +6 -1
- package/dist/context-D0QjfxzD.mjs.map +1 -1
- package/dist/crashreport-BCIy33Cz.mjs.map +1 -1
- package/dist/date-CgP7gMG_.mjs.map +1 -1
- package/dist/date-representation-Cr7W7Pn2.mjs.map +1 -1
- package/dist/errors-BOF68LJ5.mjs.map +1 -1
- package/dist/es-builtins-SfvXRVoG.mjs.map +1 -1
- package/dist/field-parse-C41e3UAF.mjs.map +1 -1
- package/dist/file-DKBOj5q4.mjs.map +1 -1
- package/dist/globals-BCmGX05J.mjs.map +1 -1
- package/dist/guards-yDXyKC9F.mjs.map +1 -1
- package/dist/iconv-DlFMt2gW.mjs.map +1 -1
- package/dist/idp-G_ojPBB5.mjs.map +1 -1
- package/dist/interceptor-DQg3cR_9.mjs.map +1 -1
- package/dist/kysely/index.mjs.map +1 -1
- package/dist/kysely-type-DxyIWXc6.mjs +51 -0
- package/dist/kysely-type-DxyIWXc6.mjs.map +1 -0
- package/dist/logger-DP2BjQ93.mjs.map +1 -1
- package/dist/logger-RgtbhJ83.mjs.map +1 -1
- package/dist/manager-DTRhIupk.mjs +2 -0
- package/dist/manager-DTRhIupk.mjs.map +1 -0
- package/dist/migration-steps-C6F3zNdQ.mjs.map +1 -1
- package/dist/multiline-EyzjEwn9.mjs.map +1 -1
- package/dist/node-builtins-DYfhPBnz.mjs.map +1 -1
- package/dist/package-json-C690ceex.mjs.map +1 -1
- package/dist/platform-serialize-DkiTdHOt.mjs.map +1 -1
- package/dist/plugin/builtin/enum-constants/index.mjs +2 -2
- package/dist/plugin/builtin/enum-constants/index.mjs.map +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/plugin/types.d.mts +3 -0
- package/dist/register-ts-hook-Dp9reSRG.mjs +1053 -0
- package/dist/register-ts-hook-Dp9reSRG.mjs.map +1 -0
- package/dist/registry-BijIDRVA.mjs.map +1 -1
- package/dist/repl-editor-DkrCZmmg.mjs +2 -0
- package/dist/repl-editor-DkrCZmmg.mjs.map +1 -0
- package/dist/schema-B6hJQWp6.mjs.map +1 -1
- package/dist/secret-file-C9wp_FCX.mjs.map +1 -1
- package/dist/secretmanager-vHQoXdQz.mjs.map +1 -1
- package/dist/seed/index.mjs.map +1 -1
- package/dist/seed-Cn-3JApy.mjs.map +1 -1
- package/dist/service-9SBPNpK8.mjs.map +1 -1
- package/dist/service-9rwi_I4d.mjs.map +1 -1
- package/dist/service_pb-6EkMfdOb.mjs +2 -0
- package/dist/service_pb-6EkMfdOb.mjs.map +1 -0
- package/dist/service_pb-CsJKokDl.mjs +1 -0
- package/dist/tailor-proto/src/tailor/v1/metadata_pb.d.mts +5 -2
- package/dist/tailor-proto/src/tailor/v1/security_pb.d.mts +213 -0
- package/dist/tailor-proto/src/tailor/v1/security_resource_pb.d.mts +301 -0
- package/dist/tailor-proto/src/tailor/v1/service_pb.d.mts +200 -8
- package/dist/tailor-proto/src/tailor/v1/staticwebsite_pb.d.mts +201 -1
- package/dist/tailor-proto/src/tailor/v1/staticwebsite_resource_pb.d.mts +88 -1
- package/dist/telemetry-DfT2UfI4.mjs +2 -0
- package/dist/telemetry-DfT2UfI4.mjs.map +1 -0
- package/dist/{telemetry-DpkFGBmu.mjs → telemetry-nqOtDWNO.mjs} +1 -1
- package/dist/type-source--ZNcV8RJ.mjs.map +1 -1
- package/dist/types/staticwebsite.generated.d.mts +9 -1
- package/dist/user-agent-vdHYF3QL.mjs.map +1 -1
- package/dist/utils/test/index.mjs.map +1 -1
- package/dist/vitest/environment.mjs.map +1 -1
- package/dist/vitest/index.d.mts +2 -2
- package/dist/vitest/index.mjs +1 -1
- package/dist/vitest/index.mjs.map +1 -1
- package/dist/vitest/pglite-kysely.d.mts +19 -0
- package/dist/vitest/setup.mjs.map +1 -1
- package/dist/wait-point-invoker-eiP-IIux.mjs.map +1 -1
- package/dist/wait-point-registry-B-ESkTZX.mjs.map +1 -1
- package/dist/workflow-Cs9ISw6j.mjs.map +1 -1
- package/dist/{workspace_resource_pb-CaoM2npP.mjs → workspace_resource_pb-C4CkoYww.mjs} +2 -2
- package/dist/workspace_resource_pb-C4CkoYww.mjs.map +1 -0
- package/docs/ai.md +92 -0
- package/docs/cli/tailordb.md +17 -15
- package/docs/cli/workspace.md +1 -1
- package/docs/github-actions.md +98 -11
- package/docs/plugin/custom.md +34 -0
- package/docs/plugin/index.md +1 -0
- package/docs/services/staticwebsite.md +31 -1
- package/docs/services/tailordb/migration.md +78 -41
- package/docs/testing.md +2 -1
- package/package.json +20 -13
- package/dist/application-C2bPmmbh.mjs +0 -1
- package/dist/application-D0xNJbag.mjs.map +0 -1
- package/dist/kysely-type-BWMfV301.mjs +0 -48
- package/dist/kysely-type-BWMfV301.mjs.map +0 -1
- package/dist/manager-Bk-7vkwd.mjs +0 -2
- package/dist/manager-Bk-7vkwd.mjs.map +0 -1
- package/dist/register-ts-hook-CDnN_Jx2.mjs +0 -1012
- package/dist/register-ts-hook-CDnN_Jx2.mjs.map +0 -1
- package/dist/repl-editor-DGJBfIt1.mjs +0 -2
- package/dist/repl-editor-DGJBfIt1.mjs.map +0 -1
- package/dist/service_pb-Bbu2QSIr.mjs +0 -2
- package/dist/service_pb-Bbu2QSIr.mjs.map +0 -1
- package/dist/service_pb-urxAIYHT.mjs +0 -1
- package/dist/telemetry-Xk7J829P.mjs +0 -2
- package/dist/telemetry-Xk7J829P.mjs.map +0 -1
- package/dist/workspace_resource_pb-CaoM2npP.mjs.map +0 -1
package/docs/ai.md
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Make choice, boolean, and ordered score decisions from application state through AI Gateway with the System One client from @tailor-platform/sdk/ai."
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# System One
|
|
6
|
+
|
|
7
|
+
System One makes semantic decisions from application state, a question, and a fixed answer space. It returns the selected answer and its probability without requiring prompt construction or structured-output parsing.
|
|
8
|
+
|
|
9
|
+
Create a client with the URL the platform assigns to your deployed [AI Gateway](services/aigateway.md). Inside a Tailor Function, `aigateway.get()` returns it as `url`. Omit `token`; the platform authenticates the request:
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
import { createSystemOne } from "@tailor-platform/sdk/ai";
|
|
13
|
+
import { aigateway } from "@tailor-platform/sdk/runtime";
|
|
14
|
+
|
|
15
|
+
const { url } = await aigateway.get("my-aigateway");
|
|
16
|
+
const systemOne = createSystemOne({ baseURL: url });
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
External clients pass the same URL, which `tailor show` lists, directly with an access token issued by the AI Gateway's auth namespace:
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
import { createSystemOne } from "@tailor-platform/sdk/ai";
|
|
23
|
+
|
|
24
|
+
const systemOne = createSystemOne({
|
|
25
|
+
baseURL: "https://my-aigateway-{WORKSPACE_HASH}.ai.erp.dev",
|
|
26
|
+
token: accessToken,
|
|
27
|
+
});
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Choice decisions
|
|
31
|
+
|
|
32
|
+
Use `choice()` to select one value from an answer space. Literal types are inferred without `as const`:
|
|
33
|
+
|
|
34
|
+
```typescript
|
|
35
|
+
const result = await systemOne.choice({
|
|
36
|
+
state: { ticket, customer },
|
|
37
|
+
question: "Which department should handle this ticket?",
|
|
38
|
+
choices: ["billing", "sales", "support"],
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
// result.value: "billing" | "sales" | "support"
|
|
42
|
+
// result.probabilities: Record<"billing" | "sales" | "support", number>
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Boolean decisions
|
|
46
|
+
|
|
47
|
+
Use `boolean()` for a binary decision. `value` is `true` when the probability of "yes" is at least `0.5`, and `probability` is the probability of the selected answer:
|
|
48
|
+
|
|
49
|
+
```typescript
|
|
50
|
+
const result = await systemOne.boolean({
|
|
51
|
+
state: invoice,
|
|
52
|
+
question: "Is this invoice a duplicate?",
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
if (result.value && result.probability > 0.95) {
|
|
56
|
+
// Apply the appropriate business rule.
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Ordered scores
|
|
61
|
+
|
|
62
|
+
Use `score()` when the answer space has a meaningful order. Levels are ordered from lowest to highest, and `value` is the level with the highest probability:
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
const result = await systemOne.score({
|
|
66
|
+
state: transaction,
|
|
67
|
+
question: "Assess the risk of this transaction.",
|
|
68
|
+
levels: ["low", "medium", "high"],
|
|
69
|
+
});
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Models
|
|
73
|
+
|
|
74
|
+
Decisions use `jev-1.13.0` unless a call passes `model`. `jev-latest` always points to the newest model, so its probabilities can shift when a new model is released. Use it only when your logic does not compare probabilities against fixed thresholds:
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
const result = await systemOne.boolean({
|
|
78
|
+
state: invoice,
|
|
79
|
+
question: "Is this invoice a duplicate?",
|
|
80
|
+
model: "jev-latest",
|
|
81
|
+
});
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Errors
|
|
85
|
+
|
|
86
|
+
Failures throw `SystemOneError` with a provider-independent `code`. Applications can handle stable codes such as `UNAUTHORIZED`, `RATE_LIMITED`, `PROVIDER_TIMEOUT`, and `PROVIDER_UNAVAILABLE` without depending on a model provider.
|
|
87
|
+
|
|
88
|
+
A decision waits until AI Gateway responds. To fail with `PROVIDER_TIMEOUT` instead, pass `timeoutMs`:
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
const systemOne = createSystemOne({ baseURL: url, timeoutMs: 10_000 });
|
|
92
|
+
```
|
package/docs/cli/tailordb.md
CHANGED
|
@@ -328,26 +328,28 @@ tailor tailordb migration test [options]
|
|
|
328
328
|
|
|
329
329
|
**Options**
|
|
330
330
|
|
|
331
|
-
| Option | Alias | Description
|
|
332
|
-
| --------------------------------------------- | ----- |
|
|
333
|
-
| `--workspace-id <WORKSPACE_ID>` | `-w` | Workspace ID
|
|
334
|
-
| `--profile <PROFILE>` | `-p` | Workspace profile
|
|
335
|
-
| `--config <CONFIG>` | `-c` | Path to Tailor config file
|
|
336
|
-
| `--yes` | `-y` | Acknowledge that a designated target workspace may be overwritten
|
|
337
|
-
| `--data <DATA>` | - | Data source for the migration test (seed or clone)
|
|
338
|
-
| `--target-workspace-id <TARGET_WORKSPACE_ID>` | - | Existing throwaway workspace to retain after the test (requires --yes)
|
|
339
|
-
| `--keep` | - | Keep the automatically created workspace after the test
|
|
340
|
-
| `--
|
|
341
|
-
| `--
|
|
342
|
-
| `--
|
|
343
|
-
| `--
|
|
344
|
-
| `--
|
|
331
|
+
| Option | Alias | Description | Required | Default | Env |
|
|
332
|
+
| --------------------------------------------- | ----- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | -------------------- | --------------------------------- |
|
|
333
|
+
| `--workspace-id <WORKSPACE_ID>` | `-w` | Workspace ID | No | - | `TAILOR_PLATFORM_WORKSPACE_ID` |
|
|
334
|
+
| `--profile <PROFILE>` | `-p` | Workspace profile | No | - | `TAILOR_PLATFORM_PROFILE` |
|
|
335
|
+
| `--config <CONFIG>` | `-c` | Path to Tailor config file | No | `"tailor.config.ts"` | `TAILOR_CONFIG_PATH` |
|
|
336
|
+
| `--yes` | `-y` | Acknowledge that a designated target workspace may be overwritten | No | `false` | - |
|
|
337
|
+
| `--data <DATA>` | - | Data source for the migration test (seed or clone) | No | `"seed"` | - |
|
|
338
|
+
| `--target-workspace-id <TARGET_WORKSPACE_ID>` | - | Existing throwaway workspace to retain after the test (requires --yes) | No | - | - |
|
|
339
|
+
| `--keep` | - | Keep the automatically created workspace after the test | No | `false` | - |
|
|
340
|
+
| `--organization-id <ORGANIZATION_ID>` | - | Organization to create the temporary workspace in, at its root unless --folder-id is given (default: the source workspace's organization and folder). With --target-workspace-id, must match the target's organization | No | - | `TAILOR_PLATFORM_ORGANIZATION_ID` |
|
|
341
|
+
| `--folder-id <FOLDER_ID>` | - | Folder to create the temporary workspace in (default: the source workspace's folder). Requires --organization-id when the source workspace is not in an organization. With --target-workspace-id, must match the target's folder | No | - | `TAILOR_PLATFORM_FOLDER_ID` |
|
|
342
|
+
| `--assert <ASSERT>` | - | Path to a TypeScript assertion script to run after migrations | No | - | - |
|
|
343
|
+
| `--assert-namespace <ASSERT_NAMESPACE>` | - | TailorDB namespace exposed to the assertion script | No | - | - |
|
|
344
|
+
| `--keep-ttl <KEEP_TTL>` | - | Record an expiry on the kept workspace, e.g. 24h or 7d, so workspace prune --expired can delete it (requires --keep) | No | - | - |
|
|
345
|
+
| `--clone-timeout <CLONE_TIMEOUT>` | - | How long to wait for the clone to finish with --data clone, e.g. 30s or 10m (default: 30m) | No | - | - |
|
|
346
|
+
| `--machine-user <MACHINE_USER>` | - | Machine user for seed and assertion script execution | No | - | - |
|
|
345
347
|
|
|
346
348
|
See [Global Options](../cli-reference.md#global-options) for options available to all commands.
|
|
347
349
|
|
|
348
350
|
**Notes**
|
|
349
351
|
|
|
350
|
-
The source workspace is read-only. Without --target-workspace-id, the command creates a workspace in the source workspace's region and deletes it after success or failure; pass --keep to retain it for inspection. A designated target is retained and requires --yes. Clone mode copies TailorDB records only; it does not copy IdP users or file blobs. With --keep-ttl, the kept workspace records an expiry; it is not deleted automatically, but workspace prune --expired removes it once the expiry has passed.
|
|
352
|
+
The source workspace is read-only. Without --target-workspace-id, the command creates a workspace in the source workspace's region and deletes it after success or failure; pass --keep to retain it for inspection. Right after creating the workspace it records a 24h expiry (unless --keep is given without --keep-ttl), so if the run is interrupted before the command can delete the workspace, workspace prune --expired removes it later. A designated target is retained and requires --yes. Clone mode copies TailorDB records only; it does not copy IdP users or file blobs. With --keep-ttl, the kept workspace records an expiry; it is not deleted automatically, but workspace prune --expired removes it once the expiry has passed. Organization and folder IDs loaded by --env-file are used the same way as the options; command-line options take precedence, and empty env-file values are ignored.
|
|
351
353
|
|
|
352
354
|
#### tailordb migration validate
|
|
353
355
|
|
package/docs/cli/workspace.md
CHANGED
|
@@ -107,7 +107,7 @@ tailor workspace create [options]
|
|
|
107
107
|
| Option | Alias | Description | Required | Default | Env |
|
|
108
108
|
| ------------------------------------- | ----- | --------------------------------------------------------------------------------------------------------------------------------------------- | -------- | --------- | --------------------------------- |
|
|
109
109
|
| `--name <NAME>` | `-n` | Workspace name | Yes | - | - |
|
|
110
|
-
| `--region <REGION>` | `-r` | Workspace region (asia-northeast, us-west)
|
|
110
|
+
| `--region <REGION>` | `-r` | Workspace region (asia-northeast, us-west, europe-west) | Yes | - | - |
|
|
111
111
|
| `--delete-protection` | `-d` | Enable delete protection | No | `false` | - |
|
|
112
112
|
| `--organization-id <ORGANIZATION_ID>` | `-o` | Organization ID to workspace associate with | No | - | `TAILOR_PLATFORM_ORGANIZATION_ID` |
|
|
113
113
|
| `--folder-id <FOLDER_ID>` | `-f` | Folder ID to workspace associate with | No | - | `TAILOR_PLATFORM_FOLDER_ID` |
|
package/docs/github-actions.md
CHANGED
|
@@ -117,6 +117,92 @@ all-added or all-removed viewer artifacts. Re-run `setup ci branch` after adding
|
|
|
117
117
|
removing TailorDB namespaces. `setup check` reports drift when the recorded ERD
|
|
118
118
|
preview namespaces no longer match the current config.
|
|
119
119
|
|
|
120
|
+
#### Migration test on a labeled pull request
|
|
121
|
+
|
|
122
|
+
Pass `--migration-test` on a branch target to add a job that runs
|
|
123
|
+
[`tailor tailordb migration test`](./cli/tailordb.md) against a pull request on
|
|
124
|
+
demand. It is opt-in and requires a config with TailorDB migrations.
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
tailor setup ci branch --name my-app-stg --migration-test
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
The job runs only when someone adds the `tailor:migration-test` label to a pull
|
|
131
|
+
request from the same repository (change the label with
|
|
132
|
+
`--migration-test-label`). It runs the pending migrations in a temporary
|
|
133
|
+
workspace created next to the source workspace, writes the `--json` result to
|
|
134
|
+
the job summary, and removes the label as its last step, whether the test
|
|
135
|
+
succeeded, failed, or was cancelled while running. To run it again, add the label
|
|
136
|
+
again. If a run is cancelled before the job starts (for example, a reviewer
|
|
137
|
+
rejects the environment's approval), the label stays on the pull request: remove
|
|
138
|
+
it and add it again.
|
|
139
|
+
Anyone who can label pull requests in your repository can start the job, and
|
|
140
|
+
each run creates and deletes a workspace. Runs for one pull request never
|
|
141
|
+
cancel each other.
|
|
142
|
+
|
|
143
|
+
The generated workflow also lists `labeled` in its `pull_request` types. The
|
|
144
|
+
plan and ERD preview jobs skip label events, so adding an unrelated label does
|
|
145
|
+
not re-run them.
|
|
146
|
+
|
|
147
|
+
Runs started by a label report their result job as `tailor-result (<name>) [label]`
|
|
148
|
+
instead of `tailor-result (<name>)`. A label event therefore never replaces the
|
|
149
|
+
result of the check you require for branch protection. The migration test result
|
|
150
|
+
appears only under the `[label]` name, so it does not block merging through the
|
|
151
|
+
check you require.
|
|
152
|
+
|
|
153
|
+
The job clones the source workspace's TailorDB records and passes
|
|
154
|
+
`--clone-timeout 30m`, which bounds only the wait for the data clone. If the clone takes longer, the command
|
|
155
|
+
fails with the clone's operation ID in the error and removes its temporary
|
|
156
|
+
workspace, while the clone itself keeps running on the platform.
|
|
157
|
+
|
|
158
|
+
The migration test step is limited to 50 minutes and the job to 60, so the label
|
|
159
|
+
is still removed when the step times out. A step that is stopped at its limit
|
|
160
|
+
(or a job cancelled at the job limit) gives the command no chance to clean up:
|
|
161
|
+
delete the leftover temporary workspace with `tailor workspace delete`.
|
|
162
|
+
|
|
163
|
+
##### Choosing the source workspace
|
|
164
|
+
|
|
165
|
+
`migration test` reads the source workspace (it is not modified), builds a
|
|
166
|
+
temporary workspace from it in the same organization and folder, and deletes
|
|
167
|
+
that workspace afterwards. Because the machine user creates and deletes that
|
|
168
|
+
workspace, it needs an editor or admin role on the organization or folder that
|
|
169
|
+
holds the source workspace; a viewer role is not enough. The clone also needs the
|
|
170
|
+
same role on the source side. The clone copies TailorDB records only: IdP users
|
|
171
|
+
and file blobs are not copied.
|
|
172
|
+
|
|
173
|
+
Two setups are supported:
|
|
174
|
+
|
|
175
|
+
- **Source is the plan/deploy workspace (default).** The job uses the same GitHub
|
|
176
|
+
Environment as the plan and deploy jobs, so it reads the same
|
|
177
|
+
`TAILOR_PLATFORM_WORKSPACE_ID` variable and machine-user secrets. Nothing
|
|
178
|
+
extra to configure. If that workspace holds too little data to be a useful
|
|
179
|
+
test, point the job at a workspace that does with the next setup.
|
|
180
|
+
- **Source is a different workspace, such as production.** Pass
|
|
181
|
+
`--migration-test-environment <env>`. The job then uses that GitHub
|
|
182
|
+
Environment and reads the source workspace from its
|
|
183
|
+
`TAILOR_PLATFORM_MIGRATION_TEST_SOURCE_WORKSPACE_ID` variable, together with the
|
|
184
|
+
machine-user secrets set on that same environment. Give this environment a
|
|
185
|
+
machine user whose role you are willing to hold on the source workspace's
|
|
186
|
+
organization or folder, since it needs the editor-or-admin role described
|
|
187
|
+
above. Pending migrations run from the source workspace's migration number up
|
|
188
|
+
to the latest, so a source that is behind the deploy target replays more
|
|
189
|
+
migrations, which is closer to what a production deploy will do.
|
|
190
|
+
|
|
191
|
+
A job can declare only one GitHub Environment, and a repository secret or
|
|
192
|
+
variable is read from that environment, which is why a different source needs its
|
|
193
|
+
own environment. `tailor setup ci env` prints what each environment needs,
|
|
194
|
+
including the dedicated one. Keep the dedicated environment separate from your
|
|
195
|
+
production deploy environment: a pull request job runs on the pull request merge
|
|
196
|
+
ref (`refs/pull/<number>/merge`), so if an environment restricts which branches
|
|
197
|
+
may deploy or requires reviewers, check how that affects the pull request job
|
|
198
|
+
before pointing the migration test at it. A required-reviewers rule makes the
|
|
199
|
+
job wait for approval before it can read the environment's secrets. The job runs
|
|
200
|
+
the pull request's own code with that environment's credentials, so add one when
|
|
201
|
+
the source workspace holds production data.
|
|
202
|
+
|
|
203
|
+
Fork pull requests cannot read secrets, so the job is skipped for them.
|
|
204
|
+
`--migration-test` is not available together with several `--dir` values.
|
|
205
|
+
|
|
120
206
|
### Tag target (recommended for production)
|
|
121
207
|
|
|
122
208
|
The tag target fires when a tag matching `--tag-pattern` (default `v*`) is
|
|
@@ -501,17 +587,18 @@ tailor setup ci env --check # check what is registered in GitHu
|
|
|
501
587
|
|
|
502
588
|
The list follows what each generated workflow actually reads:
|
|
503
589
|
|
|
504
|
-
| Name
|
|
505
|
-
|
|
|
506
|
-
| `TAILOR_PLATFORM_MACHINE_USER_CLIENT_ID`
|
|
507
|
-
| `TAILOR_PLATFORM_MACHINE_USER_CLIENT_SECRET`
|
|
508
|
-
| `TAILOR_PLATFORM_WORKSPACE_ID`
|
|
509
|
-
| `
|
|
510
|
-
| `
|
|
511
|
-
| `
|
|
512
|
-
| `
|
|
513
|
-
| `
|
|
514
|
-
| `
|
|
590
|
+
| Name | Kind | Targets | Required | Where the value comes from |
|
|
591
|
+
| ---------------------------------------------------- | -------- | ----------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
592
|
+
| `TAILOR_PLATFORM_MACHINE_USER_CLIENT_ID` | variable | all | yes | Client ID of the platform machine user CI signs in as (an existing secret of the same name still works as a deprecated fallback); it needs an editor or admin role on the organization or folder that holds the workspace. An organization or folder admin creates one in the Tailor Console and grants it a role; without the required permission you cannot view or create machine users |
|
|
593
|
+
| `TAILOR_PLATFORM_MACHINE_USER_CLIENT_SECRET` | secret | all | yes | Client secret of the same platform machine user |
|
|
594
|
+
| `TAILOR_PLATFORM_WORKSPACE_ID` | variable | branch, tag | yes | `id` printed by `tailor workspace create`, or listed by `tailor workspace list` |
|
|
595
|
+
| `TAILOR_PLATFORM_MIGRATION_TEST_SOURCE_WORKSPACE_ID` | variable | branch (migration test environment) | yes | ID of the workspace the migration test starts from, set on the environment passed to `--migration-test-environment`; it is only read to build the temporary workspace. Needs the machine user's editor or admin role on that workspace's organization or folder |
|
|
596
|
+
| `TAILOR_PLATFORM_ORGANIZATION_ID` | variable | preview | yes | Organization to create the per-PR workspaces in (a machine user cannot create a workspace without one): `organizationId` listed by `tailor organization list` |
|
|
597
|
+
| `TAILOR_PLATFORM_FOLDER_ID` | variable | preview | no | Folder to create the per-PR workspaces in: `id` listed by `tailor organization folder list -o <organization id>`. When unset they go directly under the organization, which needs the machine user's role on the organization itself |
|
|
598
|
+
| `TAILOR_PLATFORM_FAIL_ON_DRIFT` | variable | all | no | `true` to fail the drift check when it finds drift |
|
|
599
|
+
| `TAILOR_SLACK_BOT_TOKEN` | secret | branch, tag | no | Bot User OAuth Token (`xoxb-...`) of a Slack app with the `chat:write` scope |
|
|
600
|
+
| `TAILOR_SLACK_CHANNEL_ID` | variable | branch, tag | no | Channel ID (`C...`) from the channel details in Slack; invite the bot to the channel |
|
|
601
|
+
| `TAILOR_SLACK_USER_MAPPING` | variable | branch, tag | no | JSON object mapping GitHub usernames to Slack member IDs (for example `{"alice":"U0123456"}`) so notifications mention the actor; read only after you uncomment the `user-mapping` input of the `tailor-notify` step |
|
|
515
602
|
|
|
516
603
|
See [Account management](https://docs.tailor.tech/administration/account-management)
|
|
517
604
|
for how organizations, folders, workspaces, and machine users relate.
|
package/docs/plugin/custom.md
CHANGED
|
@@ -90,6 +90,40 @@ interface Plugin<TableConfig = unknown, PluginConfig = unknown> {
|
|
|
90
90
|
| `executors` | `PluginGeneratedExecutor[]` | Additional executors to generate |
|
|
91
91
|
| `extends` | `{ fields?: Record<string, TailorAnyDBField> }` | Fields to add to the source table |
|
|
92
92
|
|
|
93
|
+
Resolvers returned by `onTableLoaded` or `onNamespaceLoaded` are loaded, bundled, and deployed to
|
|
94
|
+
the resolver namespace (a `resolver` key in your config) with the same name as the hook's TailorDB
|
|
95
|
+
namespace (a `db` key). These are separate namespaces that only share the name: with
|
|
96
|
+
`db: { main: ... }` and `resolver: { billing: ... }`, generated resolvers go to a `main` resolver
|
|
97
|
+
namespace, not `billing`. If you configure a resolver namespace with that name, generated resolvers
|
|
98
|
+
join its configured files and use its `defaultPermission`. Otherwise, a resolver namespace is created
|
|
99
|
+
automatically. Configure `defaultPermission` to restrict access; without it, generated resolvers are
|
|
100
|
+
accessible to anonymous callers, like regular resolvers with no permission declared. Generating into
|
|
101
|
+
an external resolver namespace or duplicating a resolver name within a namespace fails the build.
|
|
102
|
+
|
|
103
|
+
For example, a namespace hook can return a query using `t` field builders:
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
onNamespaceLoaded() {
|
|
107
|
+
return {
|
|
108
|
+
resolvers: [{
|
|
109
|
+
name: "greet",
|
|
110
|
+
operation: "query",
|
|
111
|
+
inputFields: { name: t.string() },
|
|
112
|
+
outputFields: { message: t.string() },
|
|
113
|
+
body: 'return { message: `Hello, ${context.input.name}!` };',
|
|
114
|
+
}],
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
The `body` string contains JavaScript statements with access to `context.input`, `context.caller`,
|
|
120
|
+
`context.invoker`, and `context.env`. It can use `await` and platform globals, but cannot capture
|
|
121
|
+
plugin-local variables. Embed configuration values as literals with `JSON.stringify` when building
|
|
122
|
+
the string. Field validators must also be self-contained: they can use their arguments and standard
|
|
123
|
+
JavaScript globals, and references to other names are rejected during generation. Input validation and date conversion follow the same rules as regular
|
|
124
|
+
resolvers. Invalid field definitions or JavaScript syntax fail the build with the plugin and namespace
|
|
125
|
+
identified in the error.
|
|
126
|
+
|
|
93
127
|
Tables in `tables` are validated as complete TailorDB table definitions before registration.
|
|
94
128
|
Fields in `extends.fields` are validated as part of the resulting source table. You can return a
|
|
95
129
|
table builder directly or a structural copy such as `{ ...db.table(...) }`; a copy is accepted as
|
package/docs/plugin/index.md
CHANGED
|
@@ -102,6 +102,7 @@ export const plugins = definePlugins(
|
|
|
102
102
|
Plugins can generate:
|
|
103
103
|
|
|
104
104
|
- **Tables**: Additional TailorDB tables (e.g., `CustomerHistory`, `Deleted_Customer`)
|
|
105
|
+
- **Resolvers**: Queries and mutations
|
|
105
106
|
- **Executors**: Event handlers triggered by record changes
|
|
106
107
|
- **Field Extensions**: Additional fields added to the source table
|
|
107
108
|
- **Output Files**: TypeScript code and other files via generation-time hooks
|
|
@@ -78,7 +78,37 @@ defineStaticWebSite("my-website", {
|
|
|
78
78
|
|
|
79
79
|
After deploying, use `tailor staticwebsite domain get <domain>` to check domain status and retrieve the CNAME targets required for DNS configuration.
|
|
80
80
|
|
|
81
|
-
A domain can be associated with only one workspace at a time. To set custom domains only in the workspace that owns the domain, see [Multi-Environment Configuration](../multi-environment.md#settings-that-belong-to-a-single-environment).
|
|
81
|
+
A domain can be associated with only one workspace at a time. To set custom domains only in the workspace that owns the domain, see [Multi-Environment Configuration](../multi-environment.md#settings-that-belong-to-a-single-environment). To hand a domain to another site or workspace without taking it offline, see [Moving a domain](#moving-a-domain).
|
|
82
|
+
|
|
83
|
+
### Moving a domain
|
|
84
|
+
|
|
85
|
+
A domain already serving traffic can be moved to another static website — in this workspace or another one — without downtime, without reissuing its certificate and without changing DNS. The site that currently holds the domain offers it; the receiving site accepts by listing the domain normally.
|
|
86
|
+
|
|
87
|
+
On the side giving the domain up, replace the plain entry with the destination:
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
defineStaticWebSite("my-website", {
|
|
91
|
+
customDomains: [{ domain: "app.example.com", transferTo: { workspaceId: "..." } }],
|
|
92
|
+
});
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Deploying opens the offer. On the receiving side, list the domain as usual and deploy:
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
defineStaticWebSite("new-website", {
|
|
99
|
+
customDomains: ["app.example.com"],
|
|
100
|
+
});
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
That deploy completes the move. The next plan on the giving side reports that the domain moved, and the entry should then be deleted — it describes a move that already happened, not ongoing state.
|
|
104
|
+
|
|
105
|
+
The two deploys must be separate runs, even when both sites live in the same workspace: the receiving side cannot accept an offer that the same run is still opening, and `tailor deploy` says so rather than failing partway.
|
|
106
|
+
|
|
107
|
+
These rules apply while an offer is open:
|
|
108
|
+
|
|
109
|
+
- An offer expires after 7 days. Deploying the entry again after that opens a fresh offer.
|
|
110
|
+
- Neither the domain nor the static website holding it can be removed. Change the entry back to a plain string and deploy to withdraw the offer first; `tailor deploy` and `tailor remove` both refuse before changing anything.
|
|
111
|
+
- An offer takes a moment to become ready. Until it is, the receiving side cannot accept it and its deploy is refused; the giving side's plan says so.
|
|
82
112
|
|
|
83
113
|
## Type-safe URL References
|
|
84
114
|
|