@tailor-platform/sdk 1.76.2 → 1.78.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 (88) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/dist/{application-CqjCcZ2n.mjs → application-CUxVA7Fs.mjs} +8 -8
  3. package/dist/application-CUxVA7Fs.mjs.map +1 -0
  4. package/dist/application-Dp_-ioiP.mjs +3 -0
  5. package/dist/cli/commands/deploy/deploy.d.mts +8 -3
  6. package/dist/cli/commands/show.d.mts +9 -3
  7. package/dist/cli/commands/workspace/create.d.mts +3 -0
  8. package/dist/cli/commands/workspace/list.d.mts +1 -0
  9. package/dist/cli/commands/workspace/transform.d.mts +2 -0
  10. package/dist/cli/index.mjs +69 -22
  11. package/dist/cli/index.mjs.map +1 -1
  12. package/dist/cli/lib.d.mts +2 -2
  13. package/dist/cli/lib.mjs +2 -2
  14. package/dist/cli/lib.mjs.map +1 -1
  15. package/dist/cli/shared/workspace-name.d.mts +1 -0
  16. package/dist/cli/skills.mjs +1 -1
  17. package/dist/completion/zsh-worker.zsh +18 -1
  18. package/dist/configure/index.mjs +198 -4
  19. package/dist/configure/index.mjs.map +1 -1
  20. package/dist/configure/services/idp/index.d.mts +1 -4
  21. package/dist/{crashreport-DZDr-TvH.mjs → crashreport-BNWUM6Kf.mjs} +2 -2
  22. package/dist/{crashreport-DZDr-TvH.mjs.map → crashreport-BNWUM6Kf.mjs.map} +1 -1
  23. package/dist/{crashreport-np4-_DX2.mjs → crashreport-BafWvjjX.mjs} +1 -1
  24. package/dist/errors-DVFS0AZk.mjs +100 -0
  25. package/dist/errors-DVFS0AZk.mjs.map +1 -0
  26. package/dist/{globals-z6zYMjlr.mjs → globals-CvizbGLY.mjs} +2 -2
  27. package/dist/{globals-z6zYMjlr.mjs.map → globals-CvizbGLY.mjs.map} +1 -1
  28. package/dist/{logger-BEiZZ3qT.mjs → logger-BwS4ppwO.mjs} +3 -3
  29. package/dist/logger-BwS4ppwO.mjs.map +1 -0
  30. package/dist/{registry-CTgoVWc_.mjs → registry-CYBRvfaU.mjs} +2 -2
  31. package/dist/{registry-CTgoVWc_.mjs.map → registry-CYBRvfaU.mjs.map} +1 -1
  32. package/dist/{runtime-DlklyuHN.mjs → runtime-BD2vYJFT.mjs} +1169 -539
  33. package/dist/runtime-BD2vYJFT.mjs.map +1 -0
  34. package/dist/{schema-DbTR1c6M.mjs → schema-U6DxoZ8D.mjs} +203 -3
  35. package/dist/schema-U6DxoZ8D.mjs.map +1 -0
  36. package/dist/{secretmanager-Bd45j7an.mjs → secretmanager-IY4UvinW.mjs} +42 -9
  37. package/dist/secretmanager-IY4UvinW.mjs.map +1 -0
  38. package/dist/service-CghpdV-9.mjs +3 -0
  39. package/dist/{service-DBFZQloR.mjs → service-Cp0I7ZFe.mjs} +3 -3
  40. package/dist/{service-DBFZQloR.mjs.map → service-Cp0I7ZFe.mjs.map} +1 -1
  41. package/dist/{service-BCRJ-3NV.mjs → service-D12iQGcS.mjs} +2 -2
  42. package/dist/{service-BCRJ-3NV.mjs.map → service-D12iQGcS.mjs.map} +1 -1
  43. package/dist/{test-env-key-IPapa1KJ.mjs → test-env-key-DuZycyWM.mjs} +2 -2
  44. package/dist/{test-env-key-IPapa1KJ.mjs.map → test-env-key-DuZycyWM.mjs.map} +1 -1
  45. package/dist/types/auth.generated.d.mts +9 -36
  46. package/dist/types/executor.generated.d.mts +19 -59
  47. package/dist/types/idp.generated.d.mts +518 -517
  48. package/dist/types/resolver.generated.d.mts +6 -2
  49. package/dist/types/tailordb.generated.d.mts +8 -7
  50. package/dist/utils/test/index.mjs +1 -1
  51. package/dist/vitest/environment.mjs +1 -1
  52. package/dist/vitest/index.d.mts +8 -8
  53. package/dist/vitest/index.mjs +600 -186
  54. package/dist/vitest/index.mjs.map +1 -1
  55. package/dist/vitest/mock.d.mts +8 -8
  56. package/dist/vitest/mocks/aigateway.d.mts +14 -4
  57. package/dist/vitest/mocks/authconnection.d.mts +14 -4
  58. package/dist/vitest/mocks/file.d.mts +24 -6
  59. package/dist/vitest/mocks/iconv.d.mts +28 -4
  60. package/dist/vitest/mocks/idp.d.mts +25 -9
  61. package/dist/vitest/mocks/secretmanager.d.mts +13 -4
  62. package/dist/vitest/mocks/tailordb.d.mts +48 -7
  63. package/dist/vitest/mocks/workflow.d.mts +41 -9
  64. package/dist/vitest/setup.mjs +2 -2
  65. package/docs/cli/application.md +58 -11
  66. package/docs/cli/setup.md +1 -1
  67. package/docs/cli/workspace.md +6 -4
  68. package/docs/cli-reference.md +12 -8
  69. package/docs/runtime.md +3 -4
  70. package/docs/services/aigateway.md +2 -0
  71. package/docs/services/tailordb.md +42 -0
  72. package/docs/services/workflow.md +1 -1
  73. package/docs/testing.md +103 -89
  74. package/package.json +7 -7
  75. package/dist/application-6zsDLGKv.mjs +0 -3
  76. package/dist/application-CqjCcZ2n.mjs.map +0 -1
  77. package/dist/errors-Dtf2WPaW.mjs +0 -42
  78. package/dist/errors-Dtf2WPaW.mjs.map +0 -1
  79. package/dist/field-runtime-D4QWRiB1.mjs +0 -203
  80. package/dist/field-runtime-D4QWRiB1.mjs.map +0 -1
  81. package/dist/logger-BEiZZ3qT.mjs.map +0 -1
  82. package/dist/runtime-DlklyuHN.mjs.map +0 -1
  83. package/dist/schema-DbTR1c6M.mjs.map +0 -1
  84. package/dist/secretmanager-Bd45j7an.mjs.map +0 -1
  85. package/dist/service-CPMlIg3X.mjs +0 -3
  86. package/dist/types-BzJ7A_fn.mjs +0 -199
  87. package/dist/types-BzJ7A_fn.mjs.map +0 -1
  88. package/dist/types-CG9H7HuE.mjs +0 -4
@@ -0,0 +1,3 @@
1
+ import { n as generatePluginFilesIfNeeded, r as loadApplication, t as defineApplication } from "./application-CUxVA7Fs.mjs";
2
+
3
+ export { defineApplication, generatePluginFilesIfNeeded };
@@ -15,12 +15,17 @@ interface DeployOptions {
15
15
  noValidate?: boolean;
16
16
  noCache?: boolean;
17
17
  cleanCache?: boolean;
18
+ createWorkspace?: boolean;
19
+ workspaceName?: string;
20
+ workspaceRegion?: string;
21
+ organizationId?: string;
22
+ folderId?: string;
18
23
  buildOnly?: boolean;
19
24
  }
20
25
  /**
21
- * Deploy the configured application to the Tailor platform.
22
- * @param options - Options for deploy execution
23
- * @returns Promise that resolves to `{ bundledScripts }` when `buildOnly` is true, otherwise void
26
+ * Deploy using the programmatic CLI API.
27
+ * @param options - Deploy execution options
28
+ * @returns Deploy result
24
29
  */
