@tailor-platform/sdk 1.37.0 → 1.39.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 (56) hide show
  1. package/CHANGELOG.md +66 -0
  2. package/dist/application-C1ipG5Q6.mjs +4 -0
  3. package/dist/{application-qRGMV8Tr.mjs → application-DhQrXEld.mjs} +13 -5
  4. package/dist/{application-qRGMV8Tr.mjs.map → application-DhQrXEld.mjs.map} +1 -1
  5. package/dist/cli/index.mjs +364 -123
  6. package/dist/cli/index.mjs.map +1 -1
  7. package/dist/cli/lib.d.mts +6 -6
  8. package/dist/cli/lib.mjs +3 -3
  9. package/dist/{client-424n_3T9.mjs → client-BWAbbA1C.mjs} +1 -1
  10. package/dist/{client-DllDLYmZ.mjs → client-xzPXtc_e.mjs} +9 -3
  11. package/dist/{client-DllDLYmZ.mjs.map → client-xzPXtc_e.mjs.map} +1 -1
  12. package/dist/configure/index.d.mts +5 -5
  13. package/dist/configure/index.mjs +4 -1
  14. package/dist/configure/index.mjs.map +1 -1
  15. package/dist/{crash-report-aHnky_xH.mjs → crash-report-BEAiCSCl.mjs} +1 -1
  16. package/dist/{crash-report-CDQ2JvgR.mjs → crash-report-DXhPL8Ue.mjs} +3 -3
  17. package/dist/{crash-report-CDQ2JvgR.mjs.map → crash-report-DXhPL8Ue.mjs.map} +1 -1
  18. package/dist/{env-04IQXqsl.d.mts → env-CgI46oPS.d.mts} +2 -2
  19. package/dist/errors-D9f2UJpT.mjs +43 -0
  20. package/dist/errors-D9f2UJpT.mjs.map +1 -0
  21. package/dist/{index-BVJQLjyN.d.mts → index-31hm0Fq7.d.mts} +23 -6
  22. package/dist/{index-DnIg_LfT.d.mts → index-B2tsEXdh.d.mts} +2 -2
  23. package/dist/{index-C3kcXHXJ.d.mts → index-DbzopC7M.d.mts} +2 -2
  24. package/dist/{index-CeS4FA9o.d.mts → index-DeBFa7oc.d.mts} +2 -2
  25. package/dist/{index-BUT18Kak.d.mts → index-y5790SX_.d.mts} +2 -2
  26. package/dist/{interceptor-dSNiQq71.mjs → interceptor-CzaH2Ur6.mjs} +1 -1
  27. package/dist/{interceptor-dSNiQq71.mjs.map → interceptor-CzaH2Ur6.mjs.map} +1 -1
  28. package/dist/{logger-C8qBDCKO.mjs → logger-5_JMzHmw.mjs} +42 -3
  29. package/dist/logger-5_JMzHmw.mjs.map +1 -0
  30. package/dist/plugin/builtin/enum-constants/index.d.mts +1 -1
  31. package/dist/plugin/builtin/file-utils/index.d.mts +1 -1
  32. package/dist/plugin/builtin/kysely-type/index.d.mts +1 -1
  33. package/dist/plugin/builtin/seed/index.d.mts +1 -1
  34. package/dist/plugin/index.d.mts +2 -2
  35. package/dist/{plugin-D6P4g_2L.d.mts → plugin-_K3ZfP8B.d.mts} +18 -3
  36. package/dist/{runtime-D9ejnCm6.mjs → runtime-DtSOnOHh.mjs} +32 -54
  37. package/dist/runtime-DtSOnOHh.mjs.map +1 -0
  38. package/dist/service-Bcp6JB3w.mjs +132 -0
  39. package/dist/service-Bcp6JB3w.mjs.map +1 -0
  40. package/dist/utils/test/index.d.mts +2 -2
  41. package/dist/utils/test/index.mjs +6 -2
  42. package/dist/utils/test/index.mjs.map +1 -1
  43. package/dist/{workflow.generated-Bj_DVqGh.d.mts → workflow.generated-BxbnuzAE.d.mts} +2 -2
  44. package/docs/cli/function.md +42 -16
  45. package/docs/cli/upgrade.md +51 -0
  46. package/docs/cli/user.md +1 -1
  47. package/docs/cli/workflow.md +10 -10
  48. package/docs/cli-reference.md +24 -14
  49. package/docs/configuration.md +9 -7
  50. package/docs/generator/index.md +10 -0
  51. package/docs/services/executor.md +39 -0
  52. package/docs/services/tailordb.md +20 -0
  53. package/package.json +7 -7
  54. package/dist/application-ILhZq_oW.mjs +0 -4
  55. package/dist/logger-C8qBDCKO.mjs.map +0 -1
  56. package/dist/runtime-D9ejnCm6.mjs.map +0 -1
@@ -0,0 +1,132 @@
1
+
2
+ import { n as logger, r as styles } from "./logger-5_JMzHmw.mjs";
3
+ import { t as createCLIError } from "./errors-D9f2UJpT.mjs";
4
+ import * as path from "pathe";
5
+ import { readPackageJSON } from "pkg-types";
6
+ import { spawnSync } from "node:child_process";
7
+
8
+ //#region src/cli/commands/upgrade/version-detector.ts
9
+ const SDK_PACKAGE_NAME = "@tailor-platform/sdk";
10
+ /**
11
+ * Detect the installed SDK version from the user's project.
12
+ * Walks up from projectRoot to find the SDK package in node_modules,
13
+ * matching Node's module resolution for workspace setups with hoisted deps.
14
+ * @param projectRoot - The project root directory to search from
15
+ * @returns The installed SDK version string, or null if not found
16
+ */
17
+ async function detectInstalledVersion(projectRoot) {
18
+ let dir = path.resolve(projectRoot);
19
+ while (true) {
20
+ try {
21
+ const pkg = await readPackageJSON(path.join(dir, "node_modules", SDK_PACKAGE_NAME));
22
+ if (pkg.version) return pkg.version;
23
+ } catch {}
24
+ const parent = path.dirname(dir);
25
+ if (parent === dir) break;
26
+ dir = parent;
27
+ }
28
+ return null;
29
+ }
30
+
31
+ //#endregion
32
+ //#region src/cli/commands/upgrade/service.ts
33
+ /**
34
+ * Print the upgrade summary to the terminal.
35
+ * @param output - The parsed JSON output from sdk-codemod
36
+ * @param dryRun - Whether this was a dry-run
37
+ */
38
+ function printUpgradeSummary(output, dryRun) {
39
+ if (dryRun) {
40
+ logger.info(`${styles.bold("[Dry Run]")} No files were modified.`);
41
+ logger.log("");
42
+ }
43
+ const total = output.codemodsApplied + output.codemodsSkipped + output.errors.length;
44
+ logger.info(`Upgrade complete: ${styles.success(`${output.codemodsApplied} applied`)}, ${styles.dim(`${output.codemodsSkipped} skipped`)} (${total} total codemods)`);
45
+ if (output.filesModified.length > 0) {
46
+ logger.log("");
47
+ logger.info(`${dryRun ? "Files that would be modified" : "Modified files"} (${output.filesModified.length}):`);
48
+ for (const file of output.filesModified) logger.log(` ${styles.path(file)}`);
49
+ }
50
+ if (output.warnings.length > 0) {
51
+ logger.log("");
52
+ logger.warn(`Manual attention needed (${output.warnings.length}):`);
53
+ for (const warning of output.warnings) logger.log(` ${styles.warning("!")} ${warning}`);
54
+ }
55
+ if (output.errors.length > 0) {
56
+ logger.log("");
57
+ logger.error(`Failed codemods (${output.errors.length}):`);
58
+ for (const { codemodId, message } of output.errors) logger.log(` ${styles.error(codemodId)}: ${message}`);
59
+ }
60
+ }
61
+ /**
62
+ * Run the upgrade pipeline:
63
+ * 1. Detect target SDK version from node_modules
64
+ * 2. Invoke @tailor-platform/sdk-codemod CLI
65
+ * 3. Parse JSON output and display results
66
+ * @param options - Upgrade options
67
+ */
68
+ async function upgrade(options) {
69
+ const projectRoot = options.path;
70
+ const targetVersion = await detectInstalledVersion(projectRoot);
71
+ if (!targetVersion) throw createCLIError({
72
+ message: `Could not detect installed @tailor-platform/sdk version in ${projectRoot}`,
73
+ suggestion: "Ensure @tailor-platform/sdk is installed. Run 'pnpm install' or 'npm install' first.",
74
+ command: "upgrade"
75
+ });
76
+ logger.info(`Upgrading from ${styles.highlight(options.from)} → ${styles.highlight(targetVersion)}`);
77
+ if (options.dryRun) logger.info(`${styles.bold("[Dry Run]")} Changes will be previewed but not applied.`);
78
+ logger.log("");
79
+ const result = spawnSync(process.platform === "win32" ? "npx.cmd" : "npx", [
80
+ "@tailor-platform/sdk-codemod@latest",
81
+ "--from",
82
+ options.from,
83
+ "--to",
84
+ targetVersion,
85
+ "--target",
86
+ projectRoot,
87
+ ...options.dryRun ? ["--dry-run"] : []
88
+ ], {
89
+ cwd: projectRoot,
90
+ stdio: [
91
+ "ignore",
92
+ "pipe",
93
+ "pipe"
94
+ ],
95
+ encoding: "utf-8",
96
+ timeout: 3e5
97
+ });
98
+ if (result.error) throw createCLIError({
99
+ message: `Failed to run @tailor-platform/sdk-codemod: ${result.error.message}`,
100
+ suggestion: "Ensure npx is available and the network is accessible.",
101
+ command: "upgrade"
102
+ });
103
+ if (result.status !== 0 && !result.stdout?.trim()) throw createCLIError({
104
+ message: `@tailor-platform/sdk-codemod exited with code ${result.status}`,
105
+ details: result.stderr?.trim() || "(no stderr output)",
106
+ suggestion: "Review the error above. Common causes: invalid version arguments, network issues, or missing package registry access.",
107
+ command: "upgrade"
108
+ });
109
+ if (result.stderr) process.stderr.write(result.stderr);
110
+ let output;
111
+ try {
112
+ output = JSON.parse(result.stdout);
113
+ } catch {
114
+ throw createCLIError({
115
+ message: "Failed to parse output from @tailor-platform/sdk-codemod",
116
+ details: result.stdout || "(empty stdout)",
117
+ suggestion: "This is likely a bug. Please report it.",
118
+ command: "upgrade"
119
+ });
120
+ }
121
+ logger.out(output);
122
+ printUpgradeSummary(output, options.dryRun);
123
+ if (output.errors.length > 0) throw createCLIError({
124
+ message: `Upgrade completed with ${output.errors.length} error(s)`,
125
+ suggestion: "Review the errors above and re-run the upgrade after fixing the issues.",
126
+ command: "upgrade"
127
+ });
128
+ }
129
+
130
+ //#endregion
131
+ export { upgrade };
132
+ //# sourceMappingURL=service-Bcp6JB3w.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service-Bcp6JB3w.mjs","names":["CLIError"],"sources":["../src/cli/commands/upgrade/version-detector.ts","../src/cli/commands/upgrade/service.ts"],"sourcesContent":["import * as path from \"pathe\";\nimport { readPackageJSON } from \"pkg-types\";\n\nconst SDK_PACKAGE_NAME = \"@tailor-platform/sdk\";\n\n/**\n * Detect the installed SDK version from the user's project.\n * Walks up from projectRoot to find the SDK package in node_modules,\n * matching Node's module resolution for workspace setups with hoisted deps.\n * @param projectRoot - The project root directory to search from\n * @returns The installed SDK version string, or null if not found\n */\nexport async function detectInstalledVersion(projectRoot: string): Promise<string | null> {\n let dir = path.resolve(projectRoot);\n while (true) {\n try {\n const sdkPath = path.join(dir, \"node_modules\", SDK_PACKAGE_NAME);\n const pkg = await readPackageJSON(sdkPath);\n if (pkg.version) return pkg.version;\n } catch {\n // Not found at this level, try parent\n }\n const parent = path.dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n return null;\n}\n","import { spawnSync } from \"node:child_process\";\nimport { CLIError } from \"@/cli/shared/errors\";\nimport { logger, styles } from \"@/cli/shared/logger\";\nimport { detectInstalledVersion } from \"./version-detector\";\nimport type { RunOutput } from \"./types\";\n\ninterface UpgradeOptions {\n from: string;\n dryRun: boolean;\n path: string;\n}\n\n/**\n * Print the upgrade summary to the terminal.\n * @param output - The parsed JSON output from sdk-codemod\n * @param dryRun - Whether this was a dry-run\n */\nfunction printUpgradeSummary(output: RunOutput, dryRun: boolean): void {\n if (dryRun) {\n logger.info(`${styles.bold(\"[Dry Run]\")} No files were modified.`);\n logger.log(\"\");\n }\n\n const total = output.codemodsApplied + output.codemodsSkipped + output.errors.length;\n logger.info(\n `Upgrade complete: ${styles.success(`${output.codemodsApplied} applied`)}, ${styles.dim(`${output.codemodsSkipped} skipped`)} (${total} total codemods)`,\n );\n\n if (output.filesModified.length > 0) {\n logger.log(\"\");\n logger.info(\n `${dryRun ? \"Files that would be modified\" : \"Modified files\"} (${output.filesModified.length}):`,\n );\n for (const file of output.filesModified) {\n logger.log(` ${styles.path(file)}`);\n }\n }\n\n if (output.warnings.length > 0) {\n logger.log(\"\");\n logger.warn(`Manual attention needed (${output.warnings.length}):`);\n for (const warning of output.warnings) {\n logger.log(` ${styles.warning(\"!\")} ${warning}`);\n }\n }\n\n if (output.errors.length > 0) {\n logger.log(\"\");\n logger.error(`Failed codemods (${output.errors.length}):`);\n for (const { codemodId, message } of output.errors) {\n logger.log(` ${styles.error(codemodId)}: ${message}`);\n }\n }\n}\n\n/**\n * Run the upgrade pipeline:\n * 1. Detect target SDK version from node_modules\n * 2. Invoke @tailor-platform/sdk-codemod CLI\n * 3. Parse JSON output and display results\n * @param options - Upgrade options\n */\nexport async function upgrade(options: UpgradeOptions): Promise<void> {\n const projectRoot = options.path;\n\n // Step 1: Detect target SDK version (the newly installed version)\n const targetVersion = await detectInstalledVersion(projectRoot);\n if (!targetVersion) {\n throw CLIError({\n message: `Could not detect installed @tailor-platform/sdk version in ${projectRoot}`,\n suggestion:\n \"Ensure @tailor-platform/sdk is installed. Run 'pnpm install' or 'npm install' first.\",\n command: \"upgrade\",\n });\n }\n\n logger.info(\n `Upgrading from ${styles.highlight(options.from)} → ${styles.highlight(targetVersion)}`,\n );\n\n if (options.dryRun) {\n logger.info(`${styles.bold(\"[Dry Run]\")} Changes will be previewed but not applied.`);\n }\n\n logger.log(\"\");\n\n // Step 2: Invoke sdk-codemod CLI\n // Use \"latest\" because sdk-codemod may not be published at the exact same\n // version as @tailor-platform/sdk. Version filtering is handled internally\n // by sdk-codemod's registry via the --from / --to arguments.\n const npxCommand = process.platform === \"win32\" ? \"npx.cmd\" : \"npx\";\n\n const result = spawnSync(\n npxCommand,\n [\n \"@tailor-platform/sdk-codemod@latest\",\n \"--from\",\n options.from,\n \"--to\",\n targetVersion,\n \"--target\",\n projectRoot,\n ...(options.dryRun ? [\"--dry-run\"] : []),\n ],\n {\n cwd: projectRoot,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n encoding: \"utf-8\",\n timeout: 300_000,\n },\n );\n\n if (result.error) {\n throw CLIError({\n message: `Failed to run @tailor-platform/sdk-codemod: ${result.error.message}`,\n suggestion: \"Ensure npx is available and the network is accessible.\",\n command: \"upgrade\",\n });\n }\n\n // Check for non-zero exit without a launch error (e.g. registry/auth/network failures)\n if (result.status !== 0 && !result.stdout?.trim()) {\n throw CLIError({\n message: `@tailor-platform/sdk-codemod exited with code ${result.status}`,\n details: result.stderr?.trim() || \"(no stderr output)\",\n suggestion:\n \"Review the error above. Common causes: invalid version arguments, network issues, or missing package registry access.\",\n command: \"upgrade\",\n });\n }\n\n // Forward captured stderr so users see dry-run diffs and progress messages\n // written by sdk-codemod. stderr is piped (not inherited) so that the error\n // path above can surface it via CLIError, but on success we still need to\n // replay it verbatim to keep the colorized unified diff output visible.\n if (result.stderr) {\n process.stderr.write(result.stderr);\n }\n\n // Step 3: Parse JSON output\n let output: RunOutput;\n try {\n output = JSON.parse(result.stdout);\n } catch {\n throw CLIError({\n message: \"Failed to parse output from @tailor-platform/sdk-codemod\",\n details: result.stdout || \"(empty stdout)\",\n suggestion: \"This is likely a bug. Please report it.\",\n command: \"upgrade\",\n });\n }\n\n // Step 4: Display results\n // Emit structured data on stdout (honors --json via logger.out) and\n // human-readable summary on stderr (via printUpgradeSummary).\n logger.out(output);\n printUpgradeSummary(output, options.dryRun);\n\n if (output.errors.length > 0) {\n throw CLIError({\n message: `Upgrade completed with ${output.errors.length} error(s)`,\n suggestion: \"Review the errors above and re-run the upgrade after fixing the issues.\",\n command: \"upgrade\",\n });\n }\n}\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  /// <reference types="@tailor-platform/function-types" />
2
- import { U as TailorDBType, rt as TailorField } from "../../plugin-D6P4g_2L.mjs";
3
- import { n as output, rt as WORKFLOW_TEST_ENV_KEY } from "../../index-BVJQLjyN.mjs";
2
+ import { U as TailorDBType, rt as TailorField } from "../../plugin-_K3ZfP8B.mjs";
3
+ import { n as output, ot as WORKFLOW_TEST_ENV_KEY } from "../../index-31hm0Fq7.mjs";
4
4
  import { StandardSchemaV1 } from "@standard-schema/spec";
5
5
 
6
6
  //#region src/utils/test/mock.d.ts
@@ -113,8 +113,12 @@ function createTailorDBHook(type) {
113
113
  return Object.entries(type.fields).reduce((hooked, [key, value]) => {
114
114
  const field = value;
115
115
  if (key === "id") hooked[key] = (data && typeof data === "object" ? data[key] : void 0) ?? crypto.randomUUID();
116
- else if (field.type === "nested") hooked[key] = createTailorDBHook({ fields: field.fields })(data[key]);
117
- else if (field.metadata.hooks?.create) {
116
+ else if (field.type === "nested") {
117
+ const nestedValue = data && typeof data === "object" ? data[key] : void 0;
118
+ const nestedHook = createTailorDBHook({ fields: field.fields });
119
+ if (field.metadata.array) hooked[key] = Array.isArray(nestedValue) ? nestedValue.map((item) => nestedHook(item)) : nestedValue;
120
+ else hooked[key] = nestedHook(nestedValue);
121
+ } else if (field.metadata.hooks?.create) {
118
122
  hooked[key] = field.metadata.hooks.create({
119
123
  value: data[key],
120
124
  data,
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../../src/utils/test/mock.ts","../../../src/utils/test/index.ts"],"sourcesContent":["import * as path from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\n\ntype MainFunction = (args: Record<string, unknown>) => unknown | Promise<unknown>;\ntype QueryResolver = (query: string, params: unknown[]) => unknown[];\ntype JobHandler = (jobName: string, args: unknown) => unknown;\n\ninterface TailordbGlobal {\n tailordb?: {\n Client: new (config: { namespace?: string }) => {\n connect(): Promise<void> | void;\n end(): Promise<void> | void;\n queryObject(\n query: string,\n params?: unknown[],\n ): Promise<{ rows: unknown[] }> | { rows: unknown[] };\n };\n };\n tailor?: {\n workflow: {\n triggerJobFunction: (jobName: string, args: unknown) => unknown;\n };\n };\n}\n\ninterface TailorErrorItem {\n message: string;\n path: (string | number)[];\n}\n\ninterface TailorErrorsGlobal {\n TailorErrors?: new (errors: TailorErrorItem[]) => Error;\n}\n\nconst GlobalThis = globalThis as TailordbGlobal & TailorErrorsGlobal;\n\n/**\n * Sets up a mock for `globalThis.tailordb.Client` used in bundled resolver/executor tests.\n * @param resolver - Optional function to resolve query results. Defaults to returning empty arrays.\n * @returns Object containing arrays of executed queries and created clients for assertions.\n */\nexport function setupTailordbMock(resolver: QueryResolver = () => []): {\n executedQueries: { query: string; params: unknown[] }[];\n createdClients: { namespace?: string; ended: boolean }[];\n} {\n const executedQueries: { query: string; params: unknown[] }[] = [];\n const createdClients: { namespace?: string; ended: boolean }[] = [];\n\n class MockTailordbClient {\n private record: { namespace?: string; ended: boolean };\n\n constructor({ namespace }: { namespace?: string }) {\n this.record = { namespace, ended: false };\n createdClients.push(this.record);\n }\n\n async connect(): Promise<void> {\n /* noop */\n }\n\n async end(): Promise<void> {\n this.record.ended = true;\n }\n\n async queryObject(query: string, params: unknown[] = []): Promise<{ rows: unknown[] }> {\n executedQueries.push({ query, params });\n return { rows: resolver(query, params) ?? [] };\n }\n }\n\n GlobalThis.tailordb = {\n Client: MockTailordbClient,\n } as typeof GlobalThis.tailordb;\n\n return { executedQueries, createdClients };\n}\n\n/**\n * Sets up a mock for `globalThis.tailor.workflow.triggerJobFunction` used in bundled workflow tests.\n * @param handler - Function that handles triggered job calls and returns results.\n * @returns Object containing an array of triggered jobs for assertions.\n */\nexport function setupWorkflowMock(handler: JobHandler): {\n triggeredJobs: { jobName: string; args: unknown }[];\n} {\n const triggeredJobs: { jobName: string; args: unknown }[] = [];\n\n GlobalThis.tailor = {\n ...GlobalThis.tailor,\n workflow: {\n triggerJobFunction: (jobName: string, args: unknown) => {\n triggeredJobs.push({ jobName, args });\n return handler(jobName, args);\n },\n },\n } as typeof GlobalThis.tailor;\n\n return { triggeredJobs };\n}\n\n/**\n * Sets up a mock for `globalThis.TailorErrors` used in bundled resolver tests.\n * Mimics the PF runtime's TailorErrors class that serializes errors with the `TailorErrors: ` prefix.\n */\nexport function setupTailorErrorsMock(): void {\n GlobalThis.TailorErrors = class TailorErrors extends Error {\n errors: TailorErrorItem[];\n\n constructor(errors: TailorErrorItem[]) {\n super(`TailorErrors: ${JSON.stringify({ errors })}`);\n this.name = \"TailorErrors\";\n this.errors = errors;\n }\n };\n}\n\n/**\n * Creates a function that imports a bundled JS file and returns its `main` export.\n * Used to test bundled output from `apply --buildOnly`.\n * @param baseDir - Base directory where bundled files are located.\n * @returns An async function that takes a relative path and returns the `main` function.\n */\nexport function createImportMain(baseDir: string): (relativePath: string) => Promise<MainFunction> {\n return async (relativePath: string): Promise<MainFunction> => {\n const fileUrl = pathToFileURL(path.join(baseDir, relativePath));\n fileUrl.searchParams.set(\"v\", `${Date.now()}-${Math.random()}`);\n const module = await import(fileUrl.href);\n const main = module.main;\n if (typeof main !== \"function\") {\n throw new Error(`Expected \"main\" to be a function in ${relativePath}, got ${typeof main}`);\n }\n return main;\n };\n}\n","import type { output, TailorUser } from \"@/configure\";\nimport type { TailorDBType } from \"@/configure/services/tailordb/schema\";\nimport type { TailorField } from \"@/configure/types/type\";\nimport type { StandardSchemaV1 } from \"@standard-schema/spec\";\n\nexport { WORKFLOW_TEST_ENV_KEY } from \"@/configure/services/workflow/job\";\nexport {\n setupTailordbMock,\n setupTailorErrorsMock,\n setupWorkflowMock,\n createImportMain,\n} from \"./mock\";\n\n/** Represents an unauthenticated user in the Tailor platform. */\nexport const unauthenticatedTailorUser = {\n id: \"00000000-0000-0000-0000-000000000000\",\n type: \"\",\n workspaceId: \"00000000-0000-0000-0000-000000000000\",\n attributes: null,\n attributeList: [],\n} as const satisfies TailorUser;\n\n/**\n * Creates a hook function that processes TailorDB type fields\n * - Uses existing id from data if provided, otherwise generates UUID for id fields\n * - Recursively processes nested types\n * - Executes hooks.create for fields with create hooks\n * @template T - The output type of the hook function\n * @param type - TailorDB type definition\n * @returns A function that transforms input data according to field hooks\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function createTailorDBHook<T extends TailorDBType<any, any>>(type: T) {\n return (data: unknown) => {\n return Object.entries(type.fields).reduce(\n (hooked, [key, value]) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const field = value as TailorField<any, any, any>;\n if (key === \"id\") {\n // Use existing id from data if provided, otherwise generate new UUID\n const existingId =\n data && typeof data === \"object\" ? (data as Record<string, unknown>)[key] : undefined;\n hooked[key] = existingId ?? crypto.randomUUID();\n } else if (field.type === \"nested\") {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n hooked[key] = createTailorDBHook({ fields: field.fields } as any)(\n (data as Record<string, unknown>)[key],\n );\n } else if (field.metadata.hooks?.create) {\n hooked[key] = field.metadata.hooks.create({\n value: (data as Record<string, unknown>)[key],\n data: data,\n user: unauthenticatedTailorUser,\n });\n if (hooked[key] instanceof Date) {\n hooked[key] = hooked[key].toISOString();\n }\n } else if (data && typeof data === \"object\") {\n hooked[key] = (data as Record<string, unknown>)[key];\n }\n return hooked;\n },\n {} as Record<string, unknown>,\n ) as Partial<output<T>>;\n };\n}\n\n/**\n * Creates the standard schema definition for lines-db\n * This returns the first argument for defineSchema with the ~standard section\n * @template T - The output type after validation\n * @param schemaType - TailorDB field schema for validation\n * @param hook - Hook function to transform data before validation\n * @returns Schema object with ~standard section for defineSchema\n */\nexport function createStandardSchema<T = Record<string, unknown>>(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n schemaType: TailorField<any, T>,\n hook: (data: unknown) => Partial<T>,\n) {\n return {\n \"~standard\": {\n version: 1,\n vendor: \"@tailor-platform/sdk\",\n validate: (value: unknown) => {\n const hooked = hook(value);\n const result = schemaType.parse({\n value: hooked,\n data: hooked,\n user: unauthenticatedTailorUser,\n });\n if (result.issues) {\n return result;\n }\n return { value: hooked as T };\n },\n },\n } as const satisfies StandardSchemaV1<T>;\n}\n"],"mappings":";;;;;;AAkCA,MAAM,aAAa;;;;;;AAOnB,SAAgB,kBAAkB,iBAAgC,EAAE,EAGlE;CACA,MAAM,kBAA0D,EAAE;CAClE,MAAM,iBAA2D,EAAE;CAEnE,MAAM,mBAAmB;EACvB,AAAQ;EAER,YAAY,EAAE,aAAqC;AACjD,QAAK,SAAS;IAAE;IAAW,OAAO;IAAO;AACzC,kBAAe,KAAK,KAAK,OAAO;;EAGlC,MAAM,UAAyB;EAI/B,MAAM,MAAqB;AACzB,QAAK,OAAO,QAAQ;;EAGtB,MAAM,YAAY,OAAe,SAAoB,EAAE,EAAgC;AACrF,mBAAgB,KAAK;IAAE;IAAO;IAAQ,CAAC;AACvC,UAAO,EAAE,MAAM,SAAS,OAAO,OAAO,IAAI,EAAE,EAAE;;;AAIlD,YAAW,WAAW,EACpB,QAAQ,oBACT;AAED,QAAO;EAAE;EAAiB;EAAgB;;;;;;;AAQ5C,SAAgB,kBAAkB,SAEhC;CACA,MAAM,gBAAsD,EAAE;AAE9D,YAAW,SAAS;EAClB,GAAG,WAAW;EACd,UAAU,EACR,qBAAqB,SAAiB,SAAkB;AACtD,iBAAc,KAAK;IAAE;IAAS;IAAM,CAAC;AACrC,UAAO,QAAQ,SAAS,KAAK;KAEhC;EACF;AAED,QAAO,EAAE,eAAe;;;;;;AAO1B,SAAgB,wBAA8B;AAC5C,YAAW,eAAe,MAAM,qBAAqB,MAAM;EACzD;EAEA,YAAY,QAA2B;AACrC,SAAM,iBAAiB,KAAK,UAAU,EAAE,QAAQ,CAAC,GAAG;AACpD,QAAK,OAAO;AACZ,QAAK,SAAS;;;;;;;;;;AAWpB,SAAgB,iBAAiB,SAAkE;AACjG,QAAO,OAAO,iBAAgD;EAC5D,MAAM,UAAU,cAAc,KAAK,KAAK,SAAS,aAAa,CAAC;AAC/D,UAAQ,aAAa,IAAI,KAAK,GAAG,KAAK,KAAK,CAAC,GAAG,KAAK,QAAQ,GAAG;EAE/D,MAAM,QADS,MAAM,OAAO,QAAQ,OAChB;AACpB,MAAI,OAAO,SAAS,WAClB,OAAM,IAAI,MAAM,uCAAuC,aAAa,QAAQ,OAAO,OAAO;AAE5F,SAAO;;;;;;;ACrHX,MAAa,4BAA4B;CACvC,IAAI;CACJ,MAAM;CACN,aAAa;CACb,YAAY;CACZ,eAAe,EAAE;CAClB;;;;;;;;;;AAYD,SAAgB,mBAAqD,MAAS;AAC5E,SAAQ,SAAkB;AACxB,SAAO,OAAO,QAAQ,KAAK,OAAO,CAAC,QAChC,QAAQ,CAAC,KAAK,WAAW;GAExB,MAAM,QAAQ;AACd,OAAI,QAAQ,KAIV,QAAO,QADL,QAAQ,OAAO,SAAS,WAAY,KAAiC,OAAO,WAClD,OAAO,YAAY;YACtC,MAAM,SAAS,SAExB,QAAO,OAAO,mBAAmB,EAAE,QAAQ,MAAM,QAAQ,CAAQ,CAC9D,KAAiC,KACnC;YACQ,MAAM,SAAS,OAAO,QAAQ;AACvC,WAAO,OAAO,MAAM,SAAS,MAAM,OAAO;KACxC,OAAQ,KAAiC;KACnC;KACN,MAAM;KACP,CAAC;AACF,QAAI,OAAO,gBAAgB,KACzB,QAAO,OAAO,OAAO,KAAK,aAAa;cAEhC,QAAQ,OAAO,SAAS,SACjC,QAAO,OAAQ,KAAiC;AAElD,UAAO;KAET,EAAE,CACH;;;;;;;;;;;AAYL,SAAgB,qBAEd,YACA,MACA;AACA,QAAO,EACL,aAAa;EACX,SAAS;EACT,QAAQ;EACR,WAAW,UAAmB;GAC5B,MAAM,SAAS,KAAK,MAAM;GAC1B,MAAM,SAAS,WAAW,MAAM;IAC9B,OAAO;IACP,MAAM;IACN,MAAM;IACP,CAAC;AACF,OAAI,OAAO,OACT,QAAO;AAET,UAAO,EAAE,OAAO,QAAa;;EAEhC,EACF"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../../src/utils/test/mock.ts","../../../src/utils/test/index.ts"],"sourcesContent":["import * as path from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\n\ntype MainFunction = (args: Record<string, unknown>) => unknown | Promise<unknown>;\ntype QueryResolver = (query: string, params: unknown[]) => unknown[];\ntype JobHandler = (jobName: string, args: unknown) => unknown;\n\ninterface TailordbGlobal {\n tailordb?: {\n Client: new (config: { namespace?: string }) => {\n connect(): Promise<void> | void;\n end(): Promise<void> | void;\n queryObject(\n query: string,\n params?: unknown[],\n ): Promise<{ rows: unknown[] }> | { rows: unknown[] };\n };\n };\n tailor?: {\n workflow: {\n triggerJobFunction: (jobName: string, args: unknown) => unknown;\n };\n };\n}\n\ninterface TailorErrorItem {\n message: string;\n path: (string | number)[];\n}\n\ninterface TailorErrorsGlobal {\n TailorErrors?: new (errors: TailorErrorItem[]) => Error;\n}\n\nconst GlobalThis = globalThis as TailordbGlobal & TailorErrorsGlobal;\n\n/**\n * Sets up a mock for `globalThis.tailordb.Client` used in bundled resolver/executor tests.\n * @param resolver - Optional function to resolve query results. Defaults to returning empty arrays.\n * @returns Object containing arrays of executed queries and created clients for assertions.\n */\nexport function setupTailordbMock(resolver: QueryResolver = () => []): {\n executedQueries: { query: string; params: unknown[] }[];\n createdClients: { namespace?: string; ended: boolean }[];\n} {\n const executedQueries: { query: string; params: unknown[] }[] = [];\n const createdClients: { namespace?: string; ended: boolean }[] = [];\n\n class MockTailordbClient {\n private record: { namespace?: string; ended: boolean };\n\n constructor({ namespace }: { namespace?: string }) {\n this.record = { namespace, ended: false };\n createdClients.push(this.record);\n }\n\n async connect(): Promise<void> {\n /* noop */\n }\n\n async end(): Promise<void> {\n this.record.ended = true;\n }\n\n async queryObject(query: string, params: unknown[] = []): Promise<{ rows: unknown[] }> {\n executedQueries.push({ query, params });\n return { rows: resolver(query, params) ?? [] };\n }\n }\n\n GlobalThis.tailordb = {\n Client: MockTailordbClient,\n } as typeof GlobalThis.tailordb;\n\n return { executedQueries, createdClients };\n}\n\n/**\n * Sets up a mock for `globalThis.tailor.workflow.triggerJobFunction` used in bundled workflow tests.\n * @param handler - Function that handles triggered job calls and returns results.\n * @returns Object containing an array of triggered jobs for assertions.\n */\nexport function setupWorkflowMock(handler: JobHandler): {\n triggeredJobs: { jobName: string; args: unknown }[];\n} {\n const triggeredJobs: { jobName: string; args: unknown }[] = [];\n\n GlobalThis.tailor = {\n ...GlobalThis.tailor,\n workflow: {\n triggerJobFunction: (jobName: string, args: unknown) => {\n triggeredJobs.push({ jobName, args });\n return handler(jobName, args);\n },\n },\n } as typeof GlobalThis.tailor;\n\n return { triggeredJobs };\n}\n\n/**\n * Sets up a mock for `globalThis.TailorErrors` used in bundled resolver tests.\n * Mimics the PF runtime's TailorErrors class that serializes errors with the `TailorErrors: ` prefix.\n */\nexport function setupTailorErrorsMock(): void {\n GlobalThis.TailorErrors = class TailorErrors extends Error {\n errors: TailorErrorItem[];\n\n constructor(errors: TailorErrorItem[]) {\n super(`TailorErrors: ${JSON.stringify({ errors })}`);\n this.name = \"TailorErrors\";\n this.errors = errors;\n }\n };\n}\n\n/**\n * Creates a function that imports a bundled JS file and returns its `main` export.\n * Used to test bundled output from `apply --buildOnly`.\n * @param baseDir - Base directory where bundled files are located.\n * @returns An async function that takes a relative path and returns the `main` function.\n */\nexport function createImportMain(baseDir: string): (relativePath: string) => Promise<MainFunction> {\n return async (relativePath: string): Promise<MainFunction> => {\n const fileUrl = pathToFileURL(path.join(baseDir, relativePath));\n fileUrl.searchParams.set(\"v\", `${Date.now()}-${Math.random()}`);\n const module = await import(fileUrl.href);\n const main = module.main;\n if (typeof main !== \"function\") {\n throw new Error(`Expected \"main\" to be a function in ${relativePath}, got ${typeof main}`);\n }\n return main;\n };\n}\n","import type { output, TailorUser } from \"@/configure\";\nimport type { TailorDBType } from \"@/configure/services/tailordb/schema\";\nimport type { TailorField } from \"@/configure/types/type\";\nimport type { StandardSchemaV1 } from \"@standard-schema/spec\";\n\nexport { WORKFLOW_TEST_ENV_KEY } from \"@/configure/services/workflow/job\";\nexport {\n setupTailordbMock,\n setupTailorErrorsMock,\n setupWorkflowMock,\n createImportMain,\n} from \"./mock\";\n\n/** Represents an unauthenticated user in the Tailor platform. */\nexport const unauthenticatedTailorUser = {\n id: \"00000000-0000-0000-0000-000000000000\",\n type: \"\",\n workspaceId: \"00000000-0000-0000-0000-000000000000\",\n attributes: null,\n attributeList: [],\n} as const satisfies TailorUser;\n\n/**\n * Creates a hook function that processes TailorDB type fields\n * - Uses existing id from data if provided, otherwise generates UUID for id fields\n * - Recursively processes nested types\n * - Executes hooks.create for fields with create hooks\n * @template T - The output type of the hook function\n * @param type - TailorDB type definition\n * @returns A function that transforms input data according to field hooks\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function createTailorDBHook<T extends TailorDBType<any, any>>(type: T) {\n return (data: unknown) => {\n return Object.entries(type.fields).reduce(\n (hooked, [key, value]) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const field = value as TailorField<any, any, any>;\n if (key === \"id\") {\n // Use existing id from data if provided, otherwise generate new UUID\n const existingId =\n data && typeof data === \"object\" ? (data as Record<string, unknown>)[key] : undefined;\n hooked[key] = existingId ?? crypto.randomUUID();\n } else if (field.type === \"nested\") {\n const nestedValue =\n data && typeof data === \"object\" ? (data as Record<string, unknown>)[key] : undefined;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const nestedHook = createTailorDBHook({ fields: field.fields } as any);\n if (field.metadata.array) {\n // For nested array fields, recurse per element and pass through non-array values\n // (e.g. null/undefined for optional fields) so validation sees the original value.\n hooked[key] = Array.isArray(nestedValue)\n ? nestedValue.map((item) => nestedHook(item))\n : nestedValue;\n } else {\n hooked[key] = nestedHook(nestedValue);\n }\n } else if (field.metadata.hooks?.create) {\n hooked[key] = field.metadata.hooks.create({\n value: (data as Record<string, unknown>)[key],\n data: data,\n user: unauthenticatedTailorUser,\n });\n if (hooked[key] instanceof Date) {\n hooked[key] = hooked[key].toISOString();\n }\n } else if (data && typeof data === \"object\") {\n hooked[key] = (data as Record<string, unknown>)[key];\n }\n return hooked;\n },\n {} as Record<string, unknown>,\n ) as Partial<output<T>>;\n };\n}\n\n/**\n * Creates the standard schema definition for lines-db\n * This returns the first argument for defineSchema with the ~standard section\n * @template T - The output type after validation\n * @param schemaType - TailorDB field schema for validation\n * @param hook - Hook function to transform data before validation\n * @returns Schema object with ~standard section for defineSchema\n */\nexport function createStandardSchema<T = Record<string, unknown>>(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n schemaType: TailorField<any, T>,\n hook: (data: unknown) => Partial<T>,\n) {\n return {\n \"~standard\": {\n version: 1,\n vendor: \"@tailor-platform/sdk\",\n validate: (value: unknown) => {\n const hooked = hook(value);\n const result = schemaType.parse({\n value: hooked,\n data: hooked,\n user: unauthenticatedTailorUser,\n });\n if (result.issues) {\n return result;\n }\n return { value: hooked as T };\n },\n },\n } as const satisfies StandardSchemaV1<T>;\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  /// <reference types="@tailor-platform/function-types" />
2
- import { Nt as BuiltinIdP, S as TailorDBServiceInput, T as AuthConfig } from "./plugin-D6P4g_2L.mjs";
2
+ import { Pt as BuiltinIdP, S as TailorDBServiceInput, T as AuthConfig } from "./plugin-_K3ZfP8B.mjs";
3
3
 
4
4
  //#region src/types/idp.generated.d.ts
5
5
  /**
@@ -411,4 +411,4 @@ type RetryPolicy = {
411
411
  };
412
412
  //#endregion
413
413
  export { IdpDefinitionBrand as _, ResolverExternalConfig as a, IdPGqlOperationsInput as b, WorkflowServiceConfig as c, defineStaticWebSite as d, SecretsConfig as f, IdPUserField as g, IdPExternalConfig as h, ExecutorServiceInput as i, WorkflowServiceInput as l, IdPConfig as m, AppConfig as n, ResolverServiceConfig as o, defineSecretManager as p, ExecutorServiceConfig as r, ResolverServiceInput as s, RetryPolicy as t, StaticWebsiteConfig as u, IdPEmailConfig as v, IdPInput as x, IdPGqlOperations as y };
414
- //# sourceMappingURL=workflow.generated-Bj_DVqGh.d.mts.map
414
+ //# sourceMappingURL=workflow.generated-BxbnuzAE.d.mts.map
@@ -89,20 +89,46 @@ See [Global Options](../cli-reference.md#global-options) for options available t
89
89
 
90
90
  <!-- politty:command:function logs:global-options-link:end -->
91
91
 
92
- **Usage Examples:**
92
+ <!-- politty:command:function logs:examples:start -->
93
+
94
+ **Examples**
95
+
96
+ **List all function execution logs**
97
+
98
+ ```bash
99
+ $ tailor-sdk function logs
100
+ ```
101
+
102
+ **Get execution details with logs**
103
+
104
+ ```bash
105
+ $ tailor-sdk function logs <execution-id>
106
+ ```
107
+
108
+ **Output as JSON**
93
109
 
94
110
  ```bash
95
- # List all function execution logs
96
- tailor-sdk function logs
111
+ $ tailor-sdk function logs --json
112
+ ```
97
113
 
98
- # Get execution details with logs
99
- tailor-sdk function logs <execution-id>
114
+ **Get execution details as JSON**
100
115
 
101
- # Output as JSON
102
- tailor-sdk function logs --json
103
- tailor-sdk function logs <execution-id> --json
116
+ ```bash
117
+ $ tailor-sdk function logs <execution-id> --json
104
118
  ```
105
119
 
120
+ <!-- politty:command:function logs:examples:end -->
121
+
122
+ <!-- politty:command:function logs:notes:start -->
123
+
124
+ **Notes**
125
+
126
+ When viewing a specific execution that failed, the command displays error details with the stack trace mapped back to original source files via the inline sourcemap (clickable file links and code snippets, matching `function test-run` output).
127
+
128
+ When the deployed script cannot be downloaded or the function has been redeployed since the execution, the command falls back to a plain-text error display to avoid showing misleading source locations.
129
+
130
+ <!-- politty:command:function logs:notes:end -->
131
+
106
132
  <!-- politty:command:function test-run:heading:start -->
107
133
 
108
134
  ### function test-run
@@ -135,14 +161,14 @@ tailor-sdk function test-run [options] <file>
135
161
 
136
162
  **Options**
137
163
 
138
- | Option | Alias | Description | Required | Default | Env |
139
- | ------------------------------- | ----- | ------------------------------------------------------------------------ | -------- | -------------------- | ------------------------------ |
140
- | `--workspace-id <WORKSPACE_ID>` | `-w` | Workspace ID | No | - | `TAILOR_PLATFORM_WORKSPACE_ID` |
141
- | `--profile <PROFILE>` | `-p` | Workspace profile | No | - | `TAILOR_PLATFORM_PROFILE` |
142
- | `--name <NAME>` | `-n` | Workflow job name to run (matches the `name` field of createWorkflowJob) | No | - | - |
143
- | `--arg <ARG>` | `-a` | JSON argument to pass to the function | No | - | - |
144
- | `--machine-user <MACHINE_USER>` | `-m` | Machine user name for authentication | No | - | - |
145
- | `--config <CONFIG>` | `-c` | Path to SDK config file | No | `"tailor.config.ts"` | - |
164
+ | Option | Alias | Description | Required | Default | Env |
165
+ | ------------------------------- | ----- | ------------------------------------------------------------------------ | -------- | -------------------- | ----------------------------------- |
166
+ | `--workspace-id <WORKSPACE_ID>` | `-w` | Workspace ID | No | - | `TAILOR_PLATFORM_WORKSPACE_ID` |
167
+ | `--profile <PROFILE>` | `-p` | Workspace profile | No | - | `TAILOR_PLATFORM_PROFILE` |
168
+ | `--name <NAME>` | `-n` | Workflow job name to run (matches the `name` field of createWorkflowJob) | No | - | - |
169
+ | `--arg <ARG>` | `-a` | JSON argument to pass to the function | No | - | - |
170
+ | `--machine-user <MACHINE_USER>` | `-m` | Machine user name for authentication | No | - | `TAILOR_PLATFORM_MACHINE_USER_NAME` |
171
+ | `--config <CONFIG>` | `-c` | Path to SDK config file | No | `"tailor.config.ts"` | - |
146
172
 
147
173
  <!-- politty:command:function test-run:options:end -->
148
174
  <!-- politty:command:function test-run:examples:start -->
@@ -0,0 +1,51 @@
1
+ <!-- politty:command:upgrade:heading:start -->
2
+
3
+ ## upgrade
4
+
5
+ <!-- politty:command:upgrade:heading:end -->
6
+
7
+ <!-- politty:command:upgrade:description:start -->
8
+
9
+ Run codemods to upgrade your project to a newer SDK version.
10
+
11
+ <!-- politty:command:upgrade:description:end -->
12
+
13
+ <!-- politty:command:upgrade:usage:start -->
14
+
15
+ **Usage**
16
+
17
+ ```
18
+ tailor-sdk upgrade [options]
19
+ ```
20
+
21
+ <!-- politty:command:upgrade:usage:end -->
22
+
23
+ <!-- politty:command:upgrade:options:start -->
24
+
25
+ **Options**
26
+
27
+ | Option | Alias | Description | Required | Default |
28
+ | --------------- | ----- | --------------------------------------------- | -------- | ------- |
29
+ | `--from <FROM>` | - | SDK version before the upgrade (e.g., 1.33.0) | Yes | - |
30
+ | `--dry-run` | `-d` | Preview changes without modifying files | No | `false` |
31
+ | `--path <PATH>` | - | Project directory to upgrade | No | `"."` |
32
+
33
+ <!-- politty:command:upgrade:options:end -->
34
+
35
+ <!-- politty:command:upgrade:global-options-link:start -->
36
+
37
+ See [Global Options](../cli-reference.md#global-options) for options available to all commands.
38
+
39
+ <!-- politty:command:upgrade:global-options-link:end -->
40
+
41
+ ### How It Works
42
+
43
+ The `upgrade` command runs codemods that automatically transform your project code for breaking changes between SDK versions. The target version (`--to`) is auto-detected from the installed `@tailor-platform/sdk` in `node_modules`.
44
+
45
+ **Typical workflow:**
46
+
47
+ 1. Update your SDK packages to the new version (e.g., `pnpm update @tailor-platform/sdk`)
48
+ 2. Run `tailor-sdk upgrade --from <old-version>` to apply codemods
49
+ 3. Review changes and commit
50
+
51
+ Use `--dry-run` to preview what changes will be made before applying them.
package/docs/cli/user.md CHANGED
@@ -38,7 +38,7 @@ _no options_
38
38
 
39
39
  | Option | Alias | Description | Required | Default | Env |
40
40
  | --------------------------------- | ----- | --------------------------------- | -------- | ------- | -------------------------------------------- |
41
- | `--machineuser <MACHINEUSER>` | - | Login as a platform machine user. | Yes | - | - |
41
+ | `--machine-user <MACHINE_USER>` | - | Login as a platform machine user. | Yes | - | - |
42
42
  | `--client-id <CLIENT_ID>` | - | Client ID | Yes | - | `TAILOR_PLATFORM_MACHINE_USER_CLIENT_ID` |
43
43
  | `--client-secret <CLIENT_SECRET>` | - | Client secret | No | - | `TAILOR_PLATFORM_MACHINE_USER_CLIENT_SECRET` |
44
44
 
@@ -165,16 +165,16 @@ tailor-sdk workflow start [options] <name>
165
165
 
166
166
  **Options**
167
167
 
168
- | Option | Alias | Description | Required | Default | Env |
169
- | ------------------------------- | ----- | -------------------------------------------------------------- | -------- | -------------------- | --------------------------------- |
170
- | `--workspace-id <WORKSPACE_ID>` | `-w` | Workspace ID | No | - | `TAILOR_PLATFORM_WORKSPACE_ID` |
171
- | `--profile <PROFILE>` | `-p` | Workspace profile | No | - | `TAILOR_PLATFORM_PROFILE` |
172
- | `--config <CONFIG>` | `-c` | Path to SDK config file | No | `"tailor.config.ts"` | `TAILOR_PLATFORM_SDK_CONFIG_PATH` |
173
- | `--machineuser <MACHINEUSER>` | `-m` | Machine user name | Yes | - | - |
174
- | `--arg <ARG>` | `-a` | Workflow argument (JSON string) | No | - | - |
175
- | `--wait` | `-W` | Wait for execution to complete | No | `false` | - |
176
- | `--interval <INTERVAL>` | `-i` | Polling interval when using --wait (e.g., '3s', '500ms', '1m') | No | `"3s"` | - |
177
- | `--logs` | `-l` | Display job execution logs after completion (requires --wait) | No | `false` | - |
168
+ | Option | Alias | Description | Required | Default | Env |
169
+ | ------------------------------- | ----- | -------------------------------------------------------------- | -------- | -------------------- | ----------------------------------- |
170
+ | `--workspace-id <WORKSPACE_ID>` | `-w` | Workspace ID | No | - | `TAILOR_PLATFORM_WORKSPACE_ID` |
171
+ | `--profile <PROFILE>` | `-p` | Workspace profile | No | - | `TAILOR_PLATFORM_PROFILE` |
172
+ | `--config <CONFIG>` | `-c` | Path to SDK config file | No | `"tailor.config.ts"` | `TAILOR_PLATFORM_SDK_CONFIG_PATH` |
173
+ | `--machine-user <MACHINE_USER>` | `-m` | Machine user name | Yes | - | `TAILOR_PLATFORM_MACHINE_USER_NAME` |
174
+ | `--arg <ARG>` | `-a` | Workflow argument (JSON string) | No | - | - |
175
+ | `--wait` | `-W` | Wait for execution to complete | No | `false` | - |
176
+ | `--interval <INTERVAL>` | `-i` | Polling interval when using --wait (e.g., '3s', '500ms', '1m') | No | `"3s"` | - |
177
+ | `--logs` | `-l` | Display job execution logs after completion (requires --wait) | No | `false` | - |
178
178
 
179
179
  <!-- politty:command:workflow start:options:end -->
180
180
 
@@ -53,20 +53,22 @@ tailor-sdk apply --env-file .env --env-file .env.production
53
53
 
54
54
  You can use environment variables to configure workspace and authentication:
55
55
 
56
- | Variable | Description |
57
- | -------------------------------------------- | --------------------------------------------------------------------------- |
58
- | `TAILOR_PLATFORM_WORKSPACE_ID` | Workspace ID for deployment commands |
59
- | `TAILOR_PLATFORM_ORGANIZATION_ID` | Organization ID for organization commands |
60
- | `TAILOR_PLATFORM_FOLDER_ID` | Folder ID for folder commands |
61
- | `TAILOR_PLATFORM_TOKEN` | Authentication token (alternative to `login`) |
62
- | `TAILOR_TOKEN` | **Deprecated.** Use `TAILOR_PLATFORM_TOKEN` instead |
63
- | `TAILOR_PLATFORM_PROFILE` | Workspace profile name |
64
- | `TAILOR_PLATFORM_SDK_CONFIG_PATH` | Path to SDK config file |
65
- | `TAILOR_PLATFORM_MACHINE_USER_CLIENT_ID` | Client ID for `login --machineuser` |
66
- | `TAILOR_PLATFORM_MACHINE_USER_CLIENT_SECRET` | Client secret for `login --machineuser` |
67
- | `VISUAL` / `EDITOR` | Preferred editor for commands that open files (e.g., `vim`, `code`, `nano`) |
68
- | `TAILOR_CRASH_REPORTS_LOCAL` | Local crash log writing: `on` (default) or `off` |
69
- | `TAILOR_CRASH_REPORTS_REMOTE` | Automatic crash report submission: `off` (default) or `on` |
56
+ | Variable | Description |
57
+ | -------------------------------------------- | ---------------------------------------------------------------------------- |
58
+ | `TAILOR_PLATFORM_WORKSPACE_ID` | Workspace ID for deployment commands |
59
+ | `TAILOR_PLATFORM_ORGANIZATION_ID` | Organization ID for organization commands |
60
+ | `TAILOR_PLATFORM_FOLDER_ID` | Folder ID for folder commands |
61
+ | `TAILOR_PLATFORM_TOKEN` | Authentication token (alternative to `login`) |
62
+ | `TAILOR_TOKEN` | **Deprecated.** Use `TAILOR_PLATFORM_TOKEN` instead |
63
+ | `TAILOR_PLATFORM_PROFILE` | Workspace profile name |
64
+ | `TAILOR_PLATFORM_SDK_CONFIG_PATH` | Path to SDK config file |
65
+ | `TAILOR_PLATFORM_SDK_DTS_PATH` | Output path for generated `tailor.d.ts` type definition file |
66
+ | `TAILOR_PLATFORM_MACHINE_USER_CLIENT_ID` | Client ID for `login --machine-user` |
67
+ | `TAILOR_PLATFORM_MACHINE_USER_CLIENT_SECRET` | Client secret for `login --machine-user` |
68
+ | `TAILOR_PLATFORM_MACHINE_USER_NAME` | Default machine user name for `query`, `workflow start`, `function test-run` |
69
+ | `VISUAL` / `EDITOR` | Preferred editor for commands that open files (e.g., `vim`, `code`, `nano`) |
70
+ | `TAILOR_CRASH_REPORTS_LOCAL` | Local crash log writing: `on` (default) or `off` |
71
+ | `TAILOR_CRASH_REPORTS_REMOTE` | Automatic crash report submission: `off` (default) or `on` |
70
72
 
71
73
  ### Authentication Token Priority
72
74
 
@@ -259,6 +261,14 @@ Commands for setting up project infrastructure.
259
261
  | ------------------------------------------- | ------------------------------------------------------- |
260
262
  | [setup github](./cli/setup.md#setup-github) | Generate GitHub Actions workflow for deployment. (beta) |
261
263
 
264
+ ### [Upgrade Commands](./cli/upgrade.md)
265
+
266
+ Commands for upgrading SDK versions with automated code migration.
267
+
268
+ | Command | Description |
269
+ | ----------------------------------- | ------------------------------------------------------------ |
270
+ | [upgrade](./cli/upgrade.md#upgrade) | Run codemods to upgrade your project to a newer SDK version. |
271
+
262
272
  ### [Completion](./cli/completion.md)
263
273
 
264
274
  Generate shell completion scripts for bash, zsh, and fish.
@@ -218,17 +218,19 @@ export default defineConfig({
218
218
 
219
219
  **ignores**: Glob patterns to exclude files. Optional.
220
220
 
221
- ### Generators
221
+ ### Plugins
222
222
 
223
- Configure code generators using `defineGenerators()`. Generators must be exported as a named export.
223
+ Configure plugins using `definePlugins()`. Plugins must be exported as a named export.
224
224
 
225
225
  ```typescript
226
- import { defineGenerators } from "@tailor-platform/sdk";
226
+ import { definePlugins } from "@tailor-platform/sdk";
227
+ import { kyselyTypePlugin } from "@tailor-platform/sdk/plugin/kysely-type";
228
+ import { enumConstantsPlugin } from "@tailor-platform/sdk/plugin/enum-constants";
227
229
 
228
- export const generators = defineGenerators(
229
- ["@tailor-platform/kysely-type", { distPath: "./generated/tailordb.ts" }],
230
- ["@tailor-platform/enum-constants", { distPath: "./generated/enums.ts" }],
230
+ export const plugins = definePlugins(
231
+ kyselyTypePlugin({ distPath: "./generated/tailordb.ts" }),
232
+ enumConstantsPlugin({ distPath: "./generated/enums.ts" }),
231
233
  );
232
234
  ```
233
235
 
234
- See [Generators](./generator/index.md) for full documentation.
236
+ See [Generators](./generator/index.md) for legacy `defineGenerators()` documentation.
@@ -50,6 +50,16 @@ tailor-sdk generate --watch
50
50
 
51
51
  Watches for file changes and regenerates automatically.
52
52
 
53
+ ## Environment Variables
54
+
55
+ ### `TAILOR_PLATFORM_SDK_DTS_PATH`
56
+
57
+ Customize the output path of the generated `tailor.d.ts` type definition file. By default, `tailor.d.ts` is written next to `tailor.config.ts`.
58
+
59
+ ```bash
60
+ TAILOR_PLATFORM_SDK_DTS_PATH=src/types/tailor.d.ts tailor-sdk generate
61
+ ```
62
+
53
63
  ## Generator Types
54
64
 
55
65
  - [Builtin Generators](./builtin.md) - Ready-to-use generators included with the SDK
@@ -88,6 +88,25 @@ type WebhookRequest = {
88
88
  incomingWebhookTrigger<WebhookRequest>();
89
89
  ```
90
90
 
91
+ You can customize the HTTP response returned to the webhook caller:
92
+
93
+ ```typescript
94
+ // Response body only (shorthand)
95
+ incomingWebhookTrigger<WebhookRequest>({
96
+ response: (args) => ({ challenge: args.body.challenge }),
97
+ });
98
+
99
+ // Response body with custom status code
100
+ incomingWebhookTrigger<WebhookRequest>({
101
+ response: {
102
+ body: (args) => ({ challenge: args.body.challenge }),
103
+ statusCode: 201,
104
+ },
105
+ });
106
+ ```
107
+
108
+ If `body` is set without `statusCode`, the platform uses 200. If neither is set, the platform returns 204.
109
+
91
110
  ### Resolver Executed Trigger
92
111
 
93
112
  Fires when a resolver is executed:
@@ -433,6 +452,26 @@ export default createExecutor({
433
452
  });
434
453
  ```
435
454
 
455
+ **With custom response:**
456
+
457
+ ```typescript
458
+ export default createExecutor({
459
+ name: "slack-challenge",
460
+ trigger: incomingWebhookTrigger<{
461
+ body: { challenge: string; type: string };
462
+ headers: Record<string, string>;
463
+ }>({
464
+ response: (args) => ({ challenge: args.body.challenge }),
465
+ }),
466
+ operation: {
467
+ kind: "function",
468
+ body: async ({ body }) => {
469
+ console.log(`Received ${body.type} event`);
470
+ },
471
+ },
472
+ });
473
+ ```
474
+
436
475
  ### Resolver Executed Payload
437
476
 
438
477
  Resolver triggers receive the resolver's result or error:
@@ -96,11 +96,31 @@ db.enum([
96
96
  ### Object Fields
97
97
 
98
98
  ```typescript
99
+ // Object field
99
100
  db.object({
100
101
  street: db.string(),
101
102
  city: db.string(),
102
103
  country: db.string(),
103
104
  });
105
+
106
+ // Object array field
107
+ db.object(
108
+ {
109
+ id: db.uuid(),
110
+ name: db.string(),
111
+ size: db.int(),
112
+ },
113
+ { array: true },
114
+ );
115
+
116
+ // Optional object array field
117
+ db.object(
118
+ {
119
+ kind: db.string(),
120
+ days: db.int(),
121
+ },
122
+ { optional: true, array: true },
123
+ );
104
124
  ```
105
125
 
106
126
  ## Field Modifiers