@fragno-dev/db 0.0.1 → 0.1.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/.turbo/turbo-build.log +137 -13
- package/.turbo/turbo-test.log +36 -0
- package/CHANGELOG.md +7 -0
- package/dist/adapters/adapters.d.ts +18 -0
- package/dist/adapters/adapters.d.ts.map +1 -0
- package/dist/adapters/drizzle/drizzle-adapter.d.ts +21 -0
- package/dist/adapters/drizzle/drizzle-adapter.d.ts.map +1 -0
- package/dist/adapters/drizzle/drizzle-adapter.js +62 -0
- package/dist/adapters/drizzle/drizzle-adapter.js.map +1 -0
- package/dist/adapters/drizzle/drizzle-query.d.ts +17 -0
- package/dist/adapters/drizzle/drizzle-query.d.ts.map +1 -0
- package/dist/adapters/drizzle/drizzle-query.js +139 -0
- package/dist/adapters/drizzle/drizzle-query.js.map +1 -0
- package/dist/adapters/drizzle/drizzle-uow-compiler.d.ts +9 -0
- package/dist/adapters/drizzle/drizzle-uow-compiler.d.ts.map +1 -0
- package/dist/adapters/drizzle/drizzle-uow-compiler.js +300 -0
- package/dist/adapters/drizzle/drizzle-uow-compiler.js.map +1 -0
- package/dist/adapters/drizzle/drizzle-uow-decoder.js +82 -0
- package/dist/adapters/drizzle/drizzle-uow-decoder.js.map +1 -0
- package/dist/adapters/drizzle/drizzle-uow-executor.js +125 -0
- package/dist/adapters/drizzle/drizzle-uow-executor.js.map +1 -0
- package/dist/adapters/drizzle/generate.js +273 -0
- package/dist/adapters/drizzle/generate.js.map +1 -0
- package/dist/adapters/drizzle/join-column-utils.js +28 -0
- package/dist/adapters/drizzle/join-column-utils.js.map +1 -0
- package/dist/adapters/drizzle/shared.js +11 -0
- package/dist/adapters/drizzle/shared.js.map +1 -0
- package/dist/adapters/kysely/kysely-adapter.d.ts +23 -0
- package/dist/adapters/kysely/kysely-adapter.d.ts.map +1 -0
- package/dist/adapters/kysely/kysely-adapter.js +119 -0
- package/dist/adapters/kysely/kysely-adapter.js.map +1 -0
- package/dist/adapters/kysely/kysely-query-builder.js +306 -0
- package/dist/adapters/kysely/kysely-query-builder.js.map +1 -0
- package/dist/adapters/kysely/kysely-query-compiler.js +67 -0
- package/dist/adapters/kysely/kysely-query-compiler.js.map +1 -0
- package/dist/adapters/kysely/kysely-query.js +158 -0
- package/dist/adapters/kysely/kysely-query.js.map +1 -0
- package/dist/adapters/kysely/kysely-uow-compiler.js +139 -0
- package/dist/adapters/kysely/kysely-uow-compiler.js.map +1 -0
- package/dist/adapters/kysely/kysely-uow-executor.js +89 -0
- package/dist/adapters/kysely/kysely-uow-executor.js.map +1 -0
- package/dist/adapters/kysely/migration/execute.js +176 -0
- package/dist/adapters/kysely/migration/execute.js.map +1 -0
- package/dist/fragment.d.ts +54 -0
- package/dist/fragment.d.ts.map +1 -0
- package/dist/fragment.js +92 -0
- package/dist/fragment.js.map +1 -0
- package/dist/id.d.ts +2 -0
- package/dist/migration-engine/auto-from-schema.js +116 -0
- package/dist/migration-engine/auto-from-schema.js.map +1 -0
- package/dist/migration-engine/create.d.ts +41 -0
- package/dist/migration-engine/create.d.ts.map +1 -0
- package/dist/migration-engine/create.js +58 -0
- package/dist/migration-engine/create.js.map +1 -0
- package/dist/migration-engine/shared.d.ts +90 -0
- package/dist/migration-engine/shared.d.ts.map +1 -0
- package/dist/migration-engine/shared.js +8 -0
- package/dist/migration-engine/shared.js.map +1 -0
- package/dist/mod.d.ts +55 -2
- package/dist/mod.d.ts.map +1 -1
- package/dist/mod.js +111 -2
- package/dist/mod.js.map +1 -1
- package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/column-builder.js +108 -0
- package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/column-builder.js.map +1 -0
- package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/column.js +55 -0
- package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/column.js.map +1 -0
- package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/entity.js +18 -0
- package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/entity.js.map +1 -0
- package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/pg-core/columns/common.js +183 -0
- package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/pg-core/columns/common.js.map +1 -0
- package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/pg-core/columns/enum.js +58 -0
- package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/pg-core/columns/enum.js.map +1 -0
- package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/pg-core/foreign-keys.js +68 -0
- package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/pg-core/foreign-keys.js.map +1 -0
- package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/pg-core/unique-constraint.js +56 -0
- package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/pg-core/unique-constraint.js.map +1 -0
- package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/pg-core/utils/array.js +65 -0
- package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/pg-core/utils/array.js.map +1 -0
- package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/sql/expressions/conditions.js +81 -0
- package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/sql/expressions/conditions.js.map +1 -0
- package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/sql/expressions/select.js +13 -0
- package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/sql/expressions/select.js.map +1 -0
- package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/sql/functions/aggregate.js +10 -0
- package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/sql/functions/aggregate.js.map +1 -0
- package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/sql/sql.js +372 -0
- package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/sql/sql.js.map +1 -0
- package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/subquery.js +23 -0
- package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/subquery.js.map +1 -0
- package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/table.js +62 -0
- package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/table.js.map +1 -0
- package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/table.utils.js +6 -0
- package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/table.utils.js.map +1 -0
- package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/tracing-utils.js +8 -0
- package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/tracing-utils.js.map +1 -0
- package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/tracing.js +8 -0
- package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/tracing.js.map +1 -0
- package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/view-common.js +6 -0
- package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/view-common.js.map +1 -0
- package/dist/query/condition-builder.d.ts +41 -0
- package/dist/query/condition-builder.d.ts.map +1 -0
- package/dist/query/condition-builder.js +93 -0
- package/dist/query/condition-builder.js.map +1 -0
- package/dist/query/cursor.d.ts +88 -0
- package/dist/query/cursor.d.ts.map +1 -0
- package/dist/query/cursor.js +103 -0
- package/dist/query/cursor.js.map +1 -0
- package/dist/query/orm/orm.d.ts +18 -0
- package/dist/query/orm/orm.d.ts.map +1 -0
- package/dist/query/orm/orm.js +48 -0
- package/dist/query/orm/orm.js.map +1 -0
- package/dist/query/query.d.ts +79 -0
- package/dist/query/query.d.ts.map +1 -0
- package/dist/query/query.js +1 -0
- package/dist/query/result-transform.js +155 -0
- package/dist/query/result-transform.js.map +1 -0
- package/dist/query/unit-of-work.d.ts +435 -0
- package/dist/query/unit-of-work.d.ts.map +1 -0
- package/dist/query/unit-of-work.js +549 -0
- package/dist/query/unit-of-work.js.map +1 -0
- package/dist/schema/create.d.ts +273 -116
- package/dist/schema/create.d.ts.map +1 -1
- package/dist/schema/create.js +410 -222
- package/dist/schema/create.js.map +1 -1
- package/dist/schema/serialize.js +101 -0
- package/dist/schema/serialize.js.map +1 -0
- package/dist/schema-generator/schema-generator.d.ts +15 -0
- package/dist/schema-generator/schema-generator.d.ts.map +1 -0
- package/dist/shared/providers.d.ts +6 -0
- package/dist/shared/providers.d.ts.map +1 -0
- package/dist/util/import-generator.js +26 -0
- package/dist/util/import-generator.js.map +1 -0
- package/dist/util/parse.js +15 -0
- package/dist/util/parse.js.map +1 -0
- package/dist/util/types.d.ts +8 -0
- package/dist/util/types.d.ts.map +1 -0
- package/package.json +63 -2
- package/src/adapters/adapters.ts +22 -0
- package/src/adapters/drizzle/drizzle-adapter-pglite.test.ts +433 -0
- package/src/adapters/drizzle/drizzle-adapter.test.ts +122 -0
- package/src/adapters/drizzle/drizzle-adapter.ts +118 -0
- package/src/adapters/drizzle/drizzle-query.ts +234 -0
- package/src/adapters/drizzle/drizzle-uow-compiler.test.ts +1084 -0
- package/src/adapters/drizzle/drizzle-uow-compiler.ts +546 -0
- package/src/adapters/drizzle/drizzle-uow-decoder.ts +165 -0
- package/src/adapters/drizzle/drizzle-uow-executor.ts +213 -0
- package/src/adapters/drizzle/generate.test.ts +643 -0
- package/src/adapters/drizzle/generate.ts +481 -0
- package/src/adapters/drizzle/join-column-utils.test.ts +79 -0
- package/src/adapters/drizzle/join-column-utils.ts +39 -0
- package/src/adapters/drizzle/migrate-drizzle.test.ts +226 -0
- package/src/adapters/drizzle/shared.ts +22 -0
- package/src/adapters/drizzle/test-utils.ts +56 -0
- package/src/adapters/kysely/kysely-adapter-pglite.test.ts +789 -0
- package/src/adapters/kysely/kysely-adapter.ts +196 -0
- package/src/adapters/kysely/kysely-query-builder.test.ts +1344 -0
- package/src/adapters/kysely/kysely-query-builder.ts +611 -0
- package/src/adapters/kysely/kysely-query-compiler.ts +124 -0
- package/src/adapters/kysely/kysely-query.ts +254 -0
- package/src/adapters/kysely/kysely-uow-compiler.test.ts +916 -0
- package/src/adapters/kysely/kysely-uow-compiler.ts +271 -0
- package/src/adapters/kysely/kysely-uow-executor.ts +149 -0
- package/src/adapters/kysely/kysely-uow-joins.test.ts +811 -0
- package/src/adapters/kysely/migration/execute-mysql.test.ts +1173 -0
- package/src/adapters/kysely/migration/execute-postgres.test.ts +2657 -0
- package/src/adapters/kysely/migration/execute.ts +382 -0
- package/src/adapters/kysely/migration/kysely-migrator.test.ts +197 -0
- package/src/fragment.test.ts +287 -0
- package/src/fragment.ts +198 -0
- package/src/migration-engine/auto-from-schema.test.ts +118 -58
- package/src/migration-engine/auto-from-schema.ts +103 -32
- package/src/migration-engine/create.test.ts +34 -46
- package/src/migration-engine/create.ts +41 -26
- package/src/migration-engine/shared.ts +26 -6
- package/src/mod.ts +197 -1
- package/src/query/condition-builder.test.ts +379 -0
- package/src/query/condition-builder.ts +294 -0
- package/src/query/cursor.test.ts +296 -0
- package/src/query/cursor.ts +147 -0
- package/src/query/orm/orm.ts +92 -0
- package/src/query/query-type.test.ts +429 -0
- package/src/query/query.ts +200 -0
- package/src/query/result-transform.test.ts +795 -0
- package/src/query/result-transform.ts +247 -0
- package/src/query/unit-of-work-types.test.ts +192 -0
- package/src/query/unit-of-work.test.ts +947 -0
- package/src/query/unit-of-work.ts +1199 -0
- package/src/schema/create.test.ts +653 -110
- package/src/schema/create.ts +708 -337
- package/src/schema/serialize.test.ts +559 -0
- package/src/schema/serialize.ts +359 -0
- package/src/schema-generator/schema-generator.ts +12 -0
- package/src/shared/config.ts +0 -8
- package/src/util/import-generator.ts +28 -0
- package/src/util/parse.ts +16 -0
- package/src/util/types.ts +4 -0
- package/tsconfig.json +1 -1
- package/tsdown.config.ts +11 -1
- package/vitest.config.ts +3 -0
- /package/dist/{cuid.js → id.js} +0 -0
- /package/src/{cuid.ts → id.ts} +0 -0
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
import { InternalIdColumn } from "../../schema/create.js";
|
|
2
|
+
import { schemaToDBType } from "../../schema/serialize.js";
|
|
3
|
+
import { importGenerator } from "../../util/import-generator.js";
|
|
4
|
+
import { ident, parseVarchar } from "../../util/parse.js";
|
|
5
|
+
|
|
6
|
+
//#region src/adapters/drizzle/generate.ts
|
|
7
|
+
const PROVIDER_IMPORTS = {
|
|
8
|
+
mysql: "drizzle-orm/mysql-core",
|
|
9
|
+
postgresql: "drizzle-orm/pg-core",
|
|
10
|
+
sqlite: "drizzle-orm/sqlite-core"
|
|
11
|
+
};
|
|
12
|
+
const PROVIDER_TABLE_FUNCTIONS = {
|
|
13
|
+
mysql: "mysqlTable",
|
|
14
|
+
postgresql: "pgTable",
|
|
15
|
+
sqlite: "sqliteTable"
|
|
16
|
+
};
|
|
17
|
+
function createContext(provider, idGeneratorImport) {
|
|
18
|
+
return {
|
|
19
|
+
provider,
|
|
20
|
+
imports: importGenerator(),
|
|
21
|
+
importSource: PROVIDER_IMPORTS[provider],
|
|
22
|
+
generatedCustomTypes: /* @__PURE__ */ new Set(),
|
|
23
|
+
idGeneratorImport
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
function generateCustomType(ctx, name, options) {
|
|
27
|
+
if (ctx.generatedCustomTypes.has(name)) return;
|
|
28
|
+
ctx.imports.addImport("customType", ctx.importSource);
|
|
29
|
+
ctx.generatedCustomTypes.add(name);
|
|
30
|
+
return `const ${name} = customType<
|
|
31
|
+
{
|
|
32
|
+
data: ${options.dataType};
|
|
33
|
+
driverData: ${options.driverDataType};
|
|
34
|
+
}
|
|
35
|
+
>({
|
|
36
|
+
dataType() {
|
|
37
|
+
return "${options.databaseDataType}";
|
|
38
|
+
},
|
|
39
|
+
fromDriver(value) {
|
|
40
|
+
${options.fromDriverCode}
|
|
41
|
+
},
|
|
42
|
+
toDriver(value) {
|
|
43
|
+
${options.toDriverCode}
|
|
44
|
+
}
|
|
45
|
+
});`;
|
|
46
|
+
}
|
|
47
|
+
function generateBinaryCustomType(ctx, customTypes) {
|
|
48
|
+
const name = "customBinary";
|
|
49
|
+
const code = generateCustomType(ctx, name, {
|
|
50
|
+
dataType: "Uint8Array",
|
|
51
|
+
driverDataType: "Buffer",
|
|
52
|
+
databaseDataType: schemaToDBType({ type: "binary" }, ctx.provider),
|
|
53
|
+
fromDriverCode: "return new Uint8Array(value.buffer, value.byteOffset, value.byteLength)",
|
|
54
|
+
toDriverCode: `return value instanceof Buffer? value : Buffer.from(value)`
|
|
55
|
+
});
|
|
56
|
+
if (code) customTypes.push(code);
|
|
57
|
+
return name;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Maps SQL database types to Drizzle function names and parameters.
|
|
61
|
+
* Uses schemaToDBType as the source of truth for type conversion.
|
|
62
|
+
*/
|
|
63
|
+
function getColumnTypeFunction(ctx, column, customTypes) {
|
|
64
|
+
return mapDBTypeToDrizzleFunction(ctx, schemaToDBType(column, ctx.provider), column, customTypes);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Maps a database type string to a Drizzle function name and parameters.
|
|
68
|
+
*/
|
|
69
|
+
function mapDBTypeToDrizzleFunction(ctx, dbType, column, customTypes) {
|
|
70
|
+
if (ctx.provider === "postgresql") switch (dbType) {
|
|
71
|
+
case "bigserial": return {
|
|
72
|
+
name: "bigserial",
|
|
73
|
+
params: [`{ mode: "number" }`]
|
|
74
|
+
};
|
|
75
|
+
case "serial": return { name: "serial" };
|
|
76
|
+
case "boolean": return { name: "boolean" };
|
|
77
|
+
case "bytea": return {
|
|
78
|
+
name: generateBinaryCustomType(ctx, customTypes),
|
|
79
|
+
isCustomType: true
|
|
80
|
+
};
|
|
81
|
+
case "json": return { name: "json" };
|
|
82
|
+
case "text": return { name: "text" };
|
|
83
|
+
case "bigint": return {
|
|
84
|
+
name: "bigint",
|
|
85
|
+
params: [`{ mode: "number" }`]
|
|
86
|
+
};
|
|
87
|
+
default:
|
|
88
|
+
if (dbType.startsWith("varchar(")) return {
|
|
89
|
+
name: "varchar",
|
|
90
|
+
params: [`{ length: ${parseVarchar(dbType)} }`]
|
|
91
|
+
};
|
|
92
|
+
return { name: dbType };
|
|
93
|
+
}
|
|
94
|
+
if (ctx.provider === "mysql") switch (dbType) {
|
|
95
|
+
case "boolean": return { name: "boolean" };
|
|
96
|
+
case "text": return { name: "text" };
|
|
97
|
+
case "longblob": return {
|
|
98
|
+
name: generateBinaryCustomType(ctx, customTypes),
|
|
99
|
+
isCustomType: true
|
|
100
|
+
};
|
|
101
|
+
case "bigint": return { name: "bigint" };
|
|
102
|
+
default:
|
|
103
|
+
if (dbType.startsWith("varchar(")) return {
|
|
104
|
+
name: "varchar",
|
|
105
|
+
params: [`{ length: ${parseVarchar(dbType)} }`]
|
|
106
|
+
};
|
|
107
|
+
return { name: dbType };
|
|
108
|
+
}
|
|
109
|
+
if (ctx.provider === "sqlite") switch (dbType) {
|
|
110
|
+
case "integer":
|
|
111
|
+
if (column.type === "bool") return {
|
|
112
|
+
name: "integer",
|
|
113
|
+
params: [`{ mode: "boolean" }`]
|
|
114
|
+
};
|
|
115
|
+
if (column.type === "timestamp" || column.type === "date") return {
|
|
116
|
+
name: "integer",
|
|
117
|
+
params: [`{ mode: "timestamp" }`]
|
|
118
|
+
};
|
|
119
|
+
return { name: "integer" };
|
|
120
|
+
case "blob":
|
|
121
|
+
if (column.type === "bigint") return {
|
|
122
|
+
name: "blob",
|
|
123
|
+
params: [`{ mode: "bigint" }`]
|
|
124
|
+
};
|
|
125
|
+
return {
|
|
126
|
+
name: generateBinaryCustomType(ctx, customTypes),
|
|
127
|
+
isCustomType: true
|
|
128
|
+
};
|
|
129
|
+
case "text":
|
|
130
|
+
if (column.type === "json") return {
|
|
131
|
+
name: "blob",
|
|
132
|
+
params: [`{ mode: "json" }`]
|
|
133
|
+
};
|
|
134
|
+
return { name: "text" };
|
|
135
|
+
case "real": return { name: "real" };
|
|
136
|
+
default: return { name: dbType };
|
|
137
|
+
}
|
|
138
|
+
return { name: dbType };
|
|
139
|
+
}
|
|
140
|
+
function generateColumnDefinition(ctx, column, customTypes) {
|
|
141
|
+
const parts = [];
|
|
142
|
+
const typeFn = getColumnTypeFunction(ctx, column, customTypes);
|
|
143
|
+
const params = [`"${column.name}"`, ...typeFn.params ?? []];
|
|
144
|
+
if (!typeFn.isCustomType) ctx.imports.addImport(typeFn.name, ctx.importSource);
|
|
145
|
+
parts.push(`${typeFn.name}(${params.join(", ")})`);
|
|
146
|
+
if (column instanceof InternalIdColumn || column.role === "internal-id") {
|
|
147
|
+
parts.push("primaryKey()");
|
|
148
|
+
if (ctx.provider === "mysql" || ctx.provider === "sqlite") parts.push("autoincrement()");
|
|
149
|
+
}
|
|
150
|
+
if (!column.isNullable) parts.push("notNull()");
|
|
151
|
+
if (column.default) {
|
|
152
|
+
if ("value" in column.default) {
|
|
153
|
+
let value;
|
|
154
|
+
if (typeof column.default.value === "bigint") {
|
|
155
|
+
ctx.imports.addImport("sql", "drizzle-orm");
|
|
156
|
+
value = `sql\`${column.default.value.toString()}\``;
|
|
157
|
+
} else value = JSON.stringify(column.default.value);
|
|
158
|
+
parts.push(`default(${value})`);
|
|
159
|
+
} else if (column.default.runtime === "auto") {
|
|
160
|
+
const idGen = ctx.idGeneratorImport ?? {
|
|
161
|
+
name: "createId",
|
|
162
|
+
from: "@fragno-dev/db/id"
|
|
163
|
+
};
|
|
164
|
+
ctx.imports.addImport(idGen.name, idGen.from);
|
|
165
|
+
parts.push(`$defaultFn(() => ${idGen.name}())`);
|
|
166
|
+
} else if (column.default.runtime === "now") parts.push("defaultNow()");
|
|
167
|
+
}
|
|
168
|
+
return ` ${column.ormName}: ${parts.join(".")}`;
|
|
169
|
+
}
|
|
170
|
+
function generateAllColumns(ctx, table, customTypes) {
|
|
171
|
+
return Object.values(table.columns).map((column) => generateColumnDefinition(ctx, column, customTypes));
|
|
172
|
+
}
|
|
173
|
+
function generateForeignKeys(ctx, table) {
|
|
174
|
+
const keys = [];
|
|
175
|
+
for (const relation of Object.values(table.relations)) {
|
|
176
|
+
if (relation.type === "many") continue;
|
|
177
|
+
const columns = [];
|
|
178
|
+
const foreignColumns = [];
|
|
179
|
+
const isSelfReference = relation.table.ormName === table.ormName;
|
|
180
|
+
for (const [localCol, refCol] of relation.on) {
|
|
181
|
+
columns.push(`table.${localCol}`);
|
|
182
|
+
const actualRefCol = refCol === "id" ? "_internalId" : refCol;
|
|
183
|
+
if (isSelfReference) foreignColumns.push(`table.${actualRefCol}`);
|
|
184
|
+
else foreignColumns.push(`${relation.table.ormName}.${actualRefCol}`);
|
|
185
|
+
}
|
|
186
|
+
ctx.imports.addImport("foreignKey", ctx.importSource);
|
|
187
|
+
const fkName = `${table.ormName}_${relation.table.ormName}_${relation.name}_fk`;
|
|
188
|
+
keys.push(`foreignKey({
|
|
189
|
+
columns: [${columns.join(", ")}],
|
|
190
|
+
foreignColumns: [${foreignColumns.join(", ")}],
|
|
191
|
+
name: "${fkName}"
|
|
192
|
+
})`);
|
|
193
|
+
}
|
|
194
|
+
return keys;
|
|
195
|
+
}
|
|
196
|
+
function generateIndexes(ctx, table) {
|
|
197
|
+
const indexes = [];
|
|
198
|
+
for (const idx of Object.values(table.indexes)) {
|
|
199
|
+
const columns = idx.columns.map((col) => `table.${col.ormName}`).join(", ");
|
|
200
|
+
if (idx.unique) {
|
|
201
|
+
ctx.imports.addImport("uniqueIndex", ctx.importSource);
|
|
202
|
+
indexes.push(`uniqueIndex("${idx.name}").on(${columns})`);
|
|
203
|
+
} else {
|
|
204
|
+
ctx.imports.addImport("index", ctx.importSource);
|
|
205
|
+
indexes.push(`index("${idx.name}").on(${columns})`);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
return indexes;
|
|
209
|
+
}
|
|
210
|
+
function generateTableConstraints(ctx, table) {
|
|
211
|
+
return [...generateForeignKeys(ctx, table), ...generateIndexes(ctx, table)];
|
|
212
|
+
}
|
|
213
|
+
function generateTable(ctx, table, customTypes) {
|
|
214
|
+
const tableFn = PROVIDER_TABLE_FUNCTIONS[ctx.provider];
|
|
215
|
+
ctx.imports.addImport(tableFn, ctx.importSource);
|
|
216
|
+
const columns = generateAllColumns(ctx, table, customTypes);
|
|
217
|
+
const constraints = generateTableConstraints(ctx, table);
|
|
218
|
+
const args = [`"${table.ormName}"`, `{\n${columns.join(",\n")}\n}`];
|
|
219
|
+
if (constraints.length > 0) args.push(`(table) => [\n${ident(constraints.join(",\n"))}\n]`);
|
|
220
|
+
return `export const ${table.ormName} = ${tableFn}(${args.join(", ")})`;
|
|
221
|
+
}
|
|
222
|
+
function generateRelation(ctx, table) {
|
|
223
|
+
const relations = [];
|
|
224
|
+
let hasOne = false;
|
|
225
|
+
let hasMany = false;
|
|
226
|
+
for (const relation of Object.values(table.relations)) {
|
|
227
|
+
const options = [`relationName: "${relation.id}"`];
|
|
228
|
+
if (relation.type === "one") hasOne = true;
|
|
229
|
+
else if (relation.type === "many") hasMany = true;
|
|
230
|
+
if (relation.type === "one") {
|
|
231
|
+
const fields = [];
|
|
232
|
+
const references = [];
|
|
233
|
+
for (const [left, right] of relation.on) {
|
|
234
|
+
fields.push(`${table.ormName}.${left}`);
|
|
235
|
+
const actualRight = right === "id" ? "_internalId" : right;
|
|
236
|
+
references.push(`${relation.table.ormName}.${actualRight}`);
|
|
237
|
+
}
|
|
238
|
+
options.push(`fields: [${fields.join(", ")}]`, `references: [${references.join(", ")}]`);
|
|
239
|
+
}
|
|
240
|
+
const args = [relation.table.ormName];
|
|
241
|
+
if (options.length > 0) args.push(`{\n${ident(options.join(",\n"))}\n}`);
|
|
242
|
+
relations.push(ident(`${relation.name}: ${relation.type}(${args.join(", ")})`));
|
|
243
|
+
}
|
|
244
|
+
if (relations.length === 0) return;
|
|
245
|
+
const params = [];
|
|
246
|
+
if (hasOne) params.push("one");
|
|
247
|
+
if (hasMany) params.push("many");
|
|
248
|
+
const relationParams = params.length > 0 ? `{ ${params.join(", ")} }` : "{}";
|
|
249
|
+
ctx.imports.addImport("relations", "drizzle-orm");
|
|
250
|
+
return `export const ${table.ormName}Relations = relations(${table.ormName}, (${relationParams}) => ({
|
|
251
|
+
${relations.join(",\n")}
|
|
252
|
+
}));`;
|
|
253
|
+
}
|
|
254
|
+
function generateSchema(schema, provider, options) {
|
|
255
|
+
const ctx = createContext(provider, options?.idGeneratorImport);
|
|
256
|
+
const customTypes = [];
|
|
257
|
+
const tables = [];
|
|
258
|
+
for (const table of Object.values(schema.tables)) {
|
|
259
|
+
const tableCode = generateTable(ctx, table, customTypes);
|
|
260
|
+
tables.push(tableCode);
|
|
261
|
+
const relationCode = generateRelation(ctx, table);
|
|
262
|
+
if (relationCode) tables.push(relationCode);
|
|
263
|
+
}
|
|
264
|
+
return [
|
|
265
|
+
ctx.imports.format(),
|
|
266
|
+
...customTypes,
|
|
267
|
+
...tables
|
|
268
|
+
].join("\n\n");
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
//#endregion
|
|
272
|
+
export { generateSchema };
|
|
273
|
+
//# sourceMappingURL=generate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate.js","names":["parts: string[]","params: string[]","value: string","keys: string[]","columns: string[]","foreignColumns: string[]","indexes: string[]","args: string[]","relations: string[]","options: string[]","fields: string[]","references: string[]","customTypes: string[]","tables: string[]"],"sources":["../../../src/adapters/drizzle/generate.ts"],"sourcesContent":["import { importGenerator } from \"../../util/import-generator\";\nimport { ident, parseVarchar } from \"../../util/parse\";\nimport {\n type AnyColumn,\n type AnySchema,\n type AnyTable,\n InternalIdColumn,\n} from \"../../schema/create\";\nimport type { SQLProvider } from \"../../shared/providers\";\nimport { schemaToDBType, type DBTypeLiteral } from \"../../schema/serialize\";\n\n// ============================================================================\n// PROVIDER CONFIGURATION\n// ============================================================================\n\nconst PROVIDER_IMPORTS = {\n mysql: \"drizzle-orm/mysql-core\",\n postgresql: \"drizzle-orm/pg-core\",\n sqlite: \"drizzle-orm/sqlite-core\",\n} as const;\n\nconst PROVIDER_TABLE_FUNCTIONS = {\n mysql: \"mysqlTable\",\n postgresql: \"pgTable\",\n sqlite: \"sqliteTable\",\n} as const;\n\nexport type SupportedProvider = Exclude<SQLProvider, \"cockroachdb\" | \"mssql\">;\n\n// ============================================================================\n// CONTEXT\n// ============================================================================\n\ninterface GeneratorContext {\n provider: SupportedProvider;\n imports: ReturnType<typeof importGenerator>;\n importSource: string;\n generatedCustomTypes: Set<string>;\n idGeneratorImport?: { name: string; from: string };\n}\n\nfunction createContext(\n provider: SupportedProvider,\n idGeneratorImport?: { name: string; from: string },\n): GeneratorContext {\n return {\n provider,\n imports: importGenerator(),\n importSource: PROVIDER_IMPORTS[provider],\n generatedCustomTypes: new Set<string>(),\n idGeneratorImport,\n };\n}\n\n// ============================================================================\n// CUSTOM TYPE GENERATION\n// ============================================================================\n\ninterface CustomTypeOptions {\n dataType: string;\n driverDataType: string;\n databaseDataType: string;\n fromDriverCode: string;\n toDriverCode: string;\n}\n\nfunction generateCustomType(\n ctx: GeneratorContext,\n name: string,\n options: CustomTypeOptions,\n): string | undefined {\n if (ctx.generatedCustomTypes.has(name)) {\n return undefined;\n }\n\n ctx.imports.addImport(\"customType\", ctx.importSource);\n ctx.generatedCustomTypes.add(name);\n\n return `const ${name} = customType<\n {\n data: ${options.dataType};\n driverData: ${options.driverDataType};\n }\n>({\n dataType() {\n return \"${options.databaseDataType}\";\n },\n fromDriver(value) {\n ${options.fromDriverCode}\n },\n toDriver(value) {\n ${options.toDriverCode}\n }\n});`;\n}\n\nfunction generateBinaryCustomType(ctx: GeneratorContext, customTypes: string[]): string {\n const name = \"customBinary\";\n const code = generateCustomType(ctx, name, {\n dataType: \"Uint8Array\",\n driverDataType: \"Buffer\",\n databaseDataType: schemaToDBType({ type: \"binary\" }, ctx.provider),\n fromDriverCode: \"return new Uint8Array(value.buffer, value.byteOffset, value.byteLength)\",\n toDriverCode: `return value instanceof Buffer? value : Buffer.from(value)`,\n });\n\n if (code) {\n customTypes.push(code);\n }\n return name;\n}\n\n// ============================================================================\n// COLUMN TYPE MAPPING\n// ============================================================================\n\ninterface ColumnTypeFunction {\n name: string;\n isCustomType?: boolean;\n params?: string[];\n}\n\n/**\n * Maps SQL database types to Drizzle function names and parameters.\n * Uses schemaToDBType as the source of truth for type conversion.\n */\nfunction getColumnTypeFunction(\n ctx: GeneratorContext,\n column: AnyColumn,\n customTypes: string[],\n): ColumnTypeFunction {\n // Get the canonical database type from schemaToDBType\n const dbType = schemaToDBType(column, ctx.provider);\n\n // Map database types to Drizzle function names\n return mapDBTypeToDrizzleFunction(ctx, dbType, column, customTypes);\n}\n\n/**\n * Maps a database type string to a Drizzle function name and parameters.\n */\nfunction mapDBTypeToDrizzleFunction(\n ctx: GeneratorContext,\n dbType: DBTypeLiteral,\n column: AnyColumn,\n customTypes: string[],\n): ColumnTypeFunction {\n // Handle provider-specific types\n if (ctx.provider === \"postgresql\") {\n switch (dbType) {\n case \"bigserial\":\n // bigserial requires a mode parameter in Drizzle\n return { name: \"bigserial\", params: [`{ mode: \"number\" }`] };\n case \"serial\":\n return { name: \"serial\" };\n case \"boolean\":\n return { name: \"boolean\" };\n case \"bytea\":\n return { name: generateBinaryCustomType(ctx, customTypes), isCustomType: true };\n case \"json\":\n return { name: \"json\" };\n case \"text\":\n return { name: \"text\" };\n case \"bigint\":\n return { name: \"bigint\", params: [`{ mode: \"number\" }`] };\n default:\n if (dbType.startsWith(\"varchar(\")) {\n const length = parseVarchar(dbType);\n return { name: \"varchar\", params: [`{ length: ${length} }`] };\n }\n return { name: dbType };\n }\n }\n\n if (ctx.provider === \"mysql\") {\n switch (dbType) {\n case \"boolean\":\n return { name: \"boolean\" };\n case \"text\":\n return { name: \"text\" };\n case \"longblob\":\n return { name: generateBinaryCustomType(ctx, customTypes), isCustomType: true };\n case \"bigint\":\n return { name: \"bigint\" };\n default:\n if (dbType.startsWith(\"varchar(\")) {\n const length = parseVarchar(dbType);\n return { name: \"varchar\", params: [`{ length: ${length} }`] };\n }\n return { name: dbType };\n }\n }\n\n if (ctx.provider === \"sqlite\") {\n switch (dbType) {\n case \"integer\":\n // Need to determine the mode based on the original column type\n if (column.type === \"bool\") {\n return { name: \"integer\", params: [`{ mode: \"boolean\" }`] };\n }\n if (column.type === \"timestamp\" || column.type === \"date\") {\n return { name: \"integer\", params: [`{ mode: \"timestamp\" }`] };\n }\n return { name: \"integer\" };\n case \"blob\":\n // Need to determine the mode based on the original column type\n if (column.type === \"bigint\") {\n return { name: \"blob\", params: [`{ mode: \"bigint\" }`] };\n }\n return { name: generateBinaryCustomType(ctx, customTypes), isCustomType: true };\n case \"text\":\n // Check if it's JSON\n if (column.type === \"json\") {\n return { name: \"blob\", params: [`{ mode: \"json\" }`] };\n }\n return { name: \"text\" };\n case \"real\":\n return { name: \"real\" };\n default:\n return { name: dbType };\n }\n }\n\n // Fallback for other providers\n return { name: dbType };\n}\n\n// ============================================================================\n// COLUMN GENERATION\n// ============================================================================\n\nfunction generateColumnDefinition(\n ctx: GeneratorContext,\n column: AnyColumn,\n customTypes: string[],\n): string {\n const parts: string[] = [];\n const typeFn = getColumnTypeFunction(ctx, column, customTypes);\n\n // Column type with parameters\n const params: string[] = [`\"${column.name}\"`, ...(typeFn.params ?? [])];\n if (!typeFn.isCustomType) {\n ctx.imports.addImport(typeFn.name, ctx.importSource);\n }\n parts.push(`${typeFn.name}(${params.join(\", \")})`);\n\n // Primary key for internal ID\n if (column instanceof InternalIdColumn || column.role === \"internal-id\") {\n parts.push(\"primaryKey()\");\n\n // Auto-increment based on provider\n // Note: PostgreSQL uses bigserial/serial which handle auto-increment automatically\n if (ctx.provider === \"mysql\" || ctx.provider === \"sqlite\") {\n parts.push(\"autoincrement()\");\n }\n }\n\n // Nullability\n if (!column.isNullable) {\n parts.push(\"notNull()\");\n }\n\n // Default values\n if (column.default) {\n if (\"value\" in column.default) {\n let value: string;\n if (typeof column.default.value === \"bigint\") {\n ctx.imports.addImport(\"sql\", \"drizzle-orm\");\n value = `sql\\`${column.default.value.toString()}\\``;\n } else {\n value = JSON.stringify(column.default.value);\n }\n parts.push(`default(${value})`);\n } else if (column.default.runtime === \"auto\") {\n const idGen = ctx.idGeneratorImport ?? { name: \"createId\", from: \"@fragno-dev/db/id\" };\n ctx.imports.addImport(idGen.name, idGen.from);\n parts.push(`$defaultFn(() => ${idGen.name}())`);\n } else if (column.default.runtime === \"now\") {\n parts.push(\"defaultNow()\");\n }\n }\n\n return ` ${column.ormName}: ${parts.join(\".\")}`;\n}\n\nfunction generateAllColumns(\n ctx: GeneratorContext,\n table: AnyTable,\n customTypes: string[],\n): string[] {\n return Object.values(table.columns).map((column) =>\n generateColumnDefinition(ctx, column, customTypes),\n );\n}\n\n// ============================================================================\n// CONSTRAINT GENERATION\n// ============================================================================\n\nfunction generateForeignKeys(ctx: GeneratorContext, table: AnyTable): string[] {\n const keys: string[] = [];\n\n for (const relation of Object.values(table.relations)) {\n // Only \"one\" relations generate foreign keys\n // \"many\" relations don't have foreign keys (they're on the other side)\n if (relation.type === \"many\") {\n continue;\n }\n\n const columns: string[] = [];\n const foreignColumns: string[] = [];\n const isSelfReference = relation.table.ormName === table.ormName;\n\n for (const [localCol, refCol] of relation.on) {\n columns.push(`table.${localCol}`);\n // Foreign keys always reference internal IDs\n const actualRefCol = refCol === \"id\" ? \"_internalId\" : refCol;\n // For self-referencing foreign keys, use table parameter instead of table constant\n if (isSelfReference) {\n foreignColumns.push(`table.${actualRefCol}`);\n } else {\n foreignColumns.push(`${relation.table.ormName}.${actualRefCol}`);\n }\n }\n\n ctx.imports.addImport(\"foreignKey\", ctx.importSource);\n const fkName = `${table.ormName}_${relation.table.ormName}_${relation.name}_fk`;\n\n keys.push(`foreignKey({\n columns: [${columns.join(\", \")}],\n foreignColumns: [${foreignColumns.join(\", \")}],\n name: \"${fkName}\"\n})`);\n }\n\n return keys;\n}\n\nfunction generateIndexes(ctx: GeneratorContext, table: AnyTable): string[] {\n const indexes: string[] = [];\n\n for (const idx of Object.values(table.indexes)) {\n const columns = idx.columns.map((col) => `table.${col.ormName}`).join(\", \");\n\n if (idx.unique) {\n ctx.imports.addImport(\"uniqueIndex\", ctx.importSource);\n indexes.push(`uniqueIndex(\"${idx.name}\").on(${columns})`);\n } else {\n ctx.imports.addImport(\"index\", ctx.importSource);\n indexes.push(`index(\"${idx.name}\").on(${columns})`);\n }\n }\n\n return indexes;\n}\n\nfunction generateTableConstraints(ctx: GeneratorContext, table: AnyTable): string[] {\n return [...generateForeignKeys(ctx, table), ...generateIndexes(ctx, table)];\n}\n\n// ============================================================================\n// TABLE GENERATION\n// ============================================================================\n\nfunction generateTable(ctx: GeneratorContext, table: AnyTable, customTypes: string[]): string {\n const tableFn = PROVIDER_TABLE_FUNCTIONS[ctx.provider];\n ctx.imports.addImport(tableFn, ctx.importSource);\n\n const columns = generateAllColumns(ctx, table, customTypes);\n const constraints = generateTableConstraints(ctx, table);\n\n const args: string[] = [`\"${table.ormName}\"`, `{\\n${columns.join(\",\\n\")}\\n}`];\n\n if (constraints.length > 0) {\n args.push(`(table) => [\\n${ident(constraints.join(\",\\n\"))}\\n]`);\n }\n\n return `export const ${table.ormName} = ${tableFn}(${args.join(\", \")})`;\n}\n\n// ============================================================================\n// RELATION GENERATION\n// ============================================================================\n\nfunction generateRelation(ctx: GeneratorContext, table: AnyTable): string | undefined {\n const relations: string[] = [];\n let hasOne = false;\n let hasMany = false;\n\n for (const relation of Object.values(table.relations)) {\n const options: string[] = [`relationName: \"${relation.id}\"`];\n\n // Track which relation types are used\n if (relation.type === \"one\") {\n hasOne = true;\n } else if (relation.type === \"many\") {\n hasMany = true;\n }\n\n // For \"one\" relations, specify fields and references\n if (relation.type === \"one\") {\n const fields: string[] = [];\n const references: string[] = [];\n\n for (const [left, right] of relation.on) {\n fields.push(`${table.ormName}.${left}`);\n // Relations reference internal IDs\n const actualRight = right === \"id\" ? \"_internalId\" : right;\n references.push(`${relation.table.ormName}.${actualRight}`);\n }\n\n options.push(`fields: [${fields.join(\", \")}]`, `references: [${references.join(\", \")}]`);\n }\n\n const args: string[] = [relation.table.ormName];\n if (options.length > 0) {\n args.push(`{\\n${ident(options.join(\",\\n\"))}\\n}`);\n }\n\n relations.push(ident(`${relation.name}: ${relation.type}(${args.join(\", \")})`));\n }\n\n if (relations.length === 0) {\n return undefined;\n }\n\n // Only include the relation types that are actually used\n const params: string[] = [];\n if (hasOne) {\n params.push(\"one\");\n }\n if (hasMany) {\n params.push(\"many\");\n }\n const relationParams = params.length > 0 ? `{ ${params.join(\", \")} }` : \"{}\";\n\n ctx.imports.addImport(\"relations\", \"drizzle-orm\");\n return `export const ${table.ormName}Relations = relations(${table.ormName}, (${relationParams}) => ({\n${relations.join(\",\\n\")}\n}));`;\n}\n\n// ============================================================================\n// MAIN GENERATION\n// ============================================================================\n\nexport interface GenerateSchemaOptions {\n /** Custom ID generator import configuration */\n idGeneratorImport?: {\n /** Function name to import */\n name: string;\n /** Module to import from */\n from: string;\n };\n}\n\nexport function generateSchema(\n schema: AnySchema,\n provider: SupportedProvider,\n options?: GenerateSchemaOptions,\n): string {\n const ctx = createContext(provider, options?.idGeneratorImport);\n const customTypes: string[] = [];\n const tables: string[] = [];\n\n // Generate tables and collect custom types\n for (const table of Object.values(schema.tables)) {\n // Custom types might be generated during column processing\n const tableCode = generateTable(ctx, table, customTypes);\n tables.push(tableCode);\n\n const relationCode = generateRelation(ctx, table);\n if (relationCode) {\n tables.push(relationCode);\n }\n }\n\n // Assemble final output\n const lines: string[] = [ctx.imports.format(), ...customTypes, ...tables];\n return lines.join(\"\\n\\n\");\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
//#region src/adapters/drizzle/join-column-utils.ts
|
|
2
|
+
/**
|
|
3
|
+
* Determine the ordered list of columns for a join selection.
|
|
4
|
+
*
|
|
5
|
+
* This logic is shared between the compiler (which builds the SQL)
|
|
6
|
+
* and the decoder (which maps the result array back to objects).
|
|
7
|
+
* The order MUST match exactly for the decoder to work correctly.
|
|
8
|
+
*
|
|
9
|
+
* @param targetTable - The table being joined
|
|
10
|
+
* @param select - Selection options (true for all columns, or array of column keys)
|
|
11
|
+
* @returns Array of column ORM names in the order they appear in the SQL/result
|
|
12
|
+
*/
|
|
13
|
+
function getOrderedJoinColumns(targetTable, select) {
|
|
14
|
+
const orderedColumns = [];
|
|
15
|
+
if (select === true) for (const col of Object.values(targetTable.columns)) orderedColumns.push(col.ormName);
|
|
16
|
+
else {
|
|
17
|
+
for (const colKey of select) {
|
|
18
|
+
const col = targetTable.columns[colKey];
|
|
19
|
+
if (col) orderedColumns.push(col.ormName);
|
|
20
|
+
}
|
|
21
|
+
for (const col of Object.values(targetTable.columns)) if (col && col.isHidden && !orderedColumns.includes(col.ormName)) orderedColumns.push(col.ormName);
|
|
22
|
+
}
|
|
23
|
+
return orderedColumns;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
//#endregion
|
|
27
|
+
export { getOrderedJoinColumns };
|
|
28
|
+
//# sourceMappingURL=join-column-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"join-column-utils.js","names":["orderedColumns: string[]"],"sources":["../../../src/adapters/drizzle/join-column-utils.ts"],"sourcesContent":["import type { AnyTable } from \"../../schema/create\";\n\n/**\n * Determine the ordered list of columns for a join selection.\n *\n * This logic is shared between the compiler (which builds the SQL)\n * and the decoder (which maps the result array back to objects).\n * The order MUST match exactly for the decoder to work correctly.\n *\n * @param targetTable - The table being joined\n * @param select - Selection options (true for all columns, or array of column keys)\n * @returns Array of column ORM names in the order they appear in the SQL/result\n */\nexport function getOrderedJoinColumns(targetTable: AnyTable, select: true | string[]): string[] {\n const orderedColumns: string[] = [];\n\n if (select === true) {\n // All columns selected - iterate in the order they appear in targetTable.columns\n for (const col of Object.values(targetTable.columns)) {\n orderedColumns.push(col.ormName);\n }\n } else {\n // Specific columns selected\n for (const colKey of select) {\n const col = targetTable.columns[colKey];\n if (col) {\n orderedColumns.push(col.ormName);\n }\n }\n // Add hidden columns at the end (for FragnoId construction)\n for (const col of Object.values(targetTable.columns)) {\n if (col && col.isHidden && !orderedColumns.includes(col.ormName)) {\n orderedColumns.push(col.ormName);\n }\n }\n }\n\n return orderedColumns;\n}\n"],"mappings":";;;;;;;;;;;;AAaA,SAAgB,sBAAsB,aAAuB,QAAmC;CAC9F,MAAMA,iBAA2B,EAAE;AAEnC,KAAI,WAAW,KAEb,MAAK,MAAM,OAAO,OAAO,OAAO,YAAY,QAAQ,CAClD,gBAAe,KAAK,IAAI,QAAQ;MAE7B;AAEL,OAAK,MAAM,UAAU,QAAQ;GAC3B,MAAM,MAAM,YAAY,QAAQ;AAChC,OAAI,IACF,gBAAe,KAAK,IAAI,QAAQ;;AAIpC,OAAK,MAAM,OAAO,OAAO,OAAO,YAAY,QAAQ,CAClD,KAAI,OAAO,IAAI,YAAY,CAAC,eAAe,SAAS,IAAI,QAAQ,CAC9D,gBAAe,KAAK,IAAI,QAAQ;;AAKtC,QAAO"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
//#region src/adapters/drizzle/shared.ts
|
|
2
|
+
function parseDrizzle(drizzle) {
|
|
3
|
+
const db = drizzle;
|
|
4
|
+
const drizzleTables = db._.fullSchema;
|
|
5
|
+
if (!drizzleTables || Object.keys(drizzleTables).length === 0) throw new Error("Drizzle adapter requires query mode, make sure to configure it following their guide: https://orm.drizzle.team/docs/rqb.");
|
|
6
|
+
return [db, drizzleTables];
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
//#endregion
|
|
10
|
+
export { parseDrizzle };
|
|
11
|
+
//# sourceMappingURL=shared.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.js","names":[],"sources":["../../../src/adapters/drizzle/shared.ts"],"sourcesContent":["import * as Drizzle from \"drizzle-orm\";\nimport type * as MySQL from \"drizzle-orm/mysql-core\";\n\nexport type TableType = MySQL.MySqlTableWithColumns<MySQL.TableConfig>;\nexport type ColumnType = MySQL.AnyMySqlColumn;\nexport type DBType = MySQL.MySqlDatabase<\n MySQL.MySqlQueryResultHKT,\n MySQL.PreparedQueryHKTBase,\n Record<string, unknown>,\n Drizzle.TablesRelationalConfig\n>;\n\nexport function parseDrizzle(drizzle: unknown) {\n const db = drizzle as DBType;\n const drizzleTables = db._.fullSchema as Record<string, TableType>;\n if (!drizzleTables || Object.keys(drizzleTables).length === 0)\n throw new Error(\n \"Drizzle adapter requires query mode, make sure to configure it following their guide: https://orm.drizzle.team/docs/rqb.\",\n );\n\n return [db, drizzleTables] as const;\n}\n"],"mappings":";AAYA,SAAgB,aAAa,SAAkB;CAC7C,MAAM,KAAK;CACX,MAAM,gBAAgB,GAAG,EAAE;AAC3B,KAAI,CAAC,iBAAiB,OAAO,KAAK,cAAc,CAAC,WAAW,EAC1D,OAAM,IAAI,MACR,2HACD;AAEH,QAAO,CAAC,IAAI,cAAc"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { AnySchema } from "../../schema/create.js";
|
|
2
|
+
import { Migrator } from "../../migration-engine/create.js";
|
|
3
|
+
import { AbstractQuery } from "../../query/query.js";
|
|
4
|
+
import { DatabaseAdapter } from "../adapters.js";
|
|
5
|
+
import { SQLProvider } from "../../shared/providers.js";
|
|
6
|
+
import { Kysely } from "kysely";
|
|
7
|
+
|
|
8
|
+
//#region src/adapters/kysely/kysely-adapter.d.ts
|
|
9
|
+
type KyselyAny = Kysely<any>;
|
|
10
|
+
interface KyselyConfig {
|
|
11
|
+
db: KyselyAny;
|
|
12
|
+
provider: SQLProvider;
|
|
13
|
+
}
|
|
14
|
+
declare class KyselyAdapter implements DatabaseAdapter {
|
|
15
|
+
#private;
|
|
16
|
+
constructor(config: KyselyConfig);
|
|
17
|
+
createQueryEngine<T extends AnySchema>(schema: T, _namespace: string): AbstractQuery<T>;
|
|
18
|
+
createMigrationEngine(schema: AnySchema, namespace: string): Migrator;
|
|
19
|
+
getSchemaVersion(namespace: string): Promise<string | undefined>;
|
|
20
|
+
}
|
|
21
|
+
//#endregion
|
|
22
|
+
export { KyselyAdapter, KyselyConfig };
|
|
23
|
+
//# sourceMappingURL=kysely-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kysely-adapter.d.ts","names":[],"sources":["../../../src/adapters/kysely/kysely-adapter.ts"],"sourcesContent":[],"mappings":";;;;;;;;KAcK,SAAA,GAAY;UAEA,YAAA;EAFZ,EAAA,EAGC,SAHQ;EAEG,QAAA,EAEL,WAFiB;AAK7B;AAGsB,cAHT,aAAA,YAAyB,eAGhB,CAAA;EAIQ,CAAA,OAAA;EAAmB,WAAA,CAAA,MAAA,EAJ3B,YAI2B;EAAsC,iBAAA,CAAA,UAAzD,SAAyD,CAAA,CAAA,MAAA,EAAtC,CAAsC,EAAA,UAAA,EAAA,MAAA,CAAA,EAAd,aAAc,CAAA,CAAA,CAAA;EAAd,qBAAA,CAAA,MAAA,EAIzC,SAJyC,EAAA,SAAA,EAAA,MAAA,CAAA,EAIV,QAJU;EAIzC,gBAAA,CAAA,SAAA,EAAA,MAAA,CAAA,EAkGI,OAlGJ,CAAA,MAAA,GAAA,SAAA,CAAA"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { schemaToDBType } from "../../schema/serialize.js";
|
|
2
|
+
import { createMigrator } from "../../migration-engine/create.js";
|
|
3
|
+
import { execute } from "./migration/execute.js";
|
|
4
|
+
import { fromKysely } from "./kysely-query.js";
|
|
5
|
+
import { sql } from "kysely";
|
|
6
|
+
|
|
7
|
+
//#region src/adapters/kysely/kysely-adapter.ts
|
|
8
|
+
const SETTINGS_TABLE_NAME = "fragno_db_settings";
|
|
9
|
+
var KyselyAdapter = class {
|
|
10
|
+
#kyselyConfig;
|
|
11
|
+
constructor(config) {
|
|
12
|
+
this.#kyselyConfig = config;
|
|
13
|
+
}
|
|
14
|
+
createQueryEngine(schema, _namespace) {
|
|
15
|
+
return fromKysely(schema, this.#kyselyConfig);
|
|
16
|
+
}
|
|
17
|
+
createMigrationEngine(schema, namespace) {
|
|
18
|
+
const manager = createSettingsManager(this.#kyselyConfig.db, this.#kyselyConfig.provider, SETTINGS_TABLE_NAME, namespace);
|
|
19
|
+
const onCustomNode = (node, db) => {
|
|
20
|
+
const statement = sql.raw(node["sql"]);
|
|
21
|
+
return {
|
|
22
|
+
compile() {
|
|
23
|
+
return statement.compile(db);
|
|
24
|
+
},
|
|
25
|
+
execute() {
|
|
26
|
+
return statement.execute(db);
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
const preprocess = (operations, db) => {
|
|
31
|
+
if (this.#kyselyConfig.provider === "mysql") {
|
|
32
|
+
operations.unshift({
|
|
33
|
+
type: "custom",
|
|
34
|
+
sql: "SET FOREIGN_KEY_CHECKS = 0"
|
|
35
|
+
});
|
|
36
|
+
operations.push({
|
|
37
|
+
type: "custom",
|
|
38
|
+
sql: "SET FOREIGN_KEY_CHECKS = 1"
|
|
39
|
+
});
|
|
40
|
+
} else if (this.#kyselyConfig.provider === "sqlite") operations.unshift({
|
|
41
|
+
type: "custom",
|
|
42
|
+
sql: "PRAGMA defer_foreign_keys = ON"
|
|
43
|
+
});
|
|
44
|
+
return operations.flatMap((op) => execute(op, this.#kyselyConfig, (node) => onCustomNode(node, db)));
|
|
45
|
+
};
|
|
46
|
+
const migrator = createMigrator({
|
|
47
|
+
schema,
|
|
48
|
+
executor: async (operations) => {
|
|
49
|
+
await this.#kyselyConfig.db.transaction().execute(async (tx) => {
|
|
50
|
+
for (const node of preprocess(operations, tx)) try {
|
|
51
|
+
await node.execute();
|
|
52
|
+
} catch (e) {
|
|
53
|
+
console.error("failed at", node.compile(), e);
|
|
54
|
+
throw e;
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
},
|
|
58
|
+
sql: { toSql: (operations) => {
|
|
59
|
+
return preprocess(operations, this.#kyselyConfig.db).map((m) => `${m.compile().sql};`).join("\n\n");
|
|
60
|
+
} },
|
|
61
|
+
settings: {
|
|
62
|
+
getVersion: async () => {
|
|
63
|
+
const v = await manager.get(`schema_version`);
|
|
64
|
+
return v ? parseInt(v) : 0;
|
|
65
|
+
},
|
|
66
|
+
updateSettingsInMigration: async (fromVersion, toVersion) => {
|
|
67
|
+
if (fromVersion === 0) return [{
|
|
68
|
+
type: "custom",
|
|
69
|
+
sql: manager.initTable()
|
|
70
|
+
}, {
|
|
71
|
+
type: "custom",
|
|
72
|
+
sql: manager.insert(`schema_version`, toVersion.toString())
|
|
73
|
+
}];
|
|
74
|
+
return [{
|
|
75
|
+
type: "custom",
|
|
76
|
+
sql: manager.update(`schema_version`, toVersion.toString())
|
|
77
|
+
}];
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
migrator.getDefaultFileName = (namespace$1, fromVersion, toVersion) => {
|
|
82
|
+
return `${(/* @__PURE__ */ new Date()).toISOString().split("T")[0].replace(/-/g, "")}_${namespace$1.replace(/[^a-z0-9-]/gi, "_")}_migration_${fromVersion}_to_${toVersion}.sql`;
|
|
83
|
+
};
|
|
84
|
+
return migrator;
|
|
85
|
+
}
|
|
86
|
+
getSchemaVersion(namespace) {
|
|
87
|
+
return createSettingsManager(this.#kyselyConfig.db, this.#kyselyConfig.provider, SETTINGS_TABLE_NAME, namespace).get(`schema_version`);
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
function createSettingsManager(db, provider, settingsTableName, namespace) {
|
|
91
|
+
function initTable() {
|
|
92
|
+
return db.schema.createTable(settingsTableName).addColumn("key", provider === "sqlite" ? "text" : "varchar(255)", (col) => col.primaryKey()).addColumn("value", sql.raw(schemaToDBType({ type: "string" }, provider)), (col) => col.notNull());
|
|
93
|
+
}
|
|
94
|
+
return {
|
|
95
|
+
async get(key) {
|
|
96
|
+
try {
|
|
97
|
+
return (await db.selectFrom(settingsTableName).where("key", "=", sql.lit(`${namespace}.${key}`)).select(["value"]).executeTakeFirstOrThrow()).value;
|
|
98
|
+
} catch {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
initTable() {
|
|
103
|
+
return initTable().compile().sql;
|
|
104
|
+
},
|
|
105
|
+
insert(key, value) {
|
|
106
|
+
return db.insertInto(settingsTableName).values({
|
|
107
|
+
key: sql.lit(`${namespace}.${key}`),
|
|
108
|
+
value: sql.lit(value)
|
|
109
|
+
}).compile().sql;
|
|
110
|
+
},
|
|
111
|
+
update(key, value) {
|
|
112
|
+
return db.updateTable(settingsTableName).set({ value: sql.lit(value) }).where("key", "=", sql.lit(`${namespace}.${key}`)).compile().sql;
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
//#endregion
|
|
118
|
+
export { KyselyAdapter };
|
|
119
|
+
//# sourceMappingURL=kysely-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kysely-adapter.js","names":["#kyselyConfig","namespace"],"sources":["../../../src/adapters/kysely/kysely-adapter.ts"],"sourcesContent":["import { sql, type Kysely } from \"kysely\";\nimport type { SQLProvider } from \"../../shared/providers\";\nimport type { DatabaseAdapter } from \"../adapters\";\nimport { schemaToDBType } from \"../../schema/serialize\";\nimport { createMigrator, type Migrator } from \"../../migration-engine/create\";\nimport type { AnySchema } from \"../../schema/create\";\nimport type { CustomOperation, MigrationOperation } from \"../../migration-engine/shared\";\nimport { execute } from \"./migration/execute\";\nimport type { AbstractQuery } from \"../../query/query\";\nimport { fromKysely } from \"./kysely-query\";\n\nconst SETTINGS_TABLE_NAME = \"fragno_db_settings\" as const;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype KyselyAny = Kysely<any>;\n\nexport interface KyselyConfig {\n db: KyselyAny;\n provider: SQLProvider;\n}\n\nexport class KyselyAdapter implements DatabaseAdapter {\n #kyselyConfig: KyselyConfig;\n\n constructor(config: KyselyConfig) {\n this.#kyselyConfig = config;\n }\n\n createQueryEngine<T extends AnySchema>(schema: T, _namespace: string): AbstractQuery<T> {\n return fromKysely(schema, this.#kyselyConfig);\n }\n\n createMigrationEngine(schema: AnySchema, namespace: string): Migrator {\n const manager = createSettingsManager(\n this.#kyselyConfig.db,\n this.#kyselyConfig.provider,\n SETTINGS_TABLE_NAME,\n namespace,\n );\n\n const onCustomNode = (node: CustomOperation, db: KyselyAny) => {\n const statement = sql.raw(node[\"sql\"] as string);\n\n return {\n compile() {\n return statement.compile(db);\n },\n execute() {\n return statement.execute(db);\n },\n };\n };\n\n const preprocess = (operations: MigrationOperation[], db: KyselyAny) => {\n if (this.#kyselyConfig.provider === \"mysql\") {\n operations.unshift({ type: \"custom\", sql: \"SET FOREIGN_KEY_CHECKS = 0\" });\n operations.push({ type: \"custom\", sql: \"SET FOREIGN_KEY_CHECKS = 1\" });\n } else if (this.#kyselyConfig.provider === \"sqlite\") {\n operations.unshift({\n type: \"custom\",\n sql: \"PRAGMA defer_foreign_keys = ON\",\n });\n }\n\n return operations.flatMap((op) =>\n execute(op, this.#kyselyConfig, (node) => onCustomNode(node, db)),\n );\n };\n\n const migrator = createMigrator({\n schema,\n executor: async (operations) => {\n await this.#kyselyConfig.db.transaction().execute(async (tx) => {\n for (const node of preprocess(operations, tx)) {\n try {\n await node.execute();\n } catch (e) {\n console.error(\"failed at\", node.compile(), e);\n throw e;\n }\n }\n });\n },\n sql: {\n toSql: (operations) => {\n const compiled = preprocess(operations, this.#kyselyConfig.db).map(\n (m) => `${m.compile().sql};`,\n );\n\n return compiled.join(\"\\n\\n\");\n },\n },\n\n settings: {\n getVersion: async () => {\n const v = await manager.get(`schema_version`);\n return v ? parseInt(v) : 0;\n },\n updateSettingsInMigration: async (fromVersion, toVersion) => {\n // Only create the settings table if we're migrating from version 0\n if (fromVersion === 0) {\n return [\n { type: \"custom\", sql: manager.initTable() },\n {\n type: \"custom\",\n sql: manager.insert(`schema_version`, toVersion.toString()),\n },\n ];\n }\n\n return [\n {\n type: \"custom\",\n sql: manager.update(`schema_version`, toVersion.toString()),\n },\n ];\n },\n },\n });\n\n // Add getDefaultFileName implementation\n migrator.getDefaultFileName = (namespace: string, fromVersion: number, toVersion: number) => {\n const date = new Date().toISOString().split(\"T\")[0].replace(/-/g, \"\");\n const safeName = namespace.replace(/[^a-z0-9-]/gi, \"_\");\n return `${date}_${safeName}_migration_${fromVersion}_to_${toVersion}.sql`;\n };\n\n return migrator;\n }\n\n getSchemaVersion(namespace: string) {\n const manager = createSettingsManager(\n this.#kyselyConfig.db,\n this.#kyselyConfig.provider,\n SETTINGS_TABLE_NAME,\n namespace,\n );\n\n return manager.get(`schema_version`);\n }\n}\n\nfunction createSettingsManager(\n db: KyselyAny,\n provider: SQLProvider,\n settingsTableName: string,\n namespace: string,\n) {\n function initTable() {\n return db.schema\n .createTable(settingsTableName)\n .addColumn(\"key\", provider === \"sqlite\" ? \"text\" : \"varchar(255)\", (col) => col.primaryKey())\n .addColumn(\"value\", sql.raw(schemaToDBType({ type: \"string\" }, provider)), (col) =>\n col.notNull(),\n );\n }\n\n return {\n async get(key: string): Promise<string | undefined> {\n try {\n const result = await db\n .selectFrom(settingsTableName)\n .where(\"key\", \"=\", sql.lit(`${namespace}.${key}`))\n .select([\"value\"])\n .executeTakeFirstOrThrow();\n return result.value as string;\n } catch {\n return;\n }\n },\n\n initTable() {\n return initTable().compile().sql;\n },\n\n insert(key: string, value: string) {\n return db\n .insertInto(settingsTableName)\n .values({\n key: sql.lit(`${namespace}.${key}`),\n value: sql.lit(value),\n })\n .compile().sql;\n },\n\n update(key: string, value: string) {\n return db\n .updateTable(settingsTableName)\n .set({\n value: sql.lit(value),\n })\n .where(\"key\", \"=\", sql.lit(`${namespace}.${key}`))\n .compile().sql;\n },\n };\n}\n"],"mappings":"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"}
|