25
30
  declare function deploy(options?: DeployOptions): Promise<{
26
31
  bundledScripts: BundledScripts;
@@ -22,12 +22,18 @@ interface ApplicationInfo {
22
22
  createdAt: Date | null;
23
23
  updatedAt: Date | null;
24
24
  }
25
- interface ShowInfo extends ApplicationInfo, WorkspaceInfo {}
25
+ interface AIGatewayInfo {
26
+ name: string;
27
+ url: string;
28
+ }
29
+ interface ShowInfo extends ApplicationInfo, WorkspaceInfo {
30
+ aiGateways: AIGatewayInfo[];
31
+ }
26
32
  /**
27
33
  * Show applied application information for the current workspace.
28
34
  * @param options - Show options
29
- * @returns Application information
35
+ * @returns Deployed application, workspace, and AI Gateway information
30
36
  */
31
37
  declare function show(options?: ShowOptions): Promise<ShowInfo>;
32
38
  //#endregion
33
- export { ApplicationInfo, ShowInfo, ShowOptions, WorkspaceInfo, show };
39
+ export { AIGatewayInfo, ApplicationInfo, ShowInfo, ShowOptions, WorkspaceInfo, show };
@@ -1,4 +1,6 @@
1
+ import "../../shared/client.mjs";
1
2
  import { WorkspaceInfo } from "./transform.mjs";
3
+ import "../../shared/workspace-name.mjs";
2
4
  import { z } from "zod";
3
5
  //#region src/cli/commands/workspace/create.d.ts
4
6
  /**
@@ -12,6 +14,7 @@ declare const createWorkspaceOptionsSchema: z.ZodObject<{
12
14
  deleteProtection: z.ZodOptional<z.ZodBoolean>;
13
15
  organizationId: z.ZodOptional<z.ZodUUID>;
14
16
  folderId: z.ZodOptional<z.ZodUUID>;
17
+ profile: z.ZodOptional<z.ZodString>;
15
18
  }, z.core.$strip>;
16
19
  type CreateWorkspaceOptions = z.input<typeof createWorkspaceOptionsSchema>;
17
20
  /**
@@ -5,6 +5,7 @@ import { z } from "zod";
5
5
  interface ListWorkspacesOptions {
6
6
  order?: Order;
7
7
  limit?: number;
8
+ profile?: string;
8
9
  }
9
10
  /**
10
11
  * List workspaces with an optional order and limit.
@@ -5,6 +5,8 @@ interface WorkspaceInfo {
5
5
  id: string;
6
6
  name: string;
7
7
  folderName?: string;
8
+ organizationId?: string;
9
+ folderId?: string;
8
10
  region: string;
9
11
  createdAt: Date | null;
10
12
  updatedAt: Date | null;
@@ -1,17 +1,17 @@
1
1
  #!/usr/bin/env node
2
2
  import { St as AuthInvokerSchema, T as CustomDomainStatus, U as FunctionExecution_Type, kt as PATScope } from "../workspace_resource_pb-Db3fv68L.mjs";
3
3
  import { t as assertDefined } from "../assert-DBxo8jPo.mjs";
4
- import { n as logger, r as styles } from "../logger-BEiZZ3qT.mjs";
5
- import { $n as multiConfigArg, $t as compareSnapshotWithRemote, A as listCommand$13, An as apiCall, Bn as loadStoredUserTokens, C as listCommand$14, Cn as hasChanges, Dn as PluginManager, Dt as listCommand$7, E as waitCommand, En as sdkNameLabelKey, F as generateCommand$1, Fn as hasAnyUserTokenEntry, G as removeCommand$1, Gn as saveUserTokens, Gt as deploy, H as extractOwnedNamespaces, Hn as platformConfigFromProfile, Ht as formatKeyValueTable, I as generateMigrationScript, In as hasUserTokenEntry, It as getCommand$6, Jn as commonArgs, K as updateCommand$3, Kn as writePlatformConfig, Kt as ensureConfigId, L as writeDbTypesFile, Ln as loadAccessToken, Mn as loadConfig, N as truncateCommand, Nn as deleteUserTokens, O as resumeCommand, On as generateUserTypes, Pn as fetchLatestToken, Pt as startCommand, Q as getCommand$5, Qn as isVerbose, Qt as parseMigrationLabelNumber, R as getConfiguredEditorCommand, Rn as loadConsoleBaseUrl, Rt as executionsCommand, Sn as formatMigrationDiff, T as healthCommand, Tn as resourceTrn, Tt as triggerCommand, U as logBetaWarning, Un as readPlatformConfig, Ut as getCommand$1, V as showCommand, Vn as loadWorkspaceId, Vt as functionExecutionStatusToString, Wn as resolveUserTokenKey, X as listCommand$12, Xn as confirmationArgs, Xt as MIGRATION_LABEL_KEY, Y as treeCommand, Yn as configArg, Zn as deploymentArgs, Zt as handleOptionalToRequiredError, _n as loadDiff, b as createCommand$4, bn as parseMigrationNumberArg, c as listCommand$15, cn as compareLocalTypesWithSnapshot, ct as createCommand$3, dn as getLatestMigrationNumber, en as generateAllTypeManifestsFromSnapshot, er as pagedLogArgs, et as updateCommand$2, f as restoreCommand, ft as getCommand$3, g as getCommand$7, gn as isValidMigrationNumber, gt as listCommand$9, ht as tokenCommand, i as updateCommand$4, in as INITIAL_SCHEMA_NUMBER, ir as workspaceArgs, it as getCommand$4, jn as assertWritable, jt as jobsCommand, kn as prompt, m as listCommand$16, mn as getMigrationFiles, nr as resolveMachineUserInputSource, nt as listCommand$11, o as removeCommand, ot as deleteCommand$4, pn as getMigrationFilePath, qn as defineAppCommand, qt as executeScript, r as queryCommand, rr as toPageDirection, sn as assertValidMigrationFiles, t as isNativeTypeScriptRuntime, tn as protoGqlPermission, tr as paginationArgs, u as inviteCommand, un as createSnapshotFromLocalTypes, ut as listCommand$10, v as deleteCommand$5, vn as reconstructSnapshotFromMigrations, vt as generate, wn as getNamespacesWithMigrations, wt as webhookCommand, xt as getCommand$2, yn as formatMigrationNumber, yt as listCommand$8, z as openInConfiguredEditor, zn as loadMachineUserName } from "../runtime-DlklyuHN.mjs";
6
- import { A as fetchAllTolerant, B as initOperatorClient, D as closeConnectionPool, L as getOrNull, M as fetchPaged, N as fetchPlatformMachineUserToken, O as defaultPlatformBaseUrl, P as fetchUserInfo, T as hashContent$1, V as isDefaultPlatform, _ as platformBundleDefinePlugin, a as resolveInlineSourcemap, b as resolveBundleLogLevel, c as ResolverSchema, k as fetchAll, s as WorkflowJobSchema, t as defineApplication, u as INVOKER_EXPR, v as composeFunctionTreeshakeOptions, w as getDistDir, y as createLogLevelTreeshakeOptions, z as initOAuth2Client } from "../application-CqjCcZ2n.mjs";
7
- import { n as ExecutorSchema } from "../service-BCRJ-3NV.mjs";
4
+ import { n as logger, r as styles } from "../logger-BwS4ppwO.mjs";
5
+ import { $n as deploymentArgs, $t as handleOptionalToRequiredError, An as generateUserTypes, At as startCommand, Bn as loadConsoleBaseUrl, Ct as listCommand$7, Dn as resourceTrn, Dt as jobsCommand, E as listCommand$13, En as getNamespacesWithMigrations, F as openInConfiguredEditor, Fn as deleteUserTokens, G as treeCommand, Gn as readPlatformConfig, H as updateCommand$3, Hn as loadStoredUserTokens, Ht as listCommand$16, In as fetchLatestToken, J as getCommand$5, Jn as writePlatformConfig, Jt as ensureConfigId, K as listCommand$12, Kn as resolveUserTokenKey, Kt as formatKeyValueTable, L as showCommand, Ln as hasAnyUserTokenEntry, Lt as functionExecutionStatusToString, M as generateMigrationScript, Mn as apiCall, Mt as getCommand$6, N as writeDbTypesFile, Nn as assertWritable, On as sdkNameLabelKey, P as getConfiguredEditorCommand, Pn as loadConfig, Pt as executionsCommand, Q as listCommand$11, Qn as confirmationArgs, Qt as MIGRATION_LABEL_KEY, R as extractOwnedNamespaces, Rn as hasUserTokenEntry, Rt as getCommand$1, S as waitCommand, Sn as parseMigrationNumberArg, Tn as hasChanges, Un as loadWorkspaceId, V as removeCommand$1, Vn as loadMachineUserName, Vt as deployFromCLI, Wn as platformConfigFromProfile, Wt as createCommand$4, X as updateCommand$2, Xn as commonArgs, Yn as defineAppCommand, Yt as executeScript, Zn as configArg, _t as getCommand$2, ar as toPageDirection, bn as reconstructSnapshotFromMigrations, bt as webhookCommand, c as listCommand$15, ct as getCommand$3, dt as tokenCommand, en as parseMigrationLabelNumber, er as isVerbose, et as getCommand$4, f as restoreCommand, fn as createSnapshotFromLocalTypes, ft as listCommand$9, g as deleteCommand$5, gn as getMigrationFiles, hn as getMigrationFilePath, ht as listCommand$8, i as updateCommand$4, ir as resolveMachineUserInputSource, it as createCommand$3, j as generateCommand$1, jn as prompt, k as truncateCommand, kn as PluginManager, ln as assertValidMigrationFiles, m as getCommand$7, mt as generate, nn as generateAllTypeManifestsFromSnapshot, nr as pagedLogArgs, nt as deleteCommand$4, o as removeCommand, on as INITIAL_SCHEMA_NUMBER, or as workspaceArgs, ot as listCommand$10, pn as getLatestMigrationNumber, qn as saveUserTokens, qt as workspaceNameSchema, r as queryCommand, rn as protoGqlPermission, rr as paginationArgs, t as isNativeTypeScriptRuntime, tn as compareSnapshotWithRemote, tr as multiConfigArg, u as inviteCommand, un as compareLocalTypesWithSnapshot, vn as isValidMigrationNumber, w as resumeCommand, wn as formatMigrationDiff, x as healthCommand, xn as formatMigrationNumber, xt as triggerCommand, y as listCommand$14, yn as loadDiff, z as logBetaWarning, zn as loadAccessToken } from "../runtime-BD2vYJFT.mjs";
6
+ import { A as fetchAllTolerant, B as initOperatorClient, D as closeConnectionPool, L as getOrNull, M as fetchPaged, N as fetchPlatformMachineUserToken, O as defaultPlatformBaseUrl, P as fetchUserInfo, T as hashContent$1, V as isDefaultPlatform, _ as platformBundleDefinePlugin, a as resolveInlineSourcemap, b as resolveBundleLogLevel, c as ResolverSchema, k as fetchAll, s as WorkflowJobSchema, t as defineApplication, u as INVOKER_EXPR, v as composeFunctionTreeshakeOptions, w as getDistDir, y as createLogLevelTreeshakeOptions, z as initOAuth2Client } from "../application-CUxVA7Fs.mjs";
7
+ import { n as ExecutorSchema } from "../service-D12iQGcS.mjs";
8
8
  import { t as multiline } from "../multiline-sfHpTZZK.mjs";
9
9
  import { t as isPluginGeneratedType } from "../type-source-DH_LH20p.mjs";
10
10
  import { t as readPackageJson } from "../package-json-8b0O9TlX.mjs";
11
11
  import { t as userAgent } from "../user-agent-DX2Jnw0-.mjs";
12
- import { n as isCLIError, t as createCLIError } from "../errors-Dtf2WPaW.mjs";
12
+ import { n as errorToJson, r as isCLIError, t as createCLIError } from "../errors-DVFS0AZk.mjs";
13
13
  import { t as OperatorService } from "../service_pb-BoLM0X4K.mjs";
14
- import { a as JSON_FOOTER_MARKER, i as CRASH_LOG_EXTENSION, o as parseCrashReportConfig, r as sendCrashReport, t as initCrashReporting } from "../crashreport-DZDr-TvH.mjs";
14
+ import { a as JSON_FOOTER_MARKER, i as CRASH_LOG_EXTENSION, o as parseCrashReportConfig, r as sendCrashReport, t as initCrashReporting } from "../crashreport-BNWUM6Kf.mjs";
15
15
  import { arg, defineCommand, runCommand, runMain } from "politty";
16
16
  import { withCompletionCommand } from "politty/completion";
17
17
  import { z } from "zod";
@@ -1023,6 +1023,35 @@ const crashReportCommand = defineCommand({
1023
1023
  }
1024
1024
  });
1025
1025
 
1026
+ //#endregion
1027
+ //#region src/parser/service/resolver/local-input-parser.ts
1028
+ /**
1029
+ * Build a local, in-process validator for a resolver's declared input fields.
1030
+ * Each field already carries its own bound `_parseInternal` (attached when the
1031
+ * user's resolver module was loaded via dynamic import), so this only needs to
1032
+ * orchestrate calling every field and collecting issues.
1033
+ * @param fields - Resolver's raw input field definitions (already-built TailorField instances)
1034
+ * @returns An object exposing a `.parse()` method for local format detection
1035
+ */
1036
+ function buildLocalInputParser(fields) {
1037
+ return { parse(args) {
1038
+ const { value, data, user } = args;
1039
+ if (typeof value !== "object" || value === null || Array.isArray(value) || value instanceof Date) return { issues: [{ message: `Expected an object: received ${String(value)}` }] };
1040
+ const record = value;
1041
+ const issues = [];
1042
+ for (const [name, field] of Object.entries(fields)) {
1043
+ const result = field._parseInternal({
1044
+ value: record[name],
1045
+ data,
1046
+ user,
1047
+ pathArray: [name]
1048
+ });
1049
+ if (result.issues) issues.push(...result.issues);
1050
+ }
1051
+ return issues.length > 0 ? { issues } : {};
1052
+ } };
1053
+ }
1054
+
1026
1055
  //#endregion
1027
1056
  //#region src/cli/commands/deploy/index.ts
1028
1057
  const deployCommand$1 = defineAppCommand({
@@ -1033,6 +1062,17 @@ const deployCommand$1 = defineAppCommand({
1033
1062
  ...workspaceArgs,
1034
1063
  ...multiConfigArg,
1035
1064
  ...confirmationArgs,
1065
+ "create-workspace": arg(z.boolean().optional(), { description: "Create a workspace when the account has none" }),
1066
+ "workspace-name": arg(z.string().optional(), { description: "Name for a workspace created during deploy" }),
1067
+ "workspace-region": arg(z.string().optional(), { description: "Region for a workspace created during deploy" }),
1068
+ "organization-id": arg(z.string().optional(), {
1069
+ description: "Organization ID for a workspace created during deploy",
1070
+ env: "TAILOR_PLATFORM_ORGANIZATION_ID"
1071
+ }),
1072
+ "folder-id": arg(z.string().optional(), {
1073
+ description: "Folder ID for a workspace created during deploy",
1074
+ env: "TAILOR_PLATFORM_FOLDER_ID"
1075
+ }),
1036
1076
  "dry-run": arg(z.boolean().optional(), {
1037
1077
  alias: "d",
1038
1078
  description: "Run the command without making any changes"
@@ -1046,16 +1086,26 @@ const deployCommand$1 = defineAppCommand({
1046
1086
  await assertWritable({ profile: args.profile });
1047
1087
  const { initTelemetry } = await import("../telemetry-ClwW5ohF.mjs");
1048
1088
  await initTelemetry();
1049
- await deploy({
1089
+ await deployFromCLI({
1050
1090
  workspaceId: args["workspace-id"],
1051
1091
  profile: args.profile,
1052
1092
  configPath: args.config,
1053
1093
  dryRun: args["dry-run"],
1054
1094
  yes: args.yes,
1095
+ createWorkspace: args["create-workspace"],
1096
+ workspaceName: args["workspace-name"],
1097
+ workspaceRegion: args["workspace-region"],
1098
+ organizationId: args["organization-id"],
1099
+ folderId: args["folder-id"],
1055
1100
  noSchemaCheck: args["no-schema-check"],
1056
1101
  noValidate: args["no-validate"],
1057
1102
  noCache: args["no-cache"],
1058
1103
  cleanCache: args["clean-cache"]
1104
+ }, {
1105
+ envFile: args["env-file"],
1106
+ envFileIfExists: args["env-file-if-exists"],
1107
+ verbose: args.verbose,
1108
+ json: args.json
1059
1109
  });
1060
1110
  }
1061
1111
  });
@@ -1843,10 +1893,7 @@ async function detectFunctionType(options) {
1843
1893
  if (resolverResult.success) {
1844
1894
  const rawInput = module.default.input;
1845
1895
  let inputSchema;
1846
- if (rawInput) {
1847
- const { t } = await import("../types-CG9H7HuE.mjs");
1848
- inputSchema = t.object(rawInput);
1849
- }
1896
+ if (rawInput) inputSchema = buildLocalInputParser(rawInput);
1850
1897
  return {
1851
1898
  type: "resolver",
1852
1899
  name: resolverResult.data.name,
@@ -3436,7 +3483,7 @@ var action_default = "# __HEADER__\nname: __WORKSPACE_NAME__\ndescription: >-\n
3436
3483
 
3437
3484
  //#endregion
3438
3485
  //#region src/cli/commands/setup/branch.workflow.yml
3439
- var branch_workflow_default = "# __HEADER__\nname: Tailor (__WORKSPACE_NAME__)\n\non:\n # __PULL_REQUEST_START__\n pull_request:\n branches: [\"__BRANCH__\"]\n # __PATHS__\n # __PULL_REQUEST_END__\n push:\n branches: [\"__BRANCH__\"]\n # __PATHS__\n workflow_dispatch:\n # __DISPATCH_INPUTS_START__\n inputs:\n dry-run:\n description: Preview changes without deploying\n type: boolean\n default: false\n # __DISPATCH_INPUTS_END__\n\npermissions:\n contents: read\n\njobs:\n # __PLAN_JOB_START__\n tailor-plan:\n if: >-\n github.event_name == 'pull_request' ||\n (github.event_name == 'workflow_dispatch' && inputs['dry-run'])\n runs-on: ubuntu-latest\n timeout-minutes: 30\n environment: __ENVIRONMENT__\n permissions:\n contents: read\n pull-requests: write\n concurrency:\n group: tailor-plan-__WORKSPACE_NAME__-${{ github.event.pull_request.number || github.run_id }}\n cancel-in-progress: true\n steps:\n - id: tailor-checkout\n uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0\n - id: tailor-setup\n uses: tailor-platform/actions/setup@a3c3032e14277e81039eb26ae1a425adb22eb532 # v1.7.0\n with:\n package-manager: __PACKAGE_MANAGER__\n - id: tailor-install\n uses: tailor-platform/actions/install@a3c3032e14277e81039eb26ae1a425adb22eb532 # v1.7.0\n with:\n package-manager: __PACKAGE_MANAGER__\n - id: tailor-generate-check\n uses: tailor-platform/actions/generate-check@a3c3032e14277e81039eb26ae1a425adb22eb532 # v1.7.0\n with:\n package-manager: __PACKAGE_MANAGER__\n # __WORKING_DIRECTORY__\n # __SEED_VALIDATE_START__\n - id: tailor-seed-validate\n uses: tailor-platform/actions/seed-validate@a3c3032e14277e81039eb26ae1a425adb22eb532 # v1.7.0\n with:\n package-manager: __PACKAGE_MANAGER__\n # __WORKING_DIRECTORY__\n # __SEED_VALIDATE_END__\n - id: tailor-drift-check\n uses: tailor-platform/actions/drift-check@a3c3032e14277e81039eb26ae1a425adb22eb532 # v1.7.0\n with:\n package-manager: __PACKAGE_MANAGER__\n # __MIGRATION_DRIFT_CHECK_START__\n - id: tailor-migration-drift-check\n uses: tailor-platform/actions/migration-drift-check@a3c3032e14277e81039eb26ae1a425adb22eb532 # v1.7.0\n with:\n package-manager: __PACKAGE_MANAGER__\n # __WORKING_DIRECTORY__\n # __MIGRATION_DRIFT_CHECK_END__\n - id: tailor-plan\n # Fork PRs cannot read secrets; the checks above still run for them.\n if: github.event_name != 'pull_request' || !github.event.pull_request.head.repo.fork\n uses: tailor-platform/actions/plan@a3c3032e14277e81039eb26ae1a425adb22eb532 # v1.7.0\n with:\n workspace-id: ${{ vars.TAILOR_PLATFORM_WORKSPACE_ID }}\n package-manager: __PACKAGE_MANAGER__\n label: __WORKSPACE_NAME__\n # __WORKING_DIRECTORY__\n platform-client-id: ${{ secrets.TAILOR_PLATFORM_MACHINE_USER_CLIENT_ID }}\n platform-client-secret: ${{ secrets.TAILOR_PLATFORM_MACHINE_USER_CLIENT_SECRET }}\n github-token: ${{ secrets.GITHUB_TOKEN }}\n # __PLAN_JOB_END__\n # __ERD_PREVIEW_JOB_START__\n tailor-erd-preview-matrix:\n if: github.event_name == 'pull_request'\n runs-on: ubuntu-latest\n timeout-minutes: 5\n permissions:\n contents: read\n outputs:\n namespaces: ${{ steps.tailor-erd-preview-matrix.outputs.namespaces }}\n base-app-dir: ${{ steps.tailor-erd-preview-matrix.outputs['base-app-dir'] }}\n steps:\n - id: tailor-checkout\n uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0\n with:\n persist-credentials: false\n - id: tailor-checkout-base\n uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0\n with:\n repository: ${{ github.event.pull_request.base.repo.full_name }}\n ref: ${{ github.event.pull_request.base.sha }}\n path: .tailor-erd-base\n persist-credentials: false\n - id: tailor-erd-preview-matrix\n shell: bash\n env:\n APP_DIR: \"__APP_DIR__\"\n WORKSPACE_NAME: \"__WORKSPACE_NAME__\"\n run: |\n set -euo pipefail\n node <<'NODE'\n const fs = require(\"node:fs\");\n\n const appDir = process.env.APP_DIR || \".\";\n const workspaceName = process.env.WORKSPACE_NAME;\n const output = process.env.GITHUB_OUTPUT;\n const dirPattern = /^[A-Za-z0-9._/-]+$/;\n const namespacePattern = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;\n\n function lockTarget(file) {\n try {\n const lock = JSON.parse(fs.readFileSync(file, \"utf8\"));\n return lock.targets?.find(\n (candidate) =>\n candidate.kind === \"branch\" &&\n candidate.workspaceName === workspaceName,\n );\n } catch (error) {\n if (error && error.code === \"ENOENT\") return undefined;\n throw error;\n }\n }\n\n function namespacesFromTarget(target, label) {\n const namespaces =\n target?.inputs?.erdPreview === true && Array.isArray(target.inputs?.erdNamespaces)\n ? target.inputs.erdNamespaces\n : [];\n for (const namespace of namespaces) {\n if (typeof namespace !== \"string\" || !namespacePattern.test(namespace)) {\n throw new Error(`Invalid ERD namespace in ${label}: ${String(namespace)}`);\n }\n }\n return namespaces;\n }\n\n function normalizeDir(value, label) {\n const raw = typeof value === \"string\" && value.length > 0 ? value : appDir;\n const normalized =\n raw.replaceAll(\"\\\\\", \"/\").replace(/\\/{2,}/g, \"/\").replace(/^\\.\\//, \"\").replace(/\\/$/, \"\") ||\n \".\";\n if (\n !dirPattern.test(normalized) ||\n normalized.startsWith(\"/\") ||\n normalized.split(\"/\").includes(\"..\")\n ) {\n throw new Error(`Invalid ERD app dir in ${label}: ${raw}`);\n }\n return normalized;\n }\n\n const headTarget = lockTarget(\".github/tailor-sdk.lock\");\n const baseTarget = lockTarget(\".tailor-erd-base/.github/tailor-sdk.lock\");\n const baseAppDir = normalizeDir(baseTarget?.inputs?.dir, \"base setup lock\");\n const namespaces = [\n ...new Set([\n ...namespacesFromTarget(headTarget, \"head setup lock\"),\n ...namespacesFromTarget(baseTarget, \"base setup lock\"),\n ]),\n ].sort((a, b) => a.localeCompare(b));\n\n if (namespaces.length === 0) {\n console.error(\"No ERD preview namespaces found in the head or base setup lock.\");\n process.exit(1);\n }\n\n fs.appendFileSync(output, `namespaces=${JSON.stringify(namespaces)}\\n`);\n fs.appendFileSync(output, `base-app-dir=${baseAppDir}\\n`);\n NODE\n\n tailor-erd-preview:\n needs: tailor-erd-preview-matrix\n if: github.event_name == 'pull_request'\n runs-on: ubuntu-latest\n timeout-minutes: 15\n permissions:\n contents: read\n strategy:\n fail-fast: false\n matrix:\n namespace: ${{ fromJSON(needs.tailor-erd-preview-matrix.outputs.namespaces) }}\n steps:\n - id: tailor-checkout\n uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0\n with:\n persist-credentials: false\n - id: tailor-setup\n uses: tailor-platform/actions/setup@a3c3032e14277e81039eb26ae1a425adb22eb532 # v1.7.0\n with:\n package-manager: __PACKAGE_MANAGER__\n - id: tailor-checkout-base\n uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0\n with:\n repository: ${{ github.event.pull_request.base.repo.full_name }}\n ref: ${{ github.event.pull_request.base.sha }}\n path: .tailor-erd-base\n persist-credentials: false\n - id: tailor-detect-base-package-manager\n shell: bash\n run: |\n set -euo pipefail\n cd .tailor-erd-base\n base_package_manager=\"$(\n if [ -f pnpm-lock.yaml ]; then\n echo pnpm\n elif [ -f yarn.lock ]; then\n echo yarn\n elif [ -f bun.lockb ] || [ -f bun.lock ]; then\n echo bun\n elif [ -f package-lock.json ]; then\n echo npm\n else\n echo \"__PACKAGE_MANAGER__\"\n fi\n )\"\n echo \"package-manager=$base_package_manager\" >> \"$GITHUB_OUTPUT\"\n if [ \"$base_package_manager\" = \"pnpm\" ]; then\n base_pnpm_version=\"$(node <<'NODE'\n const fs = require(\"node:fs\");\n\n const fallback = \"10\";\n\n function readManifest(file) {\n try {\n return JSON.parse(fs.readFileSync(file, \"utf8\"));\n } catch {\n return {};\n }\n }\n\n function pnpmVersion(manifest) {\n const packageManager = manifest.packageManager;\n if (typeof packageManager === \"string\" && packageManager.startsWith(\"pnpm@\")) {\n return packageManager.slice(\"pnpm@\".length).split(\"+\")[0];\n }\n\n const devPackageManager = manifest.devEngines?.packageManager;\n if (devPackageManager?.name === \"pnpm\" && devPackageManager.version) {\n return devPackageManager.version;\n }\n\n return undefined;\n }\n\n process.stdout.write(\n pnpmVersion(readManifest(\"package.json\")) ?? fallback,\n );\n NODE\n )\"\n echo \"pnpm-version=$base_pnpm_version\" >> \"$GITHUB_OUTPUT\"\n fi\n - id: tailor-setup-base-pnpm\n if: steps.tailor-detect-base-package-manager.outputs['package-manager'] == 'pnpm'\n uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9\n with:\n version: ${{ steps.tailor-detect-base-package-manager.outputs['pnpm-version'] }}\n package_json_file: .tailor-erd-base/package.json\n run_install: false\n - id: tailor-setup-base-node\n if: steps.tailor-detect-base-package-manager.outputs['package-manager'] != 'bun'\n uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0\n with:\n node-version-file: .tailor-erd-base/package.json\n - id: tailor-setup-base-yarn\n if: steps.tailor-detect-base-package-manager.outputs['package-manager'] == 'yarn'\n shell: bash\n working-directory: .tailor-erd-base\n run: |\n set -euo pipefail\n corepack enable\n - id: tailor-setup-base-bun\n if: steps.tailor-detect-base-package-manager.outputs['package-manager'] == 'bun'\n uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0\n - id: tailor-install-base\n shell: bash\n working-directory: .tailor-erd-base\n env:\n BASE_PACKAGE_MANAGER: ${{ steps.tailor-detect-base-package-manager.outputs['package-manager'] }}\n run: |\n set -euo pipefail\n case \"$BASE_PACKAGE_MANAGER\" in\n pnpm) pnpm install --frozen-lockfile ;;\n npm) npm ci ;;\n yarn)\n if grep -q '^__metadata:' yarn.lock; then\n yarn install --immutable\n else\n yarn install --frozen-lockfile\n fi\n ;;\n bun) bun install --frozen-lockfile ;;\n *)\n echo \"::error::Unsupported base package-manager '$BASE_PACKAGE_MANAGER' (expected pnpm, npm, yarn, or bun)\"\n exit 1\n ;;\n esac\n - id: tailor-restore-head-setup\n uses: tailor-platform/actions/setup@a3c3032e14277e81039eb26ae1a425adb22eb532 # v1.7.0\n with:\n package-manager: __PACKAGE_MANAGER__\n - id: tailor-build-erd-preview\n shell: bash\n env:\n APP_DIR: \"__APP_DIR__\"\n BASE_APP_DIR: ${{ needs.tailor-erd-preview-matrix.outputs['base-app-dir'] }}\n BASE_PACKAGE_MANAGER: ${{ steps.tailor-detect-base-package-manager.outputs['package-manager'] }}\n NAMESPACE: ${{ matrix.namespace }}\n run: |\n set -euo pipefail\n\n run_tailor_sdk() {\n case \"__PACKAGE_MANAGER__\" in\n pnpm) pnpm exec tailor-sdk \"$@\" ;;\n npm) npx tailor-sdk \"$@\" ;;\n yarn) yarn tailor-sdk \"$@\" ;;\n bun) bunx tailor-sdk \"$@\" ;;\n *)\n echo \"::error::Unsupported package-manager '__PACKAGE_MANAGER__' (expected pnpm, npm, yarn, or bun)\"\n exit 1\n ;;\n esac\n }\n\n run_head_node() {\n case \"__PACKAGE_MANAGER__\" in\n pnpm) pnpm exec node \"$@\" ;;\n npm) node \"$@\" ;;\n yarn) yarn node \"$@\" ;;\n bun) node \"$@\" ;;\n *)\n echo \"::error::Unsupported package-manager '__PACKAGE_MANAGER__' (expected pnpm, npm, yarn, or bun)\"\n exit 1\n ;;\n esac\n }\n\n tailor_sdk_bin=\"$(\n run_head_node - <<'NODE'\n const path = require(\"node:path\");\n const { createRequire } = require(\"node:module\");\n const appDir = process.env.APP_DIR || \".\";\n const githubWorkspace = process.env.GITHUB_WORKSPACE;\n if (!githubWorkspace) {\n throw new Error(\"GITHUB_WORKSPACE is required.\");\n }\n\n let lastError;\n for (const manifestPath of [\n path.join(githubWorkspace, appDir, \"package.json\"),\n path.join(githubWorkspace, \"package.json\"),\n ]) {\n try {\n const requireFromManifest = createRequire(manifestPath);\n process.stdout.write(\n path.join(\n path.dirname(requireFromManifest.resolve(\"@tailor-platform/sdk/cli\")),\n \"index.mjs\",\n ),\n );\n process.exit(0);\n } catch (error) {\n lastError = error;\n }\n }\n throw lastError || new Error(\"Failed to resolve @tailor-platform/sdk/cli.\");\n NODE\n )\"\n\n run_head_tailor_sdk_bin() {\n local command_cwd=\"$1\"\n shift\n\n run_head_cli_env() {\n env TAILOR_SDK_BIN=\"$tailor_sdk_bin\" TAILOR_SDK_CWD=\"$command_cwd\" \"$@\"\n }\n\n (\n cd \"$GITHUB_WORKSPACE\" || exit 1\n case \"__PACKAGE_MANAGER__\" in\n pnpm) run_head_cli_env pnpm exec node \"$head_cli_runner\" \"$@\" ;;\n npm) run_head_cli_env node \"$head_cli_runner\" \"$@\" ;;\n yarn) run_head_cli_env yarn node \"$head_cli_runner\" \"$@\" ;;\n bun) run_head_cli_env bun \"$head_cli_runner\" \"$@\" ;;\n *)\n echo \"::error::Unsupported package-manager '__PACKAGE_MANAGER__' (expected pnpm, npm, yarn, or bun)\"\n exit 1\n ;;\n esac\n )\n }\n\n run_base_tailor_sdk_bin() {\n local command_cwd=\"$1\"\n shift\n\n run_head_cli_env() {\n env TAILOR_SDK_BIN=\"$tailor_sdk_bin\" TAILOR_SDK_CWD=\"$command_cwd\" \"$@\"\n }\n\n (\n cd \"$command_cwd\" || exit 1\n case \"$BASE_PACKAGE_MANAGER\" in\n pnpm) run_head_cli_env pnpm exec node \"$head_cli_runner\" \"$@\" ;;\n npm) run_head_cli_env node \"$head_cli_runner\" \"$@\" ;;\n yarn) run_head_cli_env yarn node \"$head_cli_runner\" \"$@\" ;;\n bun) run_head_cli_env bun \"$head_cli_runner\" \"$@\" ;;\n *)\n echo \"::error::Unsupported base package-manager '$BASE_PACKAGE_MANAGER' (expected pnpm, npm, yarn, or bun)\"\n exit 1\n ;;\n esac\n )\n }\n\n head_output=\"$RUNNER_TEMP/tailor-erd/head\"\n base_output=\"$RUNNER_TEMP/tailor-erd/base\"\n preview_output=\"$RUNNER_TEMP/tailor-erd/preview\"\n dts_output=\"$RUNNER_TEMP/tailor-erd/dts\"\n head_cli_runner=\"$RUNNER_TEMP/tailor-erd/run-head-tailor-sdk.mjs\"\n head_log=\"$RUNNER_TEMP/tailor-erd/head-$NAMESPACE.log\"\n base_log=\"$RUNNER_TEMP/tailor-erd/base-$NAMESPACE.log\"\n rm -rf \"$head_output\" \"$base_output\" \"$preview_output\" \"$dts_output\"\n mkdir -p \"$head_output\" \"$base_output\" \"$preview_output\" \"$dts_output\"\n cat > \"$head_cli_runner\" <<'NODE'\n import { pathToFileURL } from \"node:url\";\n\n const cliBin = process.env.TAILOR_SDK_BIN;\n const commandCwd = process.env.TAILOR_SDK_CWD;\n if (!cliBin || !commandCwd) {\n throw new Error(\"TAILOR_SDK_BIN and TAILOR_SDK_CWD are required.\");\n }\n\n process.chdir(commandCwd);\n process.argv = [process.argv[0], cliBin, ...process.argv.slice(2)];\n await import(pathToFileURL(cliBin).href);\n NODE\n\n head_config=\"$GITHUB_WORKSPACE/$APP_DIR/tailor.config.ts\"\n base_config=\"$GITHUB_WORKSPACE/.tailor-erd-base/$BASE_APP_DIR/tailor.config.ts\"\n head_html=\"$head_output/$NAMESPACE/dist/index.html\"\n base_html=\"$base_output/$NAMESPACE/dist/index.html\"\n preview_html=\"$preview_output/$NAMESPACE-viewer.html\"\n\n head_missing=\"false\"\n if [ ! -f \"$head_config\" ]; then\n echo \"Head ERD config not found; rendering base objects as removed.\"\n head_missing=\"true\"\n elif ! (\n cd \"$GITHUB_WORKSPACE/$APP_DIR\" || exit 1\n TAILOR_PLATFORM_SDK_DTS_PATH=\"$dts_output/head-$NAMESPACE.d.ts\" \\\n run_tailor_sdk tailordb erd export --config \"$head_config\" --namespace \"$NAMESPACE\" --output \"$head_output\"\n ) >\"$head_log\" 2>&1; then\n if grep -q 'not found in local config.db' \"$head_log\"; then\n cat \"$head_log\"\n echo \"Head ERD namespace '$NAMESPACE' not found; rendering base objects as removed.\"\n head_missing=\"true\"\n else\n cat \"$head_log\"\n exit 1\n fi\n elif [ -s \"$head_log\" ]; then\n cat \"$head_log\"\n fi\n\n base_missing=\"false\"\n if [ ! -f \"$base_config\" ]; then\n echo \"Base ERD config not found; rendering current objects as added.\"\n base_missing=\"true\"\n elif ! (\n TAILOR_PLATFORM_SDK_DTS_PATH=\"$dts_output/base-$NAMESPACE.d.ts\" \\\n run_base_tailor_sdk_bin \"$GITHUB_WORKSPACE/.tailor-erd-base/$BASE_APP_DIR\" tailordb erd export --config \"$base_config\" --namespace \"$NAMESPACE\" --output \"$base_output\"\n ) >\"$base_log\" 2>&1; then\n if grep -q 'not found in local config.db' \"$base_log\"; then\n cat \"$base_log\"\n echo \"Base ERD namespace '$NAMESPACE' not found; rendering current objects as added.\"\n base_missing=\"true\"\n else\n cat \"$base_log\"\n exit 1\n fi\n elif [ -s \"$base_log\" ]; then\n cat \"$base_log\"\n fi\n\n if [ \"$head_missing\" = \"true\" ] && [ \"$base_missing\" = \"true\" ]; then\n echo \"::error::ERD namespace '$NAMESPACE' was not found in head or base.\"\n exit 1\n fi\n if [ \"$head_missing\" = \"false\" ] && [ ! -f \"$head_html\" ]; then\n echo \"::error::Head ERD viewer was not generated at $head_html\"\n exit 1\n fi\n if [ \"$base_missing\" = \"false\" ] && [ ! -f \"$base_html\" ]; then\n echo \"::error::Base ERD viewer was not generated at $base_html\"\n exit 1\n fi\n\n diff_args=(--namespace \"$NAMESPACE\" --output \"$preview_html\")\n if [ \"$head_missing\" = \"false\" ]; then\n diff_args+=(--head-html \"$head_html\")\n fi\n if [ \"$base_missing\" = \"false\" ]; then\n diff_args+=(--base-html \"$base_html\")\n fi\n run_head_tailor_sdk_bin \"$GITHUB_WORKSPACE\" tailordb erd diff \"${diff_args[@]}\"\n - id: tailor-upload-erd-viewer\n uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1\n with:\n name: ${{ matrix.namespace }}-viewer.html\n path: ${{ runner.temp }}/tailor-erd/preview/${{ matrix.namespace }}-viewer.html\n if-no-files-found: error\n archive: false\n retention-days: 7\n\n # __ERD_PREVIEW_JOB_END__\n # __ERD_PREVIEW_COMMENT_JOB_START__\n tailor-erd-preview-comment:\n needs: tailor-erd-preview\n if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository\n runs-on: ubuntu-latest\n timeout-minutes: 5\n permissions:\n actions: read\n pull-requests: write\n steps:\n - id: tailor-comment-erd-preview\n env:\n GH_TOKEN: ${{ github.token }}\n REPO: ${{ github.repository }}\n RUN_ID: ${{ github.run_id }}\n SERVER: ${{ github.server_url }}\n PR_NUMBER: ${{ github.event.pull_request.number }}\n BASE_REF: ${{ github.event.pull_request.base.ref }}\n HEAD_SHA: ${{ github.event.pull_request.head.sha }}\n MARKER: \"<!-- tailor-erd-preview: __WORKSPACE_NAME__ -->\"\n run: |\n set -euo pipefail\n\n current_head=$(gh api \"repos/$REPO/pulls/$PR_NUMBER\" --jq '.head.sha')\n if [ \"$current_head\" != \"$HEAD_SHA\" ]; then\n echo \"Skipping stale ERD preview comment for $HEAD_SHA; current head is $current_head.\"\n exit 0\n fi\n\n body=\"$MARKER\"$'\\n'\"### TailorDB ERD preview (__WORKSPACE_NAME__)\"$'\\n\\n'\n body+=\"Self-contained ERD viewer HTML artifacts for this pull request. Each viewer can switch between the current schema and a diff against base branch \\`$BASE_REF\\`.\"$'\\n'\n\n while IFS=$'\\t' read -r name id; do\n [ -z \"$name\" ] && continue\n if [[ \"$name\" != *-viewer.html ]]; then\n continue\n fi\n ns=${name%-viewer.html}\n label=\"$ns viewer\"\n body+=$'\\n'\"- **$label**: [$name]($SERVER/$REPO/actions/runs/$RUN_ID/artifacts/$id)\"\n done < <(gh api \"repos/$REPO/actions/runs/$RUN_ID/artifacts\" --paginate \\\n --jq '.artifacts[] | select(.name | endswith(\"-viewer.html\")) | [.name, (.id|tostring)] | @tsv' | sort)\n\n existing=$(gh api \"repos/$REPO/issues/$PR_NUMBER/comments\" --paginate \\\n --jq 'map(select(.body | contains(env.MARKER))) | .[0].id // empty')\n if [ -n \"$existing\" ]; then\n gh api --method PATCH \"repos/$REPO/issues/comments/$existing\" -f body=\"$body\" >/dev/null\n else\n gh api --method POST \"repos/$REPO/issues/$PR_NUMBER/comments\" -f body=\"$body\" >/dev/null\n fi\n\n # __ERD_PREVIEW_COMMENT_JOB_END__\n tailor-deploy:\n # __DEPLOY_IF__\n runs-on: ubuntu-latest\n timeout-minutes: 30\n permissions:\n contents: read\n environment: __ENVIRONMENT__\n concurrency:\n group: tailor-deploy-__WORKSPACE_NAME__\n cancel-in-progress: false\n steps:\n - id: tailor-checkout\n uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0\n - id: tailor-setup\n uses: tailor-platform/actions/setup@a3c3032e14277e81039eb26ae1a425adb22eb532 # v1.7.0\n with:\n package-manager: __PACKAGE_MANAGER__\n - id: tailor-install\n uses: tailor-platform/actions/install@a3c3032e14277e81039eb26ae1a425adb22eb532 # v1.7.0\n with:\n package-manager: __PACKAGE_MANAGER__\n - id: tailor-apply\n uses: tailor-platform/actions/deploy@a3c3032e14277e81039eb26ae1a425adb22eb532 # v1.7.0\n with:\n workspace-id: ${{ vars.TAILOR_PLATFORM_WORKSPACE_ID }}\n package-manager: __PACKAGE_MANAGER__\n # __WORKING_DIRECTORY__\n platform-client-id: ${{ secrets.TAILOR_PLATFORM_MACHINE_USER_CLIENT_ID }}\n platform-client-secret: ${{ secrets.TAILOR_PLATFORM_MACHINE_USER_CLIENT_SECRET }}\n # __SEED_DATA_START__\n - id: seed-data\n if: false\n shell: bash\n # __WORKING_DIRECTORY__\n run: |\n # Uncomment and implement to seed data on deploy.\n # Run after apply so the schema is ready.\n # Example: node scripts/seed.mjs\n true\n # __SEED_DATA_END__\n - id: slack-prereq\n if: always()\n shell: bash\n env:\n SLACK_TOKEN: ${{ secrets.TAILOR_SLACK_BOT_TOKEN }}\n SLACK_CHANNEL_ID: ${{ vars.TAILOR_SLACK_CHANNEL_ID }}\n run: |\n if [[ -n \"$SLACK_TOKEN\" && -n \"$SLACK_CHANNEL_ID\" ]]; then\n echo \"ready=true\" >> \"$GITHUB_OUTPUT\"\n fi\n - id: tailor-notify\n if: always() && steps.slack-prereq.outputs.ready == 'true'\n uses: tailor-platform/actions/notify@a3c3032e14277e81039eb26ae1a425adb22eb532 # v1.7.0\n with:\n provider: slack\n status: ${{ job.status }}\n workspace-name: __WORKSPACE_NAME__\n slack-token: ${{ secrets.TAILOR_SLACK_BOT_TOKEN }}\n slack-channel-id: ${{ vars.TAILOR_SLACK_CHANNEL_ID }}\n # user-mapping: ${{ vars.TAILOR_SLACK_USER_MAPPING }}\n";
3486
+ var branch_workflow_default = "# __HEADER__\nname: Tailor (__WORKSPACE_NAME__)\n\non:\n # __PULL_REQUEST_START__\n pull_request:\n branches: [\"__BRANCH__\"]\n # __PATHS__\n # __PULL_REQUEST_END__\n push:\n branches: [\"__BRANCH__\"]\n # __PATHS__\n workflow_dispatch:\n # __DISPATCH_INPUTS_START__\n inputs:\n dry-run:\n description: Preview changes without deploying\n type: boolean\n default: false\n # __DISPATCH_INPUTS_END__\n\npermissions:\n contents: read\n\njobs:\n # __PLAN_JOB_START__\n tailor-plan:\n if: >-\n github.event_name == 'pull_request' ||\n (github.event_name == 'workflow_dispatch' && inputs['dry-run'])\n runs-on: ubuntu-latest\n timeout-minutes: 30\n environment: __ENVIRONMENT__\n permissions:\n contents: read\n pull-requests: write\n concurrency:\n group: tailor-plan-__WORKSPACE_NAME__-${{ github.event.pull_request.number || github.run_id }}\n cancel-in-progress: true\n steps:\n - id: tailor-checkout\n uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0\n - id: tailor-setup\n uses: tailor-platform/actions/setup@a3c3032e14277e81039eb26ae1a425adb22eb532 # v1.7.0\n with:\n package-manager: __PACKAGE_MANAGER__\n - id: tailor-install\n uses: tailor-platform/actions/install@a3c3032e14277e81039eb26ae1a425adb22eb532 # v1.7.0\n with:\n package-manager: __PACKAGE_MANAGER__\n - id: tailor-generate-check\n uses: tailor-platform/actions/generate-check@a3c3032e14277e81039eb26ae1a425adb22eb532 # v1.7.0\n with:\n package-manager: __PACKAGE_MANAGER__\n # __WORKING_DIRECTORY__\n # __SEED_VALIDATE_START__\n - id: tailor-seed-validate\n uses: tailor-platform/actions/seed-validate@a3c3032e14277e81039eb26ae1a425adb22eb532 # v1.7.0\n with:\n package-manager: __PACKAGE_MANAGER__\n # __WORKING_DIRECTORY__\n # __SEED_VALIDATE_END__\n - id: tailor-drift-check\n uses: tailor-platform/actions/drift-check@a3c3032e14277e81039eb26ae1a425adb22eb532 # v1.7.0\n with:\n package-manager: __PACKAGE_MANAGER__\n # __MIGRATION_DRIFT_CHECK_START__\n - id: tailor-migration-drift-check\n uses: tailor-platform/actions/migration-drift-check@a3c3032e14277e81039eb26ae1a425adb22eb532 # v1.7.0\n with:\n package-manager: __PACKAGE_MANAGER__\n # __WORKING_DIRECTORY__\n # __MIGRATION_DRIFT_CHECK_END__\n - id: tailor-plan\n # Fork PRs cannot read secrets; the checks above still run for them.\n if: github.event_name != 'pull_request' || !github.event.pull_request.head.repo.fork\n uses: tailor-platform/actions/plan@a3c3032e14277e81039eb26ae1a425adb22eb532 # v1.7.0\n with:\n workspace-id: ${{ vars.TAILOR_PLATFORM_WORKSPACE_ID }}\n package-manager: __PACKAGE_MANAGER__\n label: __WORKSPACE_NAME__\n # __WORKING_DIRECTORY__\n platform-client-id: ${{ secrets.TAILOR_PLATFORM_MACHINE_USER_CLIENT_ID }}\n platform-client-secret: ${{ secrets.TAILOR_PLATFORM_MACHINE_USER_CLIENT_SECRET }}\n github-token: ${{ secrets.GITHUB_TOKEN }}\n # __PLAN_JOB_END__\n # __ERD_PREVIEW_JOB_START__\n tailor-erd-preview-matrix:\n if: github.event_name == 'pull_request'\n runs-on: ubuntu-latest\n timeout-minutes: 5\n permissions:\n contents: read\n outputs:\n namespaces: ${{ steps.tailor-erd-preview-matrix.outputs.namespaces }}\n base-app-dir: ${{ steps.tailor-erd-preview-matrix.outputs['base-app-dir'] }}\n steps:\n - id: tailor-checkout\n uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0\n with:\n persist-credentials: false\n - id: tailor-checkout-base\n uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0\n with:\n repository: ${{ github.event.pull_request.base.repo.full_name }}\n ref: ${{ github.event.pull_request.base.sha }}\n path: .tailor-erd-base\n persist-credentials: false\n - id: tailor-erd-preview-matrix\n shell: bash\n env:\n APP_DIR: \"__APP_DIR__\"\n WORKSPACE_NAME: \"__WORKSPACE_NAME__\"\n run: |\n set -euo pipefail\n node <<'NODE'\n const fs = require(\"node:fs\");\n\n const appDir = process.env.APP_DIR || \".\";\n const workspaceName = process.env.WORKSPACE_NAME;\n const output = process.env.GITHUB_OUTPUT;\n const dirPattern = /^[A-Za-z0-9._/-]+$/;\n const namespacePattern = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;\n\n function lockTarget(file) {\n try {\n const lock = JSON.parse(fs.readFileSync(file, \"utf8\"));\n return lock.targets?.find(\n (candidate) =>\n candidate.kind === \"branch\" &&\n candidate.workspaceName === workspaceName,\n );\n } catch (error) {\n if (error && error.code === \"ENOENT\") return undefined;\n throw error;\n }\n }\n\n function namespacesFromTarget(target, label) {\n const namespaces =\n target?.inputs?.erdPreview === true && Array.isArray(target.inputs?.erdNamespaces)\n ? target.inputs.erdNamespaces\n : [];\n for (const namespace of namespaces) {\n if (typeof namespace !== \"string\" || !namespacePattern.test(namespace)) {\n throw new Error(`Invalid ERD namespace in ${label}: ${String(namespace)}`);\n }\n }\n return namespaces;\n }\n\n function normalizeDir(value, label) {\n const raw = typeof value === \"string\" && value.length > 0 ? value : appDir;\n const normalized =\n raw.replaceAll(\"\\\\\", \"/\").replace(/\\/{2,}/g, \"/\").replace(/^\\.\\//, \"\").replace(/\\/$/, \"\") ||\n \".\";\n if (\n !dirPattern.test(normalized) ||\n normalized.startsWith(\"/\") ||\n normalized.split(\"/\").includes(\"..\")\n ) {\n throw new Error(`Invalid ERD app dir in ${label}: ${raw}`);\n }\n return normalized;\n }\n\n const headTarget = lockTarget(\".github/tailor-sdk.lock\");\n const baseTarget = lockTarget(\".tailor-erd-base/.github/tailor-sdk.lock\");\n const baseAppDir = normalizeDir(baseTarget?.inputs?.dir, \"base setup lock\");\n const namespaces = [\n ...new Set([\n ...namespacesFromTarget(headTarget, \"head setup lock\"),\n ...namespacesFromTarget(baseTarget, \"base setup lock\"),\n ]),\n ].sort((a, b) => a.localeCompare(b));\n\n if (namespaces.length === 0) {\n console.error(\"No ERD preview namespaces found in the head or base setup lock.\");\n process.exit(1);\n }\n\n fs.appendFileSync(output, `namespaces=${JSON.stringify(namespaces)}\\n`);\n fs.appendFileSync(output, `base-app-dir=${baseAppDir}\\n`);\n NODE\n\n tailor-erd-preview:\n needs: tailor-erd-preview-matrix\n if: github.event_name == 'pull_request'\n runs-on: ubuntu-latest\n timeout-minutes: 15\n permissions:\n contents: read\n strategy:\n fail-fast: false\n matrix:\n namespace: ${{ fromJSON(needs.tailor-erd-preview-matrix.outputs.namespaces) }}\n steps:\n - id: tailor-checkout\n uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0\n with:\n persist-credentials: false\n - id: tailor-setup\n uses: tailor-platform/actions/setup@a3c3032e14277e81039eb26ae1a425adb22eb532 # v1.7.0\n with:\n package-manager: __PACKAGE_MANAGER__\n - id: tailor-checkout-base\n uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0\n with:\n repository: ${{ github.event.pull_request.base.repo.full_name }}\n ref: ${{ github.event.pull_request.base.sha }}\n path: .tailor-erd-base\n persist-credentials: false\n - id: tailor-detect-base-package-manager\n shell: bash\n run: |\n set -euo pipefail\n cd .tailor-erd-base\n base_package_manager=\"$(\n if [ -f pnpm-lock.yaml ]; then\n echo pnpm\n elif [ -f yarn.lock ]; then\n echo yarn\n elif [ -f bun.lockb ] || [ -f bun.lock ]; then\n echo bun\n elif [ -f package-lock.json ]; then\n echo npm\n else\n echo \"__PACKAGE_MANAGER__\"\n fi\n )\"\n echo \"package-manager=$base_package_manager\" >> \"$GITHUB_OUTPUT\"\n if [ \"$base_package_manager\" = \"pnpm\" ]; then\n base_pnpm_version=\"$(node <<'NODE'\n const fs = require(\"node:fs\");\n\n const fallback = \"10\";\n\n function readManifest(file) {\n try {\n return JSON.parse(fs.readFileSync(file, \"utf8\"));\n } catch {\n return {};\n }\n }\n\n function pnpmVersion(manifest) {\n const packageManager = manifest.packageManager;\n if (typeof packageManager === \"string\" && packageManager.startsWith(\"pnpm@\")) {\n return packageManager.slice(\"pnpm@\".length).split(\"+\")[0];\n }\n\n const devPackageManager = manifest.devEngines?.packageManager;\n if (devPackageManager?.name === \"pnpm\" && devPackageManager.version) {\n return devPackageManager.version;\n }\n\n return undefined;\n }\n\n process.stdout.write(\n pnpmVersion(readManifest(\"package.json\")) ?? fallback,\n );\n NODE\n )\"\n echo \"pnpm-version=$base_pnpm_version\" >> \"$GITHUB_OUTPUT\"\n fi\n - id: tailor-setup-base-pnpm\n if: steps.tailor-detect-base-package-manager.outputs['package-manager'] == 'pnpm'\n uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9\n with:\n version: ${{ steps.tailor-detect-base-package-manager.outputs['pnpm-version'] }}\n package_json_file: .tailor-erd-base/package.json\n run_install: false\n - id: tailor-setup-base-node\n if: steps.tailor-detect-base-package-manager.outputs['package-manager'] != 'bun'\n uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7\n with:\n node-version-file: .tailor-erd-base/package.json\n - id: tailor-setup-base-yarn\n if: steps.tailor-detect-base-package-manager.outputs['package-manager'] == 'yarn'\n shell: bash\n working-directory: .tailor-erd-base\n run: |\n set -euo pipefail\n corepack enable\n - id: tailor-setup-base-bun\n if: steps.tailor-detect-base-package-manager.outputs['package-manager'] == 'bun'\n uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0\n - id: tailor-install-base\n shell: bash\n working-directory: .tailor-erd-base\n env:\n BASE_PACKAGE_MANAGER: ${{ steps.tailor-detect-base-package-manager.outputs['package-manager'] }}\n run: |\n set -euo pipefail\n case \"$BASE_PACKAGE_MANAGER\" in\n pnpm) pnpm install --frozen-lockfile ;;\n npm) npm ci ;;\n yarn)\n if grep -q '^__metadata:' yarn.lock; then\n yarn install --immutable\n else\n yarn install --frozen-lockfile\n fi\n ;;\n bun) bun install --frozen-lockfile ;;\n *)\n echo \"::error::Unsupported base package-manager '$BASE_PACKAGE_MANAGER' (expected pnpm, npm, yarn, or bun)\"\n exit 1\n ;;\n esac\n - id: tailor-restore-head-setup\n uses: tailor-platform/actions/setup@a3c3032e14277e81039eb26ae1a425adb22eb532 # v1.7.0\n with:\n package-manager: __PACKAGE_MANAGER__\n - id: tailor-build-erd-preview\n shell: bash\n env:\n APP_DIR: \"__APP_DIR__\"\n BASE_APP_DIR: ${{ needs.tailor-erd-preview-matrix.outputs['base-app-dir'] }}\n BASE_PACKAGE_MANAGER: ${{ steps.tailor-detect-base-package-manager.outputs['package-manager'] }}\n NAMESPACE: ${{ matrix.namespace }}\n run: |\n set -euo pipefail\n\n run_tailor_sdk() {\n case \"__PACKAGE_MANAGER__\" in\n pnpm) pnpm exec tailor-sdk \"$@\" ;;\n npm) npx tailor-sdk \"$@\" ;;\n yarn) yarn tailor-sdk \"$@\" ;;\n bun) bunx tailor-sdk \"$@\" ;;\n *)\n echo \"::error::Unsupported package-manager '__PACKAGE_MANAGER__' (expected pnpm, npm, yarn, or bun)\"\n exit 1\n ;;\n esac\n }\n\n run_head_node() {\n case \"__PACKAGE_MANAGER__\" in\n pnpm) pnpm exec node \"$@\" ;;\n npm) node \"$@\" ;;\n yarn) yarn node \"$@\" ;;\n bun) node \"$@\" ;;\n *)\n echo \"::error::Unsupported package-manager '__PACKAGE_MANAGER__' (expected pnpm, npm, yarn, or bun)\"\n exit 1\n ;;\n esac\n }\n\n tailor_sdk_bin=\"$(\n run_head_node - <<'NODE'\n const path = require(\"node:path\");\n const { createRequire } = require(\"node:module\");\n const appDir = process.env.APP_DIR || \".\";\n const githubWorkspace = process.env.GITHUB_WORKSPACE;\n if (!githubWorkspace) {\n throw new Error(\"GITHUB_WORKSPACE is required.\");\n }\n\n let lastError;\n for (const manifestPath of [\n path.join(githubWorkspace, appDir, \"package.json\"),\n path.join(githubWorkspace, \"package.json\"),\n ]) {\n try {\n const requireFromManifest = createRequire(manifestPath);\n process.stdout.write(\n path.join(\n path.dirname(requireFromManifest.resolve(\"@tailor-platform/sdk/cli\")),\n \"index.mjs\",\n ),\n );\n process.exit(0);\n } catch (error) {\n lastError = error;\n }\n }\n throw lastError || new Error(\"Failed to resolve @tailor-platform/sdk/cli.\");\n NODE\n )\"\n\n run_head_tailor_sdk_bin() {\n local command_cwd=\"$1\"\n shift\n\n run_head_cli_env() {\n env TAILOR_SDK_BIN=\"$tailor_sdk_bin\" TAILOR_SDK_CWD=\"$command_cwd\" \"$@\"\n }\n\n (\n cd \"$GITHUB_WORKSPACE\" || exit 1\n case \"__PACKAGE_MANAGER__\" in\n pnpm) run_head_cli_env pnpm exec node \"$head_cli_runner\" \"$@\" ;;\n npm) run_head_cli_env node \"$head_cli_runner\" \"$@\" ;;\n yarn) run_head_cli_env yarn node \"$head_cli_runner\" \"$@\" ;;\n bun) run_head_cli_env bun \"$head_cli_runner\" \"$@\" ;;\n *)\n echo \"::error::Unsupported package-manager '__PACKAGE_MANAGER__' (expected pnpm, npm, yarn, or bun)\"\n exit 1\n ;;\n esac\n )\n }\n\n run_base_tailor_sdk_bin() {\n local command_cwd=\"$1\"\n shift\n\n run_head_cli_env() {\n env TAILOR_SDK_BIN=\"$tailor_sdk_bin\" TAILOR_SDK_CWD=\"$command_cwd\" \"$@\"\n }\n\n (\n cd \"$command_cwd\" || exit 1\n case \"$BASE_PACKAGE_MANAGER\" in\n pnpm) run_head_cli_env pnpm exec node \"$head_cli_runner\" \"$@\" ;;\n npm) run_head_cli_env node \"$head_cli_runner\" \"$@\" ;;\n yarn) run_head_cli_env yarn node \"$head_cli_runner\" \"$@\" ;;\n bun) run_head_cli_env bun \"$head_cli_runner\" \"$@\" ;;\n *)\n echo \"::error::Unsupported base package-manager '$BASE_PACKAGE_MANAGER' (expected pnpm, npm, yarn, or bun)\"\n exit 1\n ;;\n esac\n )\n }\n\n head_output=\"$RUNNER_TEMP/tailor-erd/head\"\n base_output=\"$RUNNER_TEMP/tailor-erd/base\"\n preview_output=\"$RUNNER_TEMP/tailor-erd/preview\"\n dts_output=\"$RUNNER_TEMP/tailor-erd/dts\"\n head_cli_runner=\"$RUNNER_TEMP/tailor-erd/run-head-tailor-sdk.mjs\"\n head_log=\"$RUNNER_TEMP/tailor-erd/head-$NAMESPACE.log\"\n base_log=\"$RUNNER_TEMP/tailor-erd/base-$NAMESPACE.log\"\n rm -rf \"$head_output\" \"$base_output\" \"$preview_output\" \"$dts_output\"\n mkdir -p \"$head_output\" \"$base_output\" \"$preview_output\" \"$dts_output\"\n cat > \"$head_cli_runner\" <<'NODE'\n import { pathToFileURL } from \"node:url\";\n\n const cliBin = process.env.TAILOR_SDK_BIN;\n const commandCwd = process.env.TAILOR_SDK_CWD;\n if (!cliBin || !commandCwd) {\n throw new Error(\"TAILOR_SDK_BIN and TAILOR_SDK_CWD are required.\");\n }\n\n process.chdir(commandCwd);\n process.argv = [process.argv[0], cliBin, ...process.argv.slice(2)];\n await import(pathToFileURL(cliBin).href);\n NODE\n\n head_config=\"$GITHUB_WORKSPACE/$APP_DIR/tailor.config.ts\"\n base_config=\"$GITHUB_WORKSPACE/.tailor-erd-base/$BASE_APP_DIR/tailor.config.ts\"\n head_html=\"$head_output/$NAMESPACE/dist/index.html\"\n base_html=\"$base_output/$NAMESPACE/dist/index.html\"\n preview_html=\"$preview_output/$NAMESPACE-viewer.html\"\n\n head_missing=\"false\"\n if [ ! -f \"$head_config\" ]; then\n echo \"Head ERD config not found; rendering base objects as removed.\"\n head_missing=\"true\"\n elif ! (\n cd \"$GITHUB_WORKSPACE/$APP_DIR\" || exit 1\n TAILOR_PLATFORM_SDK_DTS_PATH=\"$dts_output/head-$NAMESPACE.d.ts\" \\\n run_tailor_sdk tailordb erd export --config \"$head_config\" --namespace \"$NAMESPACE\" --output \"$head_output\"\n ) >\"$head_log\" 2>&1; then\n if grep -q 'not found in local config.db' \"$head_log\"; then\n cat \"$head_log\"\n echo \"Head ERD namespace '$NAMESPACE' not found; rendering base objects as removed.\"\n head_missing=\"true\"\n else\n cat \"$head_log\"\n exit 1\n fi\n elif [ -s \"$head_log\" ]; then\n cat \"$head_log\"\n fi\n\n base_missing=\"false\"\n if [ ! -f \"$base_config\" ]; then\n echo \"Base ERD config not found; rendering current objects as added.\"\n base_missing=\"true\"\n elif ! (\n TAILOR_PLATFORM_SDK_DTS_PATH=\"$dts_output/base-$NAMESPACE.d.ts\" \\\n run_base_tailor_sdk_bin \"$GITHUB_WORKSPACE/.tailor-erd-base/$BASE_APP_DIR\" tailordb erd export --config \"$base_config\" --namespace \"$NAMESPACE\" --output \"$base_output\"\n ) >\"$base_log\" 2>&1; then\n if grep -q 'not found in local config.db' \"$base_log\"; then\n cat \"$base_log\"\n echo \"Base ERD namespace '$NAMESPACE' not found; rendering current objects as added.\"\n base_missing=\"true\"\n else\n cat \"$base_log\"\n exit 1\n fi\n elif [ -s \"$base_log\" ]; then\n cat \"$base_log\"\n fi\n\n if [ \"$head_missing\" = \"true\" ] && [ \"$base_missing\" = \"true\" ]; then\n echo \"::error::ERD namespace '$NAMESPACE' was not found in head or base.\"\n exit 1\n fi\n if [ \"$head_missing\" = \"false\" ] && [ ! -f \"$head_html\" ]; then\n echo \"::error::Head ERD viewer was not generated at $head_html\"\n exit 1\n fi\n if [ \"$base_missing\" = \"false\" ] && [ ! -f \"$base_html\" ]; then\n echo \"::error::Base ERD viewer was not generated at $base_html\"\n exit 1\n fi\n\n diff_args=(--namespace \"$NAMESPACE\" --output \"$preview_html\")\n if [ \"$head_missing\" = \"false\" ]; then\n diff_args+=(--head-html \"$head_html\")\n fi\n if [ \"$base_missing\" = \"false\" ]; then\n diff_args+=(--base-html \"$base_html\")\n fi\n run_head_tailor_sdk_bin \"$GITHUB_WORKSPACE\" tailordb erd diff \"${diff_args[@]}\"\n - id: tailor-upload-erd-viewer\n uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1\n with:\n name: ${{ matrix.namespace }}-viewer.html\n path: ${{ runner.temp }}/tailor-erd/preview/${{ matrix.namespace }}-viewer.html\n if-no-files-found: error\n archive: false\n retention-days: 7\n\n # __ERD_PREVIEW_JOB_END__\n # __ERD_PREVIEW_COMMENT_JOB_START__\n tailor-erd-preview-comment:\n needs: tailor-erd-preview\n if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository\n runs-on: ubuntu-latest\n timeout-minutes: 5\n permissions:\n actions: read\n pull-requests: write\n steps:\n - id: tailor-comment-erd-preview\n env:\n GH_TOKEN: ${{ github.token }}\n REPO: ${{ github.repository }}\n RUN_ID: ${{ github.run_id }}\n SERVER: ${{ github.server_url }}\n PR_NUMBER: ${{ github.event.pull_request.number }}\n BASE_REF: ${{ github.event.pull_request.base.ref }}\n HEAD_SHA: ${{ github.event.pull_request.head.sha }}\n MARKER: \"<!-- tailor-erd-preview: __WORKSPACE_NAME__ -->\"\n run: |\n set -euo pipefail\n\n current_head=$(gh api \"repos/$REPO/pulls/$PR_NUMBER\" --jq '.head.sha')\n if [ \"$current_head\" != \"$HEAD_SHA\" ]; then\n echo \"Skipping stale ERD preview comment for $HEAD_SHA; current head is $current_head.\"\n exit 0\n fi\n\n body=\"$MARKER\"$'\\n'\"### TailorDB ERD preview (__WORKSPACE_NAME__)\"$'\\n\\n'\n body+=\"Self-contained ERD viewer HTML artifacts for this pull request. Each viewer can switch between the current schema and a diff against base branch \\`$BASE_REF\\`.\"$'\\n'\n\n while IFS=$'\\t' read -r name id; do\n [ -z \"$name\" ] && continue\n if [[ \"$name\" != *-viewer.html ]]; then\n continue\n fi\n ns=${name%-viewer.html}\n label=\"$ns viewer\"\n body+=$'\\n'\"- **$label**: [$name]($SERVER/$REPO/actions/runs/$RUN_ID/artifacts/$id)\"\n done < <(gh api \"repos/$REPO/actions/runs/$RUN_ID/artifacts\" --paginate \\\n --jq '.artifacts[] | select(.name | endswith(\"-viewer.html\")) | [.name, (.id|tostring)] | @tsv' | sort)\n\n existing=$(gh api \"repos/$REPO/issues/$PR_NUMBER/comments\" --paginate \\\n --jq 'map(select(.body | contains(env.MARKER))) | .[0].id // empty')\n if [ -n \"$existing\" ]; then\n gh api --method PATCH \"repos/$REPO/issues/comments/$existing\" -f body=\"$body\" >/dev/null\n else\n gh api --method POST \"repos/$REPO/issues/$PR_NUMBER/comments\" -f body=\"$body\" >/dev/null\n fi\n\n # __ERD_PREVIEW_COMMENT_JOB_END__\n tailor-deploy:\n # __DEPLOY_IF__\n runs-on: ubuntu-latest\n timeout-minutes: 30\n permissions:\n contents: read\n environment: __ENVIRONMENT__\n concurrency:\n group: tailor-deploy-__WORKSPACE_NAME__\n cancel-in-progress: false\n steps:\n - id: tailor-checkout\n uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0\n - id: tailor-setup\n uses: tailor-platform/actions/setup@a3c3032e14277e81039eb26ae1a425adb22eb532 # v1.7.0\n with:\n package-manager: __PACKAGE_MANAGER__\n - id: tailor-install\n uses: tailor-platform/actions/install@a3c3032e14277e81039eb26ae1a425adb22eb532 # v1.7.0\n with:\n package-manager: __PACKAGE_MANAGER__\n - id: tailor-apply\n uses: tailor-platform/actions/deploy@a3c3032e14277e81039eb26ae1a425adb22eb532 # v1.7.0\n with:\n workspace-id: ${{ vars.TAILOR_PLATFORM_WORKSPACE_ID }}\n package-manager: __PACKAGE_MANAGER__\n # __WORKING_DIRECTORY__\n platform-client-id: ${{ secrets.TAILOR_PLATFORM_MACHINE_USER_CLIENT_ID }}\n platform-client-secret: ${{ secrets.TAILOR_PLATFORM_MACHINE_USER_CLIENT_SECRET }}\n # __SEED_DATA_START__\n - id: seed-data\n if: false\n shell: bash\n # __WORKING_DIRECTORY__\n run: |\n # Uncomment and implement to seed data on deploy.\n # Run after apply so the schema is ready.\n # Example: node scripts/seed.mjs\n true\n # __SEED_DATA_END__\n - id: slack-prereq\n if: always()\n shell: bash\n env:\n SLACK_TOKEN: ${{ secrets.TAILOR_SLACK_BOT_TOKEN }}\n SLACK_CHANNEL_ID: ${{ vars.TAILOR_SLACK_CHANNEL_ID }}\n run: |\n if [[ -n \"$SLACK_TOKEN\" && -n \"$SLACK_CHANNEL_ID\" ]]; then\n echo \"ready=true\" >> \"$GITHUB_OUTPUT\"\n fi\n - id: tailor-notify\n if: always() && steps.slack-prereq.outputs.ready == 'true'\n uses: tailor-platform/actions/notify@a3c3032e14277e81039eb26ae1a425adb22eb532 # v1.7.0\n with:\n provider: slack\n status: ${{ job.status }}\n workspace-name: __WORKSPACE_NAME__\n slack-token: ${{ secrets.TAILOR_SLACK_BOT_TOKEN }}\n slack-channel-id: ${{ vars.TAILOR_SLACK_CHANNEL_ID }}\n # user-mapping: ${{ vars.TAILOR_SLACK_USER_MAPPING }}\n";
3440
3487
 
3441
3488
  //#endregion
3442
3489
  //#region src/cli/commands/setup/coordinate.workflow.yml
@@ -3856,9 +3903,8 @@ async function defaultLoadHasStaticWebsites$1(configPath) {
3856
3903
  const { config } = await loadConfig(configPath);
3857
3904
  return (config.staticWebsites?.length ?? 0) > 0;
3858
3905
  }
3859
- const WORKSPACE_NAME_RE = /^[a-z0-9-]+$/;
3860
3906
  function validateWorkspaceName(name) {
3861
- if (name.length < 3 || name.length > 63 || !WORKSPACE_NAME_RE.test(name) || name.startsWith("-") || name.endsWith("-")) throw new Error(`Invalid workspace name "${name}". Names must be 3-63 characters of lowercase letters, numbers, and hyphens, and cannot start or end with a hyphen. Pass a valid name with --name.`);
3907
+ if (!workspaceNameSchema.safeParse(name).success) throw new Error(`Invalid workspace name "${name}". Names must be 3-63 characters of lowercase letters, numbers, and hyphens, and cannot start or end with a hyphen. Pass a valid name with --name.`);
3862
3908
  }
3863
3909
  const BRANCH_RE = /^[A-Za-z0-9._/-]+$/;
3864
3910
  const TAG_PATTERN_RE = /^[A-Za-z0-9._/*?![\]-]+$/;
@@ -5988,7 +6034,7 @@ function resolveNamespace(options) {
5988
6034
  if (options.head && options.head.namespace !== namespace) throw new Error(`Head ERD namespace "${options.head.namespace}" does not match "${namespace}".`);
5989
6035
  return namespace;
5990
6036
  }
5991
- function writeFile(filePath, content) {
6037
+ function writeFile$1(filePath, content) {
5992
6038
  fs$1.mkdirSync(path.dirname(filePath), { recursive: true });
5993
6039
  fs$1.writeFileSync(filePath, content, "utf8");
5994
6040
  }
@@ -6017,12 +6063,12 @@ function writeErdDiff(options) {
6017
6063
  base: baseSchema,
6018
6064
  head: headSchema
6019
6065
  });
6020
- writeFile(options.outputHtml, renderErdDiffHtml({
6066
+ writeFile$1(options.outputHtml, renderErdDiffHtml({
6021
6067
  schema: viewerSchema,
6022
6068
  currentSchema: headSchema,
6023
6069
  diff
6024
6070
  }));
6025
- if (options.outputJson) writeFile(options.outputJson, `${JSON.stringify(diff, null, 2)}\n`);
6071
+ if (options.outputJson) writeFile$1(options.outputJson, `${JSON.stringify(diff, null, 2)}\n`);
6026
6072
  return {
6027
6073
  namespace,
6028
6074
  outputHtml: options.outputHtml,
@@ -6779,7 +6825,7 @@ async function fetchRemoteTypes(client, workspaceId, namespace) {
6779
6825
  async function assertMigrationsReproduceLocalTypes(loaded, target) {
6780
6826
  const { config, plugins } = loaded;
6781
6827
  const pluginManager = plugins.length > 0 ? new PluginManager(plugins) : void 0;
6782
- const { defineApplication, generatePluginFilesIfNeeded } = await import("../application-6zsDLGKv.mjs");
6828
+ const { defineApplication, generatePluginFilesIfNeeded } = await import("../application-Dp_-ioiP.mjs");
6783
6829
  const application = defineApplication({
6784
6830
  config,
6785
6831
  pluginManager
@@ -6791,7 +6837,7 @@ async function assertMigrationsReproduceLocalTypes(loaded, target) {
6791
6837
  await service.processNamespacePlugins();
6792
6838
  }
6793
6839
  const pluginExecutorFiles = generatePluginFilesIfNeeded(pluginManager, application.tailorDBServices, config.path);
6794
- const executorService = application.executorService ?? (pluginExecutorFiles.length > 0 ? (await import("../service-CPMlIg3X.mjs")).createExecutorService({ config: { files: [] } }) : void 0);
6840
+ const executorService = application.executorService ?? (pluginExecutorFiles.length > 0 ? (await import("../service-CghpdV-9.mjs")).createExecutorService({ config: { files: [] } }) : void 0);
6795
6841
  await executorService?.loadExecutors();
6796
6842
  if (pluginExecutorFiles.length > 0) await executorService?.loadPluginExecutorFiles([...pluginExecutorFiles]);
6797
6843
  const executorUsedTypes = /* @__PURE__ */ new Set();
@@ -7062,7 +7108,7 @@ const upgradeCommand = defineAppCommand({
7062
7108
  run: async (args) => {
7063
7109
  const { initTelemetry } = await import("../telemetry-ClwW5ohF.mjs");
7064
7110
  await initTelemetry();
7065
- const { upgrade } = await import("../service-DBFZQloR.mjs");
7111
+ const { upgrade } = await import("../service-Cp0I7ZFe.mjs");
7066
7112
  await upgrade({
7067
7113
  from: args.from,
7068
7114
  dryRun: args["dry-run"],
@@ -7514,7 +7560,8 @@ runMain(mainCommand, {
7514
7560
  displayErrors: false,
7515
7561
  cleanup: async ({ error }) => {
7516
7562
  if (error) {
7517
- if (isCLIError(error)) {
7563
+ if (logger.jsonMode) logger.log(JSON.stringify(errorToJson(error, { includeStack: isVerbose() })));
7564
+ else if (isCLIError(error)) {
7518
7565
  logger.log(error.format());
7519
7566
  if (isVerbose() && error.stack) logger.debug(`\nStack trace:\n${error.stack}`);
7520
7567
  } else if (error instanceof Error) {
@@ -7522,7 +7569,7 @@ runMain(mainCommand, {
7522
7569
  if (isVerbose() && error.stack) logger.debug(`\nStack trace:\n${error.stack}`);
7523
7570
  } else logger.error(`Unknown error: ${error}`);
7524
7571
  if (!isCLIError(error) && (!(error instanceof Error) || error instanceof TypeError || error instanceof RangeError)) {
7525
- const { reportCrash } = await import("../crashreport-np4-_DX2.mjs");
7572
+ const { reportCrash } = await import("../crashreport-BafWvjjX.mjs");
7526
7573
  await reportCrash(error, "handledError");
7527
7574
  }
7528
7575
  }