@tailor-platform/sdk 1.39.1 → 1.40.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 (53) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/README.md +7 -10
  3. package/dist/{actor-Bb4OVq1j.d.mts → actor-B2oEmlTc.d.mts} +2 -2
  4. package/dist/application-CEeKm4R-.mjs +4 -0
  5. package/dist/{application-BHu8YE-g.mjs → application-C_LFXkKJ.mjs} +2 -2
  6. package/dist/{application-BHu8YE-g.mjs.map → application-C_LFXkKJ.mjs.map} +1 -1
  7. package/dist/cli/index.mjs +153 -32
  8. package/dist/cli/index.mjs.map +1 -1
  9. package/dist/cli/lib.d.mts +40 -6
  10. package/dist/cli/lib.mjs +3 -3
  11. package/dist/cli/skills.mjs +13 -43
  12. package/dist/cli/skills.mjs.map +1 -1
  13. package/dist/{client-B2K45RvK.mjs → client-DjGFRjH4.mjs} +31 -3
  14. package/dist/{client-B2K45RvK.mjs.map → client-DjGFRjH4.mjs.map} +1 -1
  15. package/dist/client-Dtf48x0o.mjs +4 -0
  16. package/dist/configure/index.d.mts +4 -4
  17. package/dist/{crash-report-CPUF3T5d.mjs → crash-report-CEIXtw4D.mjs} +1 -1
  18. package/dist/{crash-report-CACiemAr.mjs → crash-report-CSWITsTz.mjs} +2 -2
  19. package/dist/{crash-report-CACiemAr.mjs.map → crash-report-CSWITsTz.mjs.map} +1 -1
  20. package/dist/{index-Cx1RYDbu.d.mts → index-BtXZdz-F.d.mts} +2 -2
  21. package/dist/{index-CeFwhUkX.d.mts → index-Chvw1Eod.d.mts} +2 -2
  22. package/dist/{index-Ch8Em3nz.d.mts → index-CiNNNpuH.d.mts} +2 -2
  23. package/dist/{index-BYmdVno1.d.mts → index-D_ezppY7.d.mts} +4 -4
  24. package/dist/{index-DLO_XvLi.d.mts → index-reFAYSX7.d.mts} +2 -2
  25. package/dist/{interceptor-B5bKVwgq.mjs → interceptor-4UC-KTno.mjs} +1 -1
  26. package/dist/{interceptor-B5bKVwgq.mjs.map → interceptor-4UC-KTno.mjs.map} +1 -1
  27. package/dist/plugin/builtin/enum-constants/index.d.mts +1 -1
  28. package/dist/plugin/builtin/file-utils/index.d.mts +1 -1
  29. package/dist/plugin/builtin/kysely-type/index.d.mts +1 -1
  30. package/dist/plugin/builtin/seed/index.d.mts +1 -1
  31. package/dist/plugin/index.d.mts +2 -2
  32. package/dist/repl-editor-DjycioU-.mjs +255 -0
  33. package/dist/repl-editor-DjycioU-.mjs.map +1 -0
  34. package/dist/{runtime-2xqzvkQv.mjs → runtime-im7Sq4jO.mjs} +231 -171
  35. package/dist/runtime-im7Sq4jO.mjs.map +1 -0
  36. package/dist/{tailor-db-field-B99RnR2N.d.mts → tailor-db-field-CoFKRCYW.d.mts} +1 -1
  37. package/dist/utils/test/index.d.mts +2 -2
  38. package/dist/{workflow.generated-DSwr-k57.d.mts → workflow.generated-Btz6srLR.d.mts} +2 -2
  39. package/docs/cli/auth.md +20 -14
  40. package/docs/cli/executor.md +17 -14
  41. package/docs/cli/function.md +6 -4
  42. package/docs/cli/query.md +45 -0
  43. package/docs/cli/secret.md +13 -9
  44. package/docs/cli/skills.md +75 -0
  45. package/docs/cli/staticwebsite.md +6 -4
  46. package/docs/cli/user.md +9 -1
  47. package/docs/cli/workflow.md +17 -13
  48. package/docs/cli-reference.md +16 -0
  49. package/docs/services/workflow.md +1 -1
  50. package/package.json +11 -8
  51. package/dist/application-C8Lr37AM.mjs +0 -4
  52. package/dist/client-CEVmv94H.mjs +0 -4
  53. package/dist/runtime-2xqzvkQv.mjs.map +0 -1
@@ -0,0 +1,4 @@
1
+
2
+ import { a as fetchMachineUserToken, c as fetchUserInfo, d as initOperatorClient, f as parseMethodName, h as userAgent, i as fetchAll, l as formatRequestParams, m as resolveStaticWebsiteUrls, n as closeConnectionPool, o as fetchPaged, p as platformBaseUrl, r as createTransport, s as fetchPlatformMachineUserToken, t as MAX_PAGE_SIZE, u as initOAuth2Client } from "./client-DjGFRjH4.mjs";
3
+
4
+ export { userAgent };
@@ -1,6 +1,6 @@
1
1
  /// <reference types="@tailor-platform/function-types" />
2
- import { B as BeforeLoginHookArgs, C as ResolverReadyContext, Ct as SCIMAuthorization, Et as TenantProvider, F as AuthConfig, G as UserAttributeListKey, H as OAuth2ClientGrantType, Ht as unauthenticatedTailorUser, I as AuthConnectionTokenResult, J as ValueOperand, K as UserAttributeMap, L as AuthExternalConfig, Lt as AttributeList, Q as Resolver, R as AuthOwnConfig, Rt as AttributeMap, S as ResolverNamespaceData, St as SCIMAttributeMapping, T as TailorDBReadyContext, Tt as SCIMResource, U as SCIMAttributeType, V as DefinedAuth, Vt as TailorUser, W as UserAttributeKey, X as AuthConnectionConfig, Z as AuthConnectionOAuth2Config, _ as PluginProcessContext, _t as IdProvider, a as NamespacePluginOutput, b as ExecutorReadyContext, bt as SAML, c as PluginConfigs, d as PluginGeneratedExecutor, f as PluginGeneratedExecutorWithFile, g as PluginOutput, gt as IDToken, h as PluginNamespaceProcessContext, ht as BuiltinIdP, l as PluginExecutorContext, m as PluginGeneratedType, o as Plugin, p as PluginGeneratedResolver, q as UsernameFieldKey, s as PluginAttachment, u as PluginExecutorContextBase, v as TailorDBTypeForPlugin, vt as OAuth2ClientInput, w as TailorDBNamespaceData, wt as SCIMConfig, x as GeneratorResult, xt as SCIMAttribute, y as TypePluginOutput, yt as OIDC, z as AuthServiceInput } from "../tailor-db-field-B99RnR2N.mjs";
3
- import { A as TailorTypeGqlPermission, C as TailorAnyDBField, D as TailorDBType, E as TailorDBInstance, M as unsafeAllowAllGqlPermission, N as unsafeAllowAllTypePermission, O as db, T as TailorDBField, a as ResolverExternalConfig, b as IdPGqlOperations, c as WorkflowServiceConfig, g as IdPExternalConfig, h as IdPConfig, i as ExecutorServiceInput, j as TailorTypePermission, k as PermissionCondition, l as WorkflowServiceInput, o as ResolverServiceConfig, p as SecretsConfig, r as ExecutorServiceConfig, s as ResolverServiceInput, t as RetryPolicy, u as StaticWebsiteConfig, w as TailorAnyDBType, x as IdPGqlOperationsInput, y as IdPEmailConfig } from "../workflow.generated-DSwr-k57.mjs";
4
- import { $ as resolverExecutedTrigger, A as IdpUserArgs, B as TailorDBTrigger, C as ScheduleTrigger, D as AuthAccessTokenRefreshedArgs, E as AuthAccessTokenIssuedArgs, F as RecordCreatedArgs, G as idpUserCreatedTrigger, H as authAccessTokenRefreshedTrigger, I as RecordDeletedArgs, J as idpUserUpdatedTrigger, K as idpUserDeletedTrigger, L as RecordUpdatedArgs, M as IdpUserDeletedArgs, N as IdpUserTrigger, O as AuthAccessTokenRevokedArgs, P as IdpUserUpdatedArgs, Q as recordUpdatedTrigger, R as ResolverExecutedArgs, S as ScheduleArgs, T as AuthAccessTokenArgs, U as authAccessTokenRevokedTrigger, V as authAccessTokenIssuedTrigger, W as authAccessTokenTrigger, X as recordDeletedTrigger, Y as recordCreatedTrigger, Z as recordTrigger, _ as IncomingWebhookResponse, _t as defineAuth, a as defineGenerators, at as Workflow, b as IncomingWebhookTriggerOptions, bt as MachineUserNameRegistry, c as defineIdp, ct as WORKFLOW_TEST_ENV_KEY, d as unsafeAllowAllIdPPermission, dt as WorkflowJobInput, et as FunctionOperation, f as defineStaticWebSite, ft as WorkflowJobOutput, g as IncomingWebhookRequest, gt as AuthInvoker, h as IncomingWebhookArgs, ht as createResolver, i as defineConfig, it as WorkflowOperation, j as IdpUserCreatedArgs, k as AuthAccessTokenTrigger, l as IdPPermission, lt as WorkflowJob, m as Trigger, mt as QueryType, n as output, nt as Operation, o as definePlugins, ot as WorkflowConfig, p as createExecutor, pt as createWorkflowJob, q as idpUserTrigger, r as t, rt as WebhookOperation, s as defineSecretManager, st as createWorkflow, t as __Infer, tt as GqlOperation, u as IdPPermissionCondition, ut as WorkflowJobContext, v as IncomingWebhookResponseConfig, vt as TailorField, w as scheduleTrigger, x as incomingWebhookTrigger, y as IncomingWebhookTrigger, yt as MachineUserName, z as ResolverExecutedTrigger } from "../index-BYmdVno1.mjs";
5
- import { n as Env } from "../actor-Bb4OVq1j.mjs";
2
+ import { B as BeforeLoginHookArgs, C as ResolverReadyContext, Ct as SCIMAuthorization, Et as TenantProvider, F as AuthConfig, G as UserAttributeListKey, H as OAuth2ClientGrantType, Ht as unauthenticatedTailorUser, I as AuthConnectionTokenResult, J as ValueOperand, K as UserAttributeMap, L as AuthExternalConfig, Lt as AttributeList, Q as Resolver, R as AuthOwnConfig, Rt as AttributeMap, S as ResolverNamespaceData, St as SCIMAttributeMapping, T as TailorDBReadyContext, Tt as SCIMResource, U as SCIMAttributeType, V as DefinedAuth, Vt as TailorUser, W as UserAttributeKey, X as AuthConnectionConfig, Z as AuthConnectionOAuth2Config, _ as PluginProcessContext, _t as IdProvider, a as NamespacePluginOutput, b as ExecutorReadyContext, bt as SAML, c as PluginConfigs, d as PluginGeneratedExecutor, f as PluginGeneratedExecutorWithFile, g as PluginOutput, gt as IDToken, h as PluginNamespaceProcessContext, ht as BuiltinIdP, l as PluginExecutorContext, m as PluginGeneratedType, o as Plugin, p as PluginGeneratedResolver, q as UsernameFieldKey, s as PluginAttachment, u as PluginExecutorContextBase, v as TailorDBTypeForPlugin, vt as OAuth2ClientInput, w as TailorDBNamespaceData, wt as SCIMConfig, x as GeneratorResult, xt as SCIMAttribute, y as TypePluginOutput, yt as OIDC, z as AuthServiceInput } from "../tailor-db-field-CoFKRCYW.mjs";
3
+ import { A as TailorTypeGqlPermission, C as TailorAnyDBField, D as TailorDBType, E as TailorDBInstance, M as unsafeAllowAllGqlPermission, N as unsafeAllowAllTypePermission, O as db, T as TailorDBField, a as ResolverExternalConfig, b as IdPGqlOperations, c as WorkflowServiceConfig, g as IdPExternalConfig, h as IdPConfig, i as ExecutorServiceInput, j as TailorTypePermission, k as PermissionCondition, l as WorkflowServiceInput, o as ResolverServiceConfig, p as SecretsConfig, r as ExecutorServiceConfig, s as ResolverServiceInput, t as RetryPolicy, u as StaticWebsiteConfig, w as TailorAnyDBType, x as IdPGqlOperationsInput, y as IdPEmailConfig } from "../workflow.generated-Btz6srLR.mjs";
4
+ import { $ as resolverExecutedTrigger, A as IdpUserArgs, B as TailorDBTrigger, C as ScheduleTrigger, D as AuthAccessTokenRefreshedArgs, E as AuthAccessTokenIssuedArgs, F as RecordCreatedArgs, G as idpUserCreatedTrigger, H as authAccessTokenRefreshedTrigger, I as RecordDeletedArgs, J as idpUserUpdatedTrigger, K as idpUserDeletedTrigger, L as RecordUpdatedArgs, M as IdpUserDeletedArgs, N as IdpUserTrigger, O as AuthAccessTokenRevokedArgs, P as IdpUserUpdatedArgs, Q as recordUpdatedTrigger, R as ResolverExecutedArgs, S as ScheduleArgs, T as AuthAccessTokenArgs, U as authAccessTokenRevokedTrigger, V as authAccessTokenIssuedTrigger, W as authAccessTokenTrigger, X as recordDeletedTrigger, Y as recordCreatedTrigger, Z as recordTrigger, _ as IncomingWebhookResponse, _t as defineAuth, a as defineGenerators, at as Workflow, b as IncomingWebhookTriggerOptions, bt as MachineUserNameRegistry, c as defineIdp, ct as WORKFLOW_TEST_ENV_KEY, d as unsafeAllowAllIdPPermission, dt as WorkflowJobInput, et as FunctionOperation, f as defineStaticWebSite, ft as WorkflowJobOutput, g as IncomingWebhookRequest, gt as AuthInvoker, h as IncomingWebhookArgs, ht as createResolver, i as defineConfig, it as WorkflowOperation, j as IdpUserCreatedArgs, k as AuthAccessTokenTrigger, l as IdPPermission, lt as WorkflowJob, m as Trigger, mt as QueryType, n as output, nt as Operation, o as definePlugins, ot as WorkflowConfig, p as createExecutor, pt as createWorkflowJob, q as idpUserTrigger, r as t, rt as WebhookOperation, s as defineSecretManager, st as createWorkflow, t as __Infer, tt as GqlOperation, u as IdPPermissionCondition, ut as WorkflowJobContext, v as IncomingWebhookResponseConfig, vt as TailorField, w as scheduleTrigger, x as incomingWebhookTrigger, y as IncomingWebhookTrigger, yt as MachineUserName, z as ResolverExecutedTrigger } from "../index-D_ezppY7.mjs";
5
+ import { n as Env } from "../actor-B2oEmlTc.mjs";
6
6
  export { AttributeList, AttributeMap, AuthAccessTokenArgs, AuthAccessTokenIssuedArgs, AuthAccessTokenRefreshedArgs, AuthAccessTokenRevokedArgs, AuthAccessTokenTrigger, AuthConfig, AuthConnectionConfig, AuthConnectionOAuth2Config, AuthConnectionTokenResult, AuthExternalConfig, AuthInvoker, AuthOwnConfig, AuthServiceInput, BeforeLoginHookArgs, BuiltinIdP, DefinedAuth, Env, ExecutorReadyContext, ExecutorServiceConfig, ExecutorServiceInput, FunctionOperation, GeneratorResult, GqlOperation, IDToken, IdPConfig, IdPEmailConfig, IdPExternalConfig, IdPGqlOperations, IdPGqlOperationsInput as IdPGqlOperationsConfig, IdPPermission, IdPPermissionCondition, IdProvider as IdProviderConfig, IdpUserArgs, IdpUserCreatedArgs, IdpUserDeletedArgs, IdpUserTrigger, IdpUserUpdatedArgs, IncomingWebhookArgs, IncomingWebhookRequest, IncomingWebhookResponse, IncomingWebhookResponseConfig, IncomingWebhookTrigger, IncomingWebhookTriggerOptions, MachineUserName, MachineUserNameRegistry, NamespacePluginOutput, OAuth2ClientInput as OAuth2Client, OAuth2ClientGrantType, OIDC, Operation, PermissionCondition, Plugin, PluginAttachment, PluginConfigs, PluginExecutorContext, PluginExecutorContextBase, PluginGeneratedExecutor, PluginGeneratedExecutorWithFile, PluginGeneratedResolver, PluginGeneratedType, PluginNamespaceProcessContext, PluginOutput, PluginProcessContext, QueryType, RecordCreatedArgs, RecordDeletedArgs, RecordUpdatedArgs, Resolver, ResolverExecutedArgs, ResolverExecutedTrigger, ResolverExternalConfig, ResolverNamespaceData, ResolverReadyContext, ResolverServiceConfig, ResolverServiceInput, RetryPolicy, SAML, SCIMAttribute, SCIMAttributeMapping, SCIMAttributeType, SCIMAuthorization, SCIMConfig, SCIMResource, ScheduleArgs, ScheduleTrigger, SecretsConfig, StaticWebsiteConfig, TailorAnyDBField, TailorAnyDBType, TailorDBField, TailorDBInstance, TailorDBNamespaceData, TailorDBReadyContext, TailorDBTrigger, TailorDBType, TailorDBTypeForPlugin, TailorField, TailorTypeGqlPermission, TailorTypePermission, TailorUser, TenantProvider as TenantProviderConfig, Trigger, TypePluginOutput, UserAttributeKey, UserAttributeListKey, UserAttributeMap, UsernameFieldKey, ValueOperand, WORKFLOW_TEST_ENV_KEY, WebhookOperation, Workflow, WorkflowConfig, WorkflowJob, WorkflowJobContext, WorkflowJobInput, WorkflowJobOutput, WorkflowOperation, WorkflowServiceConfig, WorkflowServiceInput, authAccessTokenIssuedTrigger, authAccessTokenRefreshedTrigger, authAccessTokenRevokedTrigger, authAccessTokenTrigger, createExecutor, createResolver, createWorkflow, createWorkflowJob, db, defineAuth, defineConfig, defineGenerators, defineIdp, definePlugins, defineSecretManager, defineStaticWebSite, idpUserCreatedTrigger, idpUserDeletedTrigger, idpUserTrigger, idpUserUpdatedTrigger, incomingWebhookTrigger, infer, output, recordCreatedTrigger, recordDeletedTrigger, recordTrigger, recordUpdatedTrigger, resolverExecutedTrigger, scheduleTrigger, t, unauthenticatedTailorUser, unsafeAllowAllGqlPermission, unsafeAllowAllIdPPermission, unsafeAllowAllTypePermission };
@@ -1,4 +1,4 @@
1
1
 
2
- import { n as reportCrash, t as initCrashReporting } from "./crash-report-CACiemAr.mjs";
2
+ import { n as reportCrash, t as initCrashReporting } from "./crash-report-CSWITsTz.mjs";
3
3
 
4
4
  export { reportCrash };
@@ -386,7 +386,7 @@ async function reportCrash(error, errorType) {
386
386
  ].join("\n"));
387
387
  }
388
388
  if (config.remoteEnabled) {
389
- const { userAgent } = await import("./client-CEVmv94H.mjs");
389
+ const { userAgent } = await import("./client-Dtf48x0o.mjs");
390
390
  await sendCrashReport(report, await userAgent());
391
391
  }
392
392
  } catch {}
@@ -412,4 +412,4 @@ function initCrashReporting() {
412
412
 
413
413
  //#endregion
414
414
  export { JSON_FOOTER_MARKER as a, CRASH_LOG_EXTENSION as i, reportCrash as n, parseCrashReportConfig as o, sendCrashReport as r, initCrashReporting as t };
415
- //# sourceMappingURL=crash-report-CACiemAr.mjs.map
415
+ //# sourceMappingURL=crash-report-CSWITsTz.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"crash-report-CACiemAr.mjs","names":[],"sources":["../src/cli/crash-report/config.ts","../src/cli/crash-report/writer.ts","../src/cli/crash-report/sender.ts","../src/cli/crash-report/sanitize.ts","../src/cli/crash-report/report.ts","../src/cli/crash-report/index.ts"],"sourcesContent":["import * as path from \"pathe\";\nimport { isCI } from \"std-env\";\nimport { xdgConfig } from \"xdg-basedir\";\n\nexport interface CrashReportConfig {\n readonly localEnabled: boolean;\n readonly remoteEnabled: boolean;\n readonly localDir: string;\n}\n\n/**\n * Parse crash report configuration from environment variables.\n * Local crash log writing is enabled by default (opt-out via TAILOR_CRASH_REPORTS_LOCAL=off).\n * Remote sending is disabled by default (opt-in via TAILOR_CRASH_REPORTS_REMOTE=on).\n * Both are auto-disabled in CI environments.\n * @returns Crash report configuration\n */\nexport function parseCrashReportConfig(): CrashReportConfig {\n if (isCI) {\n return {\n localEnabled: false,\n remoteEnabled: false,\n localDir: \"\",\n };\n }\n\n const localEnabled = (process.env.TAILOR_CRASH_REPORTS_LOCAL ?? \"on\").toLowerCase() !== \"off\";\n const remoteEnabled = (process.env.TAILOR_CRASH_REPORTS_REMOTE ?? \"off\").toLowerCase() === \"on\";\n const localDir = xdgConfig ? path.join(xdgConfig, \"tailor-platform\", \"crash-reports\") : \"\";\n\n return {\n localEnabled: localEnabled && localDir !== \"\",\n remoteEnabled,\n localDir,\n };\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"pathe\";\nimport type { CrashReport } from \"./report\";\n\nconst MAX_CRASH_FILES = 10;\n\n/** Marker line that separates human-readable content from the JSON footer. */\nexport const JSON_FOOTER_MARKER = \"--- JSON ---\";\n\n/** File extension for crash log files. */\nexport const CRASH_LOG_EXTENSION = \".crash.log\";\n\n/**\n * Format a CrashReport as human-readable text for local crash log files.\n * @param report - Crash report to format\n * @returns Formatted text content\n */\nexport function formatCrashReport(report: CrashReport): string {\n const lines = [\n `Crash Report: ${report.id}`,\n `Timestamp: ${report.timestamp}`,\n `Error Type: ${report.errorType}`,\n \"\",\n \"--- Environment ---\",\n `SDK Version: ${report.sdkVersion}`,\n `Node Version: ${report.nodeVersion}`,\n `OS: ${report.osPlatform} ${report.osRelease}`,\n `Arch: ${report.arch}`,\n \"\",\n \"--- Command ---\",\n `Command: ${report.command}`,\n `Arguments: ${JSON.stringify(report.argv)}`,\n \"\",\n \"--- Error ---\",\n `Name: ${report.errorName}`,\n `Message: ${report.errorMessage}`,\n \"\",\n \"--- Stack Trace ---\",\n report.stackTrace || \"(no stack trace available)\",\n \"\",\n JSON_FOOTER_MARKER,\n JSON.stringify(report),\n \"\",\n ];\n return lines.join(\"\\n\");\n}\n\n/**\n * Generate a filename for a crash log file.\n * Format: {timestamp}-{shortId}.crash.log\n * @param report - Crash report to generate filename for\n * @returns Filename string\n */\nfunction generateFilename(report: CrashReport): string {\n const safeTimestamp = report.timestamp.replace(/[:.]/g, \"-\");\n const shortId = report.id.slice(0, 8);\n return `${safeTimestamp}-${shortId}${CRASH_LOG_EXTENSION}`;\n}\n\n/**\n * Remove old crash log files, keeping only the most recent ones.\n * @param dir - Crash log directory\n */\nfunction cleanupOldFiles(dir: string): void {\n try {\n const files = fs\n .readdirSync(dir)\n .filter((f) => f.endsWith(CRASH_LOG_EXTENSION))\n .sort()\n .reverse();\n\n for (const file of files.slice(MAX_CRASH_FILES)) {\n fs.unlinkSync(path.join(dir, file));\n }\n } catch {\n // Best-effort cleanup, ignore errors\n }\n}\n\n/**\n * Write a crash report to a local file.\n * Creates the directory if it doesn't exist. Keeps only the last 10 crash files.\n * Never throws - returns the file path on success or undefined on failure.\n * @param report - Crash report to write\n * @param dir - Directory to write the crash log file to\n * @returns File path on success, undefined on failure\n */\nexport function writeCrashReport(report: CrashReport, dir: string): string | undefined {\n try {\n fs.mkdirSync(dir, { recursive: true });\n\n const filename = generateFilename(report);\n const filePath = path.join(dir, filename);\n const content = formatCrashReport(report);\n\n fs.writeFileSync(filePath, content, \"utf-8\");\n cleanupOldFiles(dir);\n\n return filePath;\n } catch {\n return undefined;\n }\n}\n","import type { CrashReport } from \"./report\";\n\nconst SEND_TIMEOUT_MS = 5000;\nconst PRODUCTION_ENDPOINT = \"https://sdk-error-tracking-926vh9t4cl.erp.dev/query\";\n\nconst SUBMIT_MUTATION = `\nmutation SubmitCrashReport(\n $id: String!\n $timestamp: String!\n $sdkVersion: String!\n $nodeVersion: String!\n $osPlatform: String!\n $osRelease: String!\n $arch: String!\n $command: String!\n $argv: [String]\n $errorName: String!\n $errorMessage: String!\n $stackTrace: String\n $errorType: String!\n $userId: String\n $userEmail: String\n) {\n submitCrashReport(\n id: $id\n timestamp: $timestamp\n sdkVersion: $sdkVersion\n nodeVersion: $nodeVersion\n osPlatform: $osPlatform\n osRelease: $osRelease\n arch: $arch\n command: $command\n argv: $argv\n errorName: $errorName\n errorMessage: $errorMessage\n stackTrace: $stackTrace\n errorType: $errorType\n userId: $userId\n userEmail: $userEmail\n ) {\n success\n }\n}`;\n\n/**\n * Send a crash report to the remote endpoint via GraphQL mutation.\n * Best-effort: never throws, returns boolean success.\n * @param report - Crash report to send\n * @param ua - User-Agent header value\n * @returns true if the request succeeded, false otherwise\n */\nexport async function sendCrashReport(report: CrashReport, ua: string): Promise<boolean> {\n try {\n const endpoint = process.env.TAILOR_CRASH_REPORT_ENDPOINT || PRODUCTION_ENDPOINT;\n const response = await fetch(endpoint, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"User-Agent\": ua,\n },\n body: JSON.stringify({\n query: SUBMIT_MUTATION,\n variables: report,\n }),\n signal: AbortSignal.timeout(SEND_TIMEOUT_MS),\n });\n\n if (!response.ok) return false;\n\n const data = (await response.json()) as {\n errors?: unknown[];\n data?: { submitCrashReport: { success: boolean } };\n };\n if (data.errors?.length) return false;\n return data.data?.submitCrashReport.success === true;\n } catch {\n return false;\n }\n}\n","import * as os from \"node:os\";\n\nconst HOME_DIR = os.homedir();\n\n// Patterns for sanitization (global variants for use with .replace())\nconst UUID_PATTERN = /\\b[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\\b/gi;\nconst LONG_HEX_PATTERN = /\\b[0-9a-fA-F]{32,}\\b/g;\nconst EMAIL_PATTERN = /\\b[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}\\b/g;\nconst ABSOLUTE_PATH_PATTERN = /(?:\\/(?:[\\w.@\\- ]+\\/)+[\\w.@\\- ]+)/g;\nconst WINDOWS_PATH_PATTERN = /(?:[A-Za-z]:\\\\(?:[\\w.@\\- ]+\\\\)+[\\w.@\\- ]+)/g;\nconst URL_QUERY_PATTERN = /[?&][^?\\s]*/g;\n\n// Non-global variants for single-match .test() calls (avoids lastIndex state issues)\nconst EMAIL_TEST_PATTERN = /\\b[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}\\b/;\nconst WINDOWS_DRIVE_TEST_PATTERN = /^[A-Za-z]:\\\\/;\n\n// SDK package path marker for relative paths\nconst SDK_PACKAGE_MARKER = \"packages/sdk/\";\n\nfunction lastSegment(filePath: string, separator: string): string {\n return filePath.split(separator).pop() ?? filePath;\n}\n\n/**\n * Sanitize a stack trace by replacing absolute paths with relative SDK paths.\n * External paths are replaced with `<external>/filename.ext`.\n * Home directories are replaced with `~/<redacted>/`.\n * @param stack - Raw stack trace string\n * @returns Sanitized stack trace\n */\nexport function sanitizeStackTrace(stack: string): string {\n // V8 stack traces start with \"ErrorType: message\\n at ...\".\n // The error message may span multiple lines before the first \" at \" frame.\n // Apply message sanitization to all message lines so secrets embedded in\n // multiline error messages are redacted consistently with errorMessage.\n const firstFrameIndex = stack.search(/\\n\\s+at /);\n let result: string;\n if (firstFrameIndex !== -1) {\n result = sanitizeMessage(stack.slice(0, firstFrameIndex)) + stack.slice(firstFrameIndex);\n } else {\n result = sanitizeMessage(stack);\n }\n\n result = result.replace(ABSOLUTE_PATH_PATTERN, (match) => {\n const sdkIndex = match.indexOf(SDK_PACKAGE_MARKER);\n if (sdkIndex !== -1) {\n return match.slice(sdkIndex);\n }\n\n if (match.startsWith(HOME_DIR)) {\n return `~/<redacted>/${lastSegment(match, \"/\")}`;\n }\n\n return `<external>/${lastSegment(match, \"/\")}`;\n });\n result = result.replace(WINDOWS_PATH_PATTERN, (match) => {\n const normalized = match.replace(/\\\\/g, \"/\");\n const sdkIndex = normalized.indexOf(SDK_PACKAGE_MARKER);\n if (sdkIndex !== -1) {\n return normalized.slice(sdkIndex);\n }\n return `<external>/${lastSegment(match, \"\\\\\")}`;\n });\n return result;\n}\n\n/**\n * Sanitize an error message by redacting sensitive information.\n * Redacts: UUIDs, long hex tokens, email addresses, absolute paths, URL query strings.\n * @param message - Raw error message\n * @returns Sanitized error message\n */\nexport function sanitizeMessage(message: string): string {\n let result = message;\n // Strip serialized request/response bodies that may contain secrets\n result = result.replace(/\\nRequest:\\s*[\\s\\S]*$/, \"\\nRequest: <redacted>\");\n result = result.replace(UUID_PATTERN, \"<uuid>\");\n result = result.replace(LONG_HEX_PATTERN, \"<redacted>\");\n result = result.replace(EMAIL_PATTERN, \"<email>\");\n result = result.replace(URL_QUERY_PATTERN, \"?<redacted>\");\n result = result.replace(ABSOLUTE_PATH_PATTERN, (match) => `<path>/${lastSegment(match, \"/\")}`);\n result = result.replace(WINDOWS_PATH_PATTERN, (match) => `<path>/${lastSegment(match, \"\\\\\")}`);\n\n return result;\n}\n\n/**\n * Sanitize process.argv by keeping command/subcommand names and redacting\n * values of sensitive flags.\n * @param argv - Raw process.argv array\n * @returns Sanitized argv array\n */\nexport function sanitizeArgv(argv: string[]): string[] {\n const result: string[] = [];\n let redactNext = false;\n\n for (const arg of argv) {\n if (redactNext) {\n // If the next token is itself a flag, treat it as a new flag rather\n // than consuming it as the previous flag's value. This avoids leaking\n // the *next* flag's value (e.g., `--verbose --workspace-id secret`\n // would otherwise expose `secret`).\n if (!arg.startsWith(\"-\")) {\n result.push(\"<redacted>\");\n redactNext = false;\n continue;\n }\n redactNext = false;\n }\n\n if (arg.startsWith(\"-\")) {\n // --flag=value: keep flag name, redact value\n const eqIndex = arg.indexOf(\"=\");\n if (eqIndex !== -1) {\n result.push(`${arg.slice(0, eqIndex)}=<redacted>`);\n continue;\n }\n\n // --flag / -f: keep flag name, redact next arg as its value\n result.push(arg);\n redactNext = true;\n continue;\n }\n\n // Redact absolute paths\n if (arg.startsWith(\"/\") && arg.includes(\"/\", 1)) {\n result.push(\"<path>\");\n continue;\n }\n\n // Redact Windows-style absolute paths\n if (WINDOWS_DRIVE_TEST_PATTERN.test(arg)) {\n result.push(\"<path>\");\n continue;\n }\n\n // Redact email addresses\n if (EMAIL_TEST_PATTERN.test(arg)) {\n result.push(\"<email>\");\n continue;\n }\n\n result.push(arg);\n }\n\n return result;\n}\n","import * as crypto from \"node:crypto\";\nimport * as fs from \"node:fs\";\nimport * as os from \"node:os\";\nimport { parseYAML } from \"confbox\";\nimport * as path from \"pathe\";\nimport { xdgConfig } from \"xdg-basedir\";\nimport { sanitizeArgv, sanitizeMessage, sanitizeStackTrace } from \"./sanitize\";\n\nexport type ErrorType = \"uncaughtException\" | \"unhandledRejection\" | \"handledError\";\n\nexport interface CrashReport {\n id: string;\n timestamp: string;\n sdkVersion: string;\n nodeVersion: string;\n osPlatform: string;\n osRelease: string;\n arch: string;\n command: string;\n argv: string[];\n errorName: string;\n errorMessage: string;\n stackTrace: string;\n errorType: ErrorType;\n userId: string | null;\n userEmail: string | null;\n}\n\ninterface BuildCrashReportOptions {\n error: unknown;\n sdkVersion: string;\n errorType: ErrorType;\n}\n\n// Maximum subcommand depth to keep (e.g., \"tailordb migrate generate\" = 3 tokens).\n// Positional arguments beyond this are potentially sensitive user input.\n// Accepted trade-off: plain-text positional args that don't match known patterns\n// (UUIDs, hex tokens, emails, paths) pass through to `command` and `argv`.\n// Full redaction would require embedding the CLI command tree here, which is fragile.\nconst MAX_COMMAND_TOKENS = 3;\n\n/**\n * Parse the command name from process.argv.\n * Extracts up to MAX_COMMAND_TOKENS non-flag arguments after the script name.\n * @returns Parsed command string\n */\nfunction parseCommand(): string {\n const args = process.argv.slice(2);\n const commandParts: string[] = [];\n for (const arg of args) {\n if (arg.startsWith(\"-\") || commandParts.length >= MAX_COMMAND_TOKENS) break;\n commandParts.push(arg);\n }\n return commandParts.join(\" \") || \"<unknown>\";\n}\n\n/**\n * Build a CrashReport data structure from an error and context.\n * All sensitive data is sanitized before inclusion.\n * @param options - Error, SDK version, and crash type\n * @returns Sanitized crash report\n */\nexport function buildCrashReport(options: BuildCrashReportOptions): CrashReport {\n const { error, sdkVersion, errorType } = options;\n\n const isError = error instanceof Error;\n const rawMessage = isError ? error.message : String(error);\n const rawStack = isError && error.stack ? error.stack : \"\";\n const errorName = isError ? error.name : \"UnknownError\";\n\n const currentUser = readCurrentUser();\n\n return {\n id: crypto.randomUUID(),\n timestamp: new Date().toISOString(),\n sdkVersion,\n nodeVersion: process.version,\n osPlatform: process.platform,\n osRelease: os.release(),\n arch: process.arch,\n command: sanitizeMessage(parseCommand()),\n argv: sanitizeArgv(process.argv),\n errorName,\n errorMessage: sanitizeMessage(rawMessage),\n stackTrace: sanitizeStackTrace(rawStack),\n errorType,\n userId: currentUser,\n userEmail: currentUser,\n };\n}\n\n/**\n * Read current_user from Tailor Platform config without side effects.\n * Unlike readPlatformConfig(), this never triggers migration or logs warnings.\n * @returns The current user email, or null if unavailable\n */\nfunction readCurrentUser(): string | null {\n try {\n if (!xdgConfig) return null;\n const configPath = path.join(xdgConfig, \"tailor-platform\", \"config.yaml\");\n if (!fs.existsSync(configPath)) return null;\n const raw = parseYAML(fs.readFileSync(configPath, \"utf-8\")) as { current_user?: string | null };\n return raw?.current_user ?? null;\n } catch {\n return null;\n }\n}\n","import { logger } from \"@/cli/shared/logger\";\nimport { readPackageJson } from \"@/cli/shared/package-json\";\nimport { parseCrashReportConfig } from \"./config\";\nimport { buildCrashReport, type ErrorType } from \"./report\";\nimport { sendCrashReport } from \"./sender\";\nimport { writeCrashReport } from \"./writer\";\n\n/**\n * Report an unexpected crash. Writes a local crash log file and optionally\n * sends the report to a remote endpoint. Displays a user-facing message\n * with the crash log path and a command to submit the report.\n *\n * Never throws - all errors are silently caught.\n * @param error - The error that caused the crash\n * @param errorType - How the error was caught\n */\nexport async function reportCrash(error: unknown, errorType: ErrorType): Promise<void> {\n try {\n const config = parseCrashReportConfig();\n if (!config.localEnabled && !config.remoteEnabled) return;\n\n const packageJson = await readPackageJson();\n const sdkVersion = packageJson.version ?? \"unknown\";\n\n const report = buildCrashReport({ error, sdkVersion, errorType });\n\n if (config.localEnabled) {\n const filePath = writeCrashReport(report, config.localDir);\n if (filePath) {\n logger.log(\n [\n \"\",\n \"An unexpected error occurred. A crash report has been saved to:\",\n ` ${filePath}`,\n \"\",\n \"To submit this report:\",\n ` tailor-sdk crash-report send --file \"${filePath}\"`,\n ].join(\"\\n\"),\n );\n }\n }\n\n if (config.remoteEnabled) {\n // Lazy import: client.ts pulls in heavy dependencies (OAuth2, Connect, Protobuf)\n // that should not be loaded on the startup critical path via initCrashReporting().\n const { userAgent } = await import(\"@/cli/shared/client\");\n const ua = await userAgent();\n await sendCrashReport(report, ua);\n }\n } catch {\n // Never throw from crash reporting\n }\n}\n\n/**\n * Register global uncaughtException and unhandledRejection handlers.\n * These catch errors outside the normal cleanup flow (e.g., during\n * argument parsing). Should be called once at CLI startup before runMain.\n */\nexport function initCrashReporting(): void {\n const config = parseCrashReportConfig();\n if (!config.localEnabled && !config.remoteEnabled) return;\n\n const handleFatal = (error: unknown, errorType: ErrorType) => {\n const message = error instanceof Error ? error.message : String(error);\n logger.error(message);\n void reportCrash(error, errorType).finally(() => {\n process.exit(1);\n });\n };\n\n process.on(\"uncaughtException\", (error) => handleFatal(error, \"uncaughtException\"));\n process.on(\"unhandledRejection\", (reason) => handleFatal(reason, \"unhandledRejection\"));\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"crash-report-CSWITsTz.mjs","names":[],"sources":["../src/cli/crash-report/config.ts","../src/cli/crash-report/writer.ts","../src/cli/crash-report/sender.ts","../src/cli/crash-report/sanitize.ts","../src/cli/crash-report/report.ts","../src/cli/crash-report/index.ts"],"sourcesContent":["import * as path from \"pathe\";\nimport { isCI } from \"std-env\";\nimport { xdgConfig } from \"xdg-basedir\";\n\nexport interface CrashReportConfig {\n readonly localEnabled: boolean;\n readonly remoteEnabled: boolean;\n readonly localDir: string;\n}\n\n/**\n * Parse crash report configuration from environment variables.\n * Local crash log writing is enabled by default (opt-out via TAILOR_CRASH_REPORTS_LOCAL=off).\n * Remote sending is disabled by default (opt-in via TAILOR_CRASH_REPORTS_REMOTE=on).\n * Both are auto-disabled in CI environments.\n * @returns Crash report configuration\n */\nexport function parseCrashReportConfig(): CrashReportConfig {\n if (isCI) {\n return {\n localEnabled: false,\n remoteEnabled: false,\n localDir: \"\",\n };\n }\n\n const localEnabled = (process.env.TAILOR_CRASH_REPORTS_LOCAL ?? \"on\").toLowerCase() !== \"off\";\n const remoteEnabled = (process.env.TAILOR_CRASH_REPORTS_REMOTE ?? \"off\").toLowerCase() === \"on\";\n const localDir = xdgConfig ? path.join(xdgConfig, \"tailor-platform\", \"crash-reports\") : \"\";\n\n return {\n localEnabled: localEnabled && localDir !== \"\",\n remoteEnabled,\n localDir,\n };\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"pathe\";\nimport type { CrashReport } from \"./report\";\n\nconst MAX_CRASH_FILES = 10;\n\n/** Marker line that separates human-readable content from the JSON footer. */\nexport const JSON_FOOTER_MARKER = \"--- JSON ---\";\n\n/** File extension for crash log files. */\nexport const CRASH_LOG_EXTENSION = \".crash.log\";\n\n/**\n * Format a CrashReport as human-readable text for local crash log files.\n * @param report - Crash report to format\n * @returns Formatted text content\n */\nexport function formatCrashReport(report: CrashReport): string {\n const lines = [\n `Crash Report: ${report.id}`,\n `Timestamp: ${report.timestamp}`,\n `Error Type: ${report.errorType}`,\n \"\",\n \"--- Environment ---\",\n `SDK Version: ${report.sdkVersion}`,\n `Node Version: ${report.nodeVersion}`,\n `OS: ${report.osPlatform} ${report.osRelease}`,\n `Arch: ${report.arch}`,\n \"\",\n \"--- Command ---\",\n `Command: ${report.command}`,\n `Arguments: ${JSON.stringify(report.argv)}`,\n \"\",\n \"--- Error ---\",\n `Name: ${report.errorName}`,\n `Message: ${report.errorMessage}`,\n \"\",\n \"--- Stack Trace ---\",\n report.stackTrace || \"(no stack trace available)\",\n \"\",\n JSON_FOOTER_MARKER,\n JSON.stringify(report),\n \"\",\n ];\n return lines.join(\"\\n\");\n}\n\n/**\n * Generate a filename for a crash log file.\n * Format: {timestamp}-{shortId}.crash.log\n * @param report - Crash report to generate filename for\n * @returns Filename string\n */\nfunction generateFilename(report: CrashReport): string {\n const safeTimestamp = report.timestamp.replace(/[:.]/g, \"-\");\n const shortId = report.id.slice(0, 8);\n return `${safeTimestamp}-${shortId}${CRASH_LOG_EXTENSION}`;\n}\n\n/**\n * Remove old crash log files, keeping only the most recent ones.\n * @param dir - Crash log directory\n */\nfunction cleanupOldFiles(dir: string): void {\n try {\n const files = fs\n .readdirSync(dir)\n .filter((f) => f.endsWith(CRASH_LOG_EXTENSION))\n .sort()\n .reverse();\n\n for (const file of files.slice(MAX_CRASH_FILES)) {\n fs.unlinkSync(path.join(dir, file));\n }\n } catch {\n // Best-effort cleanup, ignore errors\n }\n}\n\n/**\n * Write a crash report to a local file.\n * Creates the directory if it doesn't exist. Keeps only the last 10 crash files.\n * Never throws - returns the file path on success or undefined on failure.\n * @param report - Crash report to write\n * @param dir - Directory to write the crash log file to\n * @returns File path on success, undefined on failure\n */\nexport function writeCrashReport(report: CrashReport, dir: string): string | undefined {\n try {\n fs.mkdirSync(dir, { recursive: true });\n\n const filename = generateFilename(report);\n const filePath = path.join(dir, filename);\n const content = formatCrashReport(report);\n\n fs.writeFileSync(filePath, content, \"utf-8\");\n cleanupOldFiles(dir);\n\n return filePath;\n } catch {\n return undefined;\n }\n}\n","import type { CrashReport } from \"./report\";\n\nconst SEND_TIMEOUT_MS = 5000;\nconst PRODUCTION_ENDPOINT = \"https://sdk-error-tracking-926vh9t4cl.erp.dev/query\";\n\nconst SUBMIT_MUTATION = `\nmutation SubmitCrashReport(\n $id: String!\n $timestamp: String!\n $sdkVersion: String!\n $nodeVersion: String!\n $osPlatform: String!\n $osRelease: String!\n $arch: String!\n $command: String!\n $argv: [String]\n $errorName: String!\n $errorMessage: String!\n $stackTrace: String\n $errorType: String!\n $userId: String\n $userEmail: String\n) {\n submitCrashReport(\n id: $id\n timestamp: $timestamp\n sdkVersion: $sdkVersion\n nodeVersion: $nodeVersion\n osPlatform: $osPlatform\n osRelease: $osRelease\n arch: $arch\n command: $command\n argv: $argv\n errorName: $errorName\n errorMessage: $errorMessage\n stackTrace: $stackTrace\n errorType: $errorType\n userId: $userId\n userEmail: $userEmail\n ) {\n success\n }\n}`;\n\n/**\n * Send a crash report to the remote endpoint via GraphQL mutation.\n * Best-effort: never throws, returns boolean success.\n * @param report - Crash report to send\n * @param ua - User-Agent header value\n * @returns true if the request succeeded, false otherwise\n */\nexport async function sendCrashReport(report: CrashReport, ua: string): Promise<boolean> {\n try {\n const endpoint = process.env.TAILOR_CRASH_REPORT_ENDPOINT || PRODUCTION_ENDPOINT;\n const response = await fetch(endpoint, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"User-Agent\": ua,\n },\n body: JSON.stringify({\n query: SUBMIT_MUTATION,\n variables: report,\n }),\n signal: AbortSignal.timeout(SEND_TIMEOUT_MS),\n });\n\n if (!response.ok) return false;\n\n const data = (await response.json()) as {\n errors?: unknown[];\n data?: { submitCrashReport: { success: boolean } };\n };\n if (data.errors?.length) return false;\n return data.data?.submitCrashReport.success === true;\n } catch {\n return false;\n }\n}\n","import * as os from \"node:os\";\n\nconst HOME_DIR = os.homedir();\n\n// Patterns for sanitization (global variants for use with .replace())\nconst UUID_PATTERN = /\\b[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\\b/gi;\nconst LONG_HEX_PATTERN = /\\b[0-9a-fA-F]{32,}\\b/g;\nconst EMAIL_PATTERN = /\\b[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}\\b/g;\nconst ABSOLUTE_PATH_PATTERN = /(?:\\/(?:[\\w.@\\- ]+\\/)+[\\w.@\\- ]+)/g;\nconst WINDOWS_PATH_PATTERN = /(?:[A-Za-z]:\\\\(?:[\\w.@\\- ]+\\\\)+[\\w.@\\- ]+)/g;\nconst URL_QUERY_PATTERN = /[?&][^?\\s]*/g;\n\n// Non-global variants for single-match .test() calls (avoids lastIndex state issues)\nconst EMAIL_TEST_PATTERN = /\\b[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}\\b/;\nconst WINDOWS_DRIVE_TEST_PATTERN = /^[A-Za-z]:\\\\/;\n\n// SDK package path marker for relative paths\nconst SDK_PACKAGE_MARKER = \"packages/sdk/\";\n\nfunction lastSegment(filePath: string, separator: string): string {\n return filePath.split(separator).pop() ?? filePath;\n}\n\n/**\n * Sanitize a stack trace by replacing absolute paths with relative SDK paths.\n * External paths are replaced with `<external>/filename.ext`.\n * Home directories are replaced with `~/<redacted>/`.\n * @param stack - Raw stack trace string\n * @returns Sanitized stack trace\n */\nexport function sanitizeStackTrace(stack: string): string {\n // V8 stack traces start with \"ErrorType: message\\n at ...\".\n // The error message may span multiple lines before the first \" at \" frame.\n // Apply message sanitization to all message lines so secrets embedded in\n // multiline error messages are redacted consistently with errorMessage.\n const firstFrameIndex = stack.search(/\\n\\s+at /);\n let result: string;\n if (firstFrameIndex !== -1) {\n result = sanitizeMessage(stack.slice(0, firstFrameIndex)) + stack.slice(firstFrameIndex);\n } else {\n result = sanitizeMessage(stack);\n }\n\n result = result.replace(ABSOLUTE_PATH_PATTERN, (match) => {\n const sdkIndex = match.indexOf(SDK_PACKAGE_MARKER);\n if (sdkIndex !== -1) {\n return match.slice(sdkIndex);\n }\n\n if (match.startsWith(HOME_DIR)) {\n return `~/<redacted>/${lastSegment(match, \"/\")}`;\n }\n\n return `<external>/${lastSegment(match, \"/\")}`;\n });\n result = result.replace(WINDOWS_PATH_PATTERN, (match) => {\n const normalized = match.replace(/\\\\/g, \"/\");\n const sdkIndex = normalized.indexOf(SDK_PACKAGE_MARKER);\n if (sdkIndex !== -1) {\n return normalized.slice(sdkIndex);\n }\n return `<external>/${lastSegment(match, \"\\\\\")}`;\n });\n return result;\n}\n\n/**\n * Sanitize an error message by redacting sensitive information.\n * Redacts: UUIDs, long hex tokens, email addresses, absolute paths, URL query strings.\n * @param message - Raw error message\n * @returns Sanitized error message\n */\nexport function sanitizeMessage(message: string): string {\n let result = message;\n // Strip serialized request/response bodies that may contain secrets\n result = result.replace(/\\nRequest:\\s*[\\s\\S]*$/, \"\\nRequest: <redacted>\");\n result = result.replace(UUID_PATTERN, \"<uuid>\");\n result = result.replace(LONG_HEX_PATTERN, \"<redacted>\");\n result = result.replace(EMAIL_PATTERN, \"<email>\");\n result = result.replace(URL_QUERY_PATTERN, \"?<redacted>\");\n result = result.replace(ABSOLUTE_PATH_PATTERN, (match) => `<path>/${lastSegment(match, \"/\")}`);\n result = result.replace(WINDOWS_PATH_PATTERN, (match) => `<path>/${lastSegment(match, \"\\\\\")}`);\n\n return result;\n}\n\n/**\n * Sanitize process.argv by keeping command/subcommand names and redacting\n * values of sensitive flags.\n * @param argv - Raw process.argv array\n * @returns Sanitized argv array\n */\nexport function sanitizeArgv(argv: string[]): string[] {\n const result: string[] = [];\n let redactNext = false;\n\n for (const arg of argv) {\n if (redactNext) {\n // If the next token is itself a flag, treat it as a new flag rather\n // than consuming it as the previous flag's value. This avoids leaking\n // the *next* flag's value (e.g., `--verbose --workspace-id secret`\n // would otherwise expose `secret`).\n if (!arg.startsWith(\"-\")) {\n result.push(\"<redacted>\");\n redactNext = false;\n continue;\n }\n redactNext = false;\n }\n\n if (arg.startsWith(\"-\")) {\n // --flag=value: keep flag name, redact value\n const eqIndex = arg.indexOf(\"=\");\n if (eqIndex !== -1) {\n result.push(`${arg.slice(0, eqIndex)}=<redacted>`);\n continue;\n }\n\n // --flag / -f: keep flag name, redact next arg as its value\n result.push(arg);\n redactNext = true;\n continue;\n }\n\n // Redact absolute paths\n if (arg.startsWith(\"/\") && arg.includes(\"/\", 1)) {\n result.push(\"<path>\");\n continue;\n }\n\n // Redact Windows-style absolute paths\n if (WINDOWS_DRIVE_TEST_PATTERN.test(arg)) {\n result.push(\"<path>\");\n continue;\n }\n\n // Redact email addresses\n if (EMAIL_TEST_PATTERN.test(arg)) {\n result.push(\"<email>\");\n continue;\n }\n\n result.push(arg);\n }\n\n return result;\n}\n","import * as crypto from \"node:crypto\";\nimport * as fs from \"node:fs\";\nimport * as os from \"node:os\";\nimport { parseYAML } from \"confbox\";\nimport * as path from \"pathe\";\nimport { xdgConfig } from \"xdg-basedir\";\nimport { sanitizeArgv, sanitizeMessage, sanitizeStackTrace } from \"./sanitize\";\n\nexport type ErrorType = \"uncaughtException\" | \"unhandledRejection\" | \"handledError\";\n\nexport interface CrashReport {\n id: string;\n timestamp: string;\n sdkVersion: string;\n nodeVersion: string;\n osPlatform: string;\n osRelease: string;\n arch: string;\n command: string;\n argv: string[];\n errorName: string;\n errorMessage: string;\n stackTrace: string;\n errorType: ErrorType;\n userId: string | null;\n userEmail: string | null;\n}\n\ninterface BuildCrashReportOptions {\n error: unknown;\n sdkVersion: string;\n errorType: ErrorType;\n}\n\n// Maximum subcommand depth to keep (e.g., \"tailordb migrate generate\" = 3 tokens).\n// Positional arguments beyond this are potentially sensitive user input.\n// Accepted trade-off: plain-text positional args that don't match known patterns\n// (UUIDs, hex tokens, emails, paths) pass through to `command` and `argv`.\n// Full redaction would require embedding the CLI command tree here, which is fragile.\nconst MAX_COMMAND_TOKENS = 3;\n\n/**\n * Parse the command name from process.argv.\n * Extracts up to MAX_COMMAND_TOKENS non-flag arguments after the script name.\n * @returns Parsed command string\n */\nfunction parseCommand(): string {\n const args = process.argv.slice(2);\n const commandParts: string[] = [];\n for (const arg of args) {\n if (arg.startsWith(\"-\") || commandParts.length >= MAX_COMMAND_TOKENS) break;\n commandParts.push(arg);\n }\n return commandParts.join(\" \") || \"<unknown>\";\n}\n\n/**\n * Build a CrashReport data structure from an error and context.\n * All sensitive data is sanitized before inclusion.\n * @param options - Error, SDK version, and crash type\n * @returns Sanitized crash report\n */\nexport function buildCrashReport(options: BuildCrashReportOptions): CrashReport {\n const { error, sdkVersion, errorType } = options;\n\n const isError = error instanceof Error;\n const rawMessage = isError ? error.message : String(error);\n const rawStack = isError && error.stack ? error.stack : \"\";\n const errorName = isError ? error.name : \"UnknownError\";\n\n const currentUser = readCurrentUser();\n\n return {\n id: crypto.randomUUID(),\n timestamp: new Date().toISOString(),\n sdkVersion,\n nodeVersion: process.version,\n osPlatform: process.platform,\n osRelease: os.release(),\n arch: process.arch,\n command: sanitizeMessage(parseCommand()),\n argv: sanitizeArgv(process.argv),\n errorName,\n errorMessage: sanitizeMessage(rawMessage),\n stackTrace: sanitizeStackTrace(rawStack),\n errorType,\n userId: currentUser,\n userEmail: currentUser,\n };\n}\n\n/**\n * Read current_user from Tailor Platform config without side effects.\n * Unlike readPlatformConfig(), this never triggers migration or logs warnings.\n * @returns The current user email, or null if unavailable\n */\nfunction readCurrentUser(): string | null {\n try {\n if (!xdgConfig) return null;\n const configPath = path.join(xdgConfig, \"tailor-platform\", \"config.yaml\");\n if (!fs.existsSync(configPath)) return null;\n const raw = parseYAML(fs.readFileSync(configPath, \"utf-8\")) as { current_user?: string | null };\n return raw?.current_user ?? null;\n } catch {\n return null;\n }\n}\n","import { logger } from \"@/cli/shared/logger\";\nimport { readPackageJson } from \"@/cli/shared/package-json\";\nimport { parseCrashReportConfig } from \"./config\";\nimport { buildCrashReport, type ErrorType } from \"./report\";\nimport { sendCrashReport } from \"./sender\";\nimport { writeCrashReport } from \"./writer\";\n\n/**\n * Report an unexpected crash. Writes a local crash log file and optionally\n * sends the report to a remote endpoint. Displays a user-facing message\n * with the crash log path and a command to submit the report.\n *\n * Never throws - all errors are silently caught.\n * @param error - The error that caused the crash\n * @param errorType - How the error was caught\n */\nexport async function reportCrash(error: unknown, errorType: ErrorType): Promise<void> {\n try {\n const config = parseCrashReportConfig();\n if (!config.localEnabled && !config.remoteEnabled) return;\n\n const packageJson = await readPackageJson();\n const sdkVersion = packageJson.version ?? \"unknown\";\n\n const report = buildCrashReport({ error, sdkVersion, errorType });\n\n if (config.localEnabled) {\n const filePath = writeCrashReport(report, config.localDir);\n if (filePath) {\n logger.log(\n [\n \"\",\n \"An unexpected error occurred. A crash report has been saved to:\",\n ` ${filePath}`,\n \"\",\n \"To submit this report:\",\n ` tailor-sdk crash-report send --file \"${filePath}\"`,\n ].join(\"\\n\"),\n );\n }\n }\n\n if (config.remoteEnabled) {\n // Lazy import: client.ts pulls in heavy dependencies (OAuth2, Connect, Protobuf)\n // that should not be loaded on the startup critical path via initCrashReporting().\n const { userAgent } = await import(\"@/cli/shared/client\");\n const ua = await userAgent();\n await sendCrashReport(report, ua);\n }\n } catch {\n // Never throw from crash reporting\n }\n}\n\n/**\n * Register global uncaughtException and unhandledRejection handlers.\n * These catch errors outside the normal cleanup flow (e.g., during\n * argument parsing). Should be called once at CLI startup before runMain.\n */\nexport function initCrashReporting(): void {\n const config = parseCrashReportConfig();\n if (!config.localEnabled && !config.remoteEnabled) return;\n\n const handleFatal = (error: unknown, errorType: ErrorType) => {\n const message = error instanceof Error ? error.message : String(error);\n logger.error(message);\n void reportCrash(error, errorType).finally(() => {\n process.exit(1);\n });\n };\n\n process.on(\"uncaughtException\", (error) => handleFatal(error, \"uncaughtException\"));\n process.on(\"unhandledRejection\", (reason) => handleFatal(reason, \"unhandledRejection\"));\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  /// <reference types="@tailor-platform/function-types" />
2
- import { o as Plugin } from "./tailor-db-field-B99RnR2N.mjs";
2
+ import { o as Plugin } from "./tailor-db-field-CoFKRCYW.mjs";
3
3
 
4
4
  //#region src/plugin/builtin/file-utils/index.d.ts
5
5
  /** Unique identifier for the file utilities generator plugin. */
@@ -16,4 +16,4 @@ type FileUtilsPluginOptions = {
16
16
  declare function fileUtilsPlugin(options: FileUtilsPluginOptions): Plugin<unknown, FileUtilsPluginOptions>;
17
17
  //#endregion
18
18
  export { fileUtilsPlugin as n, FileUtilsGeneratorID as t };
19
- //# sourceMappingURL=index-Cx1RYDbu.d.mts.map
19
+ //# sourceMappingURL=index-BtXZdz-F.d.mts.map
@@ -1,5 +1,5 @@
1
1
  /// <reference types="@tailor-platform/function-types" />
2
- import { o as Plugin } from "./tailor-db-field-B99RnR2N.mjs";
2
+ import { o as Plugin } from "./tailor-db-field-CoFKRCYW.mjs";
3
3
 
4
4
  //#region src/plugin/builtin/kysely-type/index.d.ts
5
5
  /** Unique identifier for the Kysely type generator plugin. */
@@ -16,4 +16,4 @@ type KyselyTypePluginOptions = {
16
16
  declare function kyselyTypePlugin(options: KyselyTypePluginOptions): Plugin<unknown, KyselyTypePluginOptions>;
17
17
  //#endregion
18
18
  export { kyselyTypePlugin as n, KyselyGeneratorID as t };
19
- //# sourceMappingURL=index-CeFwhUkX.d.mts.map
19
+ //# sourceMappingURL=index-Chvw1Eod.d.mts.map
@@ -1,5 +1,5 @@
1
1
  /// <reference types="@tailor-platform/function-types" />
2
- import { o as Plugin } from "./tailor-db-field-B99RnR2N.mjs";
2
+ import { o as Plugin } from "./tailor-db-field-CoFKRCYW.mjs";
3
3
 
4
4
  //#region src/plugin/builtin/seed/index.d.ts
5
5
  /** Unique identifier for the seed generator plugin. */
@@ -18,4 +18,4 @@ type SeedPluginOptions = {
18
18
  declare function seedPlugin(options: SeedPluginOptions): Plugin<unknown, SeedPluginOptions>;
19
19
  //#endregion
20
20
  export { seedPlugin as n, SeedGeneratorID as t };
21
- //# sourceMappingURL=index-Ch8Em3nz.d.mts.map
21
+ //# sourceMappingURL=index-CiNNNpuH.d.mts.map
@@ -1,7 +1,7 @@
1
1
  /// <reference types="@tailor-platform/function-types" />
2
- import { $ as ResolverInput, At as FieldMetadata, Bt as InferredAttributeMap, Dt as ArrayFieldOutput, Ft as FieldValidateInput, G as UserAttributeListKey, Gt as JsonValue, K as UserAttributeMap, Kt as Prettify, Mt as FieldOutput, Nt as TailorFieldType, Ot as DefinedFieldMetadata, Q as Resolver, Ut as InferFieldsOutput, V as DefinedAuth, Vt as TailorUser, Wt as JsonCompatible, Y as TailorField$1, at as FunctionOperation$1, ct as IncomingWebhookTrigger$1, dt as TailorDBTrigger$1, et as GeneratorConfig, ft as WebhookOperation$1, it as ExecutorInput, jt as FieldOptions, lt as ResolverExecutedTrigger$1, mt as AuthInvoker$1, nt as AuthAccessTokenTrigger$1, o as Plugin, ot as GqlOperation$1, pt as WorkflowOperation$1, qt as output$1, st as IdpUserTrigger$1, tt as BaseGeneratorConfig, ut as ScheduleTriggerInput, z as AuthServiceInput } from "./tailor-db-field-B99RnR2N.mjs";
3
- import { D as TailorDBType, E as TailorDBInstance, F as AllowedValuesOutput, P as AllowedValues, S as IdPInput, _ as IdPUserField, d as StaticWebsiteDefinitionBrand, f as StaticWebsiteInput, m as SecretsDefinitionBrand, n as AppConfig, t as RetryPolicy, v as IdpDefinitionBrand } from "./workflow.generated-DSwr-k57.mjs";
4
- import { r as TailorEnv, t as TailorActor } from "./actor-Bb4OVq1j.mjs";
2
+ import { $ as ResolverInput, At as FieldMetadata, Bt as InferredAttributeMap, Dt as ArrayFieldOutput, Ft as FieldValidateInput, G as UserAttributeListKey, Gt as JsonValue, K as UserAttributeMap, Kt as Prettify, Mt as FieldOutput, Nt as TailorFieldType, Ot as DefinedFieldMetadata, Q as Resolver, Ut as InferFieldsOutput, V as DefinedAuth, Vt as TailorUser, Wt as JsonCompatible, Y as TailorField$1, at as FunctionOperation$1, ct as IncomingWebhookTrigger$1, dt as TailorDBTrigger$1, et as GeneratorConfig, ft as WebhookOperation$1, it as ExecutorInput, jt as FieldOptions, lt as ResolverExecutedTrigger$1, mt as AuthInvoker$1, nt as AuthAccessTokenTrigger$1, o as Plugin, ot as GqlOperation$1, pt as WorkflowOperation$1, qt as output$1, st as IdpUserTrigger$1, tt as BaseGeneratorConfig, ut as ScheduleTriggerInput, z as AuthServiceInput } from "./tailor-db-field-CoFKRCYW.mjs";
3
+ import { D as TailorDBType, E as TailorDBInstance, F as AllowedValuesOutput, P as AllowedValues, S as IdPInput, _ as IdPUserField, d as StaticWebsiteDefinitionBrand, f as StaticWebsiteInput, m as SecretsDefinitionBrand, n as AppConfig, t as RetryPolicy, v as IdpDefinitionBrand } from "./workflow.generated-Btz6srLR.mjs";
4
+ import { r as TailorEnv, t as TailorActor } from "./actor-B2oEmlTc.mjs";
5
5
  import { JsonPrimitive, Jsonifiable, Jsonify } from "type-fest";
6
6
  import { StandardSchemaV1 } from "@standard-schema/spec";
7
7
  import { Client } from "@urql/core";
@@ -1076,4 +1076,4 @@ declare namespace t {
1076
1076
  }
1077
1077
  //#endregion
1078
1078
  export { resolverExecutedTrigger as $, IdpUserArgs as A, TailorDBTrigger as B, ScheduleTrigger as C, AuthAccessTokenRefreshedArgs as D, AuthAccessTokenIssuedArgs as E, RecordCreatedArgs as F, idpUserCreatedTrigger as G, authAccessTokenRefreshedTrigger as H, RecordDeletedArgs as I, idpUserUpdatedTrigger as J, idpUserDeletedTrigger as K, RecordUpdatedArgs as L, IdpUserDeletedArgs as M, IdpUserTrigger as N, AuthAccessTokenRevokedArgs as O, IdpUserUpdatedArgs as P, recordUpdatedTrigger as Q, ResolverExecutedArgs as R, ScheduleArgs as S, AuthAccessTokenArgs as T, authAccessTokenRevokedTrigger as U, authAccessTokenIssuedTrigger as V, authAccessTokenTrigger as W, recordDeletedTrigger as X, recordCreatedTrigger as Y, recordTrigger as Z, IncomingWebhookResponse as _, defineAuth as _t, defineGenerators as a, Workflow as at, IncomingWebhookTriggerOptions as b, MachineUserNameRegistry as bt, defineIdp as c, WORKFLOW_TEST_ENV_KEY as ct, unsafeAllowAllIdPPermission as d, WorkflowJobInput as dt, FunctionOperation as et, defineStaticWebSite as f, WorkflowJobOutput as ft, IncomingWebhookRequest as g, AuthInvoker as gt, IncomingWebhookArgs as h, createResolver as ht, defineConfig as i, WorkflowOperation as it, IdpUserCreatedArgs as j, AuthAccessTokenTrigger as k, IdPPermission as l, WorkflowJob as lt, Trigger as m, QueryType as mt, output as n, Operation as nt, definePlugins as o, WorkflowConfig as ot, createExecutor as p, createWorkflowJob as pt, idpUserTrigger as q, t as r, WebhookOperation as rt, defineSecretManager as s, createWorkflow as st, infer as t, GqlOperation as tt, IdPPermissionCondition as u, WorkflowJobContext as ut, IncomingWebhookResponseConfig as v, TailorField as vt, scheduleTrigger as w, incomingWebhookTrigger as x, IncomingWebhookTrigger as y, MachineUserName as yt, ResolverExecutedTrigger as z };
1079
- //# sourceMappingURL=index-BYmdVno1.d.mts.map
1079
+ //# sourceMappingURL=index-D_ezppY7.d.mts.map
@@ -1,5 +1,5 @@
1
1
  /// <reference types="@tailor-platform/function-types" />
2
- import { o as Plugin } from "./tailor-db-field-B99RnR2N.mjs";
2
+ import { o as Plugin } from "./tailor-db-field-CoFKRCYW.mjs";
3
3
 
4
4
  //#region src/plugin/builtin/enum-constants/index.d.ts
5
5
  /** Unique identifier for the enum constants generator plugin. */
@@ -16,4 +16,4 @@ type EnumConstantsPluginOptions = {
16
16
  declare function enumConstantsPlugin(options: EnumConstantsPluginOptions): Plugin<unknown, EnumConstantsPluginOptions>;
17
17
  //#endregion
18
18
  export { enumConstantsPlugin as n, EnumConstantsGeneratorID as t };
19
- //# sourceMappingURL=index-DLO_XvLi.d.mts.map
19
+ //# sourceMappingURL=index-reFAYSX7.d.mts.map
@@ -31,4 +31,4 @@ function createTracingInterceptor() {
31
31
 
32
32
  //#endregion
33
33
  export { createTracingInterceptor };
34
- //# sourceMappingURL=interceptor-B5bKVwgq.mjs.map
34
+ //# sourceMappingURL=interceptor-4UC-KTno.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"interceptor-B5bKVwgq.mjs","names":[],"sources":["../src/cli/telemetry/interceptor.ts"],"sourcesContent":["import { trace, SpanStatusCode } from \"@opentelemetry/api\";\nimport type { Interceptor } from \"@connectrpc/connect\";\n\n/**\n * Create a Connect-RPC interceptor that records OTLP spans for each RPC call.\n * When no TracerProvider is registered, the OTel API automatically provides\n * noop spans with zero overhead.\n * @returns Tracing interceptor\n */\nexport function createTracingInterceptor(): Interceptor {\n return (next) => async (req) => {\n const tracer = trace.getTracer(\"tailor-sdk\");\n\n return tracer.startActiveSpan(`rpc.${req.method.name}`, async (span) => {\n span.setAttribute(\"rpc.method\", req.method.name);\n span.setAttribute(\"rpc.service\", \"OperatorService\");\n span.setAttribute(\"rpc.system\", \"connect-rpc\");\n\n try {\n const response = await next(req);\n span.setStatus({ code: SpanStatusCode.OK });\n return response;\n } catch (error) {\n span.setStatus({ code: SpanStatusCode.ERROR });\n if (error instanceof Error) {\n span.recordException(error);\n }\n throw error;\n } finally {\n span.end();\n }\n });\n };\n}\n"],"mappings":";;;;;;;;;;AASA,SAAgB,2BAAwC;AACtD,SAAQ,SAAS,OAAO,QAAQ;AAG9B,SAFe,MAAM,UAAU,aAAa,CAE9B,gBAAgB,OAAO,IAAI,OAAO,QAAQ,OAAO,SAAS;AACtE,QAAK,aAAa,cAAc,IAAI,OAAO,KAAK;AAChD,QAAK,aAAa,eAAe,kBAAkB;AACnD,QAAK,aAAa,cAAc,cAAc;AAE9C,OAAI;IACF,MAAM,WAAW,MAAM,KAAK,IAAI;AAChC,SAAK,UAAU,EAAE,MAAM,eAAe,IAAI,CAAC;AAC3C,WAAO;YACA,OAAO;AACd,SAAK,UAAU,EAAE,MAAM,eAAe,OAAO,CAAC;AAC9C,QAAI,iBAAiB,MACnB,MAAK,gBAAgB,MAAM;AAE7B,UAAM;aACE;AACR,SAAK,KAAK;;IAEZ"}
1
+ {"version":3,"file":"interceptor-4UC-KTno.mjs","names":[],"sources":["../src/cli/telemetry/interceptor.ts"],"sourcesContent":["import { trace, SpanStatusCode } from \"@opentelemetry/api\";\nimport type { Interceptor } from \"@connectrpc/connect\";\n\n/**\n * Create a Connect-RPC interceptor that records OTLP spans for each RPC call.\n * When no TracerProvider is registered, the OTel API automatically provides\n * noop spans with zero overhead.\n * @returns Tracing interceptor\n */\nexport function createTracingInterceptor(): Interceptor {\n return (next) => async (req) => {\n const tracer = trace.getTracer(\"tailor-sdk\");\n\n return tracer.startActiveSpan(`rpc.${req.method.name}`, async (span) => {\n span.setAttribute(\"rpc.method\", req.method.name);\n span.setAttribute(\"rpc.service\", \"OperatorService\");\n span.setAttribute(\"rpc.system\", \"connect-rpc\");\n\n try {\n const response = await next(req);\n span.setStatus({ code: SpanStatusCode.OK });\n return response;\n } catch (error) {\n span.setStatus({ code: SpanStatusCode.ERROR });\n if (error instanceof Error) {\n span.recordException(error);\n }\n throw error;\n } finally {\n span.end();\n }\n });\n };\n}\n"],"mappings":";;;;;;;;;;AASA,SAAgB,2BAAwC;AACtD,SAAQ,SAAS,OAAO,QAAQ;AAG9B,SAFe,MAAM,UAAU,aAAa,CAE9B,gBAAgB,OAAO,IAAI,OAAO,QAAQ,OAAO,SAAS;AACtE,QAAK,aAAa,cAAc,IAAI,OAAO,KAAK;AAChD,QAAK,aAAa,eAAe,kBAAkB;AACnD,QAAK,aAAa,cAAc,cAAc;AAE9C,OAAI;IACF,MAAM,WAAW,MAAM,KAAK,IAAI;AAChC,SAAK,UAAU,EAAE,MAAM,eAAe,IAAI,CAAC;AAC3C,WAAO;YACA,OAAO;AACd,SAAK,UAAU,EAAE,MAAM,eAAe,OAAO,CAAC;AAC9C,QAAI,iBAAiB,MACnB,MAAK,gBAAgB,MAAM;AAE7B,UAAM;aACE;AACR,SAAK,KAAK;;IAEZ"}
@@ -1,3 +1,3 @@
1
1
  /// <reference types="@tailor-platform/function-types" />
2
- import { n as enumConstantsPlugin, t as EnumConstantsGeneratorID } from "../../../index-DLO_XvLi.mjs";
2
+ import { n as enumConstantsPlugin, t as EnumConstantsGeneratorID } from "../../../index-reFAYSX7.mjs";
3
3
  export { EnumConstantsGeneratorID, enumConstantsPlugin };
@@ -1,3 +1,3 @@
1
1
  /// <reference types="@tailor-platform/function-types" />
2
- import { n as fileUtilsPlugin, t as FileUtilsGeneratorID } from "../../../index-Cx1RYDbu.mjs";
2
+ import { n as fileUtilsPlugin, t as FileUtilsGeneratorID } from "../../../index-BtXZdz-F.mjs";
3
3
  export { FileUtilsGeneratorID, fileUtilsPlugin };
@@ -1,3 +1,3 @@
1
1
  /// <reference types="@tailor-platform/function-types" />
2
- import { n as kyselyTypePlugin, t as KyselyGeneratorID } from "../../../index-CeFwhUkX.mjs";
2
+ import { n as kyselyTypePlugin, t as KyselyGeneratorID } from "../../../index-Chvw1Eod.mjs";
3
3
  export { KyselyGeneratorID, kyselyTypePlugin };
@@ -1,3 +1,3 @@
1
1
  /// <reference types="@tailor-platform/function-types" />
2
- import { n as seedPlugin, t as SeedGeneratorID } from "../../../index-Ch8Em3nz.mjs";
2
+ import { n as seedPlugin, t as SeedGeneratorID } from "../../../index-CiNNNpuH.mjs";
3
3
  export { SeedGeneratorID, seedPlugin };
@@ -1,6 +1,6 @@
1
1
  /// <reference types="@tailor-platform/function-types" />
2
- import { n as TailorAnyDBType } from "../tailor-db-field-B99RnR2N.mjs";
3
- import { r as TailorEnv, t as TailorActor } from "../actor-Bb4OVq1j.mjs";
2
+ import { n as TailorAnyDBType } from "../tailor-db-field-CoFKRCYW.mjs";
3
+ import { r as TailorEnv, t as TailorActor } from "../actor-B2oEmlTc.mjs";
4
4
 
5
5
  //#region src/plugin/with-context.d.ts
6
6
  /**
@@ -0,0 +1,255 @@
1
+
2
+ import { GraphQLError, Lexer, Source, TokenKind } from "graphql";
3
+ import { getSegments } from "sql-highlight";
4
+
5
+ //#region src/cli/query/repl-editor.ts
6
+ const RESET = "\x1B[0m";
7
+ const BLUE = "\x1B[34m";
8
+ const MAGENTA = "\x1B[35m";
9
+ const YELLOW = "\x1B[33m";
10
+ const BRIGHT_GREEN = "\x1B[92m";
11
+ const CYAN = "\x1B[36m";
12
+ const BRIGHT_BLUE = "\x1B[94m";
13
+ const BOLD_CYAN = "\x1B[1;36m";
14
+ const BOLD_MAGENTA = "\x1B[1;35m";
15
+ const ITALIC_YELLOW = "\x1B[3;33m";
16
+ const GREEN = "\x1B[32m";
17
+ const DIM = "\x1B[90m";
18
+ const DIM_YELLOW = "\x1B[2;33m";
19
+ const SQL_STYLE_MAP = {
20
+ keyword: BLUE,
21
+ function: MAGENTA,
22
+ identifier: YELLOW,
23
+ string: BRIGHT_GREEN,
24
+ number: CYAN,
25
+ bracket: DIM_YELLOW,
26
+ special: DIM
27
+ };
28
+ /**
29
+ * Highlight a single SQL line using the `sql-highlight` tokenizer.
30
+ * @param line - SQL text for a single editor line
31
+ * @returns ANSI-decorated line safe for terminal output
32
+ */
33
+ function highlightSqlLine(line) {
34
+ const segments = getSegments(line);
35
+ let result = "";
36
+ for (const seg of segments) {
37
+ const style = SQL_STYLE_MAP[seg.name];
38
+ result += style ? style + seg.content + RESET : seg.content;
39
+ }
40
+ return result;
41
+ }
42
+ const GQL_KEYWORDS = new Set([
43
+ "query",
44
+ "mutation",
45
+ "subscription",
46
+ "fragment",
47
+ "on",
48
+ "type",
49
+ "input",
50
+ "enum",
51
+ "interface",
52
+ "union",
53
+ "scalar",
54
+ "extend",
55
+ "schema",
56
+ "directive",
57
+ "implements"
58
+ ]);
59
+ const GQL_DEF_KEYWORDS = new Set([
60
+ "query",
61
+ "mutation",
62
+ "subscription",
63
+ "fragment"
64
+ ]);
65
+ const GQL_BUILTINS = new Set([
66
+ "true",
67
+ "false",
68
+ "null"
69
+ ]);
70
+ /**
71
+ * Highlight a single GraphQL line using the official `graphql` Lexer. Tracks
72
+ * paren depth and the previous token to provide semantic-level colouring
73
+ * (field names vs argument names vs types).
74
+ * @param line - GraphQL text for a single editor line
75
+ * @returns ANSI-decorated line, or the input unchanged when the lexer rejects it
76
+ */
77
+ function highlightGraphqlLine(line) {
78
+ if (line.trimStart().startsWith("#")) return `${DIM}${line}${RESET}`;
79
+ try {
80
+ const lexer = new Lexer(new Source(line));
81
+ let result = "";
82
+ let pos = 0;
83
+ let parenDepth = 0;
84
+ let prevKind = "";
85
+ let prevText = "";
86
+ let afterColon = false;
87
+ let token = lexer.advance();
88
+ while (token.kind !== TokenKind.EOF) {
89
+ if (token.start > pos) result += line.slice(pos, token.start);
90
+ const text = line.slice(token.start, token.end);
91
+ switch (token.kind) {
92
+ case TokenKind.NAME:
93
+ if (prevKind === TokenKind.DOLLAR) result += `${MAGENTA}${text}${RESET}`;
94
+ else if (prevKind === TokenKind.AT) result += `${BOLD_MAGENTA}${text}${RESET}`;
95
+ else if (GQL_BUILTINS.has(text) || GQL_KEYWORDS.has(text)) result += `${BLUE}${text}${RESET}`;
96
+ else if (GQL_DEF_KEYWORDS.has(prevText)) result += `${BOLD_CYAN}${text}${RESET}`;
97
+ else if (afterColon) result += `${CYAN}${text}${RESET}`;
98
+ else if (parenDepth > 0) result += `${ITALIC_YELLOW}${text}${RESET}`;
99
+ else result += `${BRIGHT_BLUE}${text}${RESET}`;
100
+ afterColon = false;
101
+ break;
102
+ case TokenKind.INT:
103
+ case TokenKind.FLOAT:
104
+ result += `${BLUE}${text}${RESET}`;
105
+ afterColon = false;
106
+ break;
107
+ case TokenKind.STRING:
108
+ case TokenKind.BLOCK_STRING:
109
+ result += `${GREEN}${text}${RESET}`;
110
+ afterColon = false;
111
+ break;
112
+ case TokenKind.DOLLAR:
113
+ result += `${MAGENTA}${text}${RESET}`;
114
+ afterColon = false;
115
+ break;
116
+ case TokenKind.AT:
117
+ result += `${BOLD_MAGENTA}${text}${RESET}`;
118
+ afterColon = false;
119
+ break;
120
+ case TokenKind.BRACE_L:
121
+ case TokenKind.BRACE_R:
122
+ result += `${YELLOW}${text}${RESET}`;
123
+ afterColon = false;
124
+ break;
125
+ case TokenKind.PAREN_L:
126
+ parenDepth += 1;
127
+ result += `${DIM_YELLOW}${text}${RESET}`;
128
+ afterColon = false;
129
+ break;
130
+ case TokenKind.PAREN_R:
131
+ parenDepth = Math.max(0, parenDepth - 1);
132
+ result += `${DIM_YELLOW}${text}${RESET}`;
133
+ afterColon = false;
134
+ break;
135
+ case TokenKind.BRACKET_L:
136
+ case TokenKind.BRACKET_R:
137
+ result += `${DIM_YELLOW}${text}${RESET}`;
138
+ afterColon = false;
139
+ break;
140
+ case TokenKind.COLON:
141
+ result += `${DIM}${text}${RESET}`;
142
+ afterColon = true;
143
+ break;
144
+ case TokenKind.BANG:
145
+ case TokenKind.EQUALS:
146
+ case TokenKind.PIPE:
147
+ case TokenKind.AMP:
148
+ case TokenKind.SPREAD:
149
+ result += `${DIM}${text}${RESET}`;
150
+ afterColon = false;
151
+ break;
152
+ default:
153
+ result += text;
154
+ afterColon = false;
155
+ }
156
+ prevKind = token.kind;
157
+ prevText = text;
158
+ pos = token.end;
159
+ token = lexer.advance();
160
+ }
161
+ if (pos < line.length) result += line.slice(pos);
162
+ return result;
163
+ } catch (error) {
164
+ if (error instanceof GraphQLError) return line;
165
+ throw error;
166
+ }
167
+ }
168
+ const BRACKET_PAIRS = {
169
+ "(": ")",
170
+ "[": "]",
171
+ "{": "}"
172
+ };
173
+ const CLOSE_BRACKETS = new Set(Object.values(BRACKET_PAIRS));
174
+ /**
175
+ * Apply auto-close brackets and auto-indent on newline. Works for both SQL
176
+ * and GraphQL because both languages share the `()`, `[]`, `{}` bracket set.
177
+ * @param state - Editor state after the last edit
178
+ * @param event - Event describing the edit that just occurred
179
+ * @returns A new editor state to apply, or `undefined` to leave the state unchanged
180
+ */
181
+ function replTransform(state, event) {
182
+ const { lines, row, col } = state;
183
+ if (event.type === "insert" && event.char in BRACKET_PAIRS) {
184
+ const close = BRACKET_PAIRS[event.char];
185
+ const line = lines[row];
186
+ const newLine = line.slice(0, col) + close + line.slice(col);
187
+ return {
188
+ lines: lines.with(row, newLine),
189
+ row,
190
+ col
191
+ };
192
+ }
193
+ if (event.type === "insert" && CLOSE_BRACKETS.has(event.char)) {
194
+ const line = lines[row];
195
+ if (line[col] === event.char) {
196
+ const newLine = line.slice(0, col) + line.slice(col + 1);
197
+ return {
198
+ lines: lines.with(row, newLine),
199
+ row,
200
+ col
201
+ };
202
+ }
203
+ }
204
+ if (event.type === "backspace") {
205
+ const line = lines[row];
206
+ const beforeCursor = line.slice(0, col);
207
+ if (beforeCursor.length >= 1 && /^ +$/.test(beforeCursor)) {
208
+ const newIndent = beforeCursor.slice(0, -1);
209
+ const newLine = newIndent + line.slice(col);
210
+ return {
211
+ lines: lines.with(row, newLine),
212
+ row,
213
+ col: newIndent.length
214
+ };
215
+ }
216
+ }
217
+ if (event.type === "newline" && row > 0) {
218
+ const prevLine = lines[row - 1];
219
+ const baseIndent = prevLine.match(/^(\s*)/)?.[1] ?? "";
220
+ const endsWithOpen = /[{([]$/.test(prevLine.trimEnd());
221
+ const startsWithClose = /^[}\])]/.test(lines[row].trimStart());
222
+ if (endsWithOpen && startsWithClose) {
223
+ const innerIndent = baseIndent + " ";
224
+ const newLines = [...lines];
225
+ newLines[row] = innerIndent;
226
+ newLines.splice(row + 1, 0, baseIndent + lines[row].trimStart());
227
+ return {
228
+ lines: newLines,
229
+ row,
230
+ col: innerIndent.length
231
+ };
232
+ }
233
+ if (endsWithOpen) {
234
+ const closeChar = BRACKET_PAIRS[prevLine.trimEnd().slice(-1)] ?? "}";
235
+ const indent = baseIndent + " ";
236
+ const newLines = [...lines];
237
+ newLines[row] = indent + lines[row];
238
+ newLines.splice(row + 1, 0, baseIndent + closeChar);
239
+ return {
240
+ lines: newLines,
241
+ row,
242
+ col: indent.length
243
+ };
244
+ }
245
+ if (baseIndent && col === 0) return {
246
+ lines: lines.with(row, baseIndent + lines[row]),
247
+ row,
248
+ col: baseIndent.length
249
+ };
250
+ }
251
+ }
252
+
253
+ //#endregion
254
+ export { highlightGraphqlLine, highlightSqlLine, replTransform };
255
+ //# sourceMappingURL=repl-editor-DjycioU-.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repl-editor-DjycioU-.mjs","names":[],"sources":["../src/cli/query/repl-editor.ts"],"sourcesContent":["import { GraphQLError, Lexer, Source, TokenKind } from \"graphql\";\nimport { getSegments } from \"sql-highlight\";\nimport type { TransformEvent, TransformState } from \"@toiroakr/read-multiline\";\n\n// ANSI colour sequences. Kept inline (rather than going through `node:util`\n// styleText) so that tests running outside a TTY still produce deterministic\n// escape sequences regardless of detected colour support.\nconst RESET = \"\\x1b[0m\";\nconst BLUE = \"\\x1b[34m\";\nconst MAGENTA = \"\\x1b[35m\";\nconst YELLOW = \"\\x1b[33m\";\nconst BRIGHT_GREEN = \"\\x1b[92m\";\nconst CYAN = \"\\x1b[36m\";\nconst BRIGHT_BLUE = \"\\x1b[94m\";\nconst BOLD_CYAN = \"\\x1b[1;36m\";\nconst BOLD_MAGENTA = \"\\x1b[1;35m\";\nconst ITALIC_YELLOW = \"\\x1b[3;33m\";\nconst GREEN = \"\\x1b[32m\";\nconst DIM = \"\\x1b[90m\";\nconst DIM_YELLOW = \"\\x1b[2;33m\";\n\nconst SQL_STYLE_MAP: Record<string, string> = {\n keyword: BLUE,\n function: MAGENTA,\n identifier: YELLOW,\n string: BRIGHT_GREEN,\n number: CYAN,\n bracket: DIM_YELLOW,\n special: DIM,\n};\n\n/**\n * Highlight a single SQL line using the `sql-highlight` tokenizer.\n * @param line - SQL text for a single editor line\n * @returns ANSI-decorated line safe for terminal output\n */\nexport function highlightSqlLine(line: string): string {\n const segments = getSegments(line);\n let result = \"\";\n for (const seg of segments) {\n const style = SQL_STYLE_MAP[seg.name];\n result += style ? style + seg.content + RESET : seg.content;\n }\n return result;\n}\n\nconst GQL_KEYWORDS = new Set([\n \"query\",\n \"mutation\",\n \"subscription\",\n \"fragment\",\n \"on\",\n \"type\",\n \"input\",\n \"enum\",\n \"interface\",\n \"union\",\n \"scalar\",\n \"extend\",\n \"schema\",\n \"directive\",\n \"implements\",\n]);\n\n// Keywords that introduce a definition name (next NAME token is the def).\nconst GQL_DEF_KEYWORDS = new Set([\"query\", \"mutation\", \"subscription\", \"fragment\"]);\n\nconst GQL_BUILTINS = new Set([\"true\", \"false\", \"null\"]);\n\n/**\n * Highlight a single GraphQL line using the official `graphql` Lexer. Tracks\n * paren depth and the previous token to provide semantic-level colouring\n * (field names vs argument names vs types).\n * @param line - GraphQL text for a single editor line\n * @returns ANSI-decorated line, or the input unchanged when the lexer rejects it\n */\nexport function highlightGraphqlLine(line: string): string {\n if (line.trimStart().startsWith(\"#\")) {\n return `${DIM}${line}${RESET}`;\n }\n\n try {\n const source = new Source(line);\n const lexer = new Lexer(source);\n let result = \"\";\n let pos = 0;\n\n let parenDepth = 0;\n let prevKind: string = \"\";\n let prevText = \"\";\n let afterColon = false;\n\n let token = lexer.advance();\n while (token.kind !== TokenKind.EOF) {\n if (token.start > pos) {\n result += line.slice(pos, token.start);\n }\n\n const text = line.slice(token.start, token.end);\n switch (token.kind) {\n case TokenKind.NAME: {\n if (prevKind === TokenKind.DOLLAR) {\n result += `${MAGENTA}${text}${RESET}`;\n } else if (prevKind === TokenKind.AT) {\n result += `${BOLD_MAGENTA}${text}${RESET}`;\n } else if (GQL_BUILTINS.has(text) || GQL_KEYWORDS.has(text)) {\n result += `${BLUE}${text}${RESET}`;\n } else if (GQL_DEF_KEYWORDS.has(prevText)) {\n result += `${BOLD_CYAN}${text}${RESET}`;\n } else if (afterColon) {\n result += `${CYAN}${text}${RESET}`;\n } else if (parenDepth > 0) {\n result += `${ITALIC_YELLOW}${text}${RESET}`;\n } else {\n result += `${BRIGHT_BLUE}${text}${RESET}`;\n }\n afterColon = false;\n break;\n }\n case TokenKind.INT:\n case TokenKind.FLOAT:\n result += `${BLUE}${text}${RESET}`;\n afterColon = false;\n break;\n case TokenKind.STRING:\n case TokenKind.BLOCK_STRING:\n result += `${GREEN}${text}${RESET}`;\n afterColon = false;\n break;\n case TokenKind.DOLLAR:\n result += `${MAGENTA}${text}${RESET}`;\n afterColon = false;\n break;\n case TokenKind.AT:\n result += `${BOLD_MAGENTA}${text}${RESET}`;\n afterColon = false;\n break;\n case TokenKind.BRACE_L:\n case TokenKind.BRACE_R:\n result += `${YELLOW}${text}${RESET}`;\n afterColon = false;\n break;\n case TokenKind.PAREN_L:\n parenDepth += 1;\n result += `${DIM_YELLOW}${text}${RESET}`;\n afterColon = false;\n break;\n case TokenKind.PAREN_R:\n parenDepth = Math.max(0, parenDepth - 1);\n result += `${DIM_YELLOW}${text}${RESET}`;\n afterColon = false;\n break;\n case TokenKind.BRACKET_L:\n case TokenKind.BRACKET_R:\n result += `${DIM_YELLOW}${text}${RESET}`;\n afterColon = false;\n break;\n case TokenKind.COLON:\n result += `${DIM}${text}${RESET}`;\n afterColon = true;\n break;\n case TokenKind.BANG:\n case TokenKind.EQUALS:\n case TokenKind.PIPE:\n case TokenKind.AMP:\n case TokenKind.SPREAD:\n result += `${DIM}${text}${RESET}`;\n afterColon = false;\n break;\n default:\n result += text;\n afterColon = false;\n }\n\n prevKind = token.kind;\n prevText = text;\n pos = token.end;\n token = lexer.advance();\n }\n\n if (pos < line.length) {\n result += line.slice(pos);\n }\n return result;\n } catch (error) {\n // The lexer throws GraphQLError on partial or invalid input (e.g. an\n // unterminated string while the user is still typing). Fall back to the\n // raw line so the editor keeps rendering without colour until the input\n // is valid. Any other error is a real bug and should surface.\n if (error instanceof GraphQLError) {\n return line;\n }\n throw error;\n }\n}\n\nconst BRACKET_PAIRS: Record<string, string> = { \"(\": \")\", \"[\": \"]\", \"{\": \"}\" };\nconst CLOSE_BRACKETS = new Set(Object.values(BRACKET_PAIRS));\n\n/**\n * Apply auto-close brackets and auto-indent on newline. Works for both SQL\n * and GraphQL because both languages share the `()`, `[]`, `{}` bracket set.\n * @param state - Editor state after the last edit\n * @param event - Event describing the edit that just occurred\n * @returns A new editor state to apply, or `undefined` to leave the state unchanged\n */\nexport function replTransform(\n state: TransformState,\n event: TransformEvent,\n): TransformState | undefined {\n const { lines, row, col } = state;\n\n if (event.type === \"insert\" && event.char in BRACKET_PAIRS) {\n const close = BRACKET_PAIRS[event.char];\n const line = lines[row];\n const newLine = line.slice(0, col) + close + line.slice(col);\n return { lines: lines.with(row, newLine), row, col };\n }\n\n if (event.type === \"insert\" && CLOSE_BRACKETS.has(event.char)) {\n const line = lines[row];\n if (line[col] === event.char) {\n const newLine = line.slice(0, col) + line.slice(col + 1);\n return { lines: lines.with(row, newLine), row, col };\n }\n }\n\n if (event.type === \"backspace\") {\n const line = lines[row];\n const beforeCursor = line.slice(0, col);\n if (beforeCursor.length >= 1 && /^ +$/.test(beforeCursor)) {\n const newIndent = beforeCursor.slice(0, -1);\n const newLine = newIndent + line.slice(col);\n return { lines: lines.with(row, newLine), row, col: newIndent.length };\n }\n }\n\n if (event.type === \"newline\" && row > 0) {\n const prevLine = lines[row - 1];\n const baseIndent = prevLine.match(/^(\\s*)/)?.[1] ?? \"\";\n const endsWithOpen = /[{([]$/.test(prevLine.trimEnd());\n const startsWithClose = /^[}\\])]/.test(lines[row].trimStart());\n\n if (endsWithOpen && startsWithClose) {\n // Bracket expansion: the cursor sits between a matching open/close\n // pair (e.g. `{|}`). Expand into a three-line block with the cursor\n // on an indented middle line.\n const innerIndent = baseIndent + \" \";\n const newLines = [...lines];\n newLines[row] = innerIndent;\n newLines.splice(row + 1, 0, baseIndent + lines[row].trimStart());\n return { lines: newLines, row, col: innerIndent.length };\n }\n if (endsWithOpen) {\n // A lone open bracket on the previous line: drop an extra indent for\n // the new line and auto-insert the matching closing bracket below.\n const openChar = prevLine.trimEnd().slice(-1);\n const closeChar = BRACKET_PAIRS[openChar] ?? \"}\";\n const indent = baseIndent + \" \";\n const newLines = [...lines];\n newLines[row] = indent + lines[row];\n newLines.splice(row + 1, 0, baseIndent + closeChar);\n return { lines: newLines, row, col: indent.length };\n }\n if (baseIndent && col === 0) {\n return { lines: lines.with(row, baseIndent + lines[row]), row, col: baseIndent.length };\n }\n }\n\n return undefined;\n}\n"],"mappings":"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"}