@tailor-platform/sdk 1.47.0 → 1.48.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 (99) hide show
  1. package/CHANGELOG.md +91 -0
  2. package/dist/{actor-DhXSqWTW.d.mts → actor-BeIEiPYM.d.mts} +3 -3
  3. package/dist/application-BNkNt47b.mjs +4 -0
  4. package/dist/{application-TasSqBTD.mjs → application-DUENhx4Y.mjs} +124 -79
  5. package/dist/application-DUENhx4Y.mjs.map +1 -0
  6. package/dist/{brand-Ll48SMXe.mjs → brand-D-d15jx3.mjs} +1 -1
  7. package/dist/{brand-Ll48SMXe.mjs.map → brand-D-d15jx3.mjs.map} +1 -1
  8. package/dist/cli/index.mjs +15 -15
  9. package/dist/cli/index.mjs.map +1 -1
  10. package/dist/cli/lib.d.mts +6 -6
  11. package/dist/cli/lib.mjs +4 -4
  12. package/dist/cli/lib.mjs.map +1 -1
  13. package/dist/cli/skills.mjs.map +1 -1
  14. package/dist/{client-DYSkSLRr.mjs → client-CPW1N1Rs.mjs} +1 -1
  15. package/dist/client-_kHh0Pip.mjs +1061 -0
  16. package/dist/client-_kHh0Pip.mjs.map +1 -0
  17. package/dist/configure/index.d.mts +4 -4
  18. package/dist/configure/index.mjs +54 -6
  19. package/dist/configure/index.mjs.map +1 -1
  20. package/dist/{crashreport-CKJwnWsX.mjs → crashreport-CvmdFs4i.mjs} +5 -5
  21. package/dist/crashreport-CvmdFs4i.mjs.map +1 -0
  22. package/dist/{crashreport-B8lVOx0U.mjs → crashreport-DHJuSmUc.mjs} +1 -1
  23. package/dist/enum-constants-C3KSpsYj.mjs.map +1 -1
  24. package/dist/{errors-wNQxQQBH.mjs → errors-pMPXghkO.mjs} +1 -1
  25. package/dist/{errors-wNQxQQBH.mjs.map → errors-pMPXghkO.mjs.map} +1 -1
  26. package/dist/{field-BY2vbJ8f.mjs → field-DLSIuMTu.mjs} +1 -1
  27. package/dist/{field-BY2vbJ8f.mjs.map → field-DLSIuMTu.mjs.map} +1 -1
  28. package/dist/file-utils-DjNi_3U_.mjs.map +1 -1
  29. package/dist/index-BQ4oi0AI.d.mts +48 -0
  30. package/dist/{index-BbOTbZFf.d.mts → index-BjXN1SdY.d.mts} +2 -2
  31. package/dist/{index-BoU_52Du.d.mts → index-C--7W0UO.d.mts} +8 -16
  32. package/dist/{index-BRvNi5q9.d.mts → index-VJW98BSy.d.mts} +2 -2
  33. package/dist/{index-iy-hNfGp.d.mts → index-nV4ZC_Ve.d.mts} +2 -2
  34. package/dist/{interceptor-CBsqEWDK.mjs → interceptor-DTNS0EtF.mjs} +1 -1
  35. package/dist/{interceptor-CBsqEWDK.mjs.map → interceptor-DTNS0EtF.mjs.map} +1 -1
  36. package/dist/{job-BOvKyNdT.mjs → job-M3Avv_SV.mjs} +5 -5
  37. package/dist/job-M3Avv_SV.mjs.map +1 -0
  38. package/dist/kysely/index.mjs.map +1 -1
  39. package/dist/kysely-type-B8aRz_oC.mjs.map +1 -1
  40. package/dist/logger-DTNAMYGy.mjs.map +1 -1
  41. package/dist/{mock-BP-9O5On.mjs → mock-BfL09ULZ.mjs} +1 -1
  42. package/dist/{mock-BP-9O5On.mjs.map → mock-BfL09ULZ.mjs.map} +1 -1
  43. package/dist/multiline-e3IpANmS.mjs.map +1 -1
  44. package/dist/package-json-6Px8bDpG.mjs.map +1 -1
  45. package/dist/plugin/builtin/enum-constants/index.d.mts +1 -1
  46. package/dist/plugin/builtin/file-utils/index.d.mts +1 -1
  47. package/dist/plugin/builtin/kysely-type/index.d.mts +1 -1
  48. package/dist/plugin/builtin/seed/index.d.mts +1 -1
  49. package/dist/plugin/builtin/seed/index.mjs +1 -1
  50. package/dist/plugin/index.d.mts +2 -2
  51. package/dist/plugin/index.mjs.map +1 -1
  52. package/dist/{repl-editor-CZpLlOBj.mjs → repl-editor-jZ493eQI.mjs} +1 -1
  53. package/dist/{repl-editor-CZpLlOBj.mjs.map → repl-editor-jZ493eQI.mjs.map} +1 -1
  54. package/dist/{runtime-DDYL2Zf1.mjs → runtime-CNg0w27y.mjs} +400 -126
  55. package/dist/runtime-CNg0w27y.mjs.map +1 -0
  56. package/dist/{tailordb-Bg9-TZj1.mjs → schema-C5QjYEc-.mjs} +4 -44
  57. package/dist/schema-C5QjYEc-.mjs.map +1 -0
  58. package/dist/secret-file-BHpxGyNf.mjs +65 -0
  59. package/dist/secret-file-BHpxGyNf.mjs.map +1 -0
  60. package/dist/seed/index.mjs.map +1 -1
  61. package/dist/{seed-DrKY5yIF.mjs → seed-DjfAn0BC.mjs} +44 -19
  62. package/dist/seed-DjfAn0BC.mjs.map +1 -0
  63. package/dist/{service-obEU5gSM.mjs → service-DCgJxdg1.mjs} +2 -2
  64. package/dist/{service-obEU5gSM.mjs.map → service-DCgJxdg1.mjs.map} +1 -1
  65. package/dist/{tailor-db-field-Bn8ZC5lK.d.mts → tailor-db-field-4bMLe25-.d.mts} +5 -1
  66. package/dist/telemetry-C13VIFpT.mjs +4 -0
  67. package/dist/{telemetry-DcL8Fsm_.mjs → telemetry-C1Y56L5E.mjs} +1 -1
  68. package/dist/{telemetry-DcL8Fsm_.mjs.map → telemetry-C1Y56L5E.mjs.map} +1 -1
  69. package/dist/types-DoIG6Nij.mjs +5 -0
  70. package/dist/{types-Duhhsx3R.mjs → types-sir9UPht.mjs} +2 -2
  71. package/dist/{types-Duhhsx3R.mjs.map → types-sir9UPht.mjs.map} +1 -1
  72. package/dist/utils/test/index.d.mts +3 -3
  73. package/dist/utils/test/index.mjs +1 -1
  74. package/dist/utils/test/index.mjs.map +1 -1
  75. package/dist/vitest/environment.mjs +1 -1
  76. package/dist/vitest/environment.mjs.map +1 -1
  77. package/dist/vitest/index.mjs +1 -1
  78. package/dist/vitest/index.mjs.map +1 -1
  79. package/dist/vitest/setup.mjs +1 -1
  80. package/dist/vitest/setup.mjs.map +1 -1
  81. package/dist/{workflow.generated-i7PK4fg-.d.mts → workflow.generated-OYAu_6zX.d.mts} +12 -2
  82. package/docs/cli/application.md +4 -0
  83. package/docs/configuration.md +4 -0
  84. package/docs/generator/builtin.md +35 -4
  85. package/docs/services/workflow.md +0 -5
  86. package/package.json +15 -14
  87. package/postinstall.mjs +1 -1
  88. package/dist/application-CN9Htzup.mjs +0 -4
  89. package/dist/application-TasSqBTD.mjs.map +0 -1
  90. package/dist/client-COfsXV69.mjs +0 -16447
  91. package/dist/client-COfsXV69.mjs.map +0 -1
  92. package/dist/crashreport-CKJwnWsX.mjs.map +0 -1
  93. package/dist/index-BXyS7xKC.d.mts +0 -21
  94. package/dist/job-BOvKyNdT.mjs.map +0 -1
  95. package/dist/runtime-DDYL2Zf1.mjs.map +0 -1
  96. package/dist/seed-DrKY5yIF.mjs.map +0 -1
  97. package/dist/tailordb-Bg9-TZj1.mjs.map +0 -1
  98. package/dist/telemetry-21afNV9_.mjs +0 -4
  99. package/dist/types-BnphjkIJ.mjs +0 -5
package/CHANGELOG.md CHANGED
@@ -1,5 +1,96 @@
1
1
  # @tailor-platform/sdk
2
2
 
3
+ ## 1.48.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#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`.
8
+
9
+ The SDK now writes a generated `id: "<uuid>"` field into the
10
+ `defineConfig({...})` call on first `deploy`, and stamps every managed
11
+ resource with an `sdk-app-id` metadata label. Subsequent deploys identify
12
+ ownership by the stable id rather than by the app name, so renaming the
13
+ app (or any of its resources) cleanly removes the old resources before
14
+ creating the new ones. The id is a plain UUID; the SDK adds the
15
+ label-compatible `app-` prefix internally at the metadata boundary.
16
+
17
+ Deleting the `id` field regenerates a new UUID on the next `deploy` —
18
+ typically done after copying `tailor.config.ts` from another project so
19
+ the new application does not share the original's id. Existing
20
+ resources keep their data and are re-tagged in place; `deploy` shows a
21
+ dedicated confirmation prompt for this case ("Application id was
22
+ regenerated for ..."), separate from the rename/transfer confirmation.
23
+
24
+ If your `tailor.config.ts` is a wrapper that re-exports `defineConfig` from
25
+ another file, the SDK skips id injection on the wrapper — add the `id`
26
+ field manually to the file that contains the actual `defineConfig({...})`
27
+ call. Existing deployments without the id continue to work and migrate
28
+ transparently on the next `deploy` run.
29
+
30
+ - [#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
31
+ `_User <-> userProfile` foreign keys emitted into the generated seed schema.
32
+
33
+ The seed plugin emits two foreign keys when `auth.userProfile` is configured
34
+ so that `validate` rejects rows on either side that lack a matching
35
+ counterpart:
36
+
37
+ - `_User.name → <userProfile>.<usernameField>` (`idpToUser`)
38
+ - `<userProfile>.<usernameField> → _User.name` (`userToIdp`)
39
+
40
+ Both are emitted by default, matching the previous behavior. Neither
41
+ direction is enforced by the runtime, so it can be useful to relax one when
42
+ seeding asymmetric production-like states such as
43
+ invited-but-not-registered users.
44
+
45
+ ```ts
46
+ // Allow seeding invited userProfile rows without a _User row
47
+ seedPlugin({
48
+ distPath: "./seed",
49
+ disableIdpUserSync: { userToIdp: true },
50
+ }),
51
+
52
+ // Allow seeding _User rows whose userProfile row does not exist yet
53
+ seedPlugin({
54
+ distPath: "./seed",
55
+ disableIdpUserSync: { idpToUser: true },
56
+ }),
57
+ ```
58
+
59
+ ### Patch Changes
60
+
61
+ - [#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:
62
+
63
+ - 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.
64
+ - 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.
65
+ - 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.
66
+
67
+ No public API surface changes.
68
+
69
+ - [#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
70
+
71
+ - [#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.
72
+
73
+ **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:
74
+
75
+ ```sh
76
+ chmod 700 ~/.config/tailor-platform
77
+ chmod 600 ~/.config/tailor-platform/config.yaml
78
+ ```
79
+
80
+ POSIX-only; on Windows the mode bits are best-effort and ACLs continue to govern access.
81
+
82
+ ## 1.47.1
83
+
84
+ ### Patch Changes
85
+
86
+ - [#1176](https://github.com/tailor-platform/sdk/pull/1176) [`5abed20`](https://github.com/tailor-platform/sdk/commit/5abed20dff48e24f23675989143e33c8afb23845) Thanks [@toiroakr](https://github.com/toiroakr)! - Declare `undici` as a direct dependency. The SDK CLI imports `getGlobalDispatcher` from `undici`, but the package was previously available only through accidental hoisting of a transitive dependency. Strict node_modules layouts (e.g. pnpm 11 with stricter hoisting) would fail to resolve the import; declaring it directly fixes that.
87
+
88
+ - [#1172](https://github.com/tailor-platform/sdk/pull/1172) [`7f37a07`](https://github.com/tailor-platform/sdk/commit/7f37a076a281fdca03d2301e1dba95668b2f7222) Thanks [@toiroakr](https://github.com/toiroakr)! - Widen `TailorEnv` fallback to `Record<string, string | number | boolean>` so it matches the values the type generator emits (string literal / number / boolean). Previously the fallback was `Record<string, string>`, which rejected number and boolean env values until `tailor.d.ts` was generated.
89
+
90
+ - [#1161](https://github.com/tailor-platform/sdk/pull/1161) [`3e835c5`](https://github.com/tailor-platform/sdk/commit/3e835c55e27fbfedff94a169d1c2fb3c4f50e0a3) Thanks [@renovate](https://github.com/apps/renovate)! - fix(deps): update rolldown
91
+
92
+ - [#1165](https://github.com/tailor-platform/sdk/pull/1165) [`f4ff7bd`](https://github.com/tailor-platform/sdk/commit/f4ff7bd5318be0a1142a557c76a17896d9df193a) Thanks [@toiroakr](https://github.com/toiroakr)! - Fix a type/runtime mismatch where calling `workflowJob.trigger()` without `await` returned a raw value at runtime even though the static type is `Promise<Awaited<Output>>`. The bundler now wraps `.trigger()` in an async IIFE (`(async () => tailor.workflow.triggerJobFunction("...", args))()`), so the returned value is always a `Promise` (including for `.then()` chains), synchronous throws from the platform surface as Promise rejections, and the platform's synchronous suspend semantics are preserved (the call site runs to completion before subsequent statements).
93
+
3
94
  ## 1.47.0
4
95
 
5
96
  ### Minor Changes
@@ -1,10 +1,10 @@
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 {}
6
6
  /** Represents environment variables in the Tailor platform. */
7
- type TailorEnv = keyof Env extends never ? Record<string, string> : Env;
7
+ type TailorEnv = keyof Env extends never ? Record<string, string | number | boolean> : Env;
8
8
  //#endregion
9
9
  //#region src/types/actor.d.ts
10
10
  /** User type enum values from the Tailor Platform server. */
@@ -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-DhXSqWTW.d.mts.map
30
+ //# sourceMappingURL=actor-BeIEiPYM.d.mts.map
@@ -0,0 +1,4 @@
1
+
2
+ import { n as generatePluginFilesIfNeeded, r as loadApplication, t as defineApplication } from "./application-DUENhx4Y.mjs";
3
+
4
+ export { defineApplication };
@@ -1,13 +1,14 @@
1
1
 
2
- import { u as initOAuth2Client } from "./client-COfsXV69.mjs";
3
- import { n as isSdkBranded } from "./brand-Ll48SMXe.mjs";
2
+ import { n as isSdkBranded } from "./brand-D-d15jx3.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";
@@ -20,14 +21,50 @@ import { parseTOML, parseYAML, stringifyYAML } from "confbox";
20
21
  import { findUpSync } from "find-up-simple";
21
22
  import { lt } from "semver";
22
23
  import { xdgConfig } from "xdg-basedir";
23
- import * as crypto from "node:crypto";
24
24
  import { resolveTSConfig } from "pkg-types";
25
+ import * as crypto from "node:crypto";
25
26
  import * as rolldown from "rolldown";
26
27
  import * as fs from "node:fs/promises";
27
28
  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() })]);
@@ -248,6 +289,7 @@ async function readPlatformConfig() {
248
289
  return migrateV1ToV2(v1Config);
249
290
  }
250
291
  const rawConfig = parseYAML(fs$1.readFileSync(configPath, "utf-8"));
292
+ tightenSecretFilePermissions(configPath);
251
293
  const version = rawConfig != null && typeof rawConfig === "object" && "version" in rawConfig ? rawConfig.version : void 0;
252
294
  if (typeof version === "number" && version > LATEST_CONFIG_VERSION) {
253
295
  const minSdk = "min_sdk_version" in rawConfig ? String(rawConfig.min_sdk_version) : void 0;
@@ -295,13 +337,14 @@ function toV1ForDisk(config) {
295
337
  * Write Tailor Platform CLI configuration to disk.
296
338
  * By default, V2 configs are converted to V1 for backward compatibility.
297
339
  * Set TAILOR_USE_KEYRING to write V2 format (required for keyring storage).
340
+ *
341
+ * The config file may contain access/refresh tokens when the OS keyring is
342
+ * unavailable, so it is written via {@link writeSecretFile} so other users
343
+ * on the host cannot read it.
298
344
  * @param config - Platform configuration to write
299
345
  */
300
346
  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));
347
+ writeSecretFile(platformConfigPath(), stringifyYAML(config.version === 2 && !process.env.TAILOR_USE_KEYRING ? toV1ForDisk(config) : config));
305
348
  }
306
349
  const tcContextConfigSchema = z.object({
307
350
  username: z.string().optional(),
@@ -508,14 +551,27 @@ function loadConfigPath(configPath) {
508
551
 
509
552
  //#endregion
510
553
  //#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
- } };
554
+ /**
555
+ * Install a stub `globalThis.tailordb` so that user code loaded by the CLI
556
+ * (e.g. via `createGetDB` in `@tailor-platform/sdk/kysely`) can reference
557
+ * `tailordb.Client` without hitting a `ReferenceError`. The CLI never
558
+ * actually executes the user code paths that issue queries, so a no-op
559
+ * client suffices.
560
+ *
561
+ * Exposed as a function (rather than a top-level statement) so that
562
+ * `package.json#sideEffects` can keep the file marked side-effect-free
563
+ * without bundlers eliminating the install step.
564
+ */
565
+ function installCliTailordbStub() {
566
+ globalThis.tailordb = { Client: class {
567
+ constructor(_config) {}
568
+ async connect() {}
569
+ async end() {}
570
+ async queryObject() {
571
+ return {};
572
+ }
573
+ } };
574
+ }
519
575
 
520
576
  //#endregion
521
577
  //#region src/cli/shared/config-loader.ts
@@ -526,12 +582,18 @@ const GeneratorConfigSchema = CodeGeneratorSchema.brand("CodeGenerator");
526
582
  * @returns Loaded config, generators, plugins, and config path
527
583
  */
528
584
  async function loadConfig(configPath) {
585
+ installCliTailordbStub();
529
586
  const foundPath = loadConfigPath(configPath);
530
587
  if (!foundPath) throw new Error("Configuration file not found: tailor.config.ts not found in current or parent directories");
531
588
  const resolvedPath = path.resolve(process.cwd(), foundPath);
532
589
  if (!fs$1.existsSync(resolvedPath)) throw new Error(`Configuration file not found: ${configPath}`);
533
590
  const configModule = await import(pathToFileURL(resolvedPath).href);
534
591
  if (!configModule || !configModule.default) throw new Error("Invalid Tailor config module: default export not found");
592
+ const validated = AppConfigSchema.safeParse(configModule.default);
593
+ if (!validated.success) {
594
+ const issues = validated.error.issues.map((i) => ` - ${i.path.join(".") || "(root)"}: ${i.message}`).join("\n");
595
+ throw new Error(`Invalid Tailor config in ${resolvedPath}:\n${issues}`);
596
+ }
535
597
  const allGenerators = [];
536
598
  const allPlugins = [];
537
599
  for (const value of Object.values(configModule)) if (Array.isArray(value)) {
@@ -1601,7 +1663,7 @@ function buildJobNameMap(jobs) {
1601
1663
  */
1602
1664
  function detectTriggerCalls(program, sourceText) {
1603
1665
  const calls = [];
1604
- function walk(node, parent = null) {
1666
+ function walk(node) {
1605
1667
  if (!node || typeof node !== "object") return;
1606
1668
  if (node.type === "CallExpression") {
1607
1669
  const callExpr = node;
@@ -1613,33 +1675,23 @@ function detectTriggerCalls(program, sourceText) {
1613
1675
  let argsText = "";
1614
1676
  if (callExpr.arguments.length > 0) {
1615
1677
  const firstArg = callExpr.arguments[0];
1616
- const lastArg = callExpr.arguments[callExpr.arguments.length - 1];
1617
- if (firstArg && lastArg && "start" in firstArg && "end" in lastArg) argsText = sourceText.slice(firstArg.start, lastArg.end);
1678
+ if (firstArg && "start" in firstArg && "end" in firstArg) argsText = sourceText.slice(firstArg.start, firstArg.end);
1618
1679
  }
1619
- const hasAwait = parent?.type === "AwaitExpression";
1620
- const awaitExpr = hasAwait ? parent : null;
1621
- const callRange = {
1622
- start: callExpr.start,
1623
- end: callExpr.end
1624
- };
1625
- const fullRange = awaitExpr ? {
1626
- start: awaitExpr.start,
1627
- end: awaitExpr.end
1628
- } : callRange;
1629
1680
  calls.push({
1630
1681
  identifierName,
1631
- callRange,
1632
- argsText,
1633
- hasAwait,
1634
- fullRange
1682
+ callRange: {
1683
+ start: callExpr.start,
1684
+ end: callExpr.end
1685
+ },
1686
+ argsText
1635
1687
  });
1636
1688
  }
1637
1689
  }
1638
1690
  }
1639
1691
  for (const key of Object.keys(node)) {
1640
1692
  const child = node[key];
1641
- if (Array.isArray(child)) child.forEach((c) => walk(c, node));
1642
- else if (child && typeof child === "object") walk(child, node);
1693
+ if (Array.isArray(child)) child.forEach((c) => walk(c));
1694
+ else if (child && typeof child === "object") walk(child);
1643
1695
  }
1644
1696
  }
1645
1697
  walk(program);
@@ -1906,7 +1958,7 @@ function findDefaultImportRemovalRange(program, localName, source) {
1906
1958
  */
1907
1959
  function detectExtendedTriggerCalls(program, sourceText, workflowNames, jobNames) {
1908
1960
  const calls = [];
1909
- function walk(node, parent = null) {
1961
+ function walk(node) {
1910
1962
  if (!node || typeof node !== "object") return;
1911
1963
  if (node.type === "CallExpression") {
1912
1964
  const callExpr = node;
@@ -1918,50 +1970,43 @@ function detectExtendedTriggerCalls(program, sourceText, workflowNames, jobNames
1918
1970
  if (identifierName && propertyName === "trigger") {
1919
1971
  const isWorkflow = workflowNames.has(identifierName);
1920
1972
  const isJob = jobNames.has(identifierName);
1921
- if (!isWorkflow && !isJob) return;
1922
- const argCount = callExpr.arguments.length;
1923
- let argsText = "";
1924
- if (argCount > 0) {
1925
- const firstArg = callExpr.arguments[0];
1926
- if (firstArg && "start" in firstArg && "end" in firstArg) argsText = sourceText.slice(firstArg.start, firstArg.end);
1927
- }
1928
- const hasAwait = parent?.type === "AwaitExpression";
1929
- const awaitExpr = hasAwait ? parent : null;
1930
- if (isWorkflow && argCount >= 2) {
1931
- const secondArg = callExpr.arguments[1];
1932
- const authInvoker = extractAuthInvokerInfo(secondArg, sourceText);
1933
- if (authInvoker) calls.push({
1934
- kind: "workflow",
1973
+ if (isWorkflow || isJob) {
1974
+ const argCount = callExpr.arguments.length;
1975
+ let argsText = "";
1976
+ if (argCount > 0) {
1977
+ const firstArg = callExpr.arguments[0];
1978
+ if (firstArg && "start" in firstArg && "end" in firstArg) argsText = sourceText.slice(firstArg.start, firstArg.end);
1979
+ }
1980
+ if (isWorkflow && argCount >= 2) {
1981
+ const secondArg = callExpr.arguments[1];
1982
+ const authInvoker = extractAuthInvokerInfo(secondArg, sourceText);
1983
+ if (authInvoker) calls.push({
1984
+ kind: "workflow",
1985
+ identifierName,
1986
+ callRange: {
1987
+ start: callExpr.start,
1988
+ end: callExpr.end
1989
+ },
1990
+ argsText,
1991
+ authInvoker
1992
+ });
1993
+ } else if (isJob) calls.push({
1994
+ kind: "job",
1935
1995
  identifierName,
1936
1996
  callRange: {
1937
1997
  start: callExpr.start,
1938
1998
  end: callExpr.end
1939
1999
  },
1940
- argsText,
1941
- authInvoker,
1942
- hasAwait: false
2000
+ argsText
1943
2001
  });
1944
- } else if (isJob) calls.push({
1945
- kind: "job",
1946
- identifierName,
1947
- callRange: {
1948
- start: callExpr.start,
1949
- end: callExpr.end
1950
- },
1951
- argsText,
1952
- hasAwait,
1953
- fullRange: awaitExpr ? {
1954
- start: awaitExpr.start,
1955
- end: awaitExpr.end
1956
- } : void 0
1957
- });
2002
+ }
1958
2003
  }
1959
2004
  }
1960
2005
  }
1961
2006
  for (const key of Object.keys(node)) {
1962
2007
  const child = node[key];
1963
- if (Array.isArray(child)) child.forEach((c) => walk(c, node));
1964
- else if (child && typeof child === "object") walk(child, node);
2008
+ if (Array.isArray(child)) child.forEach((c) => walk(c));
2009
+ else if (child && typeof child === "object") walk(child);
1965
2010
  }
1966
2011
  }
1967
2012
  walk(program);
@@ -2019,11 +2064,10 @@ function transformFunctionTriggers(source, workflowNameMap, jobNameMap, workflow
2019
2064
  } else if (call.kind === "job") {
2020
2065
  const jobName = jobNameMap.get(call.identifierName);
2021
2066
  if (jobName) {
2022
- const transformedCall = `tailor.workflow.triggerJobFunction("${jobName}", ${call.argsText || "undefined"})`;
2023
- const range = call.hasAwait && call.fullRange ? call.fullRange : call.callRange;
2067
+ const transformedCall = `(async () => tailor.workflow.triggerJobFunction("${jobName}", ${call.argsText || "undefined"}))()`;
2024
2068
  replacements.push({
2025
- start: range.start,
2026
- end: range.end,
2069
+ start: call.callRange.start,
2070
+ end: call.callRange.end,
2027
2071
  text: transformedCall
2028
2072
  });
2029
2073
  transformedCallsPerIdentifier.set(call.identifierName, (transformedCallsPerIdentifier.get(call.identifierName) ?? 0) + 1);
@@ -4406,10 +4450,10 @@ function transformWorkflowSource(source, targetJobName, targetJobExportName, oth
4406
4450
  if (isInsideRemovedRange(call.callRange.start)) continue;
4407
4451
  const jobName = jobNameMap.get(call.identifierName);
4408
4452
  if (jobName) {
4409
- const transformedCall = `tailor.workflow.triggerJobFunction("${jobName}", ${call.argsText || "undefined"})`;
4453
+ const transformedCall = `(async () => tailor.workflow.triggerJobFunction("${jobName}", ${call.argsText || "undefined"}))()`;
4410
4454
  replacements.push({
4411
- start: call.fullRange.start,
4412
- end: call.fullRange.end,
4455
+ start: call.callRange.start,
4456
+ end: call.callRange.end,
4413
4457
  text: transformedCall
4414
4458
  });
4415
4459
  }
@@ -5147,6 +5191,7 @@ function defineServices(config, pluginManager) {
5147
5191
  function buildApplication(params) {
5148
5192
  const application = {
5149
5193
  name: params.config.name,
5194
+ id: params.config.id,
5150
5195
  config: params.config,
5151
5196
  subgraphs: [
5152
5197
  ...params.tailordbResult.subgraphs,
@@ -5298,5 +5343,5 @@ async function loadApplication(params) {
5298
5343
  }
5299
5344
 
5300
5345
  //#endregion
5301
- 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 };
5302
- //# sourceMappingURL=application-TasSqBTD.mjs.map
5346
+ 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 };
5347
+ //# sourceMappingURL=application-DUENhx4Y.mjs.map