@tailor-platform/sdk 1.47.1 → 1.49.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.
Files changed (91) hide show
  1. package/CHANGELOG.md +95 -0
  2. package/dist/{actor-jk4-f0yp.d.mts → actor-BeIEiPYM.d.mts} +2 -2
  3. package/dist/{application-C7H7y0hS.mjs → application-CZMzt9jL.mjs} +82 -18
  4. package/dist/application-CZMzt9jL.mjs.map +1 -0
  5. package/dist/application-v_E2W-Fz.mjs +4 -0
  6. package/dist/brand-D-d15jx3.mjs.map +1 -1
  7. package/dist/cli/index.mjs +55 -31
  8. package/dist/cli/index.mjs.map +1 -1
  9. package/dist/cli/lib.d.mts +6 -6
  10. package/dist/cli/lib.mjs +6 -6
  11. package/dist/cli/lib.mjs.map +1 -1
  12. package/dist/cli/skills.mjs.map +1 -1
  13. package/dist/{client-DCqdtFte.mjs → client-CPW1N1Rs.mjs} +1 -1
  14. package/dist/{client-DbyKSN1F.mjs → client-_kHh0Pip.mjs} +2 -2
  15. package/dist/{client-DbyKSN1F.mjs.map → client-_kHh0Pip.mjs.map} +1 -1
  16. package/dist/configure/index.d.mts +4 -4
  17. package/dist/configure/index.mjs +51 -3
  18. package/dist/configure/index.mjs.map +1 -1
  19. package/dist/{crashreport-CNSw_BrJ.mjs → crashreport-CvmdFs4i.mjs} +5 -5
  20. package/dist/crashreport-CvmdFs4i.mjs.map +1 -0
  21. package/dist/{crashreport-DXGFd16F.mjs → crashreport-DHJuSmUc.mjs} +1 -1
  22. package/dist/enum-constants-C3KSpsYj.mjs.map +1 -1
  23. package/dist/{errors-wNQxQQBH.mjs → errors-pMPXghkO.mjs} +1 -1
  24. package/dist/{errors-wNQxQQBH.mjs.map → errors-pMPXghkO.mjs.map} +1 -1
  25. package/dist/field-DLSIuMTu.mjs.map +1 -1
  26. package/dist/file-utils-DjNi_3U_.mjs.map +1 -1
  27. package/dist/index-BQ4oi0AI.d.mts +48 -0
  28. package/dist/{index-BbOTbZFf.d.mts → index-BjXN1SdY.d.mts} +2 -2
  29. package/dist/{index-DB8EapT-.d.mts → index-C--7W0UO.d.mts} +5 -5
  30. package/dist/{index-BRvNi5q9.d.mts → index-VJW98BSy.d.mts} +2 -2
  31. package/dist/{index-iy-hNfGp.d.mts → index-nV4ZC_Ve.d.mts} +2 -2
  32. package/dist/{interceptor-CBsqEWDK.mjs → interceptor-DTNS0EtF.mjs} +1 -1
  33. package/dist/{interceptor-CBsqEWDK.mjs.map → interceptor-DTNS0EtF.mjs.map} +1 -1
  34. package/dist/{job-R5C2Hfcc.mjs → job-M3Avv_SV.mjs} +4 -3
  35. package/dist/{job-R5C2Hfcc.mjs.map → job-M3Avv_SV.mjs.map} +1 -1
  36. package/dist/kysely/index.mjs.map +1 -1
  37. package/dist/kysely-type-B8aRz_oC.mjs.map +1 -1
  38. package/dist/logger-DTNAMYGy.mjs.map +1 -1
  39. package/dist/{mock-BP-9O5On.mjs → mock-BfL09ULZ.mjs} +1 -1
  40. package/dist/{mock-BP-9O5On.mjs.map → mock-BfL09ULZ.mjs.map} +1 -1
  41. package/dist/multiline-e3IpANmS.mjs.map +1 -1
  42. package/dist/package-json-6Px8bDpG.mjs.map +1 -1
  43. package/dist/plugin/builtin/enum-constants/index.d.mts +1 -1
  44. package/dist/plugin/builtin/file-utils/index.d.mts +1 -1
  45. package/dist/plugin/builtin/kysely-type/index.d.mts +1 -1
  46. package/dist/plugin/builtin/seed/index.d.mts +1 -1
  47. package/dist/plugin/builtin/seed/index.mjs +1 -1
  48. package/dist/plugin/index.d.mts +2 -2
  49. package/dist/plugin/index.mjs.map +1 -1
  50. package/dist/{repl-editor-CZpLlOBj.mjs → repl-editor-jZ493eQI.mjs} +1 -1
  51. package/dist/{repl-editor-CZpLlOBj.mjs.map → repl-editor-jZ493eQI.mjs.map} +1 -1
  52. package/dist/{runtime-XjP6JMmP.mjs → runtime-oZgK353r.mjs} +484 -132
  53. package/dist/runtime-oZgK353r.mjs.map +1 -0
  54. package/dist/{tailordb-DjlNUV6u.mjs → schema-C5QjYEc-.mjs} +2 -42
  55. package/dist/schema-C5QjYEc-.mjs.map +1 -0
  56. package/dist/secret-file-BHpxGyNf.mjs +65 -0
  57. package/dist/secret-file-BHpxGyNf.mjs.map +1 -0
  58. package/dist/seed/index.mjs.map +1 -1
  59. package/dist/{seed-DrKY5yIF.mjs → seed-DjfAn0BC.mjs} +44 -19
  60. package/dist/seed-DjfAn0BC.mjs.map +1 -0
  61. package/dist/{service-obEU5gSM.mjs → service-DCgJxdg1.mjs} +2 -2
  62. package/dist/{service-obEU5gSM.mjs.map → service-DCgJxdg1.mjs.map} +1 -1
  63. package/dist/{tailor-db-field-Bn8ZC5lK.d.mts → tailor-db-field-4bMLe25-.d.mts} +5 -1
  64. package/dist/telemetry-C13VIFpT.mjs +4 -0
  65. package/dist/{telemetry-DcL8Fsm_.mjs → telemetry-C1Y56L5E.mjs} +1 -1
  66. package/dist/{telemetry-DcL8Fsm_.mjs.map → telemetry-C1Y56L5E.mjs.map} +1 -1
  67. package/dist/types-sir9UPht.mjs.map +1 -1
  68. package/dist/utils/test/index.d.mts +3 -3
  69. package/dist/utils/test/index.mjs +1 -1
  70. package/dist/utils/test/index.mjs.map +1 -1
  71. package/dist/vitest/environment.mjs +1 -1
  72. package/dist/vitest/environment.mjs.map +1 -1
  73. package/dist/vitest/index.mjs +1 -1
  74. package/dist/vitest/index.mjs.map +1 -1
  75. package/dist/vitest/setup.mjs +1 -1
  76. package/dist/vitest/setup.mjs.map +1 -1
  77. package/dist/{workflow.generated-i7PK4fg-.d.mts → workflow.generated-OYAu_6zX.d.mts} +12 -2
  78. package/docs/cli/application.md +4 -0
  79. package/docs/cli/workspace.md +20 -17
  80. package/docs/configuration.md +4 -0
  81. package/docs/generator/builtin.md +35 -4
  82. package/package.json +16 -16
  83. package/postinstall.mjs +1 -1
  84. package/dist/application-C7H7y0hS.mjs.map +0 -1
  85. package/dist/application-Csq5jxYP.mjs +0 -4
  86. package/dist/crashreport-CNSw_BrJ.mjs.map +0 -1
  87. package/dist/index-BXyS7xKC.d.mts +0 -21
  88. package/dist/runtime-XjP6JMmP.mjs.map +0 -1
  89. package/dist/seed-DrKY5yIF.mjs.map +0 -1
  90. package/dist/tailordb-DjlNUV6u.mjs.map +0 -1
  91. package/dist/telemetry-21afNV9_.mjs +0 -4
package/CHANGELOG.md CHANGED
@@ -1,5 +1,100 @@
1
1
  # @tailor-platform/sdk
2
2
 
3
+ ## 1.49.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#1147](https://github.com/tailor-platform/sdk/pull/1147) [`f0de80a`](https://github.com/tailor-platform/sdk/commit/f0de80ac83a3e76bcb65be7957cb3d7bd1f80ec1) Thanks [@dqn](https://github.com/dqn)! - Add `--permission <write|read>` flag to `profile create`, `profile update`, and `workspace create` (when `--profile-name` is given) so editor users can use a viewer-style profile by default. Profiles created with `--permission read` block platform-state mutations driven by the operator's bearer token (`apply`, `remove`, `workspace create/delete/restore`, `secret create/update/delete`, `tailordb migrate set`, `tailordb truncate`, `tailordb erd deploy`, `executor trigger`, `staticwebsite deploy`, `authconnection authorize/revoke`, organization / folder / PAT / workspace-user mutations, and direct `api <endpoint>` calls) with a `PROFILE_READONLY` error. Application-data operations executed under a machine user (`query`, `workflow start/resume`, `function test-run`) are not gated because the machine user's own permissions already govern those mutations. Switch profile or run `profile update <name> --permission write` to lift the restriction. Profile management itself stays available so the flag can always be cleared. `profile update` skips remote user / workspace validation when only `--permission` is changing, so the flag can be cleared offline or with an expired token.
8
+
9
+ The guard activates only when a profile is in scope: pass `--profile <name>` or set `TAILOR_PLATFORM_PROFILE`. `TAILOR_PLATFORM_TOKEN` and `--workspace-id` direct access bypass the guard by design; they are intended for machine-user / CI flows where the platform token already encodes the permitted scope.
10
+
11
+ ### Patch Changes
12
+
13
+ - [#1204](https://github.com/tailor-platform/sdk/pull/1204) [`6b1bbcb`](https://github.com/tailor-platform/sdk/commit/6b1bbcbe843340a912a3c75c2ecdb03c5697f967) Thanks [@renovate](https://github.com/apps/renovate)! - fix(deps): update dependency rolldown to v1.0.1
14
+
15
+ - [#1196](https://github.com/tailor-platform/sdk/pull/1196) [`c9b7d1e`](https://github.com/tailor-platform/sdk/commit/c9b7d1eae8a3cccf70191bd8c228cd11db6ed060) Thanks [@dqn](https://github.com/dqn)! - Eliminate the Node.js `DEP0205` `DeprecationWarning` (`` `module.register()` is deprecated. Use `module.registerHooks()` instead. ``) printed by every `tailor-sdk` CLI invocation on Node v26. The CLI now registers `tsx` through its own programmatic API (`tsx/esm/api`) instead of calling `node:module`'s `register("tsx", …)` directly, which on tsx 4.21.1+ routes through `module.registerHooks()` on Node ≥ 24.11.1 / 25.1 / 26 and falls back to `module.register()` on older runtimes. Bumps the bundled `tsx` from 4.21.0 to 4.21.1.
16
+
17
+ - [#1179](https://github.com/tailor-platform/sdk/pull/1179) [`f72ffe1`](https://github.com/tailor-platform/sdk/commit/f72ffe1aed824eb9af5e7520529c3ebde029b5a6) Thanks [@toiroakr](https://github.com/toiroakr)! - Fix `tailor-sdk deploy --no-schema-check` to reconcile the TailorDB migration label to the working tree's latest migration number when it completes. Previously, running `deploy --no-schema-check` from a revision whose working tree is older than the remote left the remote migration label stale; the next `deploy` then reconstructed a snapshot at a label that no longer existed in the working tree and aborted with a false "Remote schema drift detected" error.
18
+
19
+ ## 1.48.0
20
+
21
+ ### Minor Changes
22
+
23
+ - [#1118](https://github.com/tailor-platform/sdk/pull/1118) [`5ef8e01`](https://github.com/tailor-platform/sdk/commit/5ef8e01fbcee428d77925662006fd2cc7f64a522) Thanks [@toiroakr](https://github.com/toiroakr)! - Detect app renames via a stable, auto-injected `id` field in `tailor.config.ts`.
24
+
25
+ The SDK now writes a generated `id: "<uuid>"` field into the
26
+ `defineConfig({...})` call on first `deploy`, and stamps every managed
27
+ resource with an `sdk-app-id` metadata label. Subsequent deploys identify
28
+ ownership by the stable id rather than by the app name, so renaming the
29
+ app (or any of its resources) cleanly removes the old resources before
30
+ creating the new ones. The id is a plain UUID; the SDK adds the
31
+ label-compatible `app-` prefix internally at the metadata boundary.
32
+
33
+ Deleting the `id` field regenerates a new UUID on the next `deploy` —
34
+ typically done after copying `tailor.config.ts` from another project so
35
+ the new application does not share the original's id. Existing
36
+ resources keep their data and are re-tagged in place; `deploy` shows a
37
+ dedicated confirmation prompt for this case ("Application id was
38
+ regenerated for ..."), separate from the rename/transfer confirmation.
39
+
40
+ If your `tailor.config.ts` is a wrapper that re-exports `defineConfig` from
41
+ another file, the SDK skips id injection on the wrapper — add the `id`
42
+ field manually to the file that contains the actual `defineConfig({...})`
43
+ call. Existing deployments without the id continue to work and migrate
44
+ transparently on the next `deploy` run.
45
+
46
+ - [#1156](https://github.com/tailor-platform/sdk/pull/1156) [`4311e05`](https://github.com/tailor-platform/sdk/commit/4311e05d59f2e4b92d312b2a0e991f69553c741c) Thanks [@toiroakr](https://github.com/toiroakr)! - Add `disableIdpUserSync` option to `seedPlugin` for opting out of the
47
+ `_User <-> userProfile` foreign keys emitted into the generated seed schema.
48
+
49
+ The seed plugin emits two foreign keys when `auth.userProfile` is configured
50
+ so that `validate` rejects rows on either side that lack a matching
51
+ counterpart:
52
+
53
+ - `_User.name → <userProfile>.<usernameField>` (`idpToUser`)
54
+ - `<userProfile>.<usernameField> → _User.name` (`userToIdp`)
55
+
56
+ Both are emitted by default, matching the previous behavior. Neither
57
+ direction is enforced by the runtime, so it can be useful to relax one when
58
+ seeding asymmetric production-like states such as
59
+ invited-but-not-registered users.
60
+
61
+ ```ts
62
+ // Allow seeding invited userProfile rows without a _User row
63
+ seedPlugin({
64
+ distPath: "./seed",
65
+ disableIdpUserSync: { userToIdp: true },
66
+ }),
67
+
68
+ // Allow seeding _User rows whose userProfile row does not exist yet
69
+ seedPlugin({
70
+ distPath: "./seed",
71
+ disableIdpUserSync: { idpToUser: true },
72
+ }),
73
+ ```
74
+
75
+ ### Patch Changes
76
+
77
+ - [#1189](https://github.com/tailor-platform/sdk/pull/1189) [`7bcd9c1`](https://github.com/tailor-platform/sdk/commit/7bcd9c14eaed52df95b4a6523804a8a971797473) Thanks [@toiroakr](https://github.com/toiroakr)! - Improve tree-shaking of `@tailor-platform/sdk` so applications that only import a subset of the public API ship less unused code:
78
+
79
+ - Add a selective `sideEffects` allow-list to `package.json`: only `dist/cli/*.mjs` and `dist/vitest/setup.mjs` retain side effects, the rest of `dist/` is marked side-effect-free so bundlers can drop modules whose only imports are unused.
80
+ - Replace the top-level `export const t = { ..._t }` spread in `configure/index.ts` with a direct alias, eliminating a side-effecting object construction that prevented elimination of unused field builders.
81
+ - Annotate configure-layer factories (`defineConfig`, `defineAuth`, `defineIdp`, `defineStaticWebSite`, `definePlugins`, `createResolver`, `createExecutor`, `createWorkflow`, `createWorkflowJob`, etc.) with `@__NO_SIDE_EFFECTS__` so calls whose return values are unused can be eliminated.
82
+
83
+ No public API surface changes.
84
+
85
+ - [#1180](https://github.com/tailor-platform/sdk/pull/1180) [`3411070`](https://github.com/tailor-platform/sdk/commit/34110703daa5cafa40958f5b9dc6f21df5e201fb) Thanks [@renovate](https://github.com/apps/renovate)! - fix(deps): update @inquirer
86
+
87
+ - [#1191](https://github.com/tailor-platform/sdk/pull/1191) [`a20354d`](https://github.com/tailor-platform/sdk/commit/a20354d47211e1955acd9086c4d25228ee2873de) Thanks [@dqn](https://github.com/dqn)! - **Security**: Harden permissions of the CLI config file (`~/.config/tailor-platform/config.yaml`) and local crash reports to `0o600`, with their parent directory at `0o700`. Previously these files inherited the user's `umask` (typically `0o644`), so on multi-user hosts or shared CI volumes other accounts could read access/refresh tokens stored in the config when the OS keyring is unavailable, as well as crash payloads.
88
+
89
+ **Action recommended**: If you have used the CLI on a multi-user host or in a shared CI environment, upgrade and run any `tailor-sdk` command once to auto-tighten existing files, or manually:
90
+
91
+ ```sh
92
+ chmod 700 ~/.config/tailor-platform
93
+ chmod 600 ~/.config/tailor-platform/config.yaml
94
+ ```
95
+
96
+ POSIX-only; on Windows the mode bits are best-effort and ACLs continue to govern access.
97
+
3
98
  ## 1.47.1
4
99
 
5
100
  ### Patch Changes
@@ -1,5 +1,5 @@
1
1
  /// <reference types="@tailor-platform/function-types" />
2
- import { Bt as InferredAttributeMap, zt as InferredAttributeList } from "./tailor-db-field-Bn8ZC5lK.mjs";
2
+ import { Bt as InferredAttributeMap, zt as InferredAttributeList } from "./tailor-db-field-4bMLe25-.mjs";
3
3
 
4
4
  //#region src/types/env.d.ts
5
5
  interface Env {}
@@ -27,4 +27,4 @@ type TailorActor = {
27
27
  };
28
28
  //#endregion
29
29
  export { Env as n, TailorEnv as r, TailorActor as t };
30
- //# sourceMappingURL=actor-jk4-f0yp.d.mts.map
30
+ //# sourceMappingURL=actor-BeIEiPYM.d.mts.map
@@ -1,13 +1,14 @@
1
1
 
2
2
  import { n as isSdkBranded } from "./brand-D-d15jx3.mjs";
3
- import { u as initOAuth2Client } from "./client-DbyKSN1F.mjs";
3
+ import { u as initOAuth2Client } from "./client-_kHh0Pip.mjs";
4
4
  import { a as parseBoolean, n as logger, r as styles } from "./logger-DTNAMYGy.mjs";
5
5
  import { n as enumConstantsPlugin, t as EnumConstantsGeneratorID } from "./enum-constants-C3KSpsYj.mjs";
6
6
  import { t as multiline } from "./multiline-e3IpANmS.mjs";
7
7
  import { n as fileUtilsPlugin, t as FileUtilsGeneratorID } from "./file-utils-DjNi_3U_.mjs";
8
8
  import { n as kyselyTypePlugin, t as KyselyGeneratorID } from "./kysely-type-B8aRz_oC.mjs";
9
- import { n as seedPlugin, r as isPluginGeneratedType, t as SeedGeneratorID } from "./seed-DrKY5yIF.mjs";
9
+ import { n as seedPlugin, r as isPluginGeneratedType, t as SeedGeneratorID } from "./seed-DjfAn0BC.mjs";
10
10
  import { t as readPackageJson } from "./package-json-6Px8bDpG.mjs";
11
+ import { n as tightenSecretFilePermissions, r as writeSecretFile } from "./secret-file-BHpxGyNf.mjs";
11
12
  import { createRequire } from "node:module";
12
13
  import { z } from "zod";
13
14
  import * as fs$1 from "node:fs";
@@ -28,6 +29,42 @@ import { parseSync } from "oxc-parser";
28
29
  import * as inflection from "inflection";
29
30
  import * as globals from "globals";
30
31
 
32
+ //#region src/parser/app-config/schema.ts
33
+ const envValueSchema = z.union([
34
+ z.string(),
35
+ z.number(),
36
+ z.boolean()
37
+ ]);
38
+ /**
39
+ * Structural validation schema for `defineConfig({...})`. Validates only
40
+ * top-level fields with platform-side constraints (notably `id`); fields
41
+ * that carry SDK builder objects (`auth`, `idp`, `db`, ...) are accepted
42
+ * as opaque values, since their internal shapes are validated by their
43
+ * own factory functions and parser-level schemas.
44
+ *
45
+ * The `id` is auto-managed by `deploy` and stored as a plain UUID. A
46
+ * label-compatible prefix is added at the metadata boundary, so user-facing
47
+ * configs only need to carry a UUID.
48
+ */
49
+ const AppConfigSchema = z.object({
50
+ id: z.uuid({ message: "'id' must be a UUID." }).optional(),
51
+ name: z.string().min(1, { message: "'name' must be a non-empty string." }),
52
+ env: z.record(z.string(), envValueSchema).optional(),
53
+ cors: z.array(z.string()).optional(),
54
+ allowedIpAddresses: z.array(z.string()).optional(),
55
+ disableIntrospection: z.boolean().optional(),
56
+ inlineSourcemap: z.boolean().optional(),
57
+ db: z.unknown().optional(),
58
+ resolver: z.unknown().optional(),
59
+ idp: z.unknown().optional(),
60
+ auth: z.unknown().optional(),
61
+ executor: z.unknown().optional(),
62
+ workflow: z.unknown().optional(),
63
+ staticWebsites: z.unknown().optional(),
64
+ secrets: z.unknown().optional()
65
+ });
66
+
67
+ //#endregion
31
68
  //#region src/parser/generator-config/schema.ts
32
69
  const DependencyKindSchema = z.enum([
33
70
  "tailordb",
@@ -37,7 +74,11 @@ const DependencyKindSchema = z.enum([
37
74
  const KyselyTypeConfigSchema = z.tuple([z.literal("@tailor-platform/kysely-type"), z.object({ distPath: z.string() })]);
38
75
  const SeedConfigSchema = z.tuple([z.literal("@tailor-platform/seed"), z.object({
39
76
  distPath: z.string(),
40
- machineUserName: z.string().optional()
77
+ machineUserName: z.string().optional(),
78
+ disableIdpUserSync: z.object({
79
+ userToIdp: z.boolean().optional(),
80
+ idpToUser: z.boolean().optional()
81
+ }).optional()
41
82
  })]);
42
83
  const EnumConstantsConfigSchema = z.tuple([z.literal("@tailor-platform/enum-constants"), z.object({ distPath: z.string() })]);
43
84
  const FileUtilsConfigSchema = z.tuple([z.literal("@tailor-platform/file-utils"), z.object({ distPath: z.string() })]);
@@ -157,7 +198,8 @@ async function deleteKeyringTokens(account) {
157
198
  //#region src/cli/shared/context.ts
158
199
  const pfProfileSchema = z.object({
159
200
  user: z.string(),
160
- workspace_id: z.string()
201
+ workspace_id: z.string(),
202
+ readonly: z.boolean().optional()
161
203
  });
162
204
  const pfUserSchemaV1 = z.object({
163
205
  access_token: z.string(),
@@ -248,6 +290,7 @@ async function readPlatformConfig() {
248
290
  return migrateV1ToV2(v1Config);
249
291
  }
250
292
  const rawConfig = parseYAML(fs$1.readFileSync(configPath, "utf-8"));
293
+ tightenSecretFilePermissions(configPath);
251
294
  const version = rawConfig != null && typeof rawConfig === "object" && "version" in rawConfig ? rawConfig.version : void 0;
252
295
  if (typeof version === "number" && version > LATEST_CONFIG_VERSION) {
253
296
  const minSdk = "min_sdk_version" in rawConfig ? String(rawConfig.min_sdk_version) : void 0;
@@ -295,13 +338,14 @@ function toV1ForDisk(config) {
295
338
  * Write Tailor Platform CLI configuration to disk.
296
339
  * By default, V2 configs are converted to V1 for backward compatibility.
297
340
  * Set TAILOR_USE_KEYRING to write V2 format (required for keyring storage).
341
+ *
342
+ * The config file may contain access/refresh tokens when the OS keyring is
343
+ * unavailable, so it is written via {@link writeSecretFile} so other users
344
+ * on the host cannot read it.
298
345
  * @param config - Platform configuration to write
299
346
  */
300
347
  function writePlatformConfig(config) {
301
- const configPath = platformConfigPath();
302
- fs$1.mkdirSync(path.dirname(configPath), { recursive: true });
303
- const diskConfig = config.version === 2 && !process.env.TAILOR_USE_KEYRING ? toV1ForDisk(config) : config;
304
- fs$1.writeFileSync(configPath, stringifyYAML(diskConfig));
348
+ writeSecretFile(platformConfigPath(), stringifyYAML(config.version === 2 && !process.env.TAILOR_USE_KEYRING ? toV1ForDisk(config) : config));
305
349
  }
306
350
  const tcContextConfigSchema = z.object({
307
351
  username: z.string().optional(),
@@ -508,14 +552,27 @@ function loadConfigPath(configPath) {
508
552
 
509
553
  //#endregion
510
554
  //#region src/cli/shared/mock.ts
511
- globalThis.tailordb = { Client: class {
512
- constructor(_config) {}
513
- async connect() {}
514
- async end() {}
515
- async queryObject() {
516
- return {};
517
- }
518
- } };
555
+ /**
556
+ * Install a stub `globalThis.tailordb` so that user code loaded by the CLI
557
+ * (e.g. via `createGetDB` in `@tailor-platform/sdk/kysely`) can reference
558
+ * `tailordb.Client` without hitting a `ReferenceError`. The CLI never
559
+ * actually executes the user code paths that issue queries, so a no-op
560
+ * client suffices.
561
+ *
562
+ * Exposed as a function (rather than a top-level statement) so that
563
+ * `package.json#sideEffects` can keep the file marked side-effect-free
564
+ * without bundlers eliminating the install step.
565
+ */
566
+ function installCliTailordbStub() {
567
+ globalThis.tailordb = { Client: class {
568
+ constructor(_config) {}
569
+ async connect() {}
570
+ async end() {}
571
+ async queryObject() {
572
+ return {};
573
+ }
574
+ } };
575
+ }
519
576
 
520
577
  //#endregion
521
578
  //#region src/cli/shared/config-loader.ts
@@ -526,12 +583,18 @@ const GeneratorConfigSchema = CodeGeneratorSchema.brand("CodeGenerator");
526
583
  * @returns Loaded config, generators, plugins, and config path
527
584
  */
528
585
  async function loadConfig(configPath) {
586
+ installCliTailordbStub();
529
587
  const foundPath = loadConfigPath(configPath);
530
588
  if (!foundPath) throw new Error("Configuration file not found: tailor.config.ts not found in current or parent directories");
531
589
  const resolvedPath = path.resolve(process.cwd(), foundPath);
532
590
  if (!fs$1.existsSync(resolvedPath)) throw new Error(`Configuration file not found: ${configPath}`);
533
591
  const configModule = await import(pathToFileURL(resolvedPath).href);
534
592
  if (!configModule || !configModule.default) throw new Error("Invalid Tailor config module: default export not found");
593
+ const validated = AppConfigSchema.safeParse(configModule.default);
594
+ if (!validated.success) {
595
+ const issues = validated.error.issues.map((i) => ` - ${i.path.join(".") || "(root)"}: ${i.message}`).join("\n");
596
+ throw new Error(`Invalid Tailor config in ${resolvedPath}:\n${issues}`);
597
+ }
535
598
  const allGenerators = [];
536
599
  const allPlugins = [];
537
600
  for (const value of Object.values(configModule)) if (Array.isArray(value)) {
@@ -5129,6 +5192,7 @@ function defineServices(config, pluginManager) {
5129
5192
  function buildApplication(params) {
5130
5193
  const application = {
5131
5194
  name: params.config.name,
5195
+ id: params.config.id,
5132
5196
  config: params.config,
5133
5197
  subgraphs: [
5134
5198
  ...params.tailordbResult.subgraphs,
@@ -5280,5 +5344,5 @@ async function loadApplication(params) {
5280
5344
  }
5281
5345
 
5282
5346
  //#endregion
5283
- export { loadWorkspaceId as C, writePlatformConfig as D, saveUserTokens as E, loadAccessToken as S, resolveTokens as T, getDistDir as _, WorkflowJobSchema as a, deleteUserTokens as b, ExecutorSchema as c, buildResolverOperationHookExpr as d, OAuth2ClientSchema as f, createBundleCache as g, loadFilesWithIgnores as h, resolveInlineSourcemap as i, INVOKER_EXPR as l, stringifyFunction as m, generatePluginFilesIfNeeded as n, ResolverSchema as o, TailorDBTypeSchema as p, loadApplication as r, createExecutorService as s, defineApplication as t, buildExecutorArgsExpr as u, hashFile as v, readPlatformConfig as w, fetchLatestToken as x, loadConfig as y };
5284
- //# sourceMappingURL=application-C7H7y0hS.mjs.map
5347
+ export { loadConfigPath as C, saveUserTokens as D, resolveTokens as E, writePlatformConfig as O, loadAccessToken as S, readPlatformConfig as T, getDistDir as _, WorkflowJobSchema as a, deleteUserTokens as b, ExecutorSchema as c, buildResolverOperationHookExpr as d, OAuth2ClientSchema as f, createBundleCache as g, loadFilesWithIgnores as h, resolveInlineSourcemap as i, INVOKER_EXPR as l, stringifyFunction as m, generatePluginFilesIfNeeded as n, ResolverSchema as o, TailorDBTypeSchema as p, loadApplication as r, createExecutorService as s, defineApplication as t, buildExecutorArgsExpr as u, hashFile as v, loadWorkspaceId as w, fetchLatestToken as x, loadConfig as y };
5348
+ //# sourceMappingURL=application-CZMzt9jL.mjs.map