@tailor-platform/sdk 2.1.0 → 2.2.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.
- package/CHANGELOG.md +84 -0
- package/{dist/cli/index.mjs → bin/tailor.mjs} +1 -1
- package/dist/{application-D77KJFKD.mjs → application-BpLeawBg.mjs} +6 -6
- package/dist/{application-D77KJFKD.mjs.map → application-BpLeawBg.mjs.map} +1 -1
- package/dist/application-BxLLiLsr.mjs +3 -0
- package/dist/cli/commands/deploy/tailordb/index.d.mts +2 -1
- package/dist/cli/commands/deploy/types.d.mts +2 -1
- package/dist/cli/commands/tailordb/migrate/diff-calculator.d.mts +11 -4
- package/dist/cli/commands/tailordb/migrate/file-state.d.mts +1 -0
- package/dist/cli/commands/tailordb/migrate/schema-checks.d.mts +2 -2
- package/dist/cli/commands/tailordb/migrate/snapshot-types.d.mts +8 -1
- package/dist/cli/commands/tailordb/migrate/snapshot.d.mts +5 -3
- package/dist/cli/lib.d.mts +4 -4
- package/dist/cli/lib.mjs +3 -482
- package/dist/cli/lib.mjs.map +1 -1
- package/dist/cli/main.mjs +975 -193
- package/dist/cli/main.mjs.map +1 -1
- package/dist/completion/zsh-worker.zsh +145 -2
- package/dist/configure/index.d.mts +2 -2
- package/dist/configure/services/index.d.mts +2 -1
- package/dist/configure/services/tailordb/index.d.mts +2 -1
- package/dist/configure/services/tailordb/schema.d.mts +46 -46
- package/dist/configure/services/tailordb/types.d.mts +30 -4
- package/dist/{crashreport-B5LqCTfF.mjs → crashreport-CIIfLnoO.mjs} +2 -2
- package/dist/{crashreport-B5LqCTfF.mjs.map → crashreport-CIIfLnoO.mjs.map} +1 -1
- package/dist/{crashreport-eI7ty7ok.mjs → crashreport-CINZ5dVN.mjs} +1 -1
- package/dist/errors-CWj21238.mjs +75 -0
- package/dist/errors-CWj21238.mjs.map +1 -0
- package/dist/kysely/index.d.mts +52 -5
- package/dist/kysely/index.mjs +7 -2
- package/dist/kysely/index.mjs.map +1 -1
- package/dist/{logger-CXQq9YIp.mjs → logger-DSdExfor.mjs} +83 -42
- package/dist/logger-DSdExfor.mjs.map +1 -0
- package/dist/plugin/builtin/seed/index.mjs +1 -1
- package/dist/{register-ts-hook-BU18uU44.mjs → register-ts-hook-CTth1eqj.mjs} +1587 -272
- package/dist/register-ts-hook-CTth1eqj.mjs.map +1 -0
- package/dist/schema--xYWRGfe.mjs.map +1 -1
- package/dist/seed/index.d.mts +52 -3
- package/dist/seed/index.mjs +200 -44
- package/dist/seed/index.mjs.map +1 -1
- package/dist/{seed-B-yckgQY.mjs → seed-xqM9WIHP.mjs} +8 -8
- package/dist/seed-xqM9WIHP.mjs.map +1 -0
- package/dist/{service-B5WynBHQ.mjs → service-CCwl3Avt.mjs} +3 -3
- package/dist/{service-B5WynBHQ.mjs.map → service-CCwl3Avt.mjs.map} +1 -1
- package/dist/service-_XmjSEGr.mjs +3 -0
- package/dist/{service-k1xy_A5G.mjs → service-goqlJJgA.mjs} +2 -2
- package/dist/{service-k1xy_A5G.mjs.map → service-goqlJJgA.mjs.map} +1 -1
- package/dist/{service_pb-D5--My_M.mjs → service_pb-BEWj1pOV.mjs} +2 -2
- package/dist/{service_pb-D5--My_M.mjs.map → service_pb-BEWj1pOV.mjs.map} +1 -1
- package/dist/{service_pb-i8CmnQP4.mjs → service_pb-BjlhvK9E.mjs} +1 -1
- package/dist/utils/test/index.d.mts +6 -3
- package/dist/utils/test/index.mjs +25 -13
- package/dist/utils/test/index.mjs.map +1 -1
- package/dist/vitest/index.d.mts +2 -1
- package/dist/vitest/index.mjs +84 -2
- package/dist/vitest/index.mjs.map +1 -1
- package/dist/vitest/mocks/file.d.mts +1 -1
- package/dist/vitest/pglite-kysely.d.mts +43 -0
- package/dist/{workspace_resource_pb-DXnO2AT-.mjs → workspace_resource_pb-HNIL_Vfj.mjs} +10 -2
- package/dist/{workspace_resource_pb-DXnO2AT-.mjs.map → workspace_resource_pb-HNIL_Vfj.mjs.map} +1 -1
- package/docs/cli/tailordb.md +87 -22
- package/docs/cli-reference.md +13 -11
- package/docs/configuration.md +1 -1
- package/docs/migration/v2.md +1 -1
- package/docs/plugin/custom.md +48 -48
- package/docs/plugin/index.md +24 -24
- package/docs/services/auth.md +10 -10
- package/docs/services/executor.md +1 -1
- package/docs/services/resolver.md +2 -2
- package/docs/services/tailordb-migration.md +375 -76
- package/docs/services/tailordb.md +28 -28
- package/docs/testing.md +2 -0
- package/package.json +12 -7
- package/dist/application-Af1zIqSI.mjs +0 -3
- package/dist/errors-D7583Zz7.mjs +0 -58
- package/dist/errors-D7583Zz7.mjs.map +0 -1
- package/dist/logger-CXQq9YIp.mjs.map +0 -1
- package/dist/register-ts-hook-BU18uU44.mjs.map +0 -1
- package/dist/seed-B-yckgQY.mjs.map +0 -1
- package/dist/service-M7OYziQP.mjs +0 -3
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { i as file_tailor_v1_service, n as PingRequestSchema, r as PingResponseSchema, t as OperatorService } from "./service_pb-
|
|
1
|
+
import { i as file_tailor_v1_service, n as PingRequestSchema, r as PingResponseSchema, t as OperatorService } from "./service_pb-BEWj1pOV.mjs";
|
|
2
2
|
|
|
3
3
|
export { OperatorService, PingRequestSchema, PingResponseSchema, file_tailor_v1_service };
|
|
@@ -17,14 +17,17 @@ import { StandardSchemaV1 } from "@standard-schema/spec";
|
|
|
17
17
|
*/
|
|
18
18
|
declare function createTailorDBHook<T extends TailorDBType<any, any>>(type: T): (data: unknown, now?: Date) => Partial<output<T>>;
|
|
19
19
|
/**
|
|
20
|
-
* Creates the standard schema definition
|
|
21
|
-
*
|
|
20
|
+
* Creates the standard schema definition used to validate seed rows.
|
|
21
|
+
* Runs the hook, then the type's own `validate`, and the field schema only when
|
|
22
|
+
* that reported nothing, so both levels of validation report as issues rather
|
|
23
|
+
* than by throwing.
|
|
22
24
|
* @template T - The output type after validation
|
|
23
25
|
* @param schemaType - TailorDB field schema for validation
|
|
24
26
|
* @param hook - Hook function to transform data before validation
|
|
27
|
+
* @param type - TailorDB type definition, when it carries a type-level `validate`
|
|
25
28
|
* @returns Schema object with ~standard section for defineSchema
|
|
26
29
|
*/
|
|
27
|
-
declare function createStandardSchema<T = Record<string, unknown>>(schemaType: TailorField<any, T>, hook: (data: unknown) => Partial<T>): {
|
|
30
|
+
declare function createStandardSchema<T = Record<string, unknown>>(schemaType: TailorField<any, T>, hook: (data: unknown) => Partial<T>, type?: TailorDBType<any, any>): {
|
|
28
31
|
readonly "~standard": {
|
|
29
32
|
readonly version: 1;
|
|
30
33
|
readonly vendor: "@tailor-platform/sdk";
|
|
@@ -55,33 +55,45 @@ function createTailorDBHook(type) {
|
|
|
55
55
|
});
|
|
56
56
|
if (overrides && typeof overrides === "object") for (const [key, value] of Object.entries(overrides)) setField(hooked, key, value instanceof Date ? value.toISOString() : value);
|
|
57
57
|
}
|
|
58
|
-
if (type.metadata?.typeValidate) {
|
|
59
|
-
const { id: _id, ...newRecord } = hooked;
|
|
60
|
-
type.metadata.typeValidate({
|
|
61
|
-
newRecord,
|
|
62
|
-
oldRecord: null,
|
|
63
|
-
invoker: null
|
|
64
|
-
}, (field, message) => {
|
|
65
|
-
throw new Error(`Validation failed on field '${field}': ${message}`);
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
58
|
return hooked;
|
|
69
59
|
};
|
|
70
60
|
}
|
|
61
|
+
function typeLevelIssues(type, hooked) {
|
|
62
|
+
const typeValidate = type?.metadata?.typeValidate;
|
|
63
|
+
if (!typeValidate) return [];
|
|
64
|
+
const { id: _id, ...newRecord } = hooked;
|
|
65
|
+
const issues = [];
|
|
66
|
+
typeValidate({
|
|
67
|
+
newRecord,
|
|
68
|
+
oldRecord: null,
|
|
69
|
+
invoker: null
|
|
70
|
+
}, (field, message) => {
|
|
71
|
+
issues.push({
|
|
72
|
+
message,
|
|
73
|
+
path: [field]
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
return issues;
|
|
77
|
+
}
|
|
71
78
|
/**
|
|
72
|
-
* Creates the standard schema definition
|
|
73
|
-
*
|
|
79
|
+
* Creates the standard schema definition used to validate seed rows.
|
|
80
|
+
* Runs the hook, then the type's own `validate`, and the field schema only when
|
|
81
|
+
* that reported nothing, so both levels of validation report as issues rather
|
|
82
|
+
* than by throwing.
|
|
74
83
|
* @template T - The output type after validation
|
|
75
84
|
* @param schemaType - TailorDB field schema for validation
|
|
76
85
|
* @param hook - Hook function to transform data before validation
|
|
86
|
+
* @param type - TailorDB type definition, when it carries a type-level `validate`
|
|
77
87
|
* @returns Schema object with ~standard section for defineSchema
|
|
78
88
|
*/
|
|
79
|
-
function createStandardSchema(schemaType, hook) {
|
|
89
|
+
function createStandardSchema(schemaType, hook, type) {
|
|
80
90
|
return { "~standard": {
|
|
81
91
|
version: 1,
|
|
82
92
|
vendor: "@tailor-platform/sdk",
|
|
83
93
|
validate: (value) => {
|
|
84
94
|
const hooked = hook(value);
|
|
95
|
+
const issues = typeLevelIssues(type, hooked);
|
|
96
|
+
if (issues.length > 0) return { issues };
|
|
85
97
|
const result = schemaType.parse({
|
|
86
98
|
value: hooked,
|
|
87
99
|
data: hooked,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../../src/utils/test/index.ts"],"sourcesContent":["import type { output } from \"#/configure/index\";\nimport type { TailorDBType } from \"#/configure/services/tailordb/schema\";\nimport type { TailorField } from \"#/configure/types/type\";\nimport type { StandardSchemaV1 } from \"@standard-schema/spec\";\n\n// Not `record[key] = value`: assigning to `__proto__` goes through the inherited\n// setter, which mutates the prototype instead of recording the field and leaves\n// no own property behind for the value to be read from.\nfunction setField(record: Record<string, unknown>, key: string, value: unknown): void {\n Object.defineProperty(record, key, {\n value,\n enumerable: true,\n writable: true,\n configurable: true,\n });\n}\n\n/**\n * Creates a hook function that processes TailorDB type fields\n * - Uses existing id from data if provided, otherwise generates UUID for id fields\n * - Recursively processes nested types\n * - Executes hooks.create for fields with create hooks\n * - Takes each field from the data's own properties, so a field named after a\n * member of `Object` such as `toString` is read from the record rather than\n * from the prototype\n * @template T - The output type of the hook function\n * @param type - TailorDB type definition\n * @returns A function that transforms input data according to field hooks\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function createTailorDBHook<T extends TailorDBType<any, any>>(type: T) {\n return (data: unknown, now: Date = new Date()) => {\n const obj = data && typeof data === \"object\" ? (data as Record<string, unknown>) : undefined;\n const hooked = Object.entries(type.fields).reduce(\n (hooked, [key, value]) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const field = value as TailorField<any, any, any>;\n // `Object.hasOwn`, not `obj?.[key]`: a field named after an Object member\n // such as `toString` would otherwise read the inherited value.\n const input = obj && Object.hasOwn(obj, key) ? obj[key] : undefined;\n let hookedValue: unknown;\n if (key === \"id\") {\n hookedValue = input ?? crypto.randomUUID();\n } else if (field.type === \"nested\") {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const nestedHook = createTailorDBHook({ fields: field.fields } as any);\n if (field.metadata.array) {\n hookedValue = Array.isArray(input) ? input.map((item) => nestedHook(item, now)) : input;\n } else {\n hookedValue = nestedHook(input, now);\n }\n } else if (field.metadata.hooks?.create) {\n hookedValue = field.metadata.hooks.create({ input, invoker: null, now });\n if (hookedValue instanceof Date) {\n hookedValue = hookedValue.toISOString();\n }\n } else {\n hookedValue = input;\n }\n if (hookedValue == null && field.metadata.default !== undefined) {\n const isTimeType =\n field.type === \"datetime\" || field.type === \"date\" || field.type === \"time\";\n hookedValue =\n field.metadata.default === \"now\" && isTimeType\n ? now.toISOString()\n : field.metadata.default;\n }\n // Set even when there is no value: the key carrying `undefined` is what\n // tells a schema inferred from the record that the column is nullable,\n // and it shadows a same-named member of `Object.prototype`.\n setField(hooked, key, hookedValue);\n return hooked;\n },\n {} as Record<string, unknown>,\n );\n\n // oxlint-disable-next-line typescript/no-unnecessary-condition -- metadata absent in recursive nested calls\n if (type.metadata?.typeHook?.create) {\n const { id: _id, ...typeHookInput } = hooked;\n // oxlint-disable-next-line typescript/no-unsafe-function-type\n const overrides = (type.metadata.typeHook.create as Function)({\n input: typeHookInput,\n invoker: null,\n now,\n });\n if (overrides && typeof overrides === \"object\") {\n for (const [key, value] of Object.entries(overrides as Record<string, unknown>)) {\n setField(hooked, key, value instanceof Date ? value.toISOString() : value);\n }\n }\n }\n\n // oxlint-disable-next-line typescript/no-unnecessary-condition --
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../../src/utils/test/index.ts"],"sourcesContent":["import type { output } from \"#/configure/index\";\nimport type { TailorDBType } from \"#/configure/services/tailordb/schema\";\nimport type { TailorField } from \"#/configure/types/type\";\nimport type { StandardSchemaV1 } from \"@standard-schema/spec\";\n\n// Not `record[key] = value`: assigning to `__proto__` goes through the inherited\n// setter, which mutates the prototype instead of recording the field and leaves\n// no own property behind for the value to be read from.\nfunction setField(record: Record<string, unknown>, key: string, value: unknown): void {\n Object.defineProperty(record, key, {\n value,\n enumerable: true,\n writable: true,\n configurable: true,\n });\n}\n\n/**\n * Creates a hook function that processes TailorDB type fields\n * - Uses existing id from data if provided, otherwise generates UUID for id fields\n * - Recursively processes nested types\n * - Executes hooks.create for fields with create hooks\n * - Takes each field from the data's own properties, so a field named after a\n * member of `Object` such as `toString` is read from the record rather than\n * from the prototype\n * @template T - The output type of the hook function\n * @param type - TailorDB type definition\n * @returns A function that transforms input data according to field hooks\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function createTailorDBHook<T extends TailorDBType<any, any>>(type: T) {\n return (data: unknown, now: Date = new Date()) => {\n const obj = data && typeof data === \"object\" ? (data as Record<string, unknown>) : undefined;\n const hooked = Object.entries(type.fields).reduce(\n (hooked, [key, value]) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const field = value as TailorField<any, any, any>;\n // `Object.hasOwn`, not `obj?.[key]`: a field named after an Object member\n // such as `toString` would otherwise read the inherited value.\n const input = obj && Object.hasOwn(obj, key) ? obj[key] : undefined;\n let hookedValue: unknown;\n if (key === \"id\") {\n hookedValue = input ?? crypto.randomUUID();\n } else if (field.type === \"nested\") {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const nestedHook = createTailorDBHook({ fields: field.fields } as any);\n if (field.metadata.array) {\n hookedValue = Array.isArray(input) ? input.map((item) => nestedHook(item, now)) : input;\n } else {\n hookedValue = nestedHook(input, now);\n }\n } else if (field.metadata.hooks?.create) {\n hookedValue = field.metadata.hooks.create({ input, invoker: null, now });\n if (hookedValue instanceof Date) {\n hookedValue = hookedValue.toISOString();\n }\n } else {\n hookedValue = input;\n }\n if (hookedValue == null && field.metadata.default !== undefined) {\n const isTimeType =\n field.type === \"datetime\" || field.type === \"date\" || field.type === \"time\";\n hookedValue =\n field.metadata.default === \"now\" && isTimeType\n ? now.toISOString()\n : field.metadata.default;\n }\n // Set even when there is no value: the key carrying `undefined` is what\n // tells a schema inferred from the record that the column is nullable,\n // and it shadows a same-named member of `Object.prototype`.\n setField(hooked, key, hookedValue);\n return hooked;\n },\n {} as Record<string, unknown>,\n );\n\n // oxlint-disable-next-line typescript/no-unnecessary-condition -- metadata absent in recursive nested calls\n if (type.metadata?.typeHook?.create) {\n const { id: _id, ...typeHookInput } = hooked;\n // oxlint-disable-next-line typescript/no-unsafe-function-type\n const overrides = (type.metadata.typeHook.create as Function)({\n input: typeHookInput,\n invoker: null,\n now,\n });\n if (overrides && typeof overrides === \"object\") {\n for (const [key, value] of Object.entries(overrides as Record<string, unknown>)) {\n setField(hooked, key, value instanceof Date ? value.toISOString() : value);\n }\n }\n }\n\n return hooked as Partial<output<T>>;\n };\n}\n\n// Collect the issues the type's own `validate` reports for a record, so they\n// surface the same way a field's do instead of ending the run.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction typeLevelIssues(type: TailorDBType<any, any> | undefined, hooked: unknown) {\n // oxlint-disable-next-line typescript/no-unnecessary-condition -- absent on a nested type\n const typeValidate = type?.metadata?.typeValidate;\n if (!typeValidate) {\n return [];\n }\n const { id: _id, ...newRecord } = hooked as Record<string, unknown>;\n const issues: StandardSchemaV1.Issue[] = [];\n // oxlint-disable-next-line typescript/no-unsafe-function-type\n (typeValidate as Function)(\n { newRecord, oldRecord: null, invoker: null },\n (field: string, message: string) => {\n issues.push({ message, path: [field] });\n },\n );\n return issues;\n}\n\n/**\n * Creates the standard schema definition used to validate seed rows.\n * Runs the hook, then the type's own `validate`, and the field schema only when\n * that reported nothing, so both levels of validation report as issues rather\n * than by throwing.\n * @template T - The output type after validation\n * @param schemaType - TailorDB field schema for validation\n * @param hook - Hook function to transform data before validation\n * @param type - TailorDB type definition, when it carries a type-level `validate`\n * @returns Schema object with ~standard section for defineSchema\n */\nexport function createStandardSchema<T = Record<string, unknown>>(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n schemaType: TailorField<any, T>,\n hook: (data: unknown) => Partial<T>,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n type?: TailorDBType<any, any>,\n) {\n return {\n \"~standard\": {\n version: 1,\n vendor: \"@tailor-platform/sdk\",\n validate: (value: unknown) => {\n const hooked = hook(value);\n const issues = typeLevelIssues(type, hooked);\n if (issues.length > 0) {\n return { issues };\n }\n const result = schemaType.parse({\n value: hooked,\n data: hooked,\n invoker: null,\n });\n if (result.issues) {\n return result;\n }\n return { value: hooked as T };\n },\n },\n } as const satisfies StandardSchemaV1<T>;\n}\n"],"mappings":";AAQA,SAAS,SAAS,QAAiC,KAAa,OAAsB;CACpF,OAAO,eAAe,QAAQ,KAAK;EACjC;EACA,YAAY;EACZ,UAAU;EACV,cAAc;CAChB,CAAC;AACH;;;;;;;;;;;;;AAeA,SAAgB,mBAAqD,MAAS;CAC5E,QAAQ,MAAe,sBAAY,IAAI,KAAK,MAAM;EAChD,MAAM,MAAM,QAAQ,OAAO,SAAS,WAAY,OAAmC;EACnF,MAAM,SAAS,OAAO,QAAQ,KAAK,MAAM,CAAC,CAAC,QACxC,QAAQ,CAAC,KAAK,WAAW;GAExB,MAAM,QAAQ;GAGd,MAAM,QAAQ,OAAO,OAAO,OAAO,KAAK,GAAG,IAAI,IAAI,OAAO;GAC1D,IAAI;GACJ,IAAI,QAAQ,MACV,cAAc,SAAS,OAAO,WAAW;QACpC,IAAI,MAAM,SAAS,UAAU;IAElC,MAAM,aAAa,mBAAmB,EAAE,QAAQ,MAAM,OAAO,CAAQ;IACrE,IAAI,MAAM,SAAS,OACjB,cAAc,MAAM,QAAQ,KAAK,IAAI,MAAM,KAAK,SAAS,WAAW,MAAM,GAAG,CAAC,IAAI;SAElF,cAAc,WAAW,OAAO,GAAG;GAEvC,OAAO,IAAI,MAAM,SAAS,OAAO,QAAQ;IACvC,cAAc,MAAM,SAAS,MAAM,OAAO;KAAE;KAAO,SAAS;KAAM;IAAI,CAAC;IACvE,IAAI,uBAAuB,MACzB,cAAc,YAAY,YAAY;GAE1C,OACE,cAAc;GAEhB,IAAI,eAAe,QAAQ,MAAM,SAAS,YAAY,QAAW;IAC/D,MAAM,aACJ,MAAM,SAAS,cAAc,MAAM,SAAS,UAAU,MAAM,SAAS;IACvE,cACE,MAAM,SAAS,YAAY,SAAS,aAChC,IAAI,YAAY,IAChB,MAAM,SAAS;GACvB;GAIA,SAAS,QAAQ,KAAK,WAAW;GACjC,OAAO;EACT,GACA,CAAC,CACH;EAGA,IAAI,KAAK,UAAU,UAAU,QAAQ;GACnC,MAAM,EAAE,IAAI,KAAK,GAAG,kBAAkB;GAEtC,MAAM,YAAa,KAAK,SAAS,SAAS,OAAoB;IAC5D,OAAO;IACP,SAAS;IACT;GACF,CAAC;GACD,IAAI,aAAa,OAAO,cAAc,UACpC,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,SAAoC,GAC5E,SAAS,QAAQ,KAAK,iBAAiB,OAAO,MAAM,YAAY,IAAI,KAAK;EAG/E;EAEA,OAAO;CACT;AACF;AAKA,SAAS,gBAAgB,MAA0C,QAAiB;CAElF,MAAM,eAAe,MAAM,UAAU;CACrC,IAAI,CAAC,cACH,OAAO,CAAC;CAEV,MAAM,EAAE,IAAI,KAAK,GAAG,cAAc;CAClC,MAAM,SAAmC,CAAC;CAE1C,AAAC,aACC;EAAE;EAAW,WAAW;EAAM,SAAS;CAAK,IAC3C,OAAe,YAAoB;EAClC,OAAO,KAAK;GAAE;GAAS,MAAM,CAAC,KAAK;EAAE,CAAC;CACxC,CACF;CACA,OAAO;AACT;;;;;;;;;;;;AAaA,SAAgB,qBAEd,YACA,MAEA,MACA;CACA,OAAO,EACL,aAAa;EACX,SAAS;EACT,QAAQ;EACR,WAAW,UAAmB;GAC5B,MAAM,SAAS,KAAK,KAAK;GACzB,MAAM,SAAS,gBAAgB,MAAM,MAAM;GAC3C,IAAI,OAAO,SAAS,GAClB,OAAO,EAAE,OAAO;GAElB,MAAM,SAAS,WAAW,MAAM;IAC9B,OAAO;IACP,MAAM;IACN,SAAS;GACX,CAAC;GACD,IAAI,OAAO,QACT,OAAO;GAET,OAAO,EAAE,OAAO,OAAY;EAC9B;CACF,EACF;AACF"}
|
package/dist/vitest/index.d.mts
CHANGED
|
@@ -10,6 +10,7 @@ import { mockWorkflow } from "./mocks/workflow.mjs";
|
|
|
10
10
|
import "./mock.mjs";
|
|
11
11
|
import { RunWorkflowLocallyOptions, runWorkflowLocally } from "./workflow-local.mjs";
|
|
12
12
|
import { ExecutedQuery, KyselyMock, createKyselyMock } from "./mock-kysely.mjs";
|
|
13
|
+
import { PGliteClient, createKyselyPGlite } from "./pglite-kysely.mjs";
|
|
13
14
|
import { Plugin } from "vitest/config";
|
|
14
15
|
//#region src/vitest/index.d.ts
|
|
15
16
|
/**
|
|
@@ -71,4 +72,4 @@ declare function tailorRuntime(options?: {
|
|
|
71
72
|
config?: string;
|
|
72
73
|
}): Plugin[];
|
|
73
74
|
//#endregion
|
|
74
|
-
export { type ExecutedQuery, type KyselyMock, type MockAigatewayOptions, type MockAuthconnectionOptions, type MockFileOptions, type MockIconvOptions, type MockIdpOptions, type MockLoggerOptions, type MockSecretmanagerOptions, type MockTailordbOptions, type QueryBehavior, type QueryMatch, type QueryMatcher, type RunWorkflowLocallyOptions, createKyselyMock, mockAigateway, mockAuthconnection, mockFile, mockIconv, mockIdp, mockLogger, mockSecretmanager, mockTailordb, mockWorkflow, runWorkflowLocally, tailorRuntime };
|
|
75
|
+
export { type ExecutedQuery, type KyselyMock, type MockAigatewayOptions, type MockAuthconnectionOptions, type MockFileOptions, type MockIconvOptions, type MockIdpOptions, type MockLoggerOptions, type MockSecretmanagerOptions, type MockTailordbOptions, type PGliteClient, type QueryBehavior, type QueryMatch, type QueryMatcher, type RunWorkflowLocallyOptions, createKyselyMock, createKyselyPGlite, mockAigateway, mockAuthconnection, mockFile, mockIconv, mockIdp, mockLogger, mockSecretmanager, mockTailordb, mockWorkflow, runWorkflowLocally, tailorRuntime };
|
package/dist/vitest/index.mjs
CHANGED
|
@@ -6,7 +6,7 @@ import { t as platformSerialize } from "../platform-serialize-RoRtBS0v.mjs";
|
|
|
6
6
|
import { i as withDispose, n as tailorRoot, r as tailordbRoot, t as mockSecretmanager } from "../secretmanager-IY4UvinW.mjs";
|
|
7
7
|
import { isEqual } from "es-toolkit";
|
|
8
8
|
import { fileURLToPath } from "node:url";
|
|
9
|
-
import { ColumnNode, InsertQueryNode, Kysely, PostgresAdapter, PostgresIntrospector, PostgresQueryCompiler, PrimitiveValueListNode, ReferenceNode, UpdateQueryNode, ValueListNode, ValueNode, ValuesNode } from "kysely";
|
|
9
|
+
import { ColumnNode, CompiledQuery, InsertQueryNode, Kysely, PostgresAdapter, PostgresIntrospector, PostgresQueryCompiler, PrimitiveValueListNode, ReferenceNode, UpdateQueryNode, ValueListNode, ValueNode, ValuesNode } from "kysely";
|
|
10
10
|
import { dirname, isAbsolute, matchesGlob, relative, resolve } from "node:path";
|
|
11
11
|
import { vi } from "vitest";
|
|
12
12
|
|
|
@@ -1751,6 +1751,88 @@ function createKyselyMock() {
|
|
|
1751
1751
|
};
|
|
1752
1752
|
}
|
|
1753
1753
|
|
|
1754
|
+
//#endregion
|
|
1755
|
+
//#region src/vitest/pglite-kysely.ts
|
|
1756
|
+
/**
|
|
1757
|
+
* Kysely adapter for running migration scripts against PGlite.
|
|
1758
|
+
*
|
|
1759
|
+
* Accepts the PGlite client structurally so the SDK does not depend on
|
|
1760
|
+
* `@electric-sql/pglite`; users install it themselves as a devDependency.
|
|
1761
|
+
*/
|
|
1762
|
+
var PGliteConnection = class {
|
|
1763
|
+
#client;
|
|
1764
|
+
constructor(client) {
|
|
1765
|
+
this.#client = client;
|
|
1766
|
+
}
|
|
1767
|
+
async executeQuery(compiledQuery) {
|
|
1768
|
+
const result = await this.#client.query(compiledQuery.sql, [...compiledQuery.parameters]);
|
|
1769
|
+
return {
|
|
1770
|
+
rows: result.rows,
|
|
1771
|
+
numAffectedRows: BigInt(result.affectedRows ?? 0)
|
|
1772
|
+
};
|
|
1773
|
+
}
|
|
1774
|
+
streamQuery() {
|
|
1775
|
+
throw new Error("createKyselyPGlite: streaming is not supported");
|
|
1776
|
+
}
|
|
1777
|
+
};
|
|
1778
|
+
var PGliteDriver = class {
|
|
1779
|
+
#client;
|
|
1780
|
+
constructor(client) {
|
|
1781
|
+
this.#client = client;
|
|
1782
|
+
}
|
|
1783
|
+
async init() {}
|
|
1784
|
+
async acquireConnection() {
|
|
1785
|
+
return new PGliteConnection(this.#client);
|
|
1786
|
+
}
|
|
1787
|
+
async beginTransaction(connection, settings) {
|
|
1788
|
+
const parts = settings.isolationLevel ? ["start transaction", `isolation level ${settings.isolationLevel}`] : ["begin"];
|
|
1789
|
+
if (settings.accessMode) parts.push(settings.accessMode);
|
|
1790
|
+
await connection.executeQuery(CompiledQuery.raw(parts.join(" ")));
|
|
1791
|
+
}
|
|
1792
|
+
async commitTransaction(connection) {
|
|
1793
|
+
await connection.executeQuery(CompiledQuery.raw("commit"));
|
|
1794
|
+
}
|
|
1795
|
+
async rollbackTransaction(connection) {
|
|
1796
|
+
await connection.executeQuery(CompiledQuery.raw("rollback"));
|
|
1797
|
+
}
|
|
1798
|
+
async releaseConnection() {}
|
|
1799
|
+
async destroy() {
|
|
1800
|
+
await this.#client.close();
|
|
1801
|
+
}
|
|
1802
|
+
};
|
|
1803
|
+
/**
|
|
1804
|
+
* Create a Kysely instance backed by a PGlite in-memory Postgres, for
|
|
1805
|
+
* executing a migration script's queries against real data in tests.
|
|
1806
|
+
* Pass the migration's schema as the type argument, e.g.
|
|
1807
|
+
* `createKyselyPGlite<Database>(new PGlite())`.
|
|
1808
|
+
*
|
|
1809
|
+
* PGlite runs full PostgreSQL while TailorDB supports a subset of it, so a
|
|
1810
|
+
* statement passing here can still be rejected by the platform; keep a
|
|
1811
|
+
* statement-level test (see `createKyselyMock`) alongside.
|
|
1812
|
+
* @param client - A `PGlite` instance from `@electric-sql/pglite`
|
|
1813
|
+
* @returns A Kysely instance that executes queries on the client and closes it on `destroy()`
|
|
1814
|
+
* @example
|
|
1815
|
+
* ```typescript
|
|
1816
|
+
* // migrations/0005/migrate.test.ts
|
|
1817
|
+
* import { PGlite } from "@electric-sql/pglite";
|
|
1818
|
+
* import { createKyselyPGlite } from "@tailor-platform/sdk/vitest";
|
|
1819
|
+
* import type { Database } from "./db";
|
|
1820
|
+
* import { main } from "./migrate";
|
|
1821
|
+
*
|
|
1822
|
+
* const db = createKyselyPGlite<Database>(new PGlite());
|
|
1823
|
+
* // create tables matching db.ts, insert rows, then:
|
|
1824
|
+
* await db.transaction().execute((trx) => main(trx));
|
|
1825
|
+
* ```
|
|
1826
|
+
*/
|
|
1827
|
+
function createKyselyPGlite(client) {
|
|
1828
|
+
return new Kysely({ dialect: {
|
|
1829
|
+
createAdapter: () => new PostgresAdapter(),
|
|
1830
|
+
createDriver: () => new PGliteDriver(client),
|
|
1831
|
+
createIntrospector: (db) => new PostgresIntrospector(db),
|
|
1832
|
+
createQueryCompiler: () => new PostgresQueryCompiler()
|
|
1833
|
+
} });
|
|
1834
|
+
}
|
|
1835
|
+
|
|
1754
1836
|
//#endregion
|
|
1755
1837
|
//#region src/vitest/index.ts
|
|
1756
1838
|
/**
|
|
@@ -1813,5 +1895,5 @@ function tailorRuntime(options) {
|
|
|
1813
1895
|
}
|
|
1814
1896
|
|
|
1815
1897
|
//#endregion
|
|
1816
|
-
export { createKyselyMock, mockAigateway, mockAuthconnection, mockFile, mockIconv, mockIdp, mockLogger, mockSecretmanager, mockTailordb, mockWorkflow, runWorkflowLocally, tailorRuntime };
|
|
1898
|
+
export { createKyselyMock, createKyselyPGlite, mockAigateway, mockAuthconnection, mockFile, mockIconv, mockIdp, mockLogger, mockSecretmanager, mockTailordb, mockWorkflow, runWorkflowLocally, tailorRuntime };
|
|
1817
1899
|
//# sourceMappingURL=index.mjs.map
|