@tailor-platform/sdk 2.26.0 → 2.28.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 (222) hide show
  1. package/CHANGELOG.md +144 -0
  2. package/agent-skills/tailor/SKILL.md +4 -2
  3. package/dist/application-CgJLyJaF.mjs +200 -0
  4. package/dist/application-CgJLyJaF.mjs.map +1 -0
  5. package/dist/application-CvmKh5WT.mjs +1 -0
  6. package/dist/cli/commands/deploy/deploy.d.mts +2 -0
  7. package/dist/cli/commands/deploy/tailordb/migration-validation.d.mts +2 -1
  8. package/dist/cli/commands/executor/get.d.mts +2 -1
  9. package/dist/cli/commands/executor/jobs.d.mts +2 -1
  10. package/dist/cli/commands/executor/trigger.d.mts +2 -1
  11. package/dist/cli/commands/function/get.d.mts +2 -1
  12. package/dist/cli/commands/function/list.d.mts +2 -1
  13. package/dist/cli/commands/organization/folder/create.d.mts +2 -1
  14. package/dist/cli/commands/organization/folder/delete.d.mts +2 -1
  15. package/dist/cli/commands/organization/folder/get.d.mts +2 -1
  16. package/dist/cli/commands/organization/folder/list.d.mts +2 -1
  17. package/dist/cli/commands/organization/folder/update.d.mts +2 -1
  18. package/dist/cli/commands/organization/get.d.mts +2 -1
  19. package/dist/cli/commands/organization/tree.d.mts +2 -1
  20. package/dist/cli/commands/organization/update.d.mts +2 -1
  21. package/dist/cli/commands/show.d.mts +2 -1
  22. package/dist/cli/commands/tailordb/migrate/bundler.d.mts +4 -6
  23. package/dist/cli/commands/tailordb/migrate/diff-calculator.d.mts +8 -1
  24. package/dist/cli/commands/tailordb/migrate/remote-state.d.mts +1 -0
  25. package/dist/cli/commands/tailordb/migrate/snapshot-types.d.mts +3 -1
  26. package/dist/cli/commands/workflow/executions.d.mts +2 -1
  27. package/dist/cli/commands/workflow/get.d.mts +2 -1
  28. package/dist/cli/commands/workflow/start.d.mts +2 -1
  29. package/dist/cli/commands/workspace/app/health.d.mts +2 -1
  30. package/dist/cli/commands/workspace/app/list.d.mts +2 -1
  31. package/dist/cli/commands/workspace/create.d.mts +5 -2
  32. package/dist/cli/commands/workspace/delete.d.mts +2 -1
  33. package/dist/cli/commands/workspace/get.d.mts +2 -1
  34. package/dist/cli/commands/workspace/restore.d.mts +2 -1
  35. package/dist/cli/commands/workspace/user/invite.d.mts +2 -1
  36. package/dist/cli/commands/workspace/user/list.d.mts +2 -1
  37. package/dist/cli/commands/workspace/user/remove.d.mts +2 -1
  38. package/dist/cli/commands/workspace/user/update.d.mts +2 -1
  39. package/dist/cli/lib.d.mts +3 -3
  40. package/dist/cli/lib.mjs +1 -1
  41. package/dist/cli/lib.mjs.map +1 -1
  42. package/dist/cli/main.d.mts +2 -0
  43. package/dist/cli/main.mjs +68 -55
  44. package/dist/cli/main.mjs.map +1 -1
  45. package/dist/cli/query/index.d.mts +2 -1
  46. package/dist/cli/shared/args.d.mts +4 -2
  47. package/dist/cli/shared/client.d.mts +6 -1
  48. package/dist/cli/shared/context.d.mts +2 -1
  49. package/dist/cli/shared/logger.d.mts +5 -2
  50. package/dist/cli/shared/readonly-guard.d.mts +2 -1
  51. package/dist/cli/shared/seed-context.d.mts +5 -0
  52. package/dist/cli/shared/type-generator.d.mts +2 -1
  53. package/dist/cli/shared/workspace-name.d.mts +2 -0
  54. package/dist/completion/zsh-worker.zsh +220 -19
  55. package/dist/configure/config/types.d.mts +34 -1
  56. package/dist/configure/index.d.mts +6 -6
  57. package/dist/configure/index.mjs +1 -1
  58. package/dist/configure/index.mjs.map +1 -1
  59. package/dist/configure/services/aigateway/types.d.mts +2 -1
  60. package/dist/configure/services/auth/types.d.mts +8 -2
  61. package/dist/configure/services/executor/executor.d.mts +2 -1
  62. package/dist/configure/services/executor/operation.d.mts +2 -1
  63. package/dist/configure/services/executor/trigger/event.d.mts +3 -2
  64. package/dist/configure/services/executor/trigger/schedule.d.mts +2 -1
  65. package/dist/configure/services/executor/trigger/webhook.d.mts +1 -1
  66. package/dist/configure/services/http-adapter/http-adapter.d.mts +2 -1
  67. package/dist/configure/services/idp/permission.d.mts +4 -3
  68. package/dist/configure/services/idp/types.d.mts +2 -1
  69. package/dist/configure/services/resolver/permission.d.mts +2 -1
  70. package/dist/configure/services/resolver/resolver.d.mts +3 -2
  71. package/dist/configure/services/secrets/types.d.mts +2 -1
  72. package/dist/configure/services/staticwebsite/types.d.mts +2 -1
  73. package/dist/configure/services/tailordb/permission.d.mts +2 -1
  74. package/dist/configure/services/tailordb/schema.d.mts +5 -4
  75. package/dist/configure/services/tailordb/types.d.mts +13 -2
  76. package/dist/configure/services/workflow/execution-policy.types.d.mts +2 -1
  77. package/dist/configure/services/workflow/job.d.mts +3 -2
  78. package/dist/configure/services/workflow/wait-point.d.mts +2 -1
  79. package/dist/configure/types/field.types.d.mts +50 -12
  80. package/dist/configure/types/permission-operand.types.d.mts +2 -1
  81. package/dist/configure/types/type.d.mts +3 -2
  82. package/dist/{crashreport-DFpRn-LS.mjs → crashreport-BAG8c7hB.mjs} +4 -4
  83. package/dist/{crashreport-DFpRn-LS.mjs.map → crashreport-BAG8c7hB.mjs.map} +1 -1
  84. package/dist/crashreport-BcXuocwI.mjs +1 -0
  85. package/dist/date-CgP7gMG_.mjs +2 -0
  86. package/dist/date-CgP7gMG_.mjs.map +1 -0
  87. package/dist/{secretmanager-5olfnI1b.mjs → date-representation-Cr7W7Pn2.mjs} +2 -2
  88. package/dist/date-representation-Cr7W7Pn2.mjs.map +1 -0
  89. package/dist/{errors-CpvSChyL.mjs → errors-D3qpNHR6.mjs} +2 -2
  90. package/dist/{errors-CpvSChyL.mjs.map → errors-D3qpNHR6.mjs.map} +1 -1
  91. package/dist/{field-parse-DhnFs9WG.mjs → field-parse-C41e3UAF.mjs} +2 -2
  92. package/dist/{field-parse-DhnFs9WG.mjs.map → field-parse-C41e3UAF.mjs.map} +1 -1
  93. package/dist/idp-G_ojPBB5.mjs.map +1 -1
  94. package/dist/kysely-type-BWMfV301.mjs +48 -0
  95. package/dist/kysely-type-BWMfV301.mjs.map +1 -0
  96. package/dist/logger-DuaT2zY3.mjs +9 -0
  97. package/dist/logger-DuaT2zY3.mjs.map +1 -0
  98. package/dist/{manager-8-JOvuLl.mjs → manager-Bk-7vkwd.mjs} +2 -2
  99. package/dist/{manager-8-JOvuLl.mjs.map → manager-Bk-7vkwd.mjs.map} +1 -1
  100. package/dist/migration-steps-C6F3zNdQ.mjs +3 -0
  101. package/dist/migration-steps-C6F3zNdQ.mjs.map +1 -0
  102. package/dist/package-json-D1BRkjtr.mjs +1 -0
  103. package/dist/parser/service/tailordb/types.d.mts +3 -1
  104. package/dist/plugin/builtin/enum-constants/index.d.mts +2 -1
  105. package/dist/plugin/builtin/file-utils/index.d.mts +2 -1
  106. package/dist/plugin/builtin/kysely-type/index.d.mts +2 -1
  107. package/dist/plugin/builtin/kysely-type/index.mjs +1 -1
  108. package/dist/plugin/builtin/seed/index.d.mts +11 -1
  109. package/dist/plugin/builtin/seed/index.mjs +1 -1
  110. package/dist/plugin/index.mjs +1 -1
  111. package/dist/register-ts-hook-yxshv0LV.mjs +1013 -0
  112. package/dist/register-ts-hook-yxshv0LV.mjs.map +1 -0
  113. package/dist/runtime/aigateway.mjs +1 -1
  114. package/dist/runtime/authconnection.mjs +1 -1
  115. package/dist/runtime/context.d.mts +2 -1
  116. package/dist/runtime/context.mjs +1 -1
  117. package/dist/runtime/date.d.mts +2 -1
  118. package/dist/runtime/field-parse.d.mts +2 -1
  119. package/dist/runtime/file.d.mts +2 -1
  120. package/dist/runtime/file.mjs +1 -1
  121. package/dist/runtime/globals.d.mts +2 -1
  122. package/dist/runtime/iconv.mjs +1 -1
  123. package/dist/runtime/idp.d.mts +6 -0
  124. package/dist/runtime/idp.mjs +1 -1
  125. package/dist/runtime/index.mjs +1 -1
  126. package/dist/runtime/logger.mjs +1 -1
  127. package/dist/runtime/secretmanager.mjs +1 -1
  128. package/dist/runtime/types.d.mts +7 -1
  129. package/dist/runtime/workflow.d.mts +2 -1
  130. package/dist/runtime/workflow.mjs +1 -1
  131. package/dist/{schema-CRtAmDcl.mjs → schema-B6hJQWp6.mjs} +2 -2
  132. package/dist/schema-B6hJQWp6.mjs.map +1 -0
  133. package/dist/seed/index.d.mts +19 -4
  134. package/dist/seed/index.mjs +7 -9
  135. package/dist/seed/index.mjs.map +1 -1
  136. package/dist/seed-C3P_T_Eh.mjs.map +1 -1
  137. package/dist/service-CETr0AKY.mjs +7 -0
  138. package/dist/service-CETr0AKY.mjs.map +1 -0
  139. package/dist/service-DREWLYxD.mjs +1 -0
  140. package/dist/{service-DFmt9UJP.mjs → service-b1g22NN9.mjs} +2 -2
  141. package/dist/{service-DFmt9UJP.mjs.map → service-b1g22NN9.mjs.map} +1 -1
  142. package/dist/service_pb-Bbu2QSIr.mjs +2 -0
  143. package/dist/service_pb-Bbu2QSIr.mjs.map +1 -0
  144. package/dist/service_pb-urxAIYHT.mjs +1 -0
  145. package/dist/tailor-proto/src/tailor/v1/events_pb.d.mts +53 -1
  146. package/dist/tailor-proto/src/tailor/v1/events_resource_pb.d.mts +33 -0
  147. package/dist/tailor-proto/src/tailor/v1/function_resource_pb.d.mts +0 -8
  148. package/dist/tailor-proto/src/tailor/v1/service_pb.d.mts +18 -1
  149. package/dist/tailor-proto/src/tailor/v1/tailordb_resource_pb.d.mts +4 -0
  150. package/dist/telemetry-DpkFGBmu.mjs +1 -0
  151. package/dist/{telemetry-Bklv9kQY.mjs → telemetry-Xk7J829P.mjs} +2 -2
  152. package/dist/{telemetry-Bklv9kQY.mjs.map → telemetry-Xk7J829P.mjs.map} +1 -1
  153. package/dist/types/field.generated.d.mts +2 -2
  154. package/dist/types/tailordb.generated.d.mts +2 -0
  155. package/dist/utils/test/index.mjs +1 -1
  156. package/dist/vitest/date-representation.d.mts +23 -0
  157. package/dist/vitest/index.d.mts +3 -1
  158. package/dist/vitest/index.mjs +1 -1
  159. package/dist/vitest/index.mjs.map +1 -1
  160. package/dist/vitest/migration-steps.d.mts +45 -0
  161. package/dist/vitest/mock-kysely.d.mts +2 -1
  162. package/dist/vitest/mocks/aigateway.d.mts +2 -1
  163. package/dist/vitest/mocks/authconnection.d.mts +2 -1
  164. package/dist/vitest/mocks/file.d.mts +2 -1
  165. package/dist/vitest/mocks/iconv.d.mts +2 -1
  166. package/dist/vitest/mocks/idp.d.mts +3 -1
  167. package/dist/vitest/mocks/logger.d.mts +2 -1
  168. package/dist/vitest/mocks/secretmanager.d.mts +2 -1
  169. package/dist/vitest/mocks/tailordb-pglite.d.mts +2 -1
  170. package/dist/vitest/mocks/tailordb.d.mts +2 -1
  171. package/dist/vitest/mocks/workflow.d.mts +3 -1
  172. package/dist/vitest/pglite-kysely.d.mts +2 -1
  173. package/dist/vitest/setup.d.mts +3 -1
  174. package/dist/vitest/setup.mjs +1 -1
  175. package/dist/vitest/setup.mjs.map +1 -1
  176. package/dist/vitest/workflow-local.d.mts +2 -1
  177. package/dist/{workspace_resource_pb-CxR_6fyN.mjs → workspace_resource_pb-CaoM2npP.mjs} +2 -2
  178. package/dist/workspace_resource_pb-CaoM2npP.mjs.map +1 -0
  179. package/docs/cli/application.md +37 -16
  180. package/docs/cli/data.md +105 -0
  181. package/docs/cli/function.md +2 -0
  182. package/docs/cli/secret.md +6 -6
  183. package/docs/cli/tailordb.md +18 -16
  184. package/docs/cli/user.md +37 -7
  185. package/docs/cli/workspace.md +10 -2
  186. package/docs/cli-reference.md +25 -3
  187. package/docs/configuration.md +28 -6
  188. package/docs/github-actions.md +212 -63
  189. package/docs/multi-environment.md +24 -0
  190. package/docs/plugin/custom.md +2 -1
  191. package/docs/services/auth.md +20 -0
  192. package/docs/services/executor.md +2 -2
  193. package/docs/services/idp.md +6 -1
  194. package/docs/services/resolver.md +3 -1
  195. package/docs/services/staticwebsite.md +5 -5
  196. package/docs/services/tailordb-migration.md +222 -41
  197. package/docs/services/tailordb.md +17 -4
  198. package/docs/testing.md +4 -0
  199. package/package.json +18 -18
  200. package/dist/application-ChqHuhZW.mjs +0 -1
  201. package/dist/application-DS0XKBtK.mjs +0 -200
  202. package/dist/application-DS0XKBtK.mjs.map +0 -1
  203. package/dist/crashreport-CBaRJl5h.mjs +0 -1
  204. package/dist/date-Dri6Yas-.mjs +0 -2
  205. package/dist/date-Dri6Yas-.mjs.map +0 -1
  206. package/dist/kysely-type-RDX59E1j.mjs +0 -48
  207. package/dist/kysely-type-RDX59E1j.mjs.map +0 -1
  208. package/dist/logger-Db-YRTwK.mjs +0 -9
  209. package/dist/logger-Db-YRTwK.mjs.map +0 -1
  210. package/dist/package-json-CmqhDJ__.mjs +0 -1
  211. package/dist/register-ts-hook-BuwkLuxC.mjs +0 -925
  212. package/dist/register-ts-hook-BuwkLuxC.mjs.map +0 -1
  213. package/dist/schema-CRtAmDcl.mjs.map +0 -1
  214. package/dist/secretmanager-5olfnI1b.mjs.map +0 -1
  215. package/dist/service-Bx-7Lz06.mjs +0 -1
  216. package/dist/service-CL1Bp4It.mjs +0 -7
  217. package/dist/service-CL1Bp4It.mjs.map +0 -1
  218. package/dist/service_pb-ZClWtj1X.mjs +0 -2
  219. package/dist/service_pb-ZClWtj1X.mjs.map +0 -1
  220. package/dist/service_pb-dB3RrGeh.mjs +0 -1
  221. package/dist/telemetry-DXHP3VVi.mjs +0 -1
  222. package/dist/workspace_resource_pb-CxR_6fyN.mjs.map +0 -1
@@ -11,4 +11,5 @@ export type AIGatewayServiceInput = Omit<AIGatewayInput, "authNamespace"> & {
11
11
  };
12
12
  /** Type accepted by `AppConfig.aiGateways`. Only values returned by `defineAIGateway()` satisfy this. */
13
13
  export type AIGatewayConfig = AIGatewayInput & AIGatewayDefinitionBrand;
14
- //#endregion
14
+ //#endregion
15
+ export {};
@@ -1,6 +1,6 @@
1
+ import { NullableToOptional, output } from "../../../types/helpers.mjs";
1
2
  import { DefinedFieldMetadata, FieldMetadata, TailorField, TailorFieldType } from "../../types/field.types.mjs";
2
3
  import { TailorEnv } from "../../../runtime/types.mjs";
3
- import { NullableToOptional, output } from "../../../types/helpers.mjs";
4
4
  import { TailorDBInstance } from "../tailordb/types.mjs";
5
5
  import { AuthConnectionConfig } from "../../../types/auth-connection.generated.mjs";
6
6
  import { IdProvider, OAuth2Client, OAuth2ClientInput, SCIMAttribute, SCIMConfig, TenantProvider } from "../../../types/auth.generated.mjs";
@@ -124,6 +124,11 @@ export type FederatedIdentity = {
124
124
  export type BeforeLoginClaims = JsonObject & {
125
125
  /** Present only for federated (Google/Microsoft) logins; `undefined` for password logins. */
126
126
  federated_identity?: FederatedIdentity;
127
+ /**
128
+ * When the user's Built-in IdP password was last set, in seconds since the
129
+ * Unix epoch. `undefined` when the user has no password.
130
+ */
131
+ password_updated_at?: number;
127
132
  };
128
133
  export type BeforeLoginHookArgs = {
129
134
  claims: BeforeLoginClaims;
@@ -164,4 +169,5 @@ export type AuthExternalConfig = {
164
169
  type AuthServiceInputLoose = AuthServiceInput<any, any, any, string, any>;
165
170
  export type AuthOwnConfig = DefinedAuth<string, AuthServiceInputLoose>;
166
171
  export type AuthConfig = AuthOwnConfig | AuthExternalConfig;
167
- //#endregion
172
+ //#endregion
173
+ export {};
@@ -66,4 +66,5 @@ export declare function createExecutor<Args, O extends Operation<Args> | {
66
66
  kind: "workflow";
67
67
  workflow: Workflow;
68
68
  }>(config: Executor<Trigger<Args>, O>): Executor<Trigger<Args>, O>;
69
- //#endregion
69
+ //#endregion
70
+ export {};
@@ -46,4 +46,5 @@ export type WorkflowOperation<Args, W extends Workflow = Workflow> = Omit<Workfl
46
46
  invoker?: MachineUserName;
47
47
  } & WorkflowArgsProperty<Args, W>;
48
48
  export type Operation<Args> = FunctionOperation<Args> | GqlOperation<Args> | WebhookOperation<Args> | WorkflowOperation<Args>;
49
- //#endregion
49
+ //#endregion
50
+ export {};
@@ -1,5 +1,5 @@
1
- import { TailorEnv, TailorPrincipal } from "../../../../runtime/types.mjs";
2
1
  import { SerializeDates, output } from "../../../../types/helpers.mjs";
2
+ import { TailorEnv, TailorPrincipal } from "../../../../runtime/types.mjs";
3
3
  import { AuthAccessTokenTrigger as AuthAccessTokenTrigger$1, IdpUserTrigger as IdpUserTrigger$1, ResolverExecutedTrigger as ResolverExecutedTrigger$1, TailorDBTrigger as TailorDBTrigger$1, WorkflowExecutionTrigger as WorkflowExecutionTrigger$1, WorkflowJobExecutionTrigger as WorkflowJobExecutionTrigger$1 } from "../../../../types/executor.generated.mjs";
4
4
  import { TailorDBType } from "../../tailordb/schema.mjs";
5
5
  import { IdpName } from "../../../types/idp-name.mjs";
@@ -513,4 +513,5 @@ type WorkflowJobExecutionTriggerOptions<K extends WorkflowJobExecutionEventKind[
513
513
  * @returns Workflow job execution trigger
514
514
  */
515
515
  export declare function workflowJobExecutionTrigger<const K extends [WorkflowJobExecutionEventKind, ...WorkflowJobExecutionEventKind[]]>(options: WorkflowJobExecutionTriggerOptions<K>): WorkflowJobExecutionTrigger<WorkflowJobExecutionMultiArgs<K>>;
516
- //#endregion
516
+ //#endregion
517
+ export {};
@@ -20,4 +20,5 @@ interface ScheduleTriggerOptions<T extends string> {
20
20
  * @returns Schedule trigger
21
21
  */
22
22
  export declare function scheduleTrigger<T extends string>(options: ScheduleTriggerOptions<T>): ScheduleTrigger<ScheduleArgs>;
23
- //#endregion
23
+ //#endregion
24
+ export {};
@@ -1,5 +1,5 @@
1
- import { TailorEnv } from "../../../../runtime/types.mjs";
2
1
  import { JsonValue } from "../../../../types/helpers.mjs";
2
+ import { TailorEnv } from "../../../../runtime/types.mjs";
3
3
  import { IncomingWebhookTrigger as IncomingWebhookTrigger$1 } from "../../../../types/executor.generated.mjs";
4
4
  //#region src/configure/services/executor/trigger/webhook.d.ts
5
5
  export interface IncomingWebhookArgs<T extends IncomingWebhookRequest> {
@@ -120,4 +120,5 @@ export type HttpAdapter<Input extends HttpAdapterInput = HttpAdapterInput> = Omi
120
120
  * });
121
121
  */
122
122
  export declare function createHttpAdapter<const Input extends HttpAdapterInput>(config: HttpAdapter<Input>): HttpAdapter<Input>;
123
- //#endregion
123
+ //#endregion
124
+ export {};
@@ -37,10 +37,10 @@ type IdPActionPermission<User extends object = InferredAttributes, Update extend
37
37
  * @example
38
38
  * const permission: IdPPermission = {
39
39
  * create: [{ conditions: [[{ user: "role" }, "=", "ADMIN"]], permit: true }],
40
- * read: [{ conditions: [[{ user: "_loggedIn" }, "=", true]], permit: true }],
40
+ * read: [{ conditions: [[{ user: "role" }, "=", "ADMIN"]], permit: true }],
41
41
  * update: [{ conditions: [[{ newIdpUser: "name" }, "=", { user: "id" }]], permit: true }],
42
42
  * delete: [{ conditions: [[{ user: "role" }, "=", "ADMIN"]], permit: true }],
43
- * sendPasswordResetEmail: [{ conditions: [], permit: true }],
43
+ * sendPasswordResetEmail: [{ conditions: [[{ user: "role" }, "=", "ADMIN"]], permit: true }],
44
44
  * unenrollMfa: [{ conditions: [[{ user: "role" }, "=", "ADMIN"]], permit: true }],
45
45
  * };
46
46
  */
@@ -60,4 +60,5 @@ export type IdPPermission<User extends object = InferredAttributes> = {
60
60
  * authorization checks.
61
61
  */
62
62
  export declare const unsafeAllowAllIdPPermission: IdPPermission;
63
- //#endregion
63
+ //#endregion
64
+ export {};
@@ -19,4 +19,5 @@ type IdPOwnConfigInput = Omit<IdPInput, "permission"> & {
19
19
  };
20
20
  export type IdPOwnConfig = Omit<DefinedIdp<string, IdPOwnConfigInput, string>, "provider">;
21
21
  export type IdPConfig = IdPOwnConfig | IdPExternalConfig;
22
- //#endregion
22
+ //#endregion
23
+ export {};
@@ -60,4 +60,5 @@ export type ResolverPermissionPolicy<User extends object = InferredAttributes> =
60
60
  * const permission: ResolverPermission = "allowAnonymous";
61
61
  */
62
62
  export type ResolverPermission<User extends object = InferredAttributes> = readonly ResolverPermissionPolicy<User>[] | "allowAnonymous";
63
- //#endregion
63
+ //#endregion
64
+ export {};
@@ -1,5 +1,5 @@
1
- import { TailorEnv, TailorPrincipal } from "../../../runtime/types.mjs";
2
1
  import { InferFieldsOutput, output } from "../../../types/helpers.mjs";
2
+ import { TailorEnv, TailorPrincipal } from "../../../runtime/types.mjs";
3
3
  import { MachineUserName } from "../auth/types.mjs";
4
4
  import { ResolverInput } from "../../../types/resolver.generated.mjs";
5
5
  import { ResolverPermission } from "./permission.mjs";
@@ -84,4 +84,5 @@ export declare function createResolver<Input extends Record<string, TailorAnyFie
84
84
  permission?: ResolverPermission;
85
85
  }>): ResolverReturn<Input, Output>;
86
86
  export type ResolverConfig = ReturnType<typeof createResolver<any, any>>;
87
- //#endregion
87
+ //#endregion
88
+ export {};
@@ -6,4 +6,5 @@ export type SecretsDefinitionBrand = {
6
6
  };
7
7
  /** Type accepted by `AppConfig.secrets`. Only values returned by `defineSecretManager()` satisfy this. */
8
8
  export type SecretsConfig = SecretsInput & SecretsDefinitionBrand;
9
- //#endregion
9
+ //#endregion
10
+ export {};
@@ -6,4 +6,5 @@ export type StaticWebsiteDefinitionBrand = {
6
6
  };
7
7
  /** Type accepted by `AppConfig.staticWebsites`. Only values returned by `defineStaticWebSite()` satisfy this. */
8
8
  export type StaticWebsiteConfig = StaticWebsiteInput & StaticWebsiteDefinitionBrand;
9
- //#endregion
9
+ //#endregion
10
+ export {};
@@ -99,4 +99,5 @@ export declare const unsafeAllowAllTypePermission: TailorTypePermission;
99
99
  * authorization checks.
100
100
  */
101
101
  export declare const unsafeAllowAllGqlPermission: TailorTypeGqlPermission;
102
- //#endregion
102
+ //#endregion
103
+ export {};
@@ -1,7 +1,7 @@
1
+ import { InferFieldsOutput, IsUnion, TypeLevelError, UnionToIntersection, output } from "../../../types/helpers.mjs";
1
2
  import { FieldOptions, FieldOutput, FieldValidateInput, TailorFieldType, TailorToTs } from "../../types/field.types.mjs";
2
3
  import { InferredAttributes } from "../../../runtime/types.mjs";
3
- import { InferFieldsOutput, IsUnion, TypeLevelError, UnionToIntersection, output } from "../../../types/helpers.mjs";
4
- import { DBFieldMetadata, DefinedDBFieldMetadata, ExcludeDefaultedDBFields, ExcludeHookedDBFields, ExcludeNestedDBFields, Hook, IndexDef, RelationType, SerialConfig, TailorDBField as TailorDBField$1, TailorDBType as TailorDBType$1, TypeFeatures, TypeHook, TypeValidateFn, UpdateHookFn } from "./types.mjs";
4
+ import { DBFieldMetadata, DefinedDBFieldMetadata, ExcludeDefaultedDBFields, ExcludeHookedDBFields, ExcludeNestedDBFields, ExcludeSerialDBFields, Hook, IndexDef, RelationType, SerialConfig, TailorDBField as TailorDBField$1, TailorDBType as TailorDBType$1, TypeFeatures, TypeHook, TypeValidateFn, UpdateHookFn } from "./types.mjs";
5
5
  import { AllowedValues, AllowedValuesOutput } from "../../types/field.mjs";
6
6
  import { FieldParseArgs } from "../../../runtime/field-parse.mjs";
7
7
  import { PluginConfigs, PluginFieldExtensions } from "../../../plugin/types.mjs";
@@ -426,7 +426,7 @@ declare function _enum<const V extends AllowedValues, const Opt extends FieldOpt
426
426
  * @example db.object({ street: db.string(), city: db.string(), zip: db.string() })
427
427
  * @example db.object({ name: db.string() }, { optional: true })
428
428
  */
429
- declare function object<const F extends Record<string, TailorAnyDBField> & ExcludeNestedDBFields<F> & ExcludeHookedDBFields<F> & ExcludeDefaultedDBFields<F>, const Opt extends FieldOptions>(fields: F, options?: Opt): TailorDBField<{
429
+ declare function object<const F extends Record<string, TailorAnyDBField> & ExcludeNestedDBFields<F> & ExcludeHookedDBFields<F> & ExcludeDefaultedDBFields<F> & ExcludeSerialDBFields<F>, const Opt extends FieldOptions>(fields: F, options?: Opt): TailorDBField<{
430
430
  type: "nested";
431
431
  array: Opt extends {
432
432
  array: true;
@@ -506,4 +506,5 @@ export declare const db: {
506
506
  };
507
507
  };
508
508
  };
509
- //#endregion
509
+ //#endregion
510
+ export {};
@@ -1,11 +1,16 @@
1
+ import { DeepReadonly, InferFieldsOutput, Prettify, output } from "../../../types/helpers.mjs";
1
2
  import { DefinedFieldMetadata, FieldMetadata, TailorField, TailorFieldType } from "../../types/field.types.mjs";
2
3
  import { InferredAttributes, TailorPrincipal } from "../../../runtime/types.mjs";
3
- import { DeepReadonly, InferFieldsOutput, Prettify, output } from "../../../types/helpers.mjs";
4
4
  import { DBFieldMetadata as DBFieldMetadata$1, GqlOperationsInput, RawPermissions, TailorDBServiceConfigInput } from "../../../types/tailordb.generated.mjs";
5
5
  //#region src/configure/services/tailordb/types.d.ts
6
6
  export type SerialConfig<T extends "string" | "integer" = "string" | "integer"> = Prettify<{
7
7
  start: number;
8
8
  maxValue?: number;
9
+ /**
10
+ * Number records without gaps: a number is used only by a create that
11
+ * commits. Creates of the table that are numbered run one at a time.
12
+ */
13
+ gapless?: boolean;
9
14
  } & (T extends "string" ? {
10
15
  format?: string;
11
16
  } : object)>;
@@ -184,6 +189,11 @@ export type ExcludeDefaultedDBFields<T extends Record<string, TailorAnyDBField>>
184
189
  array: boolean;
185
190
  default: true;
186
191
  }, any> ? never : T[K]; };
192
+ export type ExcludeSerialDBFields<T extends Record<string, TailorAnyDBField>> = { [K in keyof T]: T[K] extends TailorDBField<{
193
+ type: TailorFieldType;
194
+ array: boolean;
195
+ serial: true;
196
+ }, any> ? never : T[K]; };
187
197
  export interface TypeFeatures {
188
198
  /** Custom plural form of the table name for GraphQL */
189
199
  pluralForm?: string;
@@ -223,4 +233,5 @@ type TailorDBExternalConfig = {
223
233
  export type TailorDBServiceInput = {
224
234
  [namespace: string]: TailorDBServiceConfigInput | TailorDBExternalConfig;
225
235
  };
226
- //#endregion
236
+ //#endregion
237
+ export {};
@@ -99,4 +99,5 @@ export interface ExecutionPolicyGroupOptions {
99
99
  */
100
100
  separator?: string;
101
101
  }
102
- //#endregion
102
+ //#endregion
103
+ export {};
@@ -1,5 +1,5 @@
1
- import { TailorEnv, TailorPrincipal } from "../../../runtime/types.mjs";
2
1
  import { JsonCompatible, TypeLevelError } from "../../../types/helpers.mjs";
2
+ import { TailorEnv, TailorPrincipal } from "../../../runtime/types.mjs";
3
3
  import { ExecJobFunctionOptions } from "../../../runtime/workflow.mjs";
4
4
  //#region src/configure/services/workflow/job.d.ts
5
5
  /**
@@ -98,4 +98,5 @@ interface CreateWorkflowJobConfig<Name extends string, I, O> {
98
98
  * });
99
99
  */
100
100
  export declare function createWorkflowJob<const Name extends string, I = undefined, O = undefined>(config: CreateWorkflowJobConfig<Name, I, O>): WorkflowJob<Name, I, Awaited<O>>;
101
- //#endregion
101
+ //#endregion
102
+ export {};
@@ -127,4 +127,5 @@ export declare function createWaitPoint<Payload = undefined, Result = undefined>
127
127
  * // For 2-level access, use destructured export with JSDoc attached to the export itself.
128
128
  */
129
129
  export declare function createWaitPoints<T extends Record<string, WaitPointInstance<any, any> | ParameterizedWaitPointInstance<any, any, any>>>(builder: (define: DefineFn) => T): T;
130
- //#endregion
130
+ //#endregion
131
+ export {};
@@ -1,3 +1,4 @@
1
+ import { IsUnion, TypeLevelError } from "../../types/helpers.mjs";
1
2
  import { Temporal } from "temporal-spec";
2
3
  //#region src/configure/types/field.types.d.ts
3
4
  export interface EnumValue {
@@ -20,7 +21,8 @@ export type TailorToTs = {
20
21
  nested: Record<string, unknown>;
21
22
  } & Record<TailorFieldType, unknown>;
22
23
  export interface FieldMetadata {
23
- as?: "string" | "date" | "temporal";
24
+ /** Date value representation. `"default"` follows the configured `defaultDateRepresentation`. */
25
+ as?: "string" | "date" | "temporal" | "default";
24
26
  description?: string;
25
27
  required?: boolean;
26
28
  array?: boolean;
@@ -39,31 +41,66 @@ export type FieldOptions = {
39
41
  optional?: boolean;
40
42
  array?: boolean;
41
43
  };
44
+ /**
45
+ * Registry of each application's `defaultDateRepresentation`. `tailor generate`
46
+ * writes one entry per application into `tailor.d.ts`, keyed by the app name:
47
+ * `declare module "@tailor-platform/sdk" { interface DateRepresentationRegistry { shop: "temporal" } }`.
48
+ * An app without the setting is recorded as `"unset"`. Application names are
49
+ * unique within a workspace, so two entries never share a key.
50
+ */
51
+ export interface DateRepresentationRegistry {}
52
+ /** Representation the SDK applies when no app configures one. */
53
+ type BuiltinDateDefault = undefined;
54
+ export type DateDefaultConflictMessage = "defaultDateRepresentation differs between the tailor.config.ts files included in this TypeScript program; use the same value in each, or give each application its own tsconfig.json";
55
+ type DateDefaultOfValue<Value> = Value extends "temporal" | "date" ? Value : Value extends "unset" ? undefined : never;
56
+ type NormalizeDateDefault<Value, Builtin> = Value extends undefined ? Builtin : Value;
57
+ /**
58
+ * Resolve the default date representation declared by a registry: the single
59
+ * value every included app agrees on, or a type-level error when they differ.
60
+ */
61
+ export type DateDefaultOf<Registry, Builtin = BuiltinDateDefault> = [DateDefaultOfValue<Registry[keyof Registry]>] extends [never] ? Builtin : IsUnion<NormalizeDateDefault<DateDefaultOfValue<Registry[keyof Registry]>, Builtin>> extends true ? TypeLevelError<DateDefaultConflictMessage> : NormalizeDateDefault<DateDefaultOfValue<Registry[keyof Registry]>, Builtin>;
62
+ type DefaultDateRepresentation = DateDefaultOf<DateRepresentationRegistry>;
63
+ /** Explicit `as` values a date field accepts. */
64
+ export type DateRepresentationOption = "string" | "date" | "temporal";
65
+ type ResolveDateRepresentation<As, Default> = As extends DateRepresentationOption ? As : Default;
42
66
  /** Options for a date field. */
43
67
  export type DateFieldOptions = FieldOptions & {
44
68
  /**
45
69
  * Use a Date at midnight UTC, or a Temporal.PlainDate, instead of a
46
- * YYYY-MM-DD string. Defaults to string.
70
+ * YYYY-MM-DD string. Defaults to `defaultDateRepresentation`, or string.
47
71
  */
48
- as?: "string" | "date" | "temporal";
72
+ as?: DateRepresentationOption;
49
73
  };
50
- export type DateFieldValue<As> = As extends "date" ? Date : As extends "temporal" ? Temporal.PlainDate : string;
74
+ type DateValueOf<R> = R extends "date" ? Date : R extends "temporal" ? Temporal.PlainDate : R extends TypeLevelError<string> ? R : string;
75
+ /** Value type of a date field under an explicit `Default` representation. */
76
+ export type DateFieldValueFor<As, Default> = DateValueOf<ResolveDateRepresentation<As, Default>>;
77
+ export type DateFieldValue<As> = DateFieldValueFor<As, DefaultDateRepresentation>;
51
78
  /** Options for a datetime field. */
52
79
  export type DateTimeFieldOptions = FieldOptions & {
53
- /** Choose string, Date, or Temporal.Instant values. Defaults to string input and string | Date output. */
54
- as?: "string" | "date" | "temporal";
80
+ /**
81
+ * Choose string, Date, or Temporal.Instant values. Defaults to
82
+ * `defaultDateRepresentation`, or string input and string | Date output.
83
+ */
84
+ as?: DateRepresentationOption;
55
85
  };
56
- export type DateTimeFieldValue<As> = As extends "date" ? Date : As extends "temporal" ? Temporal.Instant : As extends "string" ? string : string | Date;
86
+ type DateTimeValueOf<R> = R extends "date" ? Date : R extends "temporal" ? Temporal.Instant : R extends "string" ? string : R extends TypeLevelError<string> ? R : string | Date;
87
+ /** Value type of a datetime field under an explicit `Default` representation. */
88
+ export type DateTimeFieldValueFor<As, Default> = DateTimeValueOf<ResolveDateRepresentation<As, Default>>;
89
+ export type DateTimeFieldValue<As> = DateTimeFieldValueFor<As, DefaultDateRepresentation>;
57
90
  /** Options for a time field. */
58
91
  export type TimeFieldOptions = FieldOptions & {
59
92
  /**
60
93
  * Choose HH:mm strings, Date values on 1970-01-01 UTC, or Temporal.PlainTime values.
61
- * Defaults to string. Date output uses UTC hours/minutes and ignores the date.
62
- * Seconds and fractional seconds are truncated in both representations.
94
+ * Defaults to `defaultDateRepresentation`, or string. Date output uses UTC
95
+ * hours/minutes and ignores the date. Seconds and fractional seconds are
96
+ * truncated in both representations.
63
97
  */
64
- as?: "string" | "date" | "temporal";
98
+ as?: DateRepresentationOption;
65
99
  };
66
- export type TimeFieldValue<As> = As extends "date" ? Date : As extends "temporal" ? Temporal.PlainTime : string;
100
+ type TimeValueOf<R> = R extends "date" ? Date : R extends "temporal" ? Temporal.PlainTime : R extends TypeLevelError<string> ? R : string;
101
+ /** Value type of a time field under an explicit `Default` representation. */
102
+ export type TimeFieldValueFor<As, Default> = TimeValueOf<ResolveDateRepresentation<As, Default>>;
103
+ export type TimeFieldValue<As> = TimeFieldValueFor<As, DefaultDateRepresentation>;
67
104
  export type FieldOutput<T, O extends FieldOptions> = OptionalFieldOutput<ArrayFieldOutput<T, O>, O>;
68
105
  type OptionalFieldOutput<T, O extends FieldOptions> = O["optional"] extends true ? T | null : T;
69
106
  type ArrayFieldOutput<T, O extends FieldOptions> = [O] extends [{
@@ -93,4 +130,5 @@ export interface TailorField<Defined extends DefinedFieldMetadata = DefinedField
93
130
  readonly metadata: M;
94
131
  }
95
132
  export type TailorAnyField = TailorField<any>;
96
- //#endregion
133
+ //#endregion
134
+ export {};
@@ -16,4 +16,5 @@ export type UserBooleanOperand<User extends object = InferredAttributes> = {
16
16
  export type UserBooleanArrayOperand<User extends object = InferredAttributes> = {
17
17
  user: BooleanArrayFieldKeys<User>;
18
18
  };
19
- //#endregion
19
+ //#endregion
20
+ export {};
@@ -1,5 +1,5 @@
1
- import { DefinedFieldMetadata, FieldMetadata, FieldValidateInput, TailorField as TailorField$1, TailorFieldType } from "./field.types.mjs";
2
1
  import { TypeLevelError } from "../../types/helpers.mjs";
2
+ import { DefinedFieldMetadata, FieldMetadata, FieldValidateInput, TailorField as TailorField$1, TailorFieldType } from "./field.types.mjs";
3
3
  import "./field.mjs";
4
4
  import { FieldParseArgs } from "../../runtime/field-parse.mjs";
5
5
  import { StandardSchemaV1 } from "@standard-schema/spec";
@@ -70,4 +70,5 @@ export interface TailorField<Defined extends DefinedFieldMetadata = DefinedField
70
70
  */
71
71
  parse(args: FieldParseArgs): StandardSchemaV1.Result<Output>;
72
72
  }
73
- //#endregion
73
+ //#endregion
74
+ export {};
@@ -1,4 +1,4 @@
1
- import{a as e,i as t}from"./logger-Db-YRTwK.mjs";import{t as n}from"./package-json-C690ceex.mjs";import{n as r}from"./user-agent-vdHYF3QL.mjs";import{r as i,t as a}from"./secret-file-C9wp_FCX.mjs";import*as o from"pathe";import*as s from"node:fs";import{isCI as c}from"std-env";import{parseYAML as l}from"confbox";import{xdgConfig as u}from"xdg-basedir";import*as d from"node:crypto";import*as f from"node:os";function parseCrashReportConfig(){if(c)return{localEnabled:!1,remoteEnabled:!1,localDir:``};let e=(process.env.TAILOR_CRASH_REPORTS_LOCAL??`on`).toLowerCase()!==`off`,t=(process.env.TAILOR_CRASH_REPORTS_REMOTE??`off`).toLowerCase()===`on`,n=u?o.join(u,`tailor-platform`,`crash-reports`):``;return{localEnabled:e&&n!==``,remoteEnabled:t,localDir:n}}const p=`--- JSON ---`,m=`.crash.log`;function formatCrashReport(e){return[`Crash Report: ${e.id}`,`Timestamp: ${e.timestamp}`,`Error Type: ${e.errorType}`,``,`--- Environment ---`,`SDK Version: ${e.sdkVersion}`,`Node Version: ${e.nodeVersion}`,`OS: ${e.osPlatform} ${e.osRelease}`,`Arch: ${e.arch}`,``,`--- Command ---`,`Command: ${e.command}`,`Arguments: ${JSON.stringify(e.argv)}`,``,`--- Error ---`,`Name: ${e.errorName}`,`Message: ${e.errorMessage}`,``,`--- Stack Trace ---`,e.stackTrace||`(no stack trace available)`,``,p,JSON.stringify(e),``].join(`
1
+ import{a as e,o as t}from"./logger-DuaT2zY3.mjs";import{t as n}from"./package-json-C690ceex.mjs";import{n as r}from"./user-agent-vdHYF3QL.mjs";import{r as i,t as a}from"./secret-file-C9wp_FCX.mjs";import*as o from"pathe";import*as s from"node:fs";import{isCI as c}from"std-env";import{parseYAML as l}from"confbox";import{xdgConfig as u}from"xdg-basedir";import*as d from"node:crypto";import*as f from"node:os";function parseCrashReportConfig(){if(c)return{localEnabled:!1,remoteEnabled:!1,localDir:``};let e=(process.env.TAILOR_CRASH_REPORTS_LOCAL??`on`).toLowerCase()!==`off`,t=(process.env.TAILOR_CRASH_REPORTS_REMOTE??`off`).toLowerCase()===`on`,n=u?o.join(u,`tailor-platform`,`crash-reports`):``;return{localEnabled:e&&n!==``,remoteEnabled:t,localDir:n}}const p=`--- JSON ---`,m=`.crash.log`;function formatCrashReport(e){return[`Crash Report: ${e.id}`,`Timestamp: ${e.timestamp}`,`Error Type: ${e.errorType}`,``,`--- Environment ---`,`SDK Version: ${e.sdkVersion}`,`Node Version: ${e.nodeVersion}`,`OS: ${e.osPlatform} ${e.osRelease}`,`Arch: ${e.arch}`,``,`--- Command ---`,`Command: ${e.command}`,`Arguments: ${JSON.stringify(e.argv)}`,``,`--- Error ---`,`Name: ${e.errorName}`,`Message: ${e.errorMessage}`,``,`--- Stack Trace ---`,e.stackTrace||`(no stack trace available)`,``,p,JSON.stringify(e),``].join(`
2
2
  `)}function generateFilename(e){return`${e.timestamp.replace(/[:.]/g,`-`)}-${e.id.slice(0,8)}${m}`}function cleanupOldFiles(e){try{let t=s.readdirSync(e).filter(e=>e.endsWith(m)).toSorted().toReversed();for(let n of t.slice(10))s.unlinkSync(o.join(e,n))}catch{}}function writeCrashReport(e,t){try{a(t);let n=generateFilename(e),r=o.join(t,n),s=formatCrashReport(e);return i(r,s),cleanupOldFiles(t),r}catch{return}}async function sendCrashReport(e,t){try{let n=process.env.TAILOR_CRASH_REPORT_ENDPOINT||`https://sdk-error-tracking-926vh9t4cl.erp.dev/query`,r=await fetch(n,{method:`POST`,headers:{"Content-Type":`application/json`,"User-Agent":t},body:JSON.stringify({query:`
3
3
  mutation SubmitCrashReport(
4
4
  $id: String!
@@ -37,6 +37,6 @@ mutation SubmitCrashReport(
37
37
  success
38
38
  }
39
39
  }`,variables:e}),signal:AbortSignal.timeout(5e3)});if(!r.ok)return!1;let i=await r.json();return!i.errors?.length&&i.data?.submitCrashReport.success===!0}catch{return!1}}const h=f.homedir(),g=/\b[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\b/gi,_=/\b[0-9a-fA-F]{32,}\b/g,v=/\b[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}\b/g,y=/(?:\/(?:[\w.@\- ]+\/)+[\w.@\- ]+)/g,b=/(?:[A-Za-z]:\\(?:[\w.@\- ]+\\)+[\w.@\- ]+)/g,x=/[?&][^?\s]*/g,S=/\b[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}\b/,C=/^[A-Za-z]:\\/,w=`packages/sdk/`;function lastSegment(e,t){return e.split(t).pop()??e}function sanitizeStackTrace(e){let t=e.search(/\n\s+at /),n;return n=t===-1?sanitizeMessage(e):sanitizeMessage(e.slice(0,t))+e.slice(t),n=n.replace(y,e=>{let t=e.indexOf(w);return t===-1?e.startsWith(h)?`~/<redacted>/${lastSegment(e,`/`)}`:`<external>/${lastSegment(e,`/`)}`:e.slice(t)}),n=n.replace(b,e=>{let t=e.replace(/\\/g,`/`),n=t.indexOf(w);return n===-1?`<external>/${lastSegment(e,`\\`)}`:t.slice(n)}),n}function sanitizeMessage(e){let t=e;return t=t.replace(/\nRequest:\s*[\s\S]*$/,`
40
- Request: <redacted>`),t=t.replace(g,`<uuid>`),t=t.replace(_,`<redacted>`),t=t.replace(v,`<email>`),t=t.replace(x,`?<redacted>`),t=t.replace(y,e=>`<path>/${lastSegment(e,`/`)}`),t=t.replace(b,e=>`<path>/${lastSegment(e,`\\`)}`),t}function sanitizeArgv(e){let t=[],n=!1;for(let r of e){if(n){if(!r.startsWith(`-`)){t.push(`<redacted>`),n=!1;continue}n=!1}if(r.startsWith(`-`)){let e=r.indexOf(`=`);if(e!==-1){t.push(`${r.slice(0,e)}=<redacted>`);continue}t.push(r),n=!0;continue}if(r.startsWith(`/`)&&r.includes(`/`,1)){t.push(`<path>`);continue}if(C.test(r)){t.push(`<path>`);continue}if(S.test(r)){t.push(`<email>`);continue}t.push(r)}return t}function parseCommand(){let e=process.argv.slice(2),t=[];for(let n of e){if(n.startsWith(`-`)||t.length>=3)break;t.push(n)}return t.join(` `)||`<unknown>`}function buildCrashReport(t){let{error:n,sdkVersion:r,errorType:i}=t,a=n instanceof Error,o=a?n.message:String(n),s=a&&n.stack?n.stack:``,c=a?n.name:`UnknownError`,l=readCurrentUser();return{id:d.randomUUID(),timestamp:(/* @__PURE__ */ new Date()).toISOString(),sdkVersion:r,nodeVersion:process.version,osPlatform:process.platform,osRelease:f.release(),arch:process.arch,command:sanitizeMessage(e(parseCommand())),argv:sanitizeArgv(process.argv.map(e)),errorName:e(c),errorMessage:sanitizeMessage(e(o)),stackTrace:sanitizeStackTrace(e(s)),errorType:i,userId:l?.id?e(l.id):null,userEmail:l?.email?e(l.email):null}}function readCurrentUser(){try{if(!u)return null;let e=o.join(u,`tailor-platform`,`config.yaml`);if(!s.existsSync(e))return null;let t=l(s.readFileSync(e,`utf-8`)),n=t?.current_user??null;if(!n)return null;let r=t.users?.[n]?.email;return{id:n,email:typeof r==`string`?r:legacyEmail(n)}}catch{return null}}function legacyEmail(e){return e.includes(`@`)?e:null}async function reportCrash(e,i){try{let a=parseCrashReportConfig();if(!a.localEnabled&&!a.remoteEnabled)return;let o=(await n()).version??`unknown`,s=buildCrashReport({error:e,sdkVersion:o,errorType:i});if(a.localEnabled){let e=writeCrashReport(s,a.localDir);e&&t.log([``,`An unexpected error occurred. A crash report has been saved to:`,` ${e}`,``,`To submit this report:`,` tailor crashreport send --file "${e}"`].join(`
41
- `))}a.remoteEnabled&&await sendCrashReport(s,r(o))}catch{}}function initCrashReporting(){let e=parseCrashReportConfig();if(!e.localEnabled&&!e.remoteEnabled)return;let handleFatal=(e,n)=>{let r=e instanceof Error?e.message:String(e);t.error(r),reportCrash(e,n).finally(()=>{process.exit(1)})};process.on(`uncaughtException`,e=>handleFatal(e,`uncaughtException`)),process.on(`unhandledRejection`,e=>handleFatal(e,`unhandledRejection`))}export{p as a,m as i,reportCrash as n,parseCrashReportConfig as o,sendCrashReport as r,initCrashReporting as t};
42
- //# sourceMappingURL=crashreport-DFpRn-LS.mjs.map
40
+ Request: <redacted>`),t=t.replace(g,`<uuid>`),t=t.replace(_,`<redacted>`),t=t.replace(v,`<email>`),t=t.replace(x,`?<redacted>`),t=t.replace(y,e=>`<path>/${lastSegment(e,`/`)}`),t=t.replace(b,e=>`<path>/${lastSegment(e,`\\`)}`),t}function sanitizeArgv(e){let t=[],n=!1;for(let r of e){if(n){if(!r.startsWith(`-`)){t.push(`<redacted>`),n=!1;continue}n=!1}if(r.startsWith(`-`)){let e=r.indexOf(`=`);if(e!==-1){t.push(`${r.slice(0,e)}=<redacted>`);continue}t.push(r),n=!0}else r.startsWith(`/`)&&r.includes(`/`,1)||C.test(r)?t.push(`<path>`):S.test(r)?t.push(`<email>`):t.push(r)}return t}function parseCommand(){let e=process.argv.slice(2),t=[];for(let n of e){if(n.startsWith(`-`)||t.length>=3)break;t.push(n)}return t.join(` `)||`<unknown>`}function buildCrashReport(e){let{error:n,sdkVersion:r,errorType:i}=e,a=n instanceof Error,o=a?n.message:String(n),s=a&&n.stack?n.stack:``,c=a?n.name:`UnknownError`,l=readCurrentUser();return{id:d.randomUUID(),timestamp:(/* @__PURE__ */ new Date()).toISOString(),sdkVersion:r,nodeVersion:process.version,osPlatform:process.platform,osRelease:f.release(),arch:process.arch,command:sanitizeMessage(t(parseCommand())),argv:sanitizeArgv(process.argv.map(t)),errorName:t(c),errorMessage:sanitizeMessage(t(o)),stackTrace:sanitizeStackTrace(t(s)),errorType:i,userId:l?.id?t(l.id):null,userEmail:l?.email?t(l.email):null}}function readCurrentUser(){try{if(!u)return null;let e=o.join(u,`tailor-platform`,`config.yaml`);if(!s.existsSync(e))return null;let t=l(s.readFileSync(e,`utf-8`)),n=t?.current_user??null;if(!n)return null;let r=t.users?.[n]?.email;return{id:n,email:typeof r==`string`?r:legacyEmail(n)}}catch{return null}}function legacyEmail(e){return e.includes(`@`)?e:null}async function reportCrash(t,i){try{let a=parseCrashReportConfig();if(!a.localEnabled&&!a.remoteEnabled)return;let o=(await n()).version??`unknown`,s=buildCrashReport({error:t,sdkVersion:o,errorType:i});if(a.localEnabled){let t=writeCrashReport(s,a.localDir);t&&e.log([``,`An unexpected error occurred. A crash report has been saved to:`,` ${t}`,``,`To submit this report:`,` tailor crashreport send --file "${t}"`].join(`
41
+ `))}a.remoteEnabled&&await sendCrashReport(s,r(o))}catch{}}function initCrashReporting(){let t=parseCrashReportConfig();if(!t.localEnabled&&!t.remoteEnabled)return;let handleFatal=(t,n)=>{let r=t instanceof Error?t.message:String(t);e.error(r),reportCrash(t,n).finally(()=>{process.exit(1)})};process.on(`uncaughtException`,e=>handleFatal(e,`uncaughtException`)),process.on(`unhandledRejection`,e=>handleFatal(e,`unhandledRejection`))}export{p as a,m as i,reportCrash as n,parseCrashReportConfig as o,sendCrashReport as r,initCrashReporting as t};
42
+ //# sourceMappingURL=crashreport-BAG8c7hB.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"crashreport-DFpRn-LS.mjs","names":["redactSecrets","logger","readPackageJson","userAgentFromVersion","writeSecretFile","ensureSecretDir","path","fs","crypto","os","isCI","localEnabled","remoteEnabled","localDir","xdgConfig","JSON_FOOTER_MARKER","CRASH_LOG_EXTENSION","report","files","dir","f","file","filename","filePath","content","endpoint","response","ua","data","HOME_DIR","UUID_PATTERN","LONG_HEX_PATTERN","EMAIL_PATTERN","ABSOLUTE_PATH_PATTERN","WINDOWS_PATH_PATTERN","URL_QUERY_PATTERN","EMAIL_TEST_PATTERN","WINDOWS_DRIVE_TEST_PATTERN","SDK_PACKAGE_MARKER","separator","firstFrameIndex","stack","result","sdkIndex","match","normalized","message","redactNext","arg","argv","eqIndex","args","commandParts","options","isError","error","rawMessage","rawStack","errorName","currentUser","configPath","raw","parseYAML","email","user","config","sdkVersion","errorType","reason"],"sources":["../src/cli/crashreport/config.ts","../src/cli/crashreport/writer.ts","../src/cli/crashreport/sender.ts","../src/cli/crashreport/sanitize.ts","../src/cli/crashreport/report.ts","../src/cli/crashreport/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 { ensureSecretDir, writeSecretFile } from \"#/cli/shared/secret-file\";\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 .toSorted()\n .toReversed();\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 ensureSecretDir(dir);\n\n const filename = generateFilename(report);\n const filePath = path.join(dir, filename);\n const content = formatCrashReport(report);\n\n writeSecretFile(filePath, content);\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 { redactSecrets } from \"#/cli/shared/logger\";\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: `redactSecrets` masks every registered\n * secret first, then the pattern-based sanitizers below strip known-shape values (UUIDs,\n * long hex, emails, paths) from what's left. `redactSecrets` must run first — the path\n * sanitizer intentionally keeps a path's basename (e.g. `/home/user/.../key.json` becomes\n * `<path>/key.json`), so a registered secret shaped like a path would have that basename\n * survive if the pattern sanitizer ran on it first. This report is written to a local file\n * (and optionally sent remotely) outside the CLI's normal stderr path.\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(redactSecrets(parseCommand())),\n argv: sanitizeArgv(process.argv.map(redactSecrets)),\n errorName: redactSecrets(errorName),\n errorMessage: sanitizeMessage(redactSecrets(rawMessage)),\n stackTrace: sanitizeStackTrace(redactSecrets(rawStack)),\n errorType,\n userId: currentUser?.id ? redactSecrets(currentUser.id) : null,\n userEmail: currentUser?.email ? redactSecrets(currentUser.email) : null,\n };\n}\n\ntype CurrentUser = {\n id: string;\n email: string | null;\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 ID and email, or null if unavailable\n */\nfunction readCurrentUser(): CurrentUser | 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 {\n current_user?: string | null;\n users?: Record<string, { email?: unknown } | undefined>;\n };\n // parseYAML returns null for empty documents\n // oxlint-disable-next-line typescript/no-unnecessary-condition\n const currentUser = raw?.current_user ?? null;\n if (!currentUser) return null;\n const email = raw.users?.[currentUser]?.email;\n return {\n id: currentUser,\n email: typeof email === \"string\" ? email : legacyEmail(currentUser),\n };\n } catch {\n return null;\n }\n}\n\nfunction legacyEmail(user: string): string | null {\n return user.includes(\"@\") ? user : null;\n}\n","import { logger } from \"#/cli/shared/logger\";\nimport { readPackageJson } from \"#/cli/shared/package-json\";\nimport { userAgentFromVersion } from \"#/cli/shared/user-agent\";\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 crashreport send --file \"${filePath}\"`,\n ].join(\"\\n\"),\n );\n }\n }\n\n if (config.remoteEnabled) {\n const ua = userAgentFromVersion(sdkVersion);\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":"crashreport-BAG8c7hB.mjs","names":["logger","redactSecrets","readPackageJson","userAgentFromVersion","writeSecretFile","ensureSecretDir","path","fs","crypto","os","isCI","localEnabled","remoteEnabled","localDir","xdgConfig","JSON_FOOTER_MARKER","CRASH_LOG_EXTENSION","report","files","dir","f","file","filename","filePath","content","endpoint","response","ua","data","HOME_DIR","UUID_PATTERN","LONG_HEX_PATTERN","EMAIL_PATTERN","ABSOLUTE_PATH_PATTERN","WINDOWS_PATH_PATTERN","URL_QUERY_PATTERN","EMAIL_TEST_PATTERN","WINDOWS_DRIVE_TEST_PATTERN","SDK_PACKAGE_MARKER","separator","firstFrameIndex","stack","result","sdkIndex","match","normalized","message","redactNext","arg","argv","eqIndex","args","commandParts","options","isError","error","rawMessage","rawStack","errorName","currentUser","configPath","raw","parseYAML","email","user","config","sdkVersion","errorType","reason"],"sources":["../src/cli/crashreport/config.ts","../src/cli/crashreport/writer.ts","../src/cli/crashreport/sender.ts","../src/cli/crashreport/sanitize.ts","../src/cli/crashreport/report.ts","../src/cli/crashreport/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 { ensureSecretDir, writeSecretFile } from \"#/cli/shared/secret-file\";\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 .toSorted()\n .toReversed();\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 ensureSecretDir(dir);\n\n const filename = generateFilename(report);\n const filePath = path.join(dir, filename);\n const content = formatCrashReport(report);\n\n writeSecretFile(filePath, content);\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 { redactSecrets } from \"#/cli/shared/logger\";\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: `redactSecrets` masks every registered\n * secret first, then the pattern-based sanitizers below strip known-shape values (UUIDs,\n * long hex, emails, paths) from what's left. `redactSecrets` must run first — the path\n * sanitizer intentionally keeps a path's basename (e.g. `/home/user/.../key.json` becomes\n * `<path>/key.json`), so a registered secret shaped like a path would have that basename\n * survive if the pattern sanitizer ran on it first. This report is written to a local file\n * (and optionally sent remotely) outside the CLI's normal stderr path.\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(redactSecrets(parseCommand())),\n argv: sanitizeArgv(process.argv.map(redactSecrets)),\n errorName: redactSecrets(errorName),\n errorMessage: sanitizeMessage(redactSecrets(rawMessage)),\n stackTrace: sanitizeStackTrace(redactSecrets(rawStack)),\n errorType,\n userId: currentUser?.id ? redactSecrets(currentUser.id) : null,\n userEmail: currentUser?.email ? redactSecrets(currentUser.email) : null,\n };\n}\n\ntype CurrentUser = {\n id: string;\n email: string | null;\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 ID and email, or null if unavailable\n */\nfunction readCurrentUser(): CurrentUser | 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 {\n current_user?: string | null;\n users?: Record<string, { email?: unknown } | undefined>;\n };\n // parseYAML returns null for empty documents\n // oxlint-disable-next-line typescript/no-unnecessary-condition\n const currentUser = raw?.current_user ?? null;\n if (!currentUser) return null;\n const email = raw.users?.[currentUser]?.email;\n return {\n id: currentUser,\n email: typeof email === \"string\" ? email : legacyEmail(currentUser),\n };\n } catch {\n return null;\n }\n}\n\nfunction legacyEmail(user: string): string | null {\n return user.includes(\"@\") ? user : null;\n}\n","import { logger } from \"#/cli/shared/logger\";\nimport { readPackageJson } from \"#/cli/shared/package-json\";\nimport { userAgentFromVersion } from \"#/cli/shared/user-agent\";\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 crashreport send --file \"${filePath}\"`,\n ].join(\"\\n\"),\n );\n }\n }\n\n if (config.remoteEnabled) {\n const ua = userAgentFromVersion(sdkVersion);\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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"}
@@ -0,0 +1 @@
1
+ export{n as reportCrash}from"./crashreport-BAG8c7hB.mjs";
@@ -0,0 +1,2 @@
1
+ function getTemporal(){let e=globalThis.Temporal;if(!e)throw ReferenceError(`Temporal is unavailable. Use the Tailor Platform runtime or the SDK tailor-runtime Vitest environment.`);return e}const e={get PlainDate(){return getTemporal().PlainDate},get PlainTime(){return getTemporal().PlainTime},get PlainDateTime(){return getTemporal().PlainDateTime},get PlainYearMonth(){return getTemporal().PlainYearMonth},get PlainMonthDay(){return getTemporal().PlainMonthDay},get ZonedDateTime(){return getTemporal().ZonedDateTime},get Duration(){return getTemporal().Duration},get Instant(){return getTemporal().Instant},get Now(){return getTemporal().Now}};function formatDate(e){return formatDateTime(e).slice(0,10)}function formatDateTime(e){let t=e.getUTCFullYear();if(!Number.isFinite(t)||t<0||t>9999){let n=Number.isNaN(e.getTime())?`an invalid Date`:`year ${t}`;throw RangeError(`Expected a Date with a 4-digit year (0000-9999), but received ${n}`)}return e.toISOString()}function formatHoursMinutes(e,t){return`${String(e).padStart(2,`0`)}:${String(t).padStart(2,`0`)}`}function formatTime(e){if(!Number.isFinite(e.getTime()))throw RangeError(`Expected a valid Date, but received an invalid Date`);return formatHoursMinutes(e.getUTCHours(),e.getUTCMinutes())}function formatTemporal(e){let t=getTemporal();if(e instanceof t.PlainTime)return formatHoursMinutes(e.hour,e.minute);let n=e.toString({calendarName:`never`});if(!/^\d{4}-/.test(n)){let r=e instanceof t.Instant;throw RangeError(`Expected a Temporal.${r?`Instant`:`PlainDate`} with a 4-digit ${r?`UTC `:``}year (0000-9999), but received ${n}`)}return n}function serialize(e,t,n){if(e.metadata.array){if(!Array.isArray(t))return t;let r=t.map((t,r)=>serializeValue(e,t,`${n}[${r}]`));return r.every((e,n)=>e===t[n])?t:r}return serializeValue(e,t,n)}function describePathTarget(e){return e||`the top-level value`}function truncateForDescription(e){return e.length>100?`${e.slice(0,100)}...`:e}function describeReceivedValue(e){if(Array.isArray(e)){let t=e.slice(0,100),n=[...new Set(Array.from(t,e=>typeof e))];return n.length>0?`an array of ${n.join(`/`)}`:`an empty array`}if(typeof e==`string`)return`a string (${JSON.stringify(truncateForDescription(e))})`;let t=typeof e;return t===`object`?`an object`:t===`function`?`a function`:`a ${t} (${truncateForDescription(String(e))})`}function bundledDateDefault(){let e=globalThis.process?.env.__TAILOR_PLATFORM_BUNDLE_DATE_DEFAULT;return e===`temporal`||e===`date`?e:`legacy`}function dateRepresentationOf(e,t,n=bundledDateDefault()){if(e!==`date`&&e!==`datetime`&&e!==`time`)return;let r=t==="default"?n:t;return r===`date`||r===`temporal`?r:void 0}function isDateRepresentationField(e,t,n){let r=dateRepresentationOf(e.type,e.metadata.as,n);return r!==void 0&&(t===void 0||r===t)}function throwInvalidDate(e,t){let n=e instanceof Error?e.message:String(e);throw RangeError(`Invalid date at ${describePathTarget(t)}: ${n}`,{cause:e})}function serializeAsDate(e,t,n){if(!(t instanceof Date))throw TypeError(`Expected a Date instance at ${describePathTarget(n)}, but received ${describeReceivedValue(t)}`);try{return e===`datetime`?formatDateTime(t):e===`time`?formatTime(t):formatDate(t)}catch(e){return throwInvalidDate(e,n)}}function serializeAsTemporal(e,t,n){let r=getTemporal(),i=e===`date`?r.PlainDate:e===`datetime`?r.Instant:r.PlainTime;if(!(t instanceof i))throw TypeError(`Expected a Temporal.${i.name} instance at ${describePathTarget(n)}, but received ${describeReceivedValue(t)}`);try{return formatTemporal(t)}catch(e){return throwInvalidDate(e,n)}}const t={date:globalThis.process?.env.__TAILOR_PLATFORM_BUNDLE_WITHOUT_DATE?void 0:serializeAsDate,temporal:globalThis.process?.env.__TAILOR_PLATFORM_BUNDLE_WITHOUT_TEMPORAL?void 0:serializeAsTemporal};function serializeValue(e,n,r){if(n==null)return n;let{type:i}=e,a=dateRepresentationOf(i,e.metadata.as);if(a){let e=t[a];if(!e)throw Error(`Serializing fields declared with as: "${a}" is not included in this bundle.`);return e(i,n,r)}if(i!==`nested`||typeof n!=`object`||Array.isArray(n))return n;let o=n,s=o;for(let[t,n]of Object.entries(e.fields)){let e=serialize(n,o[t],r?`${r}.${t}`:t);e!==o[t]&&(s===o&&(s={...o}),Object.defineProperty(s,t,{value:e,enumerable:!0,configurable:!0,writable:!0}))}return s}function hasDateRepresentationFields(e,t,n){return isDateRepresentationField(e,t,n)||Object.values(e.fields).some(e=>hasDateRepresentationFields(e,t,n))}function serializeDateFields(e,t){return serialize(e,t,``)}export{e as a,serializeDateFields as i,formatDate as n,getTemporal as o,hasDateRepresentationFields as r,dateRepresentationOf as t};
2
+ //# sourceMappingURL=date-CgP7gMG_.mjs.map