@tailor-platform/sdk 1.68.0 → 1.70.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 (117) hide show
  1. package/CHANGELOG.md +105 -0
  2. package/dist/application-BakHtldG.mjs +4 -0
  3. package/dist/application-Df5_I83n.mjs +6432 -0
  4. package/dist/application-Df5_I83n.mjs.map +1 -0
  5. package/dist/cli/erd-viewer-assets/app.js +279 -36
  6. package/dist/cli/erd-viewer-assets/index.html +4 -0
  7. package/dist/cli/erd-viewer-assets/styles.css +252 -5
  8. package/dist/cli/index.mjs +650 -98
  9. package/dist/cli/index.mjs.map +1 -1
  10. package/dist/cli/lib.d.mts +247 -160
  11. package/dist/cli/lib.mjs +3 -3
  12. package/dist/cli/lib.mjs.map +1 -1
  13. package/dist/cli/skills.mjs +1 -1
  14. package/dist/completion/zsh-worker.zsh +175 -24
  15. package/dist/configure/index.d.mts +5 -5
  16. package/dist/configure/index.mjs +12 -6
  17. package/dist/configure/index.mjs.map +1 -1
  18. package/dist/{crashreport-u9y2npiy.mjs → crashreport-BqyvFk-_.mjs} +2 -2
  19. package/dist/{crashreport-u9y2npiy.mjs.map → crashreport-BqyvFk-_.mjs.map} +1 -1
  20. package/dist/{crashreport-6jpCceOF.mjs → crashreport-BwF8cHF0.mjs} +1 -1
  21. package/dist/enum-constants-C7DaWeQo.mjs.map +1 -1
  22. package/dist/field-C4zdJLW5.mjs.map +1 -1
  23. package/dist/file-utils-BHPxPXmn.mjs.map +1 -1
  24. package/dist/{idp-BlBPtXJ-.d.mts → idp-BmYwCXnJ.d.mts} +30 -3
  25. package/dist/{idp-BZPqpcYY.mjs → idp-ynUfzwpz.mjs} +9 -1
  26. package/dist/idp-ynUfzwpz.mjs.map +1 -0
  27. package/dist/{index-DvEUb3pX.d.mts → index-BAEaAqmz.d.mts} +112 -53
  28. package/dist/{index-CklcVeMG.d.mts → index-C-vsbx27.d.mts} +2 -2
  29. package/dist/{index-hXoO-AOC.d.mts → index-CKI0eZP6.d.mts} +2 -2
  30. package/dist/{index-DYhnxXYR.d.mts → index-CrqOgUF2.d.mts} +2 -2
  31. package/dist/{index-DlDRSzFZ.d.mts → index-DESLU9kI.d.mts} +2 -2
  32. package/dist/{index-DRhMpdnA.d.mts → index-dKNk8hjo.d.mts} +2 -2
  33. package/dist/job-BpsFXPbi.mjs.map +1 -1
  34. package/dist/{kysely-type-D1e0Vwkd.mjs → kysely-type-CSoZxVKN.mjs} +2 -2
  35. package/dist/{kysely-type-D1e0Vwkd.mjs.map → kysely-type-CSoZxVKN.mjs.map} +1 -1
  36. package/dist/{logger-DpJyJvNz.mjs → logger-DKF-JsAK.mjs} +3 -3
  37. package/dist/{logger-DpJyJvNz.mjs.map → logger-DKF-JsAK.mjs.map} +1 -1
  38. package/dist/{mock-DMgIygjE.mjs → mock-wf5qeZLi.mjs} +19 -9
  39. package/dist/mock-wf5qeZLi.mjs.map +1 -0
  40. package/dist/plugin/builtin/enum-constants/index.d.mts +1 -1
  41. package/dist/plugin/builtin/file-utils/index.d.mts +1 -1
  42. package/dist/plugin/builtin/kysely-type/index.d.mts +1 -1
  43. package/dist/plugin/builtin/kysely-type/index.mjs +1 -1
  44. package/dist/plugin/builtin/seed/index.d.mts +1 -1
  45. package/dist/plugin/index.d.mts +1 -1
  46. package/dist/plugin/index.mjs.map +1 -1
  47. package/dist/registry-D0uB0OrK.mjs.map +1 -1
  48. package/dist/{repl-editor-CJG3sz7A.mjs → repl-editor-DD5YP5mt.mjs} +4 -4
  49. package/dist/{repl-editor-CJG3sz7A.mjs.map → repl-editor-DD5YP5mt.mjs.map} +1 -1
  50. package/dist/runtime/globals.d.mts +3 -2
  51. package/dist/runtime/idp.d.mts +2 -2
  52. package/dist/runtime/idp.mjs +1 -1
  53. package/dist/runtime/index.d.mts +2 -2
  54. package/dist/runtime/index.mjs +1 -1
  55. package/dist/{runtime-DxaBq6U8.mjs → runtime-CSY0eD4_.mjs} +411 -221
  56. package/dist/runtime-CSY0eD4_.mjs.map +1 -0
  57. package/dist/{schema-1msIhXwA.mjs → schema-C4fkpWV_.mjs} +9 -15
  58. package/dist/schema-C4fkpWV_.mjs.map +1 -0
  59. package/dist/seed-YAbtMy65.mjs.map +1 -1
  60. package/dist/{service-wI3Hvrgx.mjs → service-B2Jd9CxS.mjs} +2 -2
  61. package/dist/service-B2Jd9CxS.mjs.map +1 -0
  62. package/dist/service-CRaa4Joe.mjs +4 -0
  63. package/dist/{service-DMohAx8a.mjs → service-DDWgZL_L2.mjs} +2 -2
  64. package/dist/service-DDWgZL_L2.mjs.map +1 -0
  65. package/dist/service_pb-DGSmn-aF.mjs +4 -0
  66. package/dist/{application-WpWwTyk9.mjs → service_pb-DSNjrcbW.mjs} +22 -6176
  67. package/dist/service_pb-DSNjrcbW.mjs.map +1 -0
  68. package/dist/telemetry-BQbbVo2t.mjs.map +1 -1
  69. package/dist/{types-2Be3wSMc.mjs → types-32lUMToj.mjs} +1 -1
  70. package/dist/{types-CmzfQP_m.mjs → types-D4QMmNWh.mjs} +1 -12
  71. package/dist/types-D4QMmNWh.mjs.map +1 -0
  72. package/dist/{types-Bzr0RQME.d.mts → types-Dynq4AJv.d.mts} +2 -2
  73. package/dist/{types-DZrtN6-H.d.mts → types-rj8YJcEe.d.mts} +5 -2
  74. package/dist/utils/test/index.d.mts +2 -2
  75. package/dist/utils/test/index.mjs.map +1 -1
  76. package/dist/vitest/environment.mjs +1 -1
  77. package/dist/vitest/environment.mjs.map +1 -1
  78. package/dist/vitest/index.mjs +4 -4
  79. package/dist/vitest/index.mjs.map +1 -1
  80. package/dist/vitest/setup.mjs +1 -1
  81. package/dist/{workflow.generated-1S50BhEb.d.mts → workflow.generated-DJULCuRr.d.mts} +274 -174
  82. package/docs/cli/application.md +39 -201
  83. package/docs/cli/auth.md +12 -256
  84. package/docs/cli/completion.md +0 -24
  85. package/docs/cli/crashreport.md +0 -58
  86. package/docs/cli/executor.md +2 -166
  87. package/docs/cli/function.md +2 -118
  88. package/docs/cli/organization.md +1 -211
  89. package/docs/cli/query.md +0 -20
  90. package/docs/cli/secret.md +70 -250
  91. package/docs/cli/setup.md +2 -41
  92. package/docs/cli/skills.md +0 -39
  93. package/docs/cli/staticwebsite.md +24 -172
  94. package/docs/cli/tailordb.md +25 -251
  95. package/docs/cli/upgrade.md +0 -20
  96. package/docs/cli/user.md +41 -246
  97. package/docs/cli/workflow.md +30 -189
  98. package/docs/cli/workspace.md +164 -537
  99. package/docs/cli-reference.md +61 -37
  100. package/docs/configuration.md +7 -1
  101. package/docs/github-actions.md +27 -0
  102. package/docs/multi-environment.md +22 -0
  103. package/docs/services/aigateway.md +4 -2
  104. package/docs/services/http-adapter.md +16 -1
  105. package/docs/services/idp.md +55 -2
  106. package/docs/services/staticwebsite.md +7 -1
  107. package/package.json +23 -18
  108. package/dist/application-Djeezk3m.mjs +0 -4
  109. package/dist/application-WpWwTyk9.mjs.map +0 -1
  110. package/dist/idp-BZPqpcYY.mjs.map +0 -1
  111. package/dist/mock-DMgIygjE.mjs.map +0 -1
  112. package/dist/runtime-DxaBq6U8.mjs.map +0 -1
  113. package/dist/schema-1msIhXwA.mjs.map +0 -1
  114. package/dist/service-BHQIerYh.mjs +0 -4
  115. package/dist/service-DMohAx8a.mjs.map +0 -1
  116. package/dist/service-wI3Hvrgx.mjs.map +0 -1
  117. package/dist/types-CmzfQP_m.mjs.map +0 -1
@@ -1,24 +1,47 @@
1
1
  import { a as TailorActor, c as TailorUser, i as InferredAttributeMap, o as TailorEnv, s as TailorInvoker } from "./types-DTcZ2Yax.mjs";
2
- import { C as FieldMetadata, D as TailorField$1, E as FieldValidateInput, F as output$1, M as JsonCompatible, N as JsonValue, O as TailorFieldType, P as Prettify, T as FieldOutput, b as ArrayFieldOutput, j as InferFieldsOutput, w as FieldOptions, x as DefinedFieldMetadata } from "./types-DZrtN6-H.mjs";
3
- import { $ as UserAttributeListKey, A as IncomingWebhookTrigger$1, C as ResolverInput, D as FunctionOperation$1, E as ExecutorInput, F as WorkflowOperation$1, I as BaseGeneratorConfig, K as DefinedAuth, M as ScheduleTriggerInput, N as TailorDBTrigger$1, O as GqlOperation$1, P as WebhookOperation$1, S as Resolver, U as AuthServiceInput, a as Plugin, et as UserAttributeMap, j as ResolverExecutedTrigger$1, k as IdpUserTrigger$1, n as GeneratorConfig, rt as AuthInvoker$1, w as AuthAccessTokenTrigger$1 } from "./types-Bzr0RQME.mjs";
4
- import { A as TailorDBInstance, C as IdPInput, E as AIGatewayInput, R as AllowedValues, T as AIGatewayDefinitionBrand, g as SecretsDefinitionBrand, i as AppConfig, j as TailorDBType, m as StaticWebsiteInput, n as RetryPolicy, p as StaticWebsiteDefinitionBrand, r as HttpAdapterConfigInput, t as ConcurrencyPolicy, y as IdpDefinitionBrand, z as AllowedValuesOutput } from "./workflow.generated-1S50BhEb.mjs";
2
+ import { C as FieldMetadata, D as TailorField$1, E as FieldValidateInput, F as output$1, M as JsonCompatible, N as JsonValue, O as TailorFieldType, P as TypeLevelError, T as FieldOutput, b as ArrayFieldOutput, j as InferFieldsOutput, w as FieldOptions, x as DefinedFieldMetadata } from "./types-rj8YJcEe.mjs";
3
+ import { $ as UserAttributeListKey, A as IncomingWebhookTrigger$1, C as ResolverInput, D as FunctionOperation$1, E as ExecutorInput, F as WorkflowOperation$1, I as BaseGeneratorConfig, K as DefinedAuth, M as ScheduleTriggerInput, N as TailorDBTrigger$1, O as GqlOperation$1, P as WebhookOperation$1, S as Resolver, U as AuthServiceInput, a as Plugin, et as UserAttributeMap, j as ResolverExecutedTrigger$1, k as IdpUserTrigger$1, n as GeneratorConfig, rt as AuthInvoker$1, w as AuthAccessTokenTrigger$1 } from "./types-Dynq4AJv.mjs";
4
+ import { A as TailorDBInstance, C as IdPInput, E as AIGatewayInput, R as AllowedValues, T as AIGatewayDefinitionBrand, g as SecretsDefinitionBrand, i as AppConfig, j as TailorDBType, m as StaticWebsiteInput, n as RetryPolicy, p as StaticWebsiteDefinitionBrand, r as HttpAdapterConfigInput, t as ConcurrencyPolicy, y as IdpDefinitionBrand, z as AllowedValuesOutput } from "./workflow.generated-DJULCuRr.mjs";
5
+ import { DocumentNode } from "graphql";
5
6
  import { StandardSchemaV1 } from "@standard-schema/spec";
6
7
  import { Client } from "@urql/core";
7
8
  import { StandardCRON } from "ts-cron-validator";
8
9
 
9
- //#region src/configure/types/machine-user.d.ts
10
- interface MachineUserNameRegistry {}
11
- /**
12
- * Machine user name.
13
- *
14
- * When `tailor.d.ts` is generated (via `tailor-sdk deploy`/`generate`), this is narrowed
15
- * to the union of defined machine user names. When no machine users are registered yet,
16
- * falls back to `string` to avoid blocking editing before the first generate run.
17
- */
18
- type MachineUserName = keyof MachineUserNameRegistry extends never ? string : keyof MachineUserNameRegistry & string;
19
- //#endregion
20
10
  //#region src/configure/types/type.d.ts
21
- type TailorAnyField = TailorField<any>;
11
+ type AnyBuilderMethod = any;
12
+ type TailorAnyField = Omit<TailorField$1<AnyBuilderMethod, AnyBuilderMethod, FieldMetadata, TailorFieldType>, "fields"> & {
13
+ readonly fields: Record<string, AnyBuilderMethod>;
14
+ _metadata: FieldMetadata;
15
+ description: AnyBuilderMethod;
16
+ typeName: AnyBuilderMethod;
17
+ validate: AnyBuilderMethod;
18
+ parse: AnyBuilderMethod;
19
+ _parseInternal: AnyBuilderMethod;
20
+ };
21
+ type IsAny<T> = 0 extends 1 & T ? true : false;
22
+ type WithFieldDescription<Defined> = Defined & {
23
+ description: true;
24
+ };
25
+ type WithFieldTypeName<Defined> = Defined & {
26
+ typeName: true;
27
+ };
28
+ type WithFieldValidate<Defined> = Defined & {
29
+ validate: true;
30
+ };
31
+ type FieldDescriptionFn<Defined extends DefinedFieldMetadata, Output> = (description: string) => TailorField<WithFieldDescription<Defined>, Output>;
32
+ type FieldTypeNameFn<Defined extends DefinedFieldMetadata, Output> = (typeName: string) => TailorField<WithFieldTypeName<Defined>, Output>;
33
+ type FieldValidateFn<Defined extends DefinedFieldMetadata, Output> = (...validate: FieldValidateInput<Output>[]) => TailorField<WithFieldValidate<Defined>, Output>;
34
+ type FieldDescriptionMethod<Defined extends DefinedFieldMetadata, Output> = IsAny<Defined> extends true ? FieldDescriptionFn<Defined, Output> : Defined extends {
35
+ description: unknown;
36
+ } ? TypeLevelError<".description() has already been set"> : FieldDescriptionFn<Defined, Output>;
37
+ type FieldTypeNameMethod<Defined extends DefinedFieldMetadata, Output> = IsAny<Defined> extends true ? TypeLevelError<string> : Defined extends {
38
+ typeName: unknown;
39
+ } ? TypeLevelError<".typeName() has already been set"> : Defined extends {
40
+ type: "enum" | "nested";
41
+ } ? FieldTypeNameFn<Defined, Output> : TypeLevelError<"typeName can only be set on enum or object fields">;
42
+ type FieldValidateMethod<Defined extends DefinedFieldMetadata, Output> = IsAny<Defined> extends true ? FieldValidateFn<Defined, Output> : Defined extends {
43
+ validate: unknown;
44
+ } ? TypeLevelError<".validate() has already been set"> : FieldValidateFn<Defined, Output>;
22
45
  /**
23
46
  * Full TailorField interface with builder methods.
24
47
  * Extends the minimal structural interface from types/ with fluent API methods.
@@ -31,33 +54,19 @@ interface TailorField<Defined extends DefinedFieldMetadata = DefinedFieldMetadat
31
54
  * @param description - The description text
32
55
  * @returns The field with updated metadata
33
56
  */
34
- description<CurrentDefined extends Defined>(this: CurrentDefined extends {
35
- description: unknown;
36
- } ? never : TailorField<CurrentDefined, Output>, description: string): TailorField<Prettify<CurrentDefined & {
37
- description: true;
38
- }>, Output>;
57
+ description: FieldDescriptionMethod<Defined, Output>;
39
58
  /**
40
59
  * Set a custom type name for enum or nested types
41
60
  * @param typeName - The custom type name
42
61
  * @returns The field with updated metadata
43
62
  */
44
- typeName<CurrentDefined extends Defined>(this: CurrentDefined extends {
45
- typeName: unknown;
46
- } ? never : CurrentDefined extends {
47
- type: "enum" | "nested";
48
- } ? TailorField<CurrentDefined, Output> : never, typeName: string): TailorField<Prettify<CurrentDefined & {
49
- typeName: true;
50
- }>, Output>;
63
+ typeName: FieldTypeNameMethod<Defined, Output>;
51
64
  /**
52
65
  * Add validation functions to the field
53
66
  * @param validate - One or more validation functions
54
67
  * @returns The field with updated metadata
55
68
  */
56
- validate<CurrentDefined extends Defined>(this: CurrentDefined extends {
57
- validate: unknown;
58
- } ? never : TailorField<CurrentDefined, Output>, ...validate: FieldValidateInput<Output>[]): TailorField<Prettify<CurrentDefined & {
59
- validate: true;
60
- }>, Output>;
69
+ validate: FieldValidateMethod<Defined, Output>;
61
70
  /**
62
71
  * Parse and validate a value against this field's validation rules
63
72
  * Returns StandardSchema Result type with success or failure
@@ -91,6 +100,17 @@ type FieldParseInternalArgs = {
91
100
  * @example t.uuid()
92
101
  */
93
102
  //#endregion
103
+ //#region src/configure/types/machine-user.d.ts
104
+ interface MachineUserNameRegistry {}
105
+ /**
106
+ * Machine user name.
107
+ *
108
+ * When `tailor.d.ts` is generated (via `tailor-sdk deploy`/`generate`), this is narrowed
109
+ * to the union of defined machine user names. When no machine users are registered yet,
110
+ * falls back to `string` to avoid blocking editing before the first generate run.
111
+ */
112
+ type MachineUserName = keyof MachineUserNameRegistry extends never ? string : keyof MachineUserNameRegistry & string;
113
+ //#endregion
94
114
  //#region src/configure/user.d.ts
95
115
  /** Represents an unauthenticated user in the Tailor platform. */
96
116
  declare const unauthenticatedTailorUser: TailorUser;
@@ -931,7 +951,8 @@ type IdPActionPermission<User extends object = InferredAttributeMap, Update exte
931
951
  } | readonly [...IdPPermissionCondition<User, Update>, ...([] | [boolean])] | readonly [...IdPPermissionCondition<User, Update>[], ...([] | [boolean])];
932
952
  /**
933
953
  * Per-operation permission policies for an IdP service.
934
- * Defines create, read, update, delete, and sendPasswordResetEmail permissions.
954
+ * Defines create, read, update, delete, sendPasswordResetEmail, and
955
+ * unenrollMfa permissions.
935
956
  *
936
957
  * For update operations, use `newIdpUser`/`oldIdpUser` operands instead of `idpUser`.
937
958
  * @example
@@ -941,6 +962,7 @@ type IdPActionPermission<User extends object = InferredAttributeMap, Update exte
941
962
  * update: [{ conditions: [[{ newIdpUser: "name" }, "=", { user: "id" }]], permit: true }],
942
963
  * delete: [{ conditions: [[{ user: "role" }, "=", "ADMIN"]], permit: true }],
943
964
  * sendPasswordResetEmail: [{ conditions: [], permit: true }],
965
+ * unenrollMfa: [{ conditions: [[{ user: "role" }, "=", "ADMIN"]], permit: true }],
944
966
  * };
945
967
  */
946
968
  type IdPPermission<User extends object = InferredAttributeMap> = {
@@ -948,7 +970,8 @@ type IdPPermission<User extends object = InferredAttributeMap> = {
948
970
  read: readonly IdPActionPermission<User, false>[];
949
971
  update: readonly IdPActionPermission<User, true>[];
950
972
  delete: readonly IdPActionPermission<User, false>[];
951
- sendPasswordResetEmail: readonly IdPActionPermission<User, false>[];
973
+ sendPasswordResetEmail?: readonly IdPActionPermission<User, false>[];
974
+ unenrollMfa?: readonly IdPActionPermission<User, false>[];
952
975
  };
953
976
  /**
954
977
  * Grants full IdP permission access without any conditions.
@@ -995,6 +1018,10 @@ declare function defineIdp<const TClients extends string[]>(name: string, config
995
1018
  allowGoogleOauth?: boolean | undefined;
996
1019
  allowMicrosoftOauth?: boolean | undefined;
997
1020
  disablePasswordAuth?: boolean | undefined;
1021
+ enableMfa?: boolean | undefined;
1022
+ requireMfa?: boolean | undefined;
1023
+ allowedReturnOrigins?: string[] | undefined;
1024
+ mfaIssuer?: string | undefined;
998
1025
  } | undefined;
999
1026
  readonly publishUserEvents?: boolean | undefined;
1000
1027
  readonly gqlOperations?: "query" | {
@@ -1003,6 +1030,8 @@ declare function defineIdp<const TClients extends string[]>(name: string, config
1003
1030
  delete?: boolean | undefined;
1004
1031
  read?: boolean | undefined;
1005
1032
  sendPasswordResetEmail?: boolean | undefined;
1033
+ requestMfaSettingsUrl?: boolean | undefined;
1034
+ unenrollMfa?: boolean | undefined;
1006
1035
  } | undefined;
1007
1036
  readonly emailConfig?: {
1008
1037
  fromName?: string | undefined;
@@ -1062,16 +1091,36 @@ type HttpAdapterRequest = {
1062
1091
  body: string;
1063
1092
  };
1064
1093
  /** GraphQL request returned by an `input` handler. */
1065
- type HttpAdapterGraphQLRequest = {
1066
- query: string;
1067
- variables?: Record<string, unknown>;
1094
+ type HttpAdapterGraphQLRequest<Query extends HttpAdapterGraphQLQuery = string> = {
1095
+ query: Query;
1068
1096
  operationName?: string;
1097
+ } & HttpAdapterGraphQLRequestVariables<Query>;
1098
+ /**
1099
+ * Typed GraphQL document accepted by an HTTP adapter input handler.
1100
+ * Compatible with generated `TypedDocumentNode` values.
1101
+ */
1102
+ type HttpAdapterTypedDocumentNode<TResult = unknown, TVariables = Record<string, unknown>> = DocumentNode & {
1103
+ __apiType?: (variables: TVariables) => TResult;
1104
+ __ensureTypesOfVariablesAndResultMatching?: (variables: TVariables) => TResult;
1069
1105
  };
1070
- /** Converts an incoming HTTP request into a GraphQL request. */
1071
- type HttpAdapterInputFn = (req: HttpAdapterRequest) => HttpAdapterGraphQLRequest;
1106
+ /** GraphQL query value accepted by an HTTP adapter input handler. */
1107
+ type HttpAdapterGraphQLQuery = string | DocumentNode;
1108
+ type HttpAdapterGraphQLData<Query> = Query extends HttpAdapterTypedDocumentNode<infer Result, infer _Variables> ? Result : unknown;
1109
+ type HttpAdapterGraphQLVariables<Query> = Query extends HttpAdapterTypedDocumentNode<infer _Result, infer Variables> ? Variables : Record<string, unknown>;
1110
+ type HttpAdapterHasRequiredVariables<T> = [T] extends [never] ? false : T extends object ? Record<never, never> extends T ? false : true : false;
1111
+ type HttpAdapterGraphQLRequestVariables<Query> = true extends HttpAdapterHasRequiredVariables<HttpAdapterGraphQLVariables<Query>> ? {
1112
+ variables: HttpAdapterGraphQLVariables<Query>;
1113
+ } : {
1114
+ variables?: HttpAdapterGraphQLVariables<Query>;
1115
+ };
1116
+ /**
1117
+ * Converts an incoming HTTP request into a GraphQL request.
1118
+ * Pass a typed document type as `Query` when annotating extracted handlers.
1119
+ */
1120
+ type HttpAdapterInputFn<Query extends HttpAdapterGraphQLQuery = string> = (req: HttpAdapterRequest) => HttpAdapterGraphQLRequest<Query>;
1072
1121
  /** GraphQL execution result passed to the `output` handler. */
1073
- type HttpAdapterGraphQLResponse = {
1074
- data?: unknown;
1122
+ type HttpAdapterGraphQLResponse<Data = unknown> = {
1123
+ data?: Data | null;
1075
1124
  errors?: unknown;
1076
1125
  extensions?: unknown;
1077
1126
  };
@@ -1082,19 +1131,27 @@ type HttpAdapterResponse = {
1082
1131
  body: string;
1083
1132
  };
1084
1133
  /** Converts a GraphQL response into an HTTP response. */
1085
- type HttpAdapterOutputFn = (resp: HttpAdapterGraphQLResponse) => HttpAdapterResponse;
1134
+ type HttpAdapterOutputFn<Data = unknown> = (resp: HttpAdapterGraphQLResponse<Data>) => HttpAdapterResponse;
1086
1135
  /**
1087
1136
  * Per-method input handlers. At least one method must be provided.
1088
1137
  * Each handler transforms an HTTP request into a GraphQL request.
1089
1138
  */
1090
- type HttpAdapterInput = Partial<Record<HttpMethodKey, HttpAdapterInputFn>>;
1139
+ type HttpAdapterInput = Partial<Record<HttpMethodKey, HttpAdapterInputFn<HttpAdapterGraphQLQuery>>>;
1140
+ type HttpAdapterInputHandlerData<Handler> = Handler extends ((req: HttpAdapterRequest) => infer Request) ? Request extends {
1141
+ query: infer Query;
1142
+ } ? HttpAdapterGraphQLData<Query> : unknown : never;
1143
+ type HttpAdapterInputData<Input extends HttpAdapterInput> = [HttpAdapterInputHandlerData<Input[keyof Input]>] extends [never] ? unknown : HttpAdapterInputHandlerData<Input[keyof Input]>;
1144
+ type HttpAdapterValidatedRequest<Request> = Request extends {
1145
+ query: infer Query extends HttpAdapterGraphQLQuery;
1146
+ } ? Request & HttpAdapterGraphQLRequest<Query> : never;
1147
+ type HttpAdapterValidatedInput<Input extends HttpAdapterInput> = { [Method in keyof Input]: Input[Method] extends ((req: HttpAdapterRequest) => infer Request) ? (req: HttpAdapterRequest) => HttpAdapterValidatedRequest<Request> : Input[Method] };
1091
1148
  /**
1092
1149
  * HTTP adapter configuration accepted by `createHttpAdapter` with typed
1093
1150
  * `input` and `output` signatures.
1094
1151
  */
1095
- type HttpAdapter = Omit<HttpAdapterConfigInput, "input" | "output"> & {
1096
- input: HttpAdapterInput;
1097
- output?: HttpAdapterOutputFn;
1152
+ type HttpAdapter<Input extends HttpAdapterInput = HttpAdapterInput> = Omit<HttpAdapterConfigInput, "input" | "output"> & {
1153
+ input: Input & HttpAdapterValidatedInput<Input>;
1154
+ output?: HttpAdapterOutputFn<HttpAdapterInputData<Input>>;
1098
1155
  };
1099
1156
  /**
1100
1157
  * Defines an HTTP adapter that translates HTTP requests to GraphQL queries
@@ -1104,12 +1161,14 @@ type HttpAdapter = Omit<HttpAdapterConfigInput, "input" | "output"> & {
1104
1161
  * Files are discovered via the `httpAdapter.files` glob in `defineConfig()`.
1105
1162
  *
1106
1163
  * `input` is an object keyed by lowercase HTTP method (`get`, `post`, `put`,
1107
- * `patch`, `delete`). At least one method must be declared; the methods the
1164
+ * `patch`, `delete`). Each handler can return a GraphQL query string or a
1165
+ * typed document node. At least one method must be declared; the methods the
1108
1166
  * adapter serves are derived from these keys.
1109
1167
  *
1110
- * `output` is optional and shared across all methods. If you need different
1111
- * response shapes per method, discriminate inside `output` based on the
1112
- * GraphQL response shape.
1168
+ * `output` is optional and shared across all methods. If `input` returns typed
1169
+ * document nodes, `output` receives the corresponding result type as
1170
+ * `resp.data`. If you need different response shapes per method, discriminate
1171
+ * inside `output` based on the GraphQL response shape.
1113
1172
  *
1114
1173
  * Each handler runs server-side and must be synchronous: Node APIs, `fetch`,
1115
1174
  * `async`/`await`, Promises, and top-level `await` are not available.
@@ -1136,7 +1195,7 @@ type HttpAdapter = Omit<HttpAdapterConfigInput, "input" | "output"> & {
1136
1195
  * }),
1137
1196
  * });
1138
1197
  */
1139
- declare function createHttpAdapter(config: HttpAdapter): HttpAdapter;
1198
+ declare function createHttpAdapter<const Input extends HttpAdapterInput>(config: HttpAdapter<Input>): HttpAdapter<Input>;
1140
1199
  //#endregion
1141
1200
  //#region src/configure/config/index.d.ts
1142
1201
  /**
@@ -1240,5 +1299,5 @@ declare namespace t {
1240
1299
  type infer<T> = TailorOutput<T>;
1241
1300
  }
1242
1301
  //#endregion
1243
- export { TailorDBTrigger as $, IncomingWebhookResponse as A, IdpNameRegistry as At, AuthAccessTokenRefreshedArgs as B, WaitPointInstance as C, createWorkflowJob as Ct, Trigger as D, AuthInvoker as Dt, createExecutor as E, createResolver as Et, ScheduleArgs as F, IdpUserDeletedArgs as G, AuthAccessTokenTrigger as H, ScheduleTrigger as I, RecordCreatedArgs as J, IdpUserTrigger as K, scheduleTrigger as L, IncomingWebhookTrigger as M, TailorField as Mt, IncomingWebhookTriggerOptions as N, MachineUserName as Nt, IncomingWebhookArgs as O, defineAuth as Ot, incomingWebhookTrigger as P, MachineUserNameRegistry as Pt, ResolverExecutedTrigger as Q, AuthAccessTokenArgs as R, defineStaticWebSite as S, WorkflowJobContext as St, defineWaitPoints as T, QueryType as Tt, IdpUserArgs as U, AuthAccessTokenRevokedArgs as V, IdpUserCreatedArgs as W, RecordUpdatedArgs as X, RecordDeletedArgs as Y, ResolverExecutedArgs as Z, defineIdp as _, WorkflowOperation as _t, defineGenerators as a, idpUserDeletedTrigger as at, unsafeAllowAllIdPPermission as b, createWorkflow as bt, HttpAdapterGraphQLRequest as c, recordCreatedTrigger as ct, HttpAdapterInputFn as d, recordUpdatedTrigger as dt, authAccessTokenIssuedTrigger as et, HttpAdapterOutputFn as f, resolverExecutedTrigger as ft, defineSecretManager as g, WebhookOperation as gt, createHttpAdapter as h, Operation as ht, defineConfig as i, idpUserCreatedTrigger as it, IncomingWebhookResponseConfig as j, unauthenticatedTailorUser as jt, IncomingWebhookRequest as k, IdpName as kt, HttpAdapterGraphQLResponse as l, recordDeletedTrigger as lt, HttpAdapterResponse as m, GqlOperation as mt, output as n, authAccessTokenRevokedTrigger as nt, definePlugins as o, idpUserTrigger as ot, HttpAdapterRequest as p, FunctionOperation as pt, IdpUserUpdatedArgs as q, t as r, authAccessTokenTrigger as rt, HttpAdapter as s, idpUserUpdatedTrigger as st, infer as t, authAccessTokenRefreshedTrigger as tt, HttpAdapterInput as u, recordTrigger as ut, IdPPermission as v, Workflow as vt, defineWaitPoint as w, WORKFLOW_TEST_ENV_KEY as wt, defineAIGateway as x, WorkflowJob as xt, IdPPermissionCondition as y, WorkflowConfig as yt, AuthAccessTokenIssuedArgs as z };
1244
- //# sourceMappingURL=index-DvEUb3pX.d.mts.map
1302
+ export { ResolverExecutedArgs as $, IncomingWebhookArgs as A, defineAuth as At, AuthAccessTokenArgs as B, defineAIGateway as C, WorkflowJob as Ct, defineWaitPoints as D, QueryType as Dt, defineWaitPoint as E, WORKFLOW_TEST_ENV_KEY as Et, IncomingWebhookTriggerOptions as F, MachineUserNameRegistry as Ft, IdpUserArgs as G, AuthAccessTokenRefreshedArgs as H, incomingWebhookTrigger as I, TailorField as It, IdpUserTrigger as J, IdpUserCreatedArgs as K, ScheduleArgs as L, IncomingWebhookResponse as M, IdpNameRegistry as Mt, IncomingWebhookResponseConfig as N, unauthenticatedTailorUser as Nt, createExecutor as O, createResolver as Ot, IncomingWebhookTrigger as P, MachineUserName as Pt, RecordUpdatedArgs as Q, ScheduleTrigger as R, unsafeAllowAllIdPPermission as S, createWorkflow as St, WaitPointInstance as T, createWorkflowJob as Tt, AuthAccessTokenRevokedArgs as U, AuthAccessTokenIssuedArgs as V, AuthAccessTokenTrigger as W, RecordCreatedArgs as X, IdpUserUpdatedArgs as Y, RecordDeletedArgs as Z, createHttpAdapter as _, Operation as _t, defineGenerators as a, authAccessTokenTrigger as at, IdPPermission as b, Workflow as bt, HttpAdapterGraphQLQuery as c, idpUserTrigger as ct, HttpAdapterInput as d, recordDeletedTrigger as dt, ResolverExecutedTrigger as et, HttpAdapterInputFn as f, recordTrigger as ft, HttpAdapterTypedDocumentNode as g, GqlOperation as gt, HttpAdapterResponse as h, FunctionOperation as ht, defineConfig as i, authAccessTokenRevokedTrigger as it, IncomingWebhookRequest as j, IdpName as jt, Trigger as k, AuthInvoker as kt, HttpAdapterGraphQLRequest as l, idpUserUpdatedTrigger as lt, HttpAdapterRequest as m, resolverExecutedTrigger as mt, output as n, authAccessTokenIssuedTrigger as nt, definePlugins as o, idpUserCreatedTrigger as ot, HttpAdapterOutputFn as p, recordUpdatedTrigger as pt, IdpUserDeletedArgs as q, t as r, authAccessTokenRefreshedTrigger as rt, HttpAdapter as s, idpUserDeletedTrigger as st, infer as t, TailorDBTrigger as tt, HttpAdapterGraphQLResponse as u, recordCreatedTrigger as ut, defineSecretManager as v, WebhookOperation as vt, defineStaticWebSite as w, WorkflowJobContext as wt, IdPPermissionCondition as x, WorkflowConfig as xt, defineIdp as y, WorkflowOperation as yt, scheduleTrigger as z };
1303
+ //# sourceMappingURL=index-BAEaAqmz.d.mts.map
@@ -1,4 +1,4 @@
1
- import { a as Plugin } from "./types-Bzr0RQME.mjs";
1
+ import { a as Plugin } from "./types-Dynq4AJv.mjs";
2
2
 
3
3
  //#region src/plugin/builtin/enum-constants/index.d.ts
4
4
  /** Unique identifier for the enum constants generator plugin. */
@@ -15,4 +15,4 @@ type EnumConstantsPluginOptions = {
15
15
  declare function enumConstantsPlugin(options: EnumConstantsPluginOptions): Plugin<unknown, EnumConstantsPluginOptions>;
16
16
  //#endregion
17
17
  export { enumConstantsPlugin as n, EnumConstantsGeneratorID as t };
18
- //# sourceMappingURL=index-CklcVeMG.d.mts.map
18
+ //# sourceMappingURL=index-C-vsbx27.d.mts.map
@@ -1,4 +1,4 @@
1
- import { a as Plugin } from "./types-Bzr0RQME.mjs";
1
+ import { a as Plugin } from "./types-Dynq4AJv.mjs";
2
2
 
3
3
  //#region src/plugin/builtin/seed/index.d.ts
4
4
  /** Unique identifier for the seed generator plugin. */
@@ -44,4 +44,4 @@ type SeedPluginOptions = {
44
44
  declare function seedPlugin(options: SeedPluginOptions): Plugin<unknown, SeedPluginOptions>;
45
45
  //#endregion
46
46
  export { seedPlugin as n, SeedGeneratorID as t };
47
- //# sourceMappingURL=index-hXoO-AOC.d.mts.map
47
+ //# sourceMappingURL=index-CKI0eZP6.d.mts.map
@@ -1,4 +1,4 @@
1
- import { a as Plugin } from "./types-Bzr0RQME.mjs";
1
+ import { a as Plugin } from "./types-Dynq4AJv.mjs";
2
2
 
3
3
  //#region src/plugin/builtin/file-utils/index.d.ts
4
4
  /** Unique identifier for the file utilities generator plugin. */
@@ -15,4 +15,4 @@ type FileUtilsPluginOptions = {
15
15
  declare function fileUtilsPlugin(options: FileUtilsPluginOptions): Plugin<unknown, FileUtilsPluginOptions>;
16
16
  //#endregion
17
17
  export { fileUtilsPlugin as n, FileUtilsGeneratorID as t };
18
- //# sourceMappingURL=index-DYhnxXYR.d.mts.map
18
+ //# sourceMappingURL=index-CrqOgUF2.d.mts.map
@@ -1,4 +1,4 @@
1
- import { a as Plugin } from "./types-Bzr0RQME.mjs";
1
+ import { a as Plugin } from "./types-Dynq4AJv.mjs";
2
2
 
3
3
  //#region src/plugin/builtin/kysely-type/index.d.ts
4
4
  /** Unique identifier for the Kysely type generator plugin. */
@@ -15,4 +15,4 @@ type KyselyTypePluginOptions = {
15
15
  declare function kyselyTypePlugin(options: KyselyTypePluginOptions): Plugin<unknown, KyselyTypePluginOptions>;
16
16
  //#endregion
17
17
  export { kyselyTypePlugin as n, KyselyGeneratorID as t };
18
- //# sourceMappingURL=index-DlDRSzFZ.d.mts.map
18
+ //# sourceMappingURL=index-DESLU9kI.d.mts.map
@@ -2,7 +2,7 @@ import { t as TailorAuthconnectionAPI } from "./authconnection-BIYzEh2p.mjs";
2
2
  import { r as TailorContextAPI } from "./context-CUBwSBq4.mjs";
3
3
  import { f as TailorDBFileAPI } from "./file-BzK8z3X-.mjs";
4
4
  import { i as TailorIconvAPI } from "./iconv-kwrmd1U_.mjs";
5
- import { l as TailorIdpAPI } from "./idp-BlBPtXJ-.mjs";
5
+ import { l as TailorIdpAPI } from "./idp-BmYwCXnJ.mjs";
6
6
  import { t as TailorSecretmanagerAPI } from "./secretmanager-CKLB3wAQ.mjs";
7
7
  import { n as TailorWorkflowAPI } from "./workflow-CMamswkK.mjs";
8
8
 
@@ -43,4 +43,4 @@ interface TailordbRuntime {
43
43
  }
44
44
  //#endregion
45
45
  export { TailordbQueryResult as a, TailordbCommandType as i, TailordbClientConstructor as n, TailordbRuntime as o, TailordbClientInstance as r, TailorRuntime as t };
46
- //# sourceMappingURL=index-DRhMpdnA.d.mts.map
46
+ //# sourceMappingURL=index-dKNk8hjo.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"job-BpsFXPbi.mjs","names":[],"sources":["../src/configure/services/workflow/job.ts"],"sourcesContent":["import { brandValue } from \"@/utils/brand\";\nimport { dispatchTriggerJob, registerJob, type RegisteredJobBody } from \"./registry\";\nimport type { TailorEnv, TailorInvoker } from \"@/runtime/types\";\nimport type { JsonCompatible } from \"@/types/helpers\";\n\n/**\n * Context object passed as the second argument to workflow job body functions.\n */\nexport type WorkflowJobContext = {\n env: TailorEnv;\n invoker?: TailorInvoker;\n};\n\n/**\n * The body function type for a workflow job.\n * Resolves to the callable signature when `I` / `O` are JsonValue-compatible,\n * or to a template-literal error string that surfaces at the `body:` property.\n */\ntype JobBody<I, O> = [null] extends [I]\n ? \"ERROR: Input cannot be null at the top level\"\n : [I] extends [undefined]\n ? [O] extends [JsonCompatible<O> | undefined | void]\n ? (input: I, context: WorkflowJobContext) => O | Promise<O>\n : \"ERROR: Output must be JsonValue-compatible (plain objects/arrays; no class instances or functions)\"\n : [undefined] extends [I]\n ? \"ERROR: Input cannot include undefined at the top level\"\n : [I] extends [JsonCompatible<I>]\n ? [O] extends [JsonCompatible<O> | undefined | void]\n ? (input: I, context: WorkflowJobContext) => O | Promise<O>\n : \"ERROR: Output must be JsonValue-compatible (plain objects/arrays; no class instances or functions)\"\n : \"ERROR: Input must be JsonValue-compatible (plain objects/arrays; no class instances or functions)\";\n\n/**\n * WorkflowJob represents a job that can be triggered in a workflow.\n *\n * Type constraints:\n * - Input: Must be JsonValue-compatible (plain objects/arrays; no class instances or functions) or undefined.\n * - Output: Must be JsonValue-compatible (plain objects/arrays; no class instances or functions), undefined, or void.\n * - Trigger returns `Awaited<Output>` as-is (no Jsonify transformation).\n */\nexport interface WorkflowJob<Name extends string = string, Input = undefined, Output = undefined> {\n name: Name;\n /**\n * Trigger this job with the given input. Returns a Promise that resolves\n * to the job's output value.\n * @example\n * body: async (input) => {\n * const a = await jobA.trigger({ id: input.id });\n * const b = await jobB.trigger({ id: input.id });\n * return { a, b };\n * }\n */\n trigger: [Input] extends [undefined]\n ? () => Promise<Awaited<Output>>\n : (input: Input) => Promise<Awaited<Output>>;\n body: (input: Input, context: WorkflowJobContext) => Output | Promise<Output>;\n}\n\nexport { WORKFLOW_TEST_ENV_KEY } from \"./test-env-key\";\n\ninterface CreateWorkflowJobConfig<Name extends string, I, O> {\n readonly name: Name;\n readonly body: JobBody<I, O>;\n}\n\n/**\n * Create a workflow job definition.\n *\n * All jobs must be named exports from the workflow file.\n * Job names must be unique across the entire project.\n *\n * Input and output must be JsonValue-compatible (primitives, plain objects, arrays).\n * Functions and objects with a `toJSON` method are rejected at the type level;\n * class instances exposing methods are rejected via the property walk.\n * @param config - Job configuration with name and body function.\n * @param config.name - Unique job name across the project.\n * @param config.body - Async function that processes the job input.\n * @returns A WorkflowJob that can be triggered from other jobs.\n * @example\n * // Simple job with async body:\n * export const fetchData = createWorkflowJob({\n * name: \"fetch-data\",\n * body: async (input: { id: string }) => {\n * const db = getDB(\"tailordb\");\n * return await db.selectFrom(\"Table\").selectAll().where(\"id\", \"=\", input.id).executeTakeFirst();\n * },\n * });\n * @example\n * // Orchestrator job that fans out to other jobs.\n * export const orchestrate = createWorkflowJob({\n * name: \"orchestrate\",\n * body: async (input: { orderId: string }) => {\n * const inventory = await checkInventory.trigger({ orderId: input.orderId });\n * const payment = await processPayment.trigger({ orderId: input.orderId });\n * return { inventory, payment };\n * },\n * });\n */\nexport function createWorkflowJob<const Name extends string, I = undefined, O = undefined>(\n config: CreateWorkflowJobConfig<Name, I, O>,\n): WorkflowJob<Name, I, Awaited<O>> {\n const body = config.body as (input: I, context: WorkflowJobContext) => O | Promise<O>;\n\n // Test-only registry/trigger shim; the platform bundle sets the flag so it is DCE'd.\n if (!process.env.TAILOR_PLATFORM_BUNDLE) {\n registerJob(config.name, body as RegisteredJobBody);\n }\n\n const trigger = process.env.TAILOR_PLATFORM_BUNDLE\n ? async () => {\n throw new Error(\n \"This workflow job's .trigger() is rewritten at build time and is unavailable in the bundle\",\n );\n }\n : async (args?: unknown) => (await dispatchTriggerJob(config.name, args)) as Awaited<O>;\n\n return brandValue(\n { name: config.name, trigger, body } as WorkflowJob<Name, I, Awaited<O>>,\n \"workflow-job\",\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkGA,SAAgB,kBACd,QACkC;CAClC,MAAM,OAAO,OAAO;CAGpB,IAAI,CAAC,QAAQ,IAAI,wBACf,YAAY,OAAO,MAAM,IAAyB;CAGpD,MAAM,UAAU,QAAQ,IAAI,yBACxB,YAAY;EACV,MAAM,IAAI,MACR,4FACF;CACF,IACA,OAAO,SAAoB,MAAM,mBAAmB,OAAO,MAAM,IAAI;CAEzE,OAAO,WACL;EAAE,MAAM,OAAO;EAAM;EAAS;CAAK,GACnC,cACF;AACF"}
1
+ {"version":3,"file":"job-BpsFXPbi.mjs","names":[],"sources":["../src/configure/services/workflow/job.ts"],"sourcesContent":["import { brandValue } from \"#/utils/brand\";\nimport { dispatchTriggerJob, registerJob, type RegisteredJobBody } from \"./registry\";\nimport type { TailorEnv, TailorInvoker } from \"#/runtime/types\";\nimport type { JsonCompatible } from \"#/types/helpers\";\n\n/**\n * Context object passed as the second argument to workflow job body functions.\n */\nexport type WorkflowJobContext = {\n env: TailorEnv;\n invoker?: TailorInvoker;\n};\n\n/**\n * The body function type for a workflow job.\n * Resolves to the callable signature when `I` / `O` are JsonValue-compatible,\n * or to a template-literal error string that surfaces at the `body:` property.\n */\ntype JobBody<I, O> = [null] extends [I]\n ? \"ERROR: Input cannot be null at the top level\"\n : [I] extends [undefined]\n ? [O] extends [JsonCompatible<O> | undefined | void]\n ? (input: I, context: WorkflowJobContext) => O | Promise<O>\n : \"ERROR: Output must be JsonValue-compatible (plain objects/arrays; no class instances or functions)\"\n : [undefined] extends [I]\n ? \"ERROR: Input cannot include undefined at the top level\"\n : [I] extends [JsonCompatible<I>]\n ? [O] extends [JsonCompatible<O> | undefined | void]\n ? (input: I, context: WorkflowJobContext) => O | Promise<O>\n : \"ERROR: Output must be JsonValue-compatible (plain objects/arrays; no class instances or functions)\"\n : \"ERROR: Input must be JsonValue-compatible (plain objects/arrays; no class instances or functions)\";\n\n/**\n * WorkflowJob represents a job that can be triggered in a workflow.\n *\n * Type constraints:\n * - Input: Must be JsonValue-compatible (plain objects/arrays; no class instances or functions) or undefined.\n * - Output: Must be JsonValue-compatible (plain objects/arrays; no class instances or functions), undefined, or void.\n * - Trigger returns `Awaited<Output>` as-is (no Jsonify transformation).\n */\nexport interface WorkflowJob<Name extends string = string, Input = undefined, Output = undefined> {\n name: Name;\n /**\n * Trigger this job with the given input. Returns a Promise that resolves\n * to the job's output value.\n * @example\n * body: async (input) => {\n * const a = await jobA.trigger({ id: input.id });\n * const b = await jobB.trigger({ id: input.id });\n * return { a, b };\n * }\n */\n trigger: [Input] extends [undefined]\n ? () => Promise<Awaited<Output>>\n : (input: Input) => Promise<Awaited<Output>>;\n body: (input: Input, context: WorkflowJobContext) => Output | Promise<Output>;\n}\n\nexport { WORKFLOW_TEST_ENV_KEY } from \"./test-env-key\";\n\ninterface CreateWorkflowJobConfig<Name extends string, I, O> {\n readonly name: Name;\n readonly body: JobBody<I, O>;\n}\n\n/**\n * Create a workflow job definition.\n *\n * All jobs must be named exports from the workflow file.\n * Job names must be unique across the entire project.\n *\n * Input and output must be JsonValue-compatible (primitives, plain objects, arrays).\n * Functions and objects with a `toJSON` method are rejected at the type level;\n * class instances exposing methods are rejected via the property walk.\n * @param config - Job configuration with name and body function.\n * @param config.name - Unique job name across the project.\n * @param config.body - Async function that processes the job input.\n * @returns A WorkflowJob that can be triggered from other jobs.\n * @example\n * // Simple job with async body:\n * export const fetchData = createWorkflowJob({\n * name: \"fetch-data\",\n * body: async (input: { id: string }) => {\n * const db = getDB(\"tailordb\");\n * return await db.selectFrom(\"Table\").selectAll().where(\"id\", \"=\", input.id).executeTakeFirst();\n * },\n * });\n * @example\n * // Orchestrator job that fans out to other jobs.\n * export const orchestrate = createWorkflowJob({\n * name: \"orchestrate\",\n * body: async (input: { orderId: string }) => {\n * const inventory = await checkInventory.trigger({ orderId: input.orderId });\n * const payment = await processPayment.trigger({ orderId: input.orderId });\n * return { inventory, payment };\n * },\n * });\n */\nexport function createWorkflowJob<const Name extends string, I = undefined, O = undefined>(\n config: CreateWorkflowJobConfig<Name, I, O>,\n): WorkflowJob<Name, I, Awaited<O>> {\n const body = config.body as (input: I, context: WorkflowJobContext) => O | Promise<O>;\n\n // Test-only registry/trigger shim; the platform bundle sets the flag so it is DCE'd.\n if (!process.env.TAILOR_PLATFORM_BUNDLE) {\n registerJob(config.name, body as RegisteredJobBody);\n }\n\n const trigger = process.env.TAILOR_PLATFORM_BUNDLE\n ? async () => {\n throw new Error(\n \"This workflow job's .trigger() is rewritten at build time and is unavailable in the bundle\",\n );\n }\n : async (args?: unknown) => (await dispatchTriggerJob(config.name, args)) as Awaited<O>;\n\n return brandValue(\n { name: config.name, trigger, body } as WorkflowJob<Name, I, Awaited<O>>,\n \"workflow-job\",\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkGA,SAAgB,kBACd,QACkC;CAClC,MAAM,OAAO,OAAO;CAGpB,IAAI,CAAC,QAAQ,IAAI,wBACf,YAAY,OAAO,MAAM,IAAyB;CAGpD,MAAM,UAAU,QAAQ,IAAI,yBACxB,YAAY;EACV,MAAM,IAAI,MACR,4FACF;CACF,IACA,OAAO,SAAoB,MAAM,mBAAmB,OAAO,MAAM,IAAI;CAEzE,OAAO,WACL;EAAE,MAAM,OAAO;EAAM;EAAS;CAAK,GACnC,cACF;AACF"}
@@ -108,7 +108,7 @@ function generateFieldType(fieldConfig) {
108
108
  const usedUtilityTypes = { ...baseTypeResult.usedUtilityTypes };
109
109
  const isArray = fieldConfig.array === true;
110
110
  const isNullable = fieldConfig.required !== true;
111
- const isColumnTypeBase = new Set(["Timestamp"]).has(baseTypeResult.type);
111
+ const isColumnTypeBase = (/* @__PURE__ */ new Set(["Timestamp"])).has(baseTypeResult.type);
112
112
  let finalType = baseTypeResult.type;
113
113
  if (isArray) if (isColumnTypeBase || finalType.startsWith("ObjectColumnType<")) finalType = `ArrayColumnType<${baseTypeResult.type}>`;
114
114
  else finalType = fieldConfig.type === "enum" ? `(${baseTypeResult.type})[]` : `${baseTypeResult.type}[]`;
@@ -272,4 +272,4 @@ function kyselyTypePlugin(options) {
272
272
 
273
273
  //#endregion
274
274
  export { kyselyTypePlugin as n, KyselyGeneratorID as t };
275
- //# sourceMappingURL=kysely-type-D1e0Vwkd.mjs.map
275
+ //# sourceMappingURL=kysely-type-CSoZxVKN.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"kysely-type-D1e0Vwkd.mjs","names":[],"sources":["../src/plugin/builtin/kysely-type/type-processor.ts","../src/plugin/builtin/kysely-type/index.ts"],"sourcesContent":["import multiline from \"@/utils/multiline\";\nimport { type KyselyNamespaceMetadata, type KyselyTypeMetadata } from \"./types\";\nimport type { OperatorFieldConfig, TailorDBType } from \"@/parser/service/tailordb/types\";\n\ntype UsedUtilityTypes = { Timestamp: boolean; Serial: boolean };\n\ntype FieldTypeResult = {\n type: string;\n usedUtilityTypes: UsedUtilityTypes;\n};\n\n/**\n * Get the enum type definition.\n * @param fieldConfig - The field configuration\n * @returns The enum type as a string union\n */\nfunction getEnumType(fieldConfig: OperatorFieldConfig): string {\n const allowedValues = fieldConfig.allowedValues;\n\n if (allowedValues && Array.isArray(allowedValues)) {\n return allowedValues\n .map((v: string | { value: string }) => {\n const value = typeof v === \"string\" ? v : v.value;\n return `\"${value}\"`;\n })\n .join(\" | \");\n }\n return \"string\";\n}\n\n/**\n * Get the nested object type definition.\n * @param fieldConfig - The field configuration\n * @returns The nested type with used utility types\n */\nfunction getNestedType(fieldConfig: OperatorFieldConfig): FieldTypeResult {\n const fields = fieldConfig.fields;\n if (!fields || typeof fields !== \"object\") {\n return {\n type: \"string\",\n usedUtilityTypes: { Timestamp: false, Serial: false },\n };\n }\n\n const fieldResults = Object.entries(fields).map(([fieldName, config]) => {\n const result = generateFieldType(config);\n const optional = config.required !== true ? \"?\" : \"\";\n return {\n fieldType: `${fieldName}${optional}: ${result.type}`,\n usedUtilityTypes: result.usedUtilityTypes,\n };\n });\n\n const aggregatedUtilityTypes = fieldResults.reduce(\n (acc, result) => ({\n Timestamp: acc.Timestamp || result.usedUtilityTypes.Timestamp,\n Serial: acc.Serial || result.usedUtilityTypes.Serial,\n }),\n { Timestamp: false, Serial: false },\n );\n\n const fieldTypes = fieldResults.map((r) => r.fieldType);\n const obj = `{\\n ${fieldTypes.join(\";\\n \")}${fieldTypes.length > 0 ? \";\" : \"\"}\\n}`;\n\n const hasOptionalFields = Object.values(fields).some((config) => config.required !== true);\n if (aggregatedUtilityTypes.Timestamp || hasOptionalFields) {\n return { type: `ObjectColumnType<${obj}>`, usedUtilityTypes: aggregatedUtilityTypes };\n }\n return { type: obj, usedUtilityTypes: aggregatedUtilityTypes };\n}\n\n/**\n * Get the base Kysely type for a field (without array/null modifiers).\n * @param fieldConfig - The field configuration\n * @returns The base type with used utility types\n */\nfunction getBaseType(fieldConfig: OperatorFieldConfig): FieldTypeResult {\n const fieldType = fieldConfig.type;\n const usedUtilityTypes = { Timestamp: false, Serial: false };\n\n let type: string;\n switch (fieldType) {\n case \"uuid\":\n case \"string\":\n case \"decimal\":\n type = \"string\";\n break;\n case \"integer\":\n case \"float\":\n type = \"number\";\n break;\n case \"date\":\n case \"datetime\":\n usedUtilityTypes.Timestamp = true;\n type = \"Timestamp\";\n break;\n case \"bool\":\n case \"boolean\":\n type = \"boolean\";\n break;\n case \"enum\":\n type = getEnumType(fieldConfig);\n break;\n case \"nested\": {\n const nestedResult = getNestedType(fieldConfig);\n return nestedResult;\n }\n default:\n type = \"string\";\n break;\n }\n\n return { type, usedUtilityTypes };\n}\n\n/**\n * Generate the complete field type including array and null modifiers.\n * @param fieldConfig - The field configuration\n * @returns The complete field type with used utility types\n */\nfunction generateFieldType(fieldConfig: OperatorFieldConfig): FieldTypeResult {\n const baseTypeResult = getBaseType(fieldConfig);\n const usedUtilityTypes = { ...baseTypeResult.usedUtilityTypes };\n\n const isArray = fieldConfig.array === true;\n const isNullable = fieldConfig.required !== true;\n\n // Types that use ColumnType internally (Timestamp, ObjectColumnType) cannot be\n // directly wrapped with [] for arrays, because Kysely only resolves ColumnType at\n // the top-level table property. Use ArrayColumnType/ObjectArrayColumnType to keep\n // the ColumnType at the top level with arrays inside.\n const columnTypeBaseTypes = new Set([\"Timestamp\"]);\n const isColumnTypeBase = columnTypeBaseTypes.has(baseTypeResult.type);\n\n let finalType = baseTypeResult.type;\n if (isArray) {\n if (isColumnTypeBase || finalType.startsWith(\"ObjectColumnType<\")) {\n finalType = `ArrayColumnType<${baseTypeResult.type}>`;\n } else {\n const needsParens = fieldConfig.type === \"enum\";\n finalType = needsParens ? `(${baseTypeResult.type})[]` : `${baseTypeResult.type}[]`;\n }\n }\n if (isNullable) {\n finalType = `${finalType} | null`;\n }\n\n if (fieldConfig.serial) {\n usedUtilityTypes.Serial = true;\n finalType = `Serial<${finalType}>`;\n }\n if (fieldConfig.hooks?.create) {\n finalType = `Generated<${finalType}>`;\n }\n\n return { type: finalType, usedUtilityTypes };\n}\n\n/**\n * Generate the table interface.\n * @param type - The parsed TailorDB type\n * @returns The type definition and used utility types\n */\nfunction generateTableInterface(type: TailorDBType): {\n typeDef: string;\n usedUtilityTypes: UsedUtilityTypes;\n} {\n const fieldEntries = Object.entries(type.fields).filter(([fieldName]) => fieldName !== \"id\");\n\n const fieldResults = fieldEntries.map(([fieldName, parsedField]) => ({\n fieldName,\n ...generateFieldType(parsedField.config),\n }));\n\n const fields = [\n \"id: Generated<string>;\",\n ...fieldResults.map((result) => `${result.fieldName}: ${result.type};`),\n ];\n\n const aggregatedUtilityTypes = fieldResults.reduce(\n (acc, result) => ({\n Timestamp: acc.Timestamp || result.usedUtilityTypes.Timestamp,\n\n Serial: acc.Serial || result.usedUtilityTypes.Serial,\n }),\n { Timestamp: false, Serial: false },\n );\n\n const typeDef = multiline /* ts */ `\n ${type.name}: {\n ${fields.join(\"\\n\")}\n }\n `;\n\n return { typeDef, usedUtilityTypes: aggregatedUtilityTypes };\n}\n\n/**\n * Convert a TailorDBType into KyselyTypeMetadata.\n * @param type - Parsed TailorDB type\n * @returns Generated Kysely type metadata\n */\nexport async function processKyselyType(type: TailorDBType): Promise<KyselyTypeMetadata> {\n const result = generateTableInterface(type);\n\n return {\n name: type.name,\n typeDef: result.typeDef,\n usedUtilityTypes: result.usedUtilityTypes,\n };\n}\n\n/**\n * Generate unified types file from multiple namespaces.\n * @param namespaceData - Namespace metadata\n * @returns Generated types file contents\n */\nexport function generateUnifiedKyselyTypes(namespaceData: KyselyNamespaceMetadata[]): string {\n if (namespaceData.length === 0) {\n return \"\";\n }\n\n // Aggregate used utility types from all namespaces\n const globalUsedUtilityTypes = namespaceData.reduce(\n (acc, ns) => ({\n Timestamp: acc.Timestamp || ns.usedUtilityTypes.Timestamp,\n Serial: acc.Serial || ns.usedUtilityTypes.Serial,\n }),\n { Timestamp: false, Serial: false },\n );\n\n const utilityTypeImports: string[] = [\"type Generated\"];\n if (globalUsedUtilityTypes.Timestamp) {\n utilityTypeImports.push(\"type Timestamp\");\n }\n const hasObjectColumnType = namespaceData.some((ns) =>\n ns.types.some((t) => t.typeDef.includes(\"ObjectColumnType<\")),\n );\n if (hasObjectColumnType) {\n utilityTypeImports.push(\"type ObjectColumnType\");\n }\n const hasArrayColumnType = namespaceData.some((ns) =>\n ns.types.some((t) => t.typeDef.includes(\"ArrayColumnType<\")),\n );\n if (hasArrayColumnType) {\n utilityTypeImports.push(\"type ArrayColumnType\");\n }\n if (globalUsedUtilityTypes.Serial) {\n utilityTypeImports.push(\"type Serial\");\n }\n\n const importsSection = multiline /* ts */ `\n import {\n createGetDB,\n ${utilityTypeImports.join(\",\\n\")},\n type NamespaceDB,\n type NamespaceInsertable,\n type NamespaceSelectable,\n type NamespaceTable,\n type NamespaceTableName,\n type NamespaceTransaction,\n type NamespaceUpdateable,\n } from \"@tailor-platform/sdk/kysely\";\n `;\n\n // Generate Namespace interface with multiple namespaces\n const namespaceInterfaces = namespaceData\n .map(({ namespace, types }) => {\n const typeDefsWithIndent = types\n .map((type) => {\n return type.typeDef\n .split(\"\\n\")\n .map((line) => (line.trim() ? ` ${line}` : \"\"))\n .join(\"\\n\");\n })\n .join(\"\\n\\n\");\n\n return ` \"${namespace}\": {\\n${typeDefsWithIndent}\\n }`;\n })\n .join(\",\\n\");\n\n const namespaceInterface = `export interface Namespace {\\n${namespaceInterfaces}\\n}`;\n\n const getDBFunction = multiline /* ts */ `\n export const getDB = createGetDB<Namespace>();\n\n export type DB<N extends keyof Namespace = keyof Namespace> = NamespaceDB<Namespace, N>;\n `;\n\n const utilityTypeExports = multiline /* ts */ `\n export type Transaction<K extends keyof Namespace | DB = keyof Namespace> =\n NamespaceTransaction<Namespace, K>;\n\n type TableName = NamespaceTableName<Namespace>;\n export type Table<T extends TableName> = NamespaceTable<Namespace, T>;\n\n export type Insertable<T extends TableName> = NamespaceInsertable<Namespace, T>;\n export type Selectable<T extends TableName> = NamespaceSelectable<Namespace, T>;\n export type Updateable<T extends TableName> = NamespaceUpdateable<Namespace, T>;\n `;\n\n return (\n [importsSection, namespaceInterface, getDBFunction, utilityTypeExports].join(\"\\n\\n\") + \"\\n\"\n );\n}\n","import { processKyselyType, generateUnifiedKyselyTypes } from \"./type-processor\";\nimport type { KyselyTypeMetadata, KyselyNamespaceMetadata } from \"./types\";\nimport type { Plugin, GeneratorResult, TailorDBReadyContext } from \"@/plugin/types\";\n\n/** Unique identifier for the Kysely type generator plugin. */\nexport const KyselyGeneratorID = \"@tailor-platform/kysely-type\";\n\ntype KyselyTypePluginOptions = {\n distPath: string;\n};\n\n/**\n * Plugin that generates Kysely type definitions for TailorDB types.\n * @param options - Plugin options\n * @param options.distPath - Output file path for generated types\n * @returns Plugin instance with onTailorDBReady hook\n */\nexport function kyselyTypePlugin(\n options: KyselyTypePluginOptions,\n): Plugin<unknown, KyselyTypePluginOptions> {\n return {\n id: KyselyGeneratorID,\n description: \"Generates Kysely type definitions for TailorDB types\",\n pluginConfig: options,\n\n async onTailorDBReady(\n ctx: TailorDBReadyContext<KyselyTypePluginOptions>,\n ): Promise<GeneratorResult> {\n const allNamespaceData: KyselyNamespaceMetadata[] = [];\n\n for (const ns of ctx.tailordb) {\n const typeMetadataList: KyselyTypeMetadata[] = [];\n\n for (const type of Object.values(ns.types)) {\n const metadata = await processKyselyType(type);\n typeMetadataList.push(metadata);\n }\n\n if (typeMetadataList.length === 0) continue;\n\n const usedUtilityTypes = typeMetadataList.reduce(\n (acc, type) => ({\n Timestamp: acc.Timestamp || type.usedUtilityTypes.Timestamp,\n Serial: acc.Serial || type.usedUtilityTypes.Serial,\n }),\n { Timestamp: false, Serial: false },\n );\n\n allNamespaceData.push({\n namespace: ns.namespace,\n types: typeMetadataList,\n usedUtilityTypes,\n });\n }\n\n const files: GeneratorResult[\"files\"] = [];\n if (allNamespaceData.length > 0) {\n const content = generateUnifiedKyselyTypes(allNamespaceData);\n files.push({\n path: ctx.pluginConfig.distPath,\n content,\n });\n }\n\n return { files };\n },\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"kysely-type-CSoZxVKN.mjs","names":[],"sources":["../src/plugin/builtin/kysely-type/type-processor.ts","../src/plugin/builtin/kysely-type/index.ts"],"sourcesContent":["import multiline from \"#/utils/multiline\";\nimport { type KyselyNamespaceMetadata, type KyselyTypeMetadata } from \"./types\";\nimport type { OperatorFieldConfig, TailorDBType } from \"#/parser/service/tailordb/types\";\n\ntype UsedUtilityTypes = { Timestamp: boolean; Serial: boolean };\n\ntype FieldTypeResult = {\n type: string;\n usedUtilityTypes: UsedUtilityTypes;\n};\n\n/**\n * Get the enum type definition.\n * @param fieldConfig - The field configuration\n * @returns The enum type as a string union\n */\nfunction getEnumType(fieldConfig: OperatorFieldConfig): string {\n const allowedValues = fieldConfig.allowedValues;\n\n if (allowedValues && Array.isArray(allowedValues)) {\n return allowedValues\n .map((v: string | { value: string }) => {\n const value = typeof v === \"string\" ? v : v.value;\n return `\"${value}\"`;\n })\n .join(\" | \");\n }\n return \"string\";\n}\n\n/**\n * Get the nested object type definition.\n * @param fieldConfig - The field configuration\n * @returns The nested type with used utility types\n */\nfunction getNestedType(fieldConfig: OperatorFieldConfig): FieldTypeResult {\n const fields = fieldConfig.fields;\n if (!fields || typeof fields !== \"object\") {\n return {\n type: \"string\",\n usedUtilityTypes: { Timestamp: false, Serial: false },\n };\n }\n\n const fieldResults = Object.entries(fields).map(([fieldName, config]) => {\n const result = generateFieldType(config);\n const optional = config.required !== true ? \"?\" : \"\";\n return {\n fieldType: `${fieldName}${optional}: ${result.type}`,\n usedUtilityTypes: result.usedUtilityTypes,\n };\n });\n\n const aggregatedUtilityTypes = fieldResults.reduce(\n (acc, result) => ({\n Timestamp: acc.Timestamp || result.usedUtilityTypes.Timestamp,\n Serial: acc.Serial || result.usedUtilityTypes.Serial,\n }),\n { Timestamp: false, Serial: false },\n );\n\n const fieldTypes = fieldResults.map((r) => r.fieldType);\n const obj = `{\\n ${fieldTypes.join(\";\\n \")}${fieldTypes.length > 0 ? \";\" : \"\"}\\n}`;\n\n const hasOptionalFields = Object.values(fields).some((config) => config.required !== true);\n if (aggregatedUtilityTypes.Timestamp || hasOptionalFields) {\n return { type: `ObjectColumnType<${obj}>`, usedUtilityTypes: aggregatedUtilityTypes };\n }\n return { type: obj, usedUtilityTypes: aggregatedUtilityTypes };\n}\n\n/**\n * Get the base Kysely type for a field (without array/null modifiers).\n * @param fieldConfig - The field configuration\n * @returns The base type with used utility types\n */\nfunction getBaseType(fieldConfig: OperatorFieldConfig): FieldTypeResult {\n const fieldType = fieldConfig.type;\n const usedUtilityTypes = { Timestamp: false, Serial: false };\n\n let type: string;\n switch (fieldType) {\n case \"uuid\":\n case \"string\":\n case \"decimal\":\n type = \"string\";\n break;\n case \"integer\":\n case \"float\":\n type = \"number\";\n break;\n case \"date\":\n case \"datetime\":\n usedUtilityTypes.Timestamp = true;\n type = \"Timestamp\";\n break;\n case \"bool\":\n case \"boolean\":\n type = \"boolean\";\n break;\n case \"enum\":\n type = getEnumType(fieldConfig);\n break;\n case \"nested\": {\n const nestedResult = getNestedType(fieldConfig);\n return nestedResult;\n }\n default:\n type = \"string\";\n break;\n }\n\n return { type, usedUtilityTypes };\n}\n\n/**\n * Generate the complete field type including array and null modifiers.\n * @param fieldConfig - The field configuration\n * @returns The complete field type with used utility types\n */\nfunction generateFieldType(fieldConfig: OperatorFieldConfig): FieldTypeResult {\n const baseTypeResult = getBaseType(fieldConfig);\n const usedUtilityTypes = { ...baseTypeResult.usedUtilityTypes };\n\n const isArray = fieldConfig.array === true;\n const isNullable = fieldConfig.required !== true;\n\n // Types that use ColumnType internally (Timestamp, ObjectColumnType) cannot be\n // directly wrapped with [] for arrays, because Kysely only resolves ColumnType at\n // the top-level table property. Use ArrayColumnType/ObjectArrayColumnType to keep\n // the ColumnType at the top level with arrays inside.\n const columnTypeBaseTypes = new Set([\"Timestamp\"]);\n const isColumnTypeBase = columnTypeBaseTypes.has(baseTypeResult.type);\n\n let finalType = baseTypeResult.type;\n if (isArray) {\n if (isColumnTypeBase || finalType.startsWith(\"ObjectColumnType<\")) {\n finalType = `ArrayColumnType<${baseTypeResult.type}>`;\n } else {\n const needsParens = fieldConfig.type === \"enum\";\n finalType = needsParens ? `(${baseTypeResult.type})[]` : `${baseTypeResult.type}[]`;\n }\n }\n if (isNullable) {\n finalType = `${finalType} | null`;\n }\n\n if (fieldConfig.serial) {\n usedUtilityTypes.Serial = true;\n finalType = `Serial<${finalType}>`;\n }\n if (fieldConfig.hooks?.create) {\n finalType = `Generated<${finalType}>`;\n }\n\n return { type: finalType, usedUtilityTypes };\n}\n\n/**\n * Generate the table interface.\n * @param type - The parsed TailorDB type\n * @returns The type definition and used utility types\n */\nfunction generateTableInterface(type: TailorDBType): {\n typeDef: string;\n usedUtilityTypes: UsedUtilityTypes;\n} {\n const fieldEntries = Object.entries(type.fields).filter(([fieldName]) => fieldName !== \"id\");\n\n const fieldResults = fieldEntries.map(([fieldName, parsedField]) => ({\n fieldName,\n ...generateFieldType(parsedField.config),\n }));\n\n const fields = [\n \"id: Generated<string>;\",\n ...fieldResults.map((result) => `${result.fieldName}: ${result.type};`),\n ];\n\n const aggregatedUtilityTypes = fieldResults.reduce(\n (acc, result) => ({\n Timestamp: acc.Timestamp || result.usedUtilityTypes.Timestamp,\n\n Serial: acc.Serial || result.usedUtilityTypes.Serial,\n }),\n { Timestamp: false, Serial: false },\n );\n\n const typeDef = multiline /* ts */ `\n ${type.name}: {\n ${fields.join(\"\\n\")}\n }\n `;\n\n return { typeDef, usedUtilityTypes: aggregatedUtilityTypes };\n}\n\n/**\n * Convert a TailorDBType into KyselyTypeMetadata.\n * @param type - Parsed TailorDB type\n * @returns Generated Kysely type metadata\n */\nexport async function processKyselyType(type: TailorDBType): Promise<KyselyTypeMetadata> {\n const result = generateTableInterface(type);\n\n return {\n name: type.name,\n typeDef: result.typeDef,\n usedUtilityTypes: result.usedUtilityTypes,\n };\n}\n\n/**\n * Generate unified types file from multiple namespaces.\n * @param namespaceData - Namespace metadata\n * @returns Generated types file contents\n */\nexport function generateUnifiedKyselyTypes(namespaceData: KyselyNamespaceMetadata[]): string {\n if (namespaceData.length === 0) {\n return \"\";\n }\n\n // Aggregate used utility types from all namespaces\n const globalUsedUtilityTypes = namespaceData.reduce(\n (acc, ns) => ({\n Timestamp: acc.Timestamp || ns.usedUtilityTypes.Timestamp,\n Serial: acc.Serial || ns.usedUtilityTypes.Serial,\n }),\n { Timestamp: false, Serial: false },\n );\n\n const utilityTypeImports: string[] = [\"type Generated\"];\n if (globalUsedUtilityTypes.Timestamp) {\n utilityTypeImports.push(\"type Timestamp\");\n }\n const hasObjectColumnType = namespaceData.some((ns) =>\n ns.types.some((t) => t.typeDef.includes(\"ObjectColumnType<\")),\n );\n if (hasObjectColumnType) {\n utilityTypeImports.push(\"type ObjectColumnType\");\n }\n const hasArrayColumnType = namespaceData.some((ns) =>\n ns.types.some((t) => t.typeDef.includes(\"ArrayColumnType<\")),\n );\n if (hasArrayColumnType) {\n utilityTypeImports.push(\"type ArrayColumnType\");\n }\n if (globalUsedUtilityTypes.Serial) {\n utilityTypeImports.push(\"type Serial\");\n }\n\n const importsSection = multiline /* ts */ `\n import {\n createGetDB,\n ${utilityTypeImports.join(\",\\n\")},\n type NamespaceDB,\n type NamespaceInsertable,\n type NamespaceSelectable,\n type NamespaceTable,\n type NamespaceTableName,\n type NamespaceTransaction,\n type NamespaceUpdateable,\n } from \"@tailor-platform/sdk/kysely\";\n `;\n\n // Generate Namespace interface with multiple namespaces\n const namespaceInterfaces = namespaceData\n .map(({ namespace, types }) => {\n const typeDefsWithIndent = types\n .map((type) => {\n return type.typeDef\n .split(\"\\n\")\n .map((line) => (line.trim() ? ` ${line}` : \"\"))\n .join(\"\\n\");\n })\n .join(\"\\n\\n\");\n\n return ` \"${namespace}\": {\\n${typeDefsWithIndent}\\n }`;\n })\n .join(\",\\n\");\n\n const namespaceInterface = `export interface Namespace {\\n${namespaceInterfaces}\\n}`;\n\n const getDBFunction = multiline /* ts */ `\n export const getDB = createGetDB<Namespace>();\n\n export type DB<N extends keyof Namespace = keyof Namespace> = NamespaceDB<Namespace, N>;\n `;\n\n const utilityTypeExports = multiline /* ts */ `\n export type Transaction<K extends keyof Namespace | DB = keyof Namespace> =\n NamespaceTransaction<Namespace, K>;\n\n type TableName = NamespaceTableName<Namespace>;\n export type Table<T extends TableName> = NamespaceTable<Namespace, T>;\n\n export type Insertable<T extends TableName> = NamespaceInsertable<Namespace, T>;\n export type Selectable<T extends TableName> = NamespaceSelectable<Namespace, T>;\n export type Updateable<T extends TableName> = NamespaceUpdateable<Namespace, T>;\n `;\n\n return (\n [importsSection, namespaceInterface, getDBFunction, utilityTypeExports].join(\"\\n\\n\") + \"\\n\"\n );\n}\n","import { processKyselyType, generateUnifiedKyselyTypes } from \"./type-processor\";\nimport type { Plugin, GeneratorResult, TailorDBReadyContext } from \"#/plugin/types\";\nimport type { KyselyTypeMetadata, KyselyNamespaceMetadata } from \"./types\";\n\n/** Unique identifier for the Kysely type generator plugin. */\nexport const KyselyGeneratorID = \"@tailor-platform/kysely-type\";\n\ntype KyselyTypePluginOptions = {\n distPath: string;\n};\n\n/**\n * Plugin that generates Kysely type definitions for TailorDB types.\n * @param options - Plugin options\n * @param options.distPath - Output file path for generated types\n * @returns Plugin instance with onTailorDBReady hook\n */\nexport function kyselyTypePlugin(\n options: KyselyTypePluginOptions,\n): Plugin<unknown, KyselyTypePluginOptions> {\n return {\n id: KyselyGeneratorID,\n description: \"Generates Kysely type definitions for TailorDB types\",\n pluginConfig: options,\n\n async onTailorDBReady(\n ctx: TailorDBReadyContext<KyselyTypePluginOptions>,\n ): Promise<GeneratorResult> {\n const allNamespaceData: KyselyNamespaceMetadata[] = [];\n\n for (const ns of ctx.tailordb) {\n const typeMetadataList: KyselyTypeMetadata[] = [];\n\n for (const type of Object.values(ns.types)) {\n const metadata = await processKyselyType(type);\n typeMetadataList.push(metadata);\n }\n\n if (typeMetadataList.length === 0) continue;\n\n const usedUtilityTypes = typeMetadataList.reduce(\n (acc, type) => ({\n Timestamp: acc.Timestamp || type.usedUtilityTypes.Timestamp,\n Serial: acc.Serial || type.usedUtilityTypes.Serial,\n }),\n { Timestamp: false, Serial: false },\n );\n\n allNamespaceData.push({\n namespace: ns.namespace,\n types: typeMetadataList,\n usedUtilityTypes,\n });\n }\n\n const files: GeneratorResult[\"files\"] = [];\n if (allNamespaceData.length > 0) {\n const content = generateUnifiedKyselyTypes(allNamespaceData);\n files.push({\n path: ctx.pluginConfig.distPath,\n content,\n });\n }\n\n return { files };\n },\n };\n}\n"],"mappings":"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"}
@@ -5,7 +5,7 @@ import { formatDistanceToNowStrict } from "date-fns";
5
5
  import { getBorderCharacters, table } from "table";
6
6
 
7
7
  //#region src/cli/shared/parse-boolean.ts
8
- const TRUTHY_VALUES = new Set([
8
+ const TRUTHY_VALUES = /* @__PURE__ */ new Set([
9
9
  "true",
10
10
  "t",
11
11
  "yes",
@@ -13,7 +13,7 @@ const TRUTHY_VALUES = new Set([
13
13
  "on",
14
14
  "1"
15
15
  ]);
16
- const FALSY_VALUES = new Set([
16
+ const FALSY_VALUES = /* @__PURE__ */ new Set([
17
17
  "false",
18
18
  "f",
19
19
  "no",
@@ -218,4 +218,4 @@ const logger = {
218
218
 
219
219
  //#endregion
220
220
  export { parseBoolean as a, symbols as i, logger as n, styles as r, CIPromptError as t };
221
- //# sourceMappingURL=logger-DpJyJvNz.mjs.map
221
+ //# sourceMappingURL=logger-DKF-JsAK.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"logger-DpJyJvNz.mjs","names":[],"sources":["../src/cli/shared/parse-boolean.ts","../src/cli/shared/logger.ts"],"sourcesContent":["const TRUTHY_VALUES = new Set([\"true\", \"t\", \"yes\", \"y\", \"on\", \"1\"]);\nconst FALSY_VALUES = new Set([\"false\", \"f\", \"no\", \"n\", \"off\", \"0\"]);\n\n/**\n * Parse a string value as a boolean.\n *\n * Recognized values (case-insensitive, trimmed) follow Python's\n * `distutils.util.strtobool` convention:\n * - truthy: `true, t, yes, y, on, 1`\n * - falsy: `false, f, no, n, off, 0`\n *\n * Undefined, empty strings, and unrecognized values return `undefined` so\n * that callers can fall back to their own defaults.\n * @param value - The input string (e.g. an environment variable or CLI flag value)\n * @returns `true`, `false`, or `undefined` when the value is unset or unrecognized\n */\nexport function parseBoolean(value: string | undefined): boolean | undefined {\n if (value === undefined) return undefined;\n const normalized = value.trim().toLowerCase();\n if (normalized === \"\") return undefined;\n if (TRUTHY_VALUES.has(normalized)) return true;\n if (FALSY_VALUES.has(normalized)) return false;\n return undefined;\n}\n","import { formatWithOptions, type InspectOptions } from \"node:util\";\nimport chalk from \"chalk\";\nimport { formatDistanceToNowStrict } from \"date-fns\";\nimport { getBorderCharacters, table } from \"table\";\nimport { parseBoolean } from \"./parse-boolean\";\n\n/**\n * Error thrown when a prompt is attempted in a CI environment\n */\nexport class CIPromptError extends Error {\n constructor(message?: string) {\n super(\n message ??\n \"Interactive prompts are not available in CI environments. Use --yes flag to skip confirmation prompts.\",\n );\n this.name = \"CIPromptError\";\n }\n}\n\n/**\n * Semantic style functions for inline text styling\n */\nexport const styles = {\n // Status colors\n success: chalk.green,\n error: chalk.red,\n warning: chalk.yellow,\n info: chalk.cyan,\n\n // Action colors (for change sets)\n create: chalk.green,\n update: chalk.yellow,\n delete: chalk.red,\n unchanged: chalk.gray,\n\n // Emphasis\n bold: chalk.bold,\n dim: chalk.gray,\n highlight: chalk.cyanBright,\n successBright: chalk.greenBright,\n errorBright: chalk.redBright,\n\n // Resource types\n resourceType: chalk.bold,\n resourceName: chalk.cyan,\n\n // File paths\n path: chalk.cyan,\n\n // Values\n value: chalk.white,\n placeholder: chalk.gray.italic,\n};\n\n/**\n * Standardized symbols for CLI output\n */\nexport const symbols = {\n success: chalk.green(\"\\u2713\"),\n error: chalk.red(\"\\u2716\"),\n warning: chalk.yellow(\"\\u26a0\"),\n info: chalk.cyan(\"i\"),\n create: chalk.green(\"+\"),\n update: chalk.yellow(\"~\"),\n delete: chalk.red(\"-\"),\n replace: chalk.magenta(\"\\u00b1\"),\n bullet: chalk.gray(\"\\u2022\"),\n arrow: chalk.gray(\"\\u2192\"),\n};\n\n/**\n * Log output modes\n */\nexport type LogMode = \"default\" | \"stream\" | \"plain\";\n\nexport interface LogOptions {\n /** Output mode (default: \"default\") */\n mode?: LogMode;\n /** Number of spaces to indent the entire line (default: 0) */\n indent?: number;\n}\n\n/** Field transformer function. null excludes the field from table output. */\nexport type FieldTransformer = ((value: unknown, item: object) => string) | null;\n\nexport interface OutOptions {\n /** Table display field transform/exclude settings. Only applied in table mode (not JSON). */\n display?: Record<string, FieldTransformer>;\n\n /** Show null values in table output (default: false) */\n showNull?: boolean;\n}\n\n// In JSON mode, all logs go to stderr to keep stdout clean for JSON data\nlet _jsonMode = false;\n\n// Type icons for log output\nconst TYPE_ICONS: Record<string, string> = {\n info: \"ℹ\",\n success: \"✔\",\n warn: \"⚠\",\n error: \"✖\",\n debug: \"⚙\",\n trace: \"→\",\n log: \"\",\n};\n\n// Color functions for icon and message text\nconst TYPE_COLORS: Record<string, (text: string) => string> = {\n info: chalk.cyan,\n success: chalk.green,\n warn: chalk.yellow,\n error: chalk.red,\n debug: chalk.gray,\n trace: chalk.gray,\n log: (text) => text,\n};\n\ninterface FormatLogLineOptions {\n mode: string;\n indent: number;\n type: string;\n message: string;\n timestamp?: string;\n}\n\n/**\n * Formats a log line with the appropriate prefix and indentation\n * @param opts - Formatting options\n * @returns Formatted log line\n */\nexport function formatLogLine(opts: FormatLogLineOptions): string {\n const { mode, indent, type, message, timestamp } = opts;\n const indentPrefix = indent > 0 ? \" \".repeat(indent) : \"\";\n const colorFn = TYPE_COLORS[type] || ((text: string) => text);\n\n // Plain mode: color only, no icon, no timestamp\n if (mode === \"plain\") {\n return `${indentPrefix}${colorFn(message)}\\n`;\n }\n\n // Default/Stream mode: with icon and color\n const icon = TYPE_ICONS[type] || \"\";\n const prefix = icon ? `${icon} ` : \"\";\n const coloredOutput = colorFn(`${prefix}${message}`);\n const timestampPrefix = timestamp ?? \"\";\n\n return `${indentPrefix}${timestampPrefix}${coloredOutput}\\n`;\n}\n\n/**\n * Writes a formatted log line to stderr.\n * @param type - Log type (info, success, warn, error, log)\n * @param message - Log message\n * @param opts - Log options (mode and indent)\n */\nfunction writeLog(type: string, message: string, opts?: LogOptions): void {\n const mode = opts?.mode ?? \"default\";\n const indent = opts?.indent ?? 0;\n const inspectOpts: InspectOptions = {\n breakLength: process.stdout.columns || 80,\n };\n const formattedMessage = formatWithOptions(inspectOpts, message);\n const timestamp = mode === \"stream\" ? `${new Date().toLocaleTimeString()} ` : \"\";\n const output = formatLogLine({ mode, indent, type, message: formattedMessage, timestamp });\n process.stderr.write(output);\n}\n\nexport const logger = {\n get jsonMode(): boolean {\n return _jsonMode;\n },\n set jsonMode(value: boolean) {\n _jsonMode = value;\n },\n\n info(message: string, opts?: LogOptions): void {\n writeLog(\"info\", message, opts);\n },\n\n success(message: string, opts?: LogOptions): void {\n writeLog(\"success\", message, opts);\n },\n\n warn(message: string, opts?: LogOptions): void {\n writeLog(\"warn\", message, opts);\n },\n\n error(message: string, opts?: LogOptions): void {\n writeLog(\"error\", message, opts);\n },\n\n log(message: string): void {\n writeLog(\"log\", message, { mode: \"plain\" });\n },\n\n newline(): void {\n process.stderr.write(\"\\n\");\n },\n\n debug(message: string): void {\n if (parseBoolean(process.env.DEBUG) === true) {\n writeLog(\"log\", styles.dim(message), { mode: \"plain\" });\n }\n },\n\n out(data: string | object | object[], options?: OutOptions): void {\n if (typeof data === \"string\") {\n process.stdout.write(data.endsWith(\"\\n\") ? data : data + \"\\n\");\n return;\n }\n\n if (this.jsonMode) {\n // eslint-disable-next-line no-restricted-syntax\n console.log(JSON.stringify(data));\n return;\n }\n\n const display = options?.display;\n\n // Helper to format a value for table display\n const formatValue = (value: unknown, pretty = false): string => {\n if (options?.showNull && value === null) return \"NULL\";\n if (value === null || value === undefined) return \"N/A\";\n if (value instanceof Date) {\n return formatDistanceToNowStrict(value, { addSuffix: true });\n }\n if (typeof value === \"object\") {\n return pretty ? JSON.stringify(value, null, 2) : JSON.stringify(value);\n }\n return String(value);\n };\n\n // Helper to check if field should be excluded\n const isExcluded = (key: string): boolean => {\n return display !== undefined && key in display && display[key] === null;\n };\n\n // Helper to apply transformer or default formatting\n const transformValue = (key: string, value: unknown, item: object, pretty = false): string => {\n if (display && key in display) {\n const transformer = display[key];\n if (transformer) {\n return transformer(value, item);\n }\n }\n return formatValue(value, pretty);\n };\n\n if (!Array.isArray(data)) {\n const entries = Object.entries(data).filter(([key]) => !isExcluded(key));\n const formattedEntries = entries.map(([key, value]) => [\n key,\n transformValue(key, value, data, true),\n ]);\n const t = table(formattedEntries, {\n singleLine: false,\n border: getBorderCharacters(\"norc\"),\n });\n process.stdout.write(t);\n return;\n }\n\n if (data.length === 0) {\n return;\n }\n\n const allHeaders = Array.from(new Set(data.flatMap((item) => Object.keys(item))));\n const headers = allHeaders.filter((h) => !isExcluded(h));\n const rows = data.map((item) =>\n headers.map((header) =>\n transformValue(header, (item as Record<string, unknown>)[header], item),\n ),\n );\n\n const t = table([headers, ...rows], {\n border: getBorderCharacters(\"norc\"),\n drawHorizontalLine: (lineIndex, rowCount) => {\n return lineIndex === 0 || lineIndex === 1 || lineIndex === rowCount;\n },\n });\n process.stdout.write(t);\n },\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"logger-DKF-JsAK.mjs","names":[],"sources":["../src/cli/shared/parse-boolean.ts","../src/cli/shared/logger.ts"],"sourcesContent":["const TRUTHY_VALUES = new Set([\"true\", \"t\", \"yes\", \"y\", \"on\", \"1\"]);\nconst FALSY_VALUES = new Set([\"false\", \"f\", \"no\", \"n\", \"off\", \"0\"]);\n\n/**\n * Parse a string value as a boolean.\n *\n * Recognized values (case-insensitive, trimmed) follow Python's\n * `distutils.util.strtobool` convention:\n * - truthy: `true, t, yes, y, on, 1`\n * - falsy: `false, f, no, n, off, 0`\n *\n * Undefined, empty strings, and unrecognized values return `undefined` so\n * that callers can fall back to their own defaults.\n * @param value - The input string (e.g. an environment variable or CLI flag value)\n * @returns `true`, `false`, or `undefined` when the value is unset or unrecognized\n */\nexport function parseBoolean(value: string | undefined): boolean | undefined {\n if (value === undefined) return undefined;\n const normalized = value.trim().toLowerCase();\n if (normalized === \"\") return undefined;\n if (TRUTHY_VALUES.has(normalized)) return true;\n if (FALSY_VALUES.has(normalized)) return false;\n return undefined;\n}\n","import { formatWithOptions, type InspectOptions } from \"node:util\";\nimport chalk from \"chalk\";\nimport { formatDistanceToNowStrict } from \"date-fns\";\nimport { getBorderCharacters, table } from \"table\";\nimport { parseBoolean } from \"./parse-boolean\";\n\n/**\n * Error thrown when a prompt is attempted in a CI environment\n */\nexport class CIPromptError extends Error {\n constructor(message?: string) {\n super(\n message ??\n \"Interactive prompts are not available in CI environments. Use --yes flag to skip confirmation prompts.\",\n );\n this.name = \"CIPromptError\";\n }\n}\n\n/**\n * Semantic style functions for inline text styling\n */\nexport const styles = {\n // Status colors\n success: chalk.green,\n error: chalk.red,\n warning: chalk.yellow,\n info: chalk.cyan,\n\n // Action colors (for change sets)\n create: chalk.green,\n update: chalk.yellow,\n delete: chalk.red,\n unchanged: chalk.gray,\n\n // Emphasis\n bold: chalk.bold,\n dim: chalk.gray,\n highlight: chalk.cyanBright,\n successBright: chalk.greenBright,\n errorBright: chalk.redBright,\n\n // Resource types\n resourceType: chalk.bold,\n resourceName: chalk.cyan,\n\n // File paths\n path: chalk.cyan,\n\n // Values\n value: chalk.white,\n placeholder: chalk.gray.italic,\n};\n\n/**\n * Standardized symbols for CLI output\n */\nexport const symbols = {\n success: chalk.green(\"\\u2713\"),\n error: chalk.red(\"\\u2716\"),\n warning: chalk.yellow(\"\\u26a0\"),\n info: chalk.cyan(\"i\"),\n create: chalk.green(\"+\"),\n update: chalk.yellow(\"~\"),\n delete: chalk.red(\"-\"),\n replace: chalk.magenta(\"\\u00b1\"),\n bullet: chalk.gray(\"\\u2022\"),\n arrow: chalk.gray(\"\\u2192\"),\n};\n\n/**\n * Log output modes\n */\nexport type LogMode = \"default\" | \"stream\" | \"plain\";\n\nexport interface LogOptions {\n /** Output mode (default: \"default\") */\n mode?: LogMode;\n /** Number of spaces to indent the entire line (default: 0) */\n indent?: number;\n}\n\n/** Field transformer function. null excludes the field from table output. */\nexport type FieldTransformer = ((value: unknown, item: object) => string) | null;\n\nexport interface OutOptions {\n /** Table display field transform/exclude settings. Only applied in table mode (not JSON). */\n display?: Record<string, FieldTransformer>;\n\n /** Show null values in table output (default: false) */\n showNull?: boolean;\n}\n\n// In JSON mode, all logs go to stderr to keep stdout clean for JSON data\nlet _jsonMode = false;\n\n// Type icons for log output\nconst TYPE_ICONS: Record<string, string> = {\n info: \"ℹ\",\n success: \"✔\",\n warn: \"⚠\",\n error: \"✖\",\n debug: \"⚙\",\n trace: \"→\",\n log: \"\",\n};\n\n// Color functions for icon and message text\nconst TYPE_COLORS: Record<string, (text: string) => string> = {\n info: chalk.cyan,\n success: chalk.green,\n warn: chalk.yellow,\n error: chalk.red,\n debug: chalk.gray,\n trace: chalk.gray,\n log: (text) => text,\n};\n\ninterface FormatLogLineOptions {\n mode: string;\n indent: number;\n type: string;\n message: string;\n timestamp?: string;\n}\n\n/**\n * Formats a log line with the appropriate prefix and indentation\n * @param opts - Formatting options\n * @returns Formatted log line\n */\nexport function formatLogLine(opts: FormatLogLineOptions): string {\n const { mode, indent, type, message, timestamp } = opts;\n const indentPrefix = indent > 0 ? \" \".repeat(indent) : \"\";\n const colorFn = TYPE_COLORS[type] || ((text: string) => text);\n\n // Plain mode: color only, no icon, no timestamp\n if (mode === \"plain\") {\n return `${indentPrefix}${colorFn(message)}\\n`;\n }\n\n // Default/Stream mode: with icon and color\n const icon = TYPE_ICONS[type] || \"\";\n const prefix = icon ? `${icon} ` : \"\";\n const coloredOutput = colorFn(`${prefix}${message}`);\n const timestampPrefix = timestamp ?? \"\";\n\n return `${indentPrefix}${timestampPrefix}${coloredOutput}\\n`;\n}\n\n/**\n * Writes a formatted log line to stderr.\n * @param type - Log type (info, success, warn, error, log)\n * @param message - Log message\n * @param opts - Log options (mode and indent)\n */\nfunction writeLog(type: string, message: string, opts?: LogOptions): void {\n const mode = opts?.mode ?? \"default\";\n const indent = opts?.indent ?? 0;\n const inspectOpts: InspectOptions = {\n breakLength: process.stdout.columns || 80,\n };\n const formattedMessage = formatWithOptions(inspectOpts, message);\n const timestamp = mode === \"stream\" ? `${new Date().toLocaleTimeString()} ` : \"\";\n const output = formatLogLine({ mode, indent, type, message: formattedMessage, timestamp });\n process.stderr.write(output);\n}\n\nexport const logger = {\n get jsonMode(): boolean {\n return _jsonMode;\n },\n set jsonMode(value: boolean) {\n _jsonMode = value;\n },\n\n info(message: string, opts?: LogOptions): void {\n writeLog(\"info\", message, opts);\n },\n\n success(message: string, opts?: LogOptions): void {\n writeLog(\"success\", message, opts);\n },\n\n warn(message: string, opts?: LogOptions): void {\n writeLog(\"warn\", message, opts);\n },\n\n error(message: string, opts?: LogOptions): void {\n writeLog(\"error\", message, opts);\n },\n\n log(message: string): void {\n writeLog(\"log\", message, { mode: \"plain\" });\n },\n\n newline(): void {\n process.stderr.write(\"\\n\");\n },\n\n debug(message: string): void {\n if (parseBoolean(process.env.DEBUG) === true) {\n writeLog(\"log\", styles.dim(message), { mode: \"plain\" });\n }\n },\n\n out(data: string | object | object[], options?: OutOptions): void {\n if (typeof data === \"string\") {\n process.stdout.write(data.endsWith(\"\\n\") ? data : data + \"\\n\");\n return;\n }\n\n if (this.jsonMode) {\n // eslint-disable-next-line no-restricted-syntax\n console.log(JSON.stringify(data));\n return;\n }\n\n const display = options?.display;\n\n // Helper to format a value for table display\n const formatValue = (value: unknown, pretty = false): string => {\n if (options?.showNull && value === null) return \"NULL\";\n if (value === null || value === undefined) return \"N/A\";\n if (value instanceof Date) {\n return formatDistanceToNowStrict(value, { addSuffix: true });\n }\n if (typeof value === \"object\") {\n return pretty ? JSON.stringify(value, null, 2) : JSON.stringify(value);\n }\n return String(value);\n };\n\n // Helper to check if field should be excluded\n const isExcluded = (key: string): boolean => {\n return display !== undefined && key in display && display[key] === null;\n };\n\n // Helper to apply transformer or default formatting\n const transformValue = (key: string, value: unknown, item: object, pretty = false): string => {\n if (display && key in display) {\n const transformer = display[key];\n if (transformer) {\n return transformer(value, item);\n }\n }\n return formatValue(value, pretty);\n };\n\n if (!Array.isArray(data)) {\n const entries = Object.entries(data).filter(([key]) => !isExcluded(key));\n const formattedEntries = entries.map(([key, value]) => [\n key,\n transformValue(key, value, data, true),\n ]);\n const t = table(formattedEntries, {\n singleLine: false,\n border: getBorderCharacters(\"norc\"),\n });\n process.stdout.write(t);\n return;\n }\n\n if (data.length === 0) {\n return;\n }\n\n const allHeaders = Array.from(new Set(data.flatMap((item) => Object.keys(item))));\n const headers = allHeaders.filter((h) => !isExcluded(h));\n const rows = data.map((item) =>\n headers.map((header) =>\n transformValue(header, (item as Record<string, unknown>)[header], item),\n ),\n );\n\n const t = table([headers, ...rows], {\n border: getBorderCharacters(\"norc\"),\n drawHorizontalLine: (lineIndex, rowCount) => {\n return lineIndex === 0 || lineIndex === 1 || lineIndex === rowCount;\n },\n });\n process.stdout.write(t);\n },\n};\n"],"mappings":"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"}