@databricks/appkit 0.64.0 → 0.66.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/CLAUDE.md +19 -0
- package/dist/appkit/package.js +1 -1
- package/dist/beta.d.ts +9 -1
- package/dist/beta.js +6 -1
- package/dist/cli/commands/doctor/resolve-targets.js +1 -1
- package/dist/cli/commands/generate-types.js +12 -3
- package/dist/cli/commands/generate-types.js.map +1 -1
- package/dist/cli/commands/plugin/create/scaffold.js +2 -2
- package/dist/cli/commands/plugin/create/scaffold.js.map +1 -1
- package/dist/core/appkit.js +1 -1
- package/dist/database/contract/index.js +3 -0
- package/dist/database/contract/registry.d.ts +26 -0
- package/dist/database/contract/registry.d.ts.map +1 -0
- package/dist/database/contract/wire.d.ts +8 -0
- package/dist/database/contract/wire.d.ts.map +1 -0
- package/dist/database/contract/wire.js +37 -0
- package/dist/database/contract/wire.js.map +1 -0
- package/dist/database/errors.js +71 -0
- package/dist/database/errors.js.map +1 -0
- package/dist/database/runtime/data-path.js +39 -0
- package/dist/database/runtime/data-path.js.map +1 -0
- package/dist/database/runtime/engine/drizzle-data-path.js +194 -0
- package/dist/database/runtime/engine/drizzle-data-path.js.map +1 -0
- package/dist/database/runtime/engine/translate.js +176 -0
- package/dist/database/runtime/engine/translate.js.map +1 -0
- package/dist/database/schema-builder/columns.d.ts +39 -0
- package/dist/database/schema-builder/columns.d.ts.map +1 -0
- package/dist/database/schema-builder/columns.js +162 -0
- package/dist/database/schema-builder/columns.js.map +1 -0
- package/dist/database/schema-builder/define-schema.d.ts +12 -0
- package/dist/database/schema-builder/define-schema.d.ts.map +1 -0
- package/dist/database/schema-builder/define-schema.js +207 -0
- package/dist/database/schema-builder/define-schema.js.map +1 -0
- package/dist/database/schema-builder/engine/relations.js +37 -0
- package/dist/database/schema-builder/engine/relations.js.map +1 -0
- package/dist/database/schema-builder/engine/tables.js +124 -0
- package/dist/database/schema-builder/engine/tables.js.map +1 -0
- package/dist/database/schema-builder/fk.d.ts +9 -0
- package/dist/database/schema-builder/fk.d.ts.map +1 -0
- package/dist/database/schema-builder/fk.js +71 -0
- package/dist/database/schema-builder/fk.js.map +1 -0
- package/dist/database/schema-builder/index.js +6 -0
- package/dist/database/schema-builder/relations.js +51 -0
- package/dist/database/schema-builder/relations.js.map +1 -0
- package/dist/database/schema-builder/types.d.ts +121 -0
- package/dist/database/schema-builder/types.d.ts.map +1 -0
- package/dist/database/schema-builder/types.js +43 -0
- package/dist/database/schema-builder/types.js.map +1 -0
- package/dist/database/schema-builder/validators.js +53 -0
- package/dist/database/schema-builder/validators.js.map +1 -0
- package/dist/index.d.ts +13 -12
- package/dist/index.js +2 -2
- package/dist/plugin/plugin.d.ts +2 -2
- package/dist/plugins/agents/agents.d.ts +3 -3
- package/dist/plugins/agents/agents.d.ts.map +1 -1
- package/dist/plugins/agents/agents.js +3 -1
- package/dist/plugins/agents/agents.js.map +1 -1
- package/dist/plugins/ai-search/ai-search.d.ts +1 -1
- package/dist/plugins/ai-search/ai-search.d.ts.map +1 -1
- package/dist/plugins/ai-search/ai-search.js +3 -1
- package/dist/plugins/ai-search/ai-search.js.map +1 -1
- package/dist/plugins/analytics/analytics.d.ts +2 -2
- package/dist/plugins/analytics/analytics.d.ts.map +1 -1
- package/dist/plugins/analytics/analytics.js +3 -1
- package/dist/plugins/analytics/analytics.js.map +1 -1
- package/dist/plugins/beta-exports.generated.d.ts +3 -1
- package/dist/plugins/beta-exports.generated.js +2 -0
- package/dist/plugins/database/database.d.ts +37 -0
- package/dist/plugins/database/database.d.ts.map +1 -0
- package/dist/plugins/database/database.js +68 -0
- package/dist/plugins/database/database.js.map +1 -0
- package/dist/plugins/database/defaults.js +12 -0
- package/dist/plugins/database/defaults.js.map +1 -0
- package/dist/plugins/database/entity-client.js +148 -0
- package/dist/plugins/database/entity-client.js.map +1 -0
- package/dist/plugins/database/entity-types.d.ts +76 -0
- package/dist/plugins/database/entity-types.d.ts.map +1 -0
- package/dist/plugins/database/index.d.ts +3 -0
- package/dist/plugins/database/index.js +3 -0
- package/dist/plugins/database/lifecycle.js +107 -0
- package/dist/plugins/database/lifecycle.js.map +1 -0
- package/dist/plugins/database/manifest.js +84 -0
- package/dist/plugins/database/manifest.js.map +1 -0
- package/dist/plugins/database/types.d.ts +10 -0
- package/dist/plugins/database/types.d.ts.map +1 -0
- package/dist/plugins/files/plugin.d.ts +5 -4
- package/dist/plugins/files/plugin.d.ts.map +1 -1
- package/dist/plugins/files/plugin.js +2 -1
- package/dist/plugins/files/plugin.js.map +1 -1
- package/dist/plugins/genie/genie.d.ts +2 -2
- package/dist/plugins/genie/genie.d.ts.map +1 -1
- package/dist/plugins/genie/genie.js +3 -1
- package/dist/plugins/genie/genie.js.map +1 -1
- package/dist/plugins/jobs/plugin.d.ts +3 -2
- package/dist/plugins/jobs/plugin.d.ts.map +1 -1
- package/dist/plugins/jobs/plugin.js +2 -1
- package/dist/plugins/jobs/plugin.js.map +1 -1
- package/dist/plugins/lakebase/lakebase.d.ts +4 -4
- package/dist/plugins/lakebase/lakebase.d.ts.map +1 -1
- package/dist/plugins/lakebase/lakebase.js +3 -1
- package/dist/plugins/lakebase/lakebase.js.map +1 -1
- package/dist/plugins/server/index.d.ts +1 -1
- package/dist/plugins/server/index.d.ts.map +1 -1
- package/dist/plugins/server/index.js +3 -1
- package/dist/plugins/server/index.js.map +1 -1
- package/dist/plugins/serving/serving.d.ts +1 -0
- package/dist/plugins/serving/serving.d.ts.map +1 -1
- package/dist/plugins/serving/serving.js +2 -1
- package/dist/plugins/serving/serving.js.map +1 -1
- package/dist/plugins/ui-variants/index.js +3 -1
- package/dist/plugins/ui-variants/index.js.map +1 -1
- package/dist/registry/index.d.ts +1 -1
- package/dist/registry/index.js +1 -1
- package/dist/registry/manifest-loader.d.ts +20 -1
- package/dist/registry/manifest-loader.d.ts.map +1 -1
- package/dist/registry/manifest-loader.js +23 -1
- package/dist/registry/manifest-loader.js.map +1 -1
- package/dist/schemas/manifest.d.ts +1 -1
- package/dist/shared/src/index.d.ts +1 -1
- package/dist/shared/src/naming.js +13 -1
- package/dist/shared/src/naming.js.map +1 -1
- package/dist/shared/src/schemas/manifest.d.ts +1 -1
- package/dist/shared/src/schemas/manifest.js +463 -0
- package/dist/shared/src/schemas/manifest.js.map +1 -0
- package/dist/testing/fixtures.d.ts +1 -1
- package/dist/type-generator/database/generate.d.ts +15 -0
- package/dist/type-generator/database/generate.d.ts.map +1 -0
- package/dist/type-generator/database/generate.js +104 -0
- package/dist/type-generator/database/generate.js.map +1 -0
- package/dist/type-generator/database/index.js +3 -0
- package/dist/type-generator/database/walk-schema.js +65 -0
- package/dist/type-generator/database/walk-schema.js.map +1 -0
- package/dist/type-generator/index.d.ts +148 -0
- package/dist/type-generator/index.d.ts.map +1 -0
- package/dist/type-generator/index.js +3 -1
- package/dist/type-generator/index.js.map +1 -1
- package/dist/type-generator/mv-registry/types.d.ts +99 -0
- package/dist/type-generator/mv-registry/types.d.ts.map +1 -0
- package/dist/type-generator/preflight.d.ts +16 -0
- package/dist/type-generator/preflight.d.ts.map +1 -0
- package/dist/type-generator/serving/generator.d.ts +20 -0
- package/dist/type-generator/serving/generator.d.ts.map +1 -0
- package/dist/type-generator/types.d.ts +72 -0
- package/dist/type-generator/types.d.ts.map +1 -0
- package/dist/type-generator/vite-plugin.d.ts +1 -0
- package/dist/type-generator/vite-plugin.d.ts.map +1 -1
- package/dist/type-generator/vite-plugin.js +41 -8
- package/dist/type-generator/vite-plugin.js.map +1 -1
- package/dist/type-generator/warehouse-status.d.ts +1 -0
- package/docs/api/appkit/Function.bigid.md +10 -0
- package/docs/api/appkit/Function.bigint.md +10 -0
- package/docs/api/appkit/Function.boolean.md +10 -0
- package/docs/api/appkit/Function.database.md +56 -0
- package/docs/api/appkit/Function.defineManifest.md +32 -0
- package/docs/api/appkit/Function.defineSchema.md +17 -0
- package/docs/api/appkit/Function.enumColumn.md +17 -0
- package/docs/api/appkit/Function.fk.md +18 -0
- package/docs/api/appkit/Function.id.md +10 -0
- package/docs/api/appkit/Function.integer.md +10 -0
- package/docs/api/appkit/Function.jsonb.md +10 -0
- package/docs/api/appkit/Function.text.md +10 -0
- package/docs/api/appkit/Function.timestamp.md +19 -0
- package/docs/api/appkit/Function.uuid.md +10 -0
- package/docs/api/appkit/Function.varchar.md +16 -0
- package/docs/api/appkit/Interface.DatabaseRegistry.md +3 -0
- package/docs/api/appkit/Interface.Schema.md +28 -0
- package/docs/api/appkit/TypeAlias.DatabaseExports.md +35 -0
- package/docs/api/appkit/TypeAlias.IDatabaseConfig.md +25 -0
- package/docs/api/appkit/Variable.agents.md +1 -1
- package/docs/api/appkit.md +19 -0
- package/llms.txt +19 -0
- package/package.json +4 -3
- package/sbom.cdx.json +1 -1
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { SchemaBuildError } from "./types.js";
|
|
2
|
+
import { columnValueSchema } from "./validators.js";
|
|
3
|
+
|
|
4
|
+
//#region src/database/schema-builder/columns.ts
|
|
5
|
+
const REFERENTIAL_ACTIONS = new Set([
|
|
6
|
+
"cascade",
|
|
7
|
+
"set null",
|
|
8
|
+
"set default",
|
|
9
|
+
"restrict",
|
|
10
|
+
"no action"
|
|
11
|
+
]);
|
|
12
|
+
const MAX_VARCHAR_LENGTH = 10485760;
|
|
13
|
+
function specStorageKind(spec) {
|
|
14
|
+
return spec.kind === "fk" ? "integer" : spec.kind;
|
|
15
|
+
}
|
|
16
|
+
function validateVarcharLength(length) {
|
|
17
|
+
if (!Number.isInteger(length) || length < 1 || length > MAX_VARCHAR_LENGTH) throw new SchemaBuildError(`varchar() length must be an integer between 1 and ${MAX_VARCHAR_LENGTH}`);
|
|
18
|
+
}
|
|
19
|
+
function validateEnum(name, values) {
|
|
20
|
+
if (!name) throw new SchemaBuildError("enum() requires a name");
|
|
21
|
+
if (values.length === 0) throw new SchemaBuildError(`enum("${name}") requires at least one value`);
|
|
22
|
+
if (values.some((value) => typeof value !== "string" || value.length === 0)) throw new SchemaBuildError(`enum("${name}") values must be non-empty strings`);
|
|
23
|
+
if (new Set(values).size !== values.length) throw new SchemaBuildError(`enum("${name}") declares duplicate values`);
|
|
24
|
+
return Object.freeze([...values]);
|
|
25
|
+
}
|
|
26
|
+
function validateReferentialAction(action) {
|
|
27
|
+
if (!REFERENTIAL_ACTIONS.has(action)) throw new SchemaBuildError("Unsupported referential action");
|
|
28
|
+
}
|
|
29
|
+
function isCompatibleLiteralDefault(meta) {
|
|
30
|
+
switch (meta.storageKind) {
|
|
31
|
+
case "id":
|
|
32
|
+
case "bigid":
|
|
33
|
+
case "bigint":
|
|
34
|
+
case "jsonb": return false;
|
|
35
|
+
default: return columnValueSchema(meta).safeParse(meta.defaultValue).success;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/** FK literals wait until finalization because fk() inherits target storage. */
|
|
39
|
+
function validateLiteralDefaults(tables) {
|
|
40
|
+
for (const table of tables) for (const meta of Object.values(table.metas)) if (Object.hasOwn(meta, "defaultValue") && !isCompatibleLiteralDefault(meta)) throw new SchemaBuildError(`Default for column "${table.name}.${meta.columnName}" is not compatible with ${meta.storageKind} storage`);
|
|
41
|
+
}
|
|
42
|
+
/** Mutable DSL builder; table() clones its metadata before finalization. */
|
|
43
|
+
var ColumnBuilder = class {
|
|
44
|
+
/** @internal */ _meta;
|
|
45
|
+
declarationKind;
|
|
46
|
+
constructor(spec, kind) {
|
|
47
|
+
this.declarationKind = spec.kind;
|
|
48
|
+
const enumValues = spec.kind === "enum" ? validateEnum(spec.enumName, spec.values) : void 0;
|
|
49
|
+
const serverGenerated = spec.kind === "id" || spec.kind === "bigid";
|
|
50
|
+
this._meta = {
|
|
51
|
+
name: "",
|
|
52
|
+
columnName: "",
|
|
53
|
+
kind,
|
|
54
|
+
storageKind: specStorageKind(spec),
|
|
55
|
+
notNull: serverGenerated,
|
|
56
|
+
primaryKey: serverGenerated,
|
|
57
|
+
unique: false,
|
|
58
|
+
isPrivate: false,
|
|
59
|
+
serverGenerated,
|
|
60
|
+
hasDefault: serverGenerated,
|
|
61
|
+
withTimezone: spec.kind === "timestamp" ? spec.withTimezone : void 0,
|
|
62
|
+
varcharLength: spec.kind === "varchar" ? spec.length : void 0,
|
|
63
|
+
enumName: spec.kind === "enum" ? spec.enumName : void 0,
|
|
64
|
+
enumValues
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
/** @internal Clone declaration state so builder reuse cannot mutate a table. */
|
|
68
|
+
_cloneMeta() {
|
|
69
|
+
return {
|
|
70
|
+
...this._meta,
|
|
71
|
+
enumValues: this._meta.enumValues ? Object.freeze([...this._meta.enumValues]) : void 0,
|
|
72
|
+
fk: this._meta.fk ? { ...this._meta.fk } : void 0
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
notNull() {
|
|
76
|
+
this._meta.notNull = true;
|
|
77
|
+
return this;
|
|
78
|
+
}
|
|
79
|
+
primaryKey() {
|
|
80
|
+
this._meta.primaryKey = true;
|
|
81
|
+
this._meta.notNull = true;
|
|
82
|
+
return this;
|
|
83
|
+
}
|
|
84
|
+
unique() {
|
|
85
|
+
this._meta.unique = true;
|
|
86
|
+
return this;
|
|
87
|
+
}
|
|
88
|
+
private() {
|
|
89
|
+
this._meta.isPrivate = true;
|
|
90
|
+
return this;
|
|
91
|
+
}
|
|
92
|
+
default(value) {
|
|
93
|
+
this.requireNoDefault();
|
|
94
|
+
this._meta.hasDefault = true;
|
|
95
|
+
this._meta.defaultValue = value;
|
|
96
|
+
return this;
|
|
97
|
+
}
|
|
98
|
+
defaultNow() {
|
|
99
|
+
this.requireNoDefault();
|
|
100
|
+
if (this.declarationKind !== "timestamp") throw new SchemaBuildError(".defaultNow() is only valid on timestamp columns");
|
|
101
|
+
this._meta.hasDefault = true;
|
|
102
|
+
this._meta.defaultNow = true;
|
|
103
|
+
return this;
|
|
104
|
+
}
|
|
105
|
+
defaultRandom() {
|
|
106
|
+
this.requireNoDefault();
|
|
107
|
+
if (this.declarationKind !== "uuid") throw new SchemaBuildError(".defaultRandom() is only valid on uuid columns");
|
|
108
|
+
this._meta.hasDefault = true;
|
|
109
|
+
this._meta.defaultRandom = true;
|
|
110
|
+
return this;
|
|
111
|
+
}
|
|
112
|
+
onDelete(action) {
|
|
113
|
+
this.requireFk("onDelete");
|
|
114
|
+
validateReferentialAction(action);
|
|
115
|
+
this._meta.onDelete = action;
|
|
116
|
+
return this;
|
|
117
|
+
}
|
|
118
|
+
onUpdate(action) {
|
|
119
|
+
this.requireFk("onUpdate");
|
|
120
|
+
validateReferentialAction(action);
|
|
121
|
+
this._meta.onUpdate = action;
|
|
122
|
+
return this;
|
|
123
|
+
}
|
|
124
|
+
requireNoDefault() {
|
|
125
|
+
if (this._meta.hasDefault) throw new SchemaBuildError("A column may declare only one default mode");
|
|
126
|
+
}
|
|
127
|
+
requireFk(modifier) {
|
|
128
|
+
if (this.declarationKind !== "fk") throw new SchemaBuildError(`.${modifier}() is only valid on fk() columns`);
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
const id = () => new ColumnBuilder({ kind: "id" }, "number");
|
|
132
|
+
const bigid = () => new ColumnBuilder({ kind: "bigid" }, "bigint");
|
|
133
|
+
const text = () => new ColumnBuilder({ kind: "text" }, "string");
|
|
134
|
+
const varchar = (length = 255) => {
|
|
135
|
+
validateVarcharLength(length);
|
|
136
|
+
return new ColumnBuilder({
|
|
137
|
+
kind: "varchar",
|
|
138
|
+
length
|
|
139
|
+
}, "string");
|
|
140
|
+
};
|
|
141
|
+
const integer = () => new ColumnBuilder({ kind: "integer" }, "number");
|
|
142
|
+
const bigint = () => new ColumnBuilder({ kind: "bigint" }, "bigint");
|
|
143
|
+
const boolean = () => new ColumnBuilder({ kind: "boolean" }, "boolean");
|
|
144
|
+
const uuid = () => new ColumnBuilder({ kind: "uuid" }, "uuid");
|
|
145
|
+
const timestamp = (opts) => {
|
|
146
|
+
return new ColumnBuilder({
|
|
147
|
+
kind: "timestamp",
|
|
148
|
+
withTimezone: opts?.withTimezone ?? false
|
|
149
|
+
}, "date");
|
|
150
|
+
};
|
|
151
|
+
const jsonb = () => new ColumnBuilder({ kind: "jsonb" }, "json");
|
|
152
|
+
function enumColumn(name, values) {
|
|
153
|
+
return new ColumnBuilder({
|
|
154
|
+
kind: "enum",
|
|
155
|
+
enumName: name,
|
|
156
|
+
values
|
|
157
|
+
}, "enum");
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
//#endregion
|
|
161
|
+
export { ColumnBuilder, bigid, bigint, boolean, enumColumn, id, integer, jsonb, text, timestamp, uuid, validateLiteralDefaults, varchar };
|
|
162
|
+
//# sourceMappingURL=columns.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"columns.js","names":[],"sources":["../../../src/database/schema-builder/columns.ts"],"sourcesContent":["import {\n type ColumnTypeSpec,\n type ColumnValueKind,\n type MutableColumnMeta,\n type ReferentialAction,\n SchemaBuildError,\n type StorageKind,\n} from \"./types\";\nimport { columnValueSchema } from \"./validators\";\n\nconst REFERENTIAL_ACTIONS = new Set<ReferentialAction>([\n \"cascade\",\n \"set null\",\n \"set default\",\n \"restrict\",\n \"no action\",\n]);\nconst MAX_VARCHAR_LENGTH = 10_485_760;\n\nfunction specStorageKind(spec: ColumnTypeSpec): StorageKind {\n return spec.kind === \"fk\" ? \"integer\" : spec.kind;\n}\n\nfunction validateVarcharLength(length: number): void {\n if (!Number.isInteger(length) || length < 1 || length > MAX_VARCHAR_LENGTH) {\n throw new SchemaBuildError(\n `varchar() length must be an integer between 1 and ${MAX_VARCHAR_LENGTH}`,\n );\n }\n}\n\nfunction validateEnum(\n name: string,\n values: readonly string[],\n): readonly string[] {\n if (!name) throw new SchemaBuildError(\"enum() requires a name\");\n if (values.length === 0) {\n throw new SchemaBuildError(`enum(\"${name}\") requires at least one value`);\n }\n if (values.some((value) => typeof value !== \"string\" || value.length === 0)) {\n throw new SchemaBuildError(\n `enum(\"${name}\") values must be non-empty strings`,\n );\n }\n if (new Set(values).size !== values.length) {\n throw new SchemaBuildError(`enum(\"${name}\") declares duplicate values`);\n }\n return Object.freeze([...values]);\n}\n\nfunction validateReferentialAction(action: ReferentialAction): void {\n if (!REFERENTIAL_ACTIONS.has(action)) {\n throw new SchemaBuildError(\"Unsupported referential action\");\n }\n}\n\ninterface DefaultValidationTable {\n readonly name: string;\n readonly metas: Readonly<Record<string, MutableColumnMeta>>;\n}\n\nfunction isCompatibleLiteralDefault(meta: MutableColumnMeta): boolean {\n switch (meta.storageKind) {\n case \"id\":\n case \"bigid\":\n case \"bigint\":\n case \"jsonb\":\n return false;\n default:\n return columnValueSchema(meta).safeParse(meta.defaultValue).success;\n }\n}\n\n/** FK literals wait until finalization because fk() inherits target storage. */\nexport function validateLiteralDefaults(\n tables: Iterable<DefaultValidationTable>,\n): void {\n for (const table of tables) {\n for (const meta of Object.values(table.metas)) {\n if (\n Object.hasOwn(meta, \"defaultValue\") &&\n !isCompatibleLiteralDefault(meta)\n ) {\n throw new SchemaBuildError(\n `Default for column \"${table.name}.${meta.columnName}\" is not compatible with ${meta.storageKind} storage`,\n );\n }\n }\n }\n}\n\n/** Mutable DSL builder; table() clones its metadata before finalization. */\nexport class ColumnBuilder {\n /** @internal */ readonly _meta: MutableColumnMeta;\n private readonly declarationKind: ColumnTypeSpec[\"kind\"];\n\n constructor(spec: ColumnTypeSpec, kind: ColumnValueKind) {\n this.declarationKind = spec.kind;\n const enumValues =\n spec.kind === \"enum\"\n ? validateEnum(spec.enumName, spec.values)\n : undefined;\n\n const serverGenerated = spec.kind === \"id\" || spec.kind === \"bigid\";\n this._meta = {\n name: \"\",\n columnName: \"\",\n kind,\n storageKind: specStorageKind(spec),\n notNull: serverGenerated,\n primaryKey: serverGenerated,\n unique: false,\n isPrivate: false,\n serverGenerated,\n hasDefault: serverGenerated,\n withTimezone: spec.kind === \"timestamp\" ? spec.withTimezone : undefined,\n varcharLength: spec.kind === \"varchar\" ? spec.length : undefined,\n enumName: spec.kind === \"enum\" ? spec.enumName : undefined,\n enumValues,\n };\n }\n\n /** @internal Clone declaration state so builder reuse cannot mutate a table. */\n _cloneMeta(): MutableColumnMeta {\n return {\n ...this._meta,\n enumValues: this._meta.enumValues\n ? Object.freeze([...this._meta.enumValues])\n : undefined,\n fk: this._meta.fk ? { ...this._meta.fk } : undefined,\n };\n }\n\n notNull(): this {\n this._meta.notNull = true;\n return this;\n }\n\n primaryKey(): this {\n this._meta.primaryKey = true;\n this._meta.notNull = true;\n return this;\n }\n\n unique(): this {\n this._meta.unique = true;\n return this;\n }\n\n private(): this {\n this._meta.isPrivate = true;\n return this;\n }\n\n default(value: string | number | boolean): this {\n this.requireNoDefault();\n this._meta.hasDefault = true;\n this._meta.defaultValue = value;\n return this;\n }\n\n defaultNow(): this {\n this.requireNoDefault();\n if (this.declarationKind !== \"timestamp\") {\n throw new SchemaBuildError(\n \".defaultNow() is only valid on timestamp columns\",\n );\n }\n this._meta.hasDefault = true;\n this._meta.defaultNow = true;\n return this;\n }\n\n defaultRandom(): this {\n this.requireNoDefault();\n if (this.declarationKind !== \"uuid\") {\n throw new SchemaBuildError(\n \".defaultRandom() is only valid on uuid columns\",\n );\n }\n this._meta.hasDefault = true;\n this._meta.defaultRandom = true;\n return this;\n }\n\n onDelete(action: ReferentialAction): this {\n this.requireFk(\"onDelete\");\n validateReferentialAction(action);\n this._meta.onDelete = action;\n return this;\n }\n\n onUpdate(action: ReferentialAction): this {\n this.requireFk(\"onUpdate\");\n validateReferentialAction(action);\n this._meta.onUpdate = action;\n return this;\n }\n\n private requireNoDefault(): void {\n if (this._meta.hasDefault) {\n throw new SchemaBuildError(\"A column may declare only one default mode\");\n }\n }\n\n private requireFk(modifier: string): void {\n if (this.declarationKind !== \"fk\") {\n throw new SchemaBuildError(\n `.${modifier}() is only valid on fk() columns`,\n );\n }\n }\n}\n\nexport const id = () => new ColumnBuilder({ kind: \"id\" }, \"number\");\nexport const bigid = () => new ColumnBuilder({ kind: \"bigid\" }, \"bigint\");\nexport const text = () => new ColumnBuilder({ kind: \"text\" }, \"string\");\nexport const varchar = (length = 255) => {\n validateVarcharLength(length);\n return new ColumnBuilder({ kind: \"varchar\", length }, \"string\");\n};\nexport const integer = () => new ColumnBuilder({ kind: \"integer\" }, \"number\");\nexport const bigint = () => new ColumnBuilder({ kind: \"bigint\" }, \"bigint\");\nexport const boolean = () => new ColumnBuilder({ kind: \"boolean\" }, \"boolean\");\nexport const uuid = () => new ColumnBuilder({ kind: \"uuid\" }, \"uuid\");\nexport const timestamp = (opts?: { withTimezone?: boolean }) => {\n const withTimezone = opts?.withTimezone ?? false;\n return new ColumnBuilder({ kind: \"timestamp\", withTimezone }, \"date\");\n};\nexport const jsonb = () => new ColumnBuilder({ kind: \"jsonb\" }, \"json\");\n\nexport function enumColumn(name: string, values: readonly string[]) {\n return new ColumnBuilder({ kind: \"enum\", enumName: name, values }, \"enum\");\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { AppKitTable, DefineSchemaOptions, Schema, TableHandle } from "./types.js";
|
|
2
|
+
import { ColumnBuilder } from "./columns.js";
|
|
3
|
+
|
|
4
|
+
//#region src/database/schema-builder/define-schema.d.ts
|
|
5
|
+
interface SchemaBuilderContext {
|
|
6
|
+
table<C extends Record<string, ColumnBuilder>>(name: string, columns: C): TableHandle<C>;
|
|
7
|
+
enum(name: string, values: readonly string[]): ColumnBuilder;
|
|
8
|
+
}
|
|
9
|
+
declare function defineSchema(builder: (context: SchemaBuilderContext) => Record<string, AppKitTable>, options?: DefineSchemaOptions): Schema;
|
|
10
|
+
//#endregion
|
|
11
|
+
export { defineSchema };
|
|
12
|
+
//# sourceMappingURL=define-schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"define-schema.d.ts","names":[],"sources":["../../../src/database/schema-builder/define-schema.ts"],"mappings":";;;;UAoCiB,oBAAA;EACf,KAAA,WAAgB,MAAA,SAAe,aAAA,GAC7B,IAAA,UACA,OAAA,EAAS,CAAA,GACR,WAAA,CAAY,CAAA;EACf,IAAA,CAAK,IAAA,UAAc,MAAA,sBAA4B,aAAA;AAAA;AAAA,iBA4SjC,YAAA,CACd,OAAA,GAAU,OAAA,EAAS,oBAAA,KAAyB,MAAA,SAAe,WAAA,GAC3D,OAAA,GAAU,mBAAA,GACT,MAAA"}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import { SchemaBuildError } from "./types.js";
|
|
2
|
+
import { deriveInsertSchema, deriveUpdateSchema } from "./validators.js";
|
|
3
|
+
import { ColumnBuilder, enumColumn, validateLiteralDefaults } from "./columns.js";
|
|
4
|
+
import { buildEngineTables } from "./engine/tables.js";
|
|
5
|
+
import { resolveForeignKeys } from "./fk.js";
|
|
6
|
+
import { buildRelations } from "./relations.js";
|
|
7
|
+
|
|
8
|
+
//#region src/database/schema-builder/define-schema.ts
|
|
9
|
+
const RESERVED_OBJECT_KEYS = new Set([
|
|
10
|
+
"__proto__",
|
|
11
|
+
"prototype",
|
|
12
|
+
"constructor"
|
|
13
|
+
]);
|
|
14
|
+
const RESERVED_DATABASE_EXPORT_KEYS = new Set(["sql", "transaction"]);
|
|
15
|
+
const FINALIZED_SCHEMA = Symbol.for("@databricks/appkit.database.schema");
|
|
16
|
+
const TABLE_METADATA_KEYS = [
|
|
17
|
+
"$name",
|
|
18
|
+
"$schemaName",
|
|
19
|
+
"$columns",
|
|
20
|
+
"$engine",
|
|
21
|
+
"$relations",
|
|
22
|
+
"$insertSchema",
|
|
23
|
+
"$updateSchema"
|
|
24
|
+
];
|
|
25
|
+
function nullRecord() {
|
|
26
|
+
return Object.create(null);
|
|
27
|
+
}
|
|
28
|
+
function assertRecord(value, label) {
|
|
29
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) throw new SchemaBuildError(`${label} must be an object`);
|
|
30
|
+
}
|
|
31
|
+
function assertName(value, label) {
|
|
32
|
+
if (!value || RESERVED_OBJECT_KEYS.has(value)) throw new SchemaBuildError(`${label} "${value}" is reserved`);
|
|
33
|
+
}
|
|
34
|
+
function assertTableName(value) {
|
|
35
|
+
assertName(value, "Table name");
|
|
36
|
+
if (RESERVED_DATABASE_EXPORT_KEYS.has(value)) throw new SchemaBuildError(`Table name "${value}" is reserved`);
|
|
37
|
+
}
|
|
38
|
+
function finalizeColumn(meta) {
|
|
39
|
+
if (!meta.engineColumn) throw new SchemaBuildError(`Engine column "${meta.columnName}" is missing during finalization`);
|
|
40
|
+
const { fkRef: _fkRef, ...published } = meta;
|
|
41
|
+
return Object.freeze({
|
|
42
|
+
...published,
|
|
43
|
+
enumValues: meta.enumValues ? Object.freeze([...meta.enumValues]) : void 0,
|
|
44
|
+
fk: meta.fk ? Object.freeze({ ...meta.fk }) : void 0,
|
|
45
|
+
engineColumn: meta.engineColumn
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
function finalizeRelations(relations) {
|
|
49
|
+
return Object.freeze(relations.map((relation) => Object.freeze({ ...relation })));
|
|
50
|
+
}
|
|
51
|
+
/** Clone builders into per-table metadata and create stable column handles. */
|
|
52
|
+
function declareTable(state, name, columns) {
|
|
53
|
+
assertTableName(name);
|
|
54
|
+
if (state.raw.has(name)) throw new SchemaBuildError(`Duplicate table "${name}"`);
|
|
55
|
+
assertRecord(columns, `Columns for table "${name}"`);
|
|
56
|
+
const metas = nullRecord();
|
|
57
|
+
const handle = Object.create(null);
|
|
58
|
+
for (const [key, column] of Object.entries(columns)) {
|
|
59
|
+
assertName(key, `Column name on table "${name}"`);
|
|
60
|
+
if (key.startsWith("$") || key === "and" || key === "or") throw new SchemaBuildError(`Column "${name}.${key}" collides with AppKit runtime metadata`);
|
|
61
|
+
if (!(column instanceof ColumnBuilder)) throw new SchemaBuildError(`Column "${name}.${key}" was not created by an AppKit column builder`);
|
|
62
|
+
const meta = column._cloneMeta();
|
|
63
|
+
meta.name = key;
|
|
64
|
+
meta.columnName = key;
|
|
65
|
+
metas[key] = meta;
|
|
66
|
+
const reference = Object.freeze({
|
|
67
|
+
__isColumnRef: true,
|
|
68
|
+
tableName: name,
|
|
69
|
+
columnName: key
|
|
70
|
+
});
|
|
71
|
+
Object.defineProperty(handle, key, {
|
|
72
|
+
enumerable: true,
|
|
73
|
+
value: reference
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
state.raw.set(name, {
|
|
77
|
+
name,
|
|
78
|
+
metas,
|
|
79
|
+
handle
|
|
80
|
+
});
|
|
81
|
+
state.handleNames.set(handle, name);
|
|
82
|
+
return handle;
|
|
83
|
+
}
|
|
84
|
+
function createBuilderContext(state) {
|
|
85
|
+
return {
|
|
86
|
+
table(name, columns) {
|
|
87
|
+
return declareTable(state, name, columns);
|
|
88
|
+
},
|
|
89
|
+
enum(name, values) {
|
|
90
|
+
return enumColumn(name, values);
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
/** Require every exact table handle once under its declared identity. */
|
|
95
|
+
function validateReturnedTables(returned, state) {
|
|
96
|
+
assertRecord(returned, "defineSchema() return value");
|
|
97
|
+
const returnedHandles = /* @__PURE__ */ new Set();
|
|
98
|
+
for (const [key, value] of Object.entries(returned)) {
|
|
99
|
+
const name = value !== null && typeof value === "object" ? state.handleNames.get(value) : void 0;
|
|
100
|
+
if (!name) throw new SchemaBuildError(`defineSchema returned a value for "${key}" that was not produced by ctx.table()`);
|
|
101
|
+
if (key !== name) throw new SchemaBuildError(`defineSchema returned table "${name}" under key "${key}"; aliases are not supported`);
|
|
102
|
+
if (returnedHandles.has(value)) throw new SchemaBuildError(`Table "${name}" was returned more than once`);
|
|
103
|
+
returnedHandles.add(value);
|
|
104
|
+
}
|
|
105
|
+
if (returnedHandles.size !== state.raw.size) {
|
|
106
|
+
const omitted = [...state.raw.values()].filter((table) => !returnedHandles.has(table.handle)).map((table) => table.name);
|
|
107
|
+
throw new SchemaBuildError(`defineSchema omitted declared table${omitted.length === 1 ? "" : "s"}: ${omitted.join(", ")}`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
/** Detect declaration-handle tampering before metadata publication. */
|
|
111
|
+
function validateHandles(raw) {
|
|
112
|
+
for (const table of raw.values()) {
|
|
113
|
+
const ownKeys = Reflect.ownKeys(table.handle);
|
|
114
|
+
const hasOnlyDeclaredColumns = ownKeys.length === Object.keys(table.metas).length && ownKeys.every((key) => typeof key === "string" && Object.hasOwn(table.metas, key));
|
|
115
|
+
const hasMetadataCollision = TABLE_METADATA_KEYS.some((key) => Object.hasOwn(table.handle, key));
|
|
116
|
+
if (Object.getPrototypeOf(table.handle) !== null || !Object.isExtensible(table.handle) || !hasOnlyDeclaredColumns || hasMetadataCollision) throw new SchemaBuildError(`Table handle "${table.name}" was modified during schema declaration`);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
/** Reject composite primary keys, which keyed operations cannot represent. */
|
|
120
|
+
function validatePrimaryKeys(raw) {
|
|
121
|
+
for (const table of raw.values()) if (Object.values(table.metas).filter((meta) => meta.primaryKey).length > 1) throw new SchemaBuildError(`Table "${table.name}" declares multiple primary-key columns; composite primary keys are not supported`);
|
|
122
|
+
}
|
|
123
|
+
/** Reject table names that collide with generated Drizzle relation keys. */
|
|
124
|
+
function validateRelationKeys(raw, relations) {
|
|
125
|
+
for (const [name, tableRelations] of relations) if (tableRelations.length > 0 && raw.has(`${name}Relations`)) throw new SchemaBuildError(`Table "${name}Relations" collides with generated relation metadata for "${name}"`);
|
|
126
|
+
}
|
|
127
|
+
/** Prepare every engine object and validator without mutating handles. */
|
|
128
|
+
function prepareTables(raw, schemaName, relations) {
|
|
129
|
+
const built = buildEngineTables(raw.values(), schemaName);
|
|
130
|
+
const candidates = /* @__PURE__ */ new Map();
|
|
131
|
+
for (const table of raw.values()) {
|
|
132
|
+
const builtTable = built.get(table.name);
|
|
133
|
+
if (!builtTable) throw new SchemaBuildError(`Engine table "${table.name}" was not constructed`);
|
|
134
|
+
const columns = nullRecord();
|
|
135
|
+
for (const [key, meta] of Object.entries(builtTable.columns)) columns[key] = finalizeColumn(meta);
|
|
136
|
+
Object.freeze(columns);
|
|
137
|
+
const tableRelations = finalizeRelations(relations.get(table.name) ?? []);
|
|
138
|
+
const validatorTable = { $columns: columns };
|
|
139
|
+
candidates.set(table.name, {
|
|
140
|
+
columns,
|
|
141
|
+
engine: builtTable.engine,
|
|
142
|
+
relations: tableRelations,
|
|
143
|
+
insertSchema: deriveInsertSchema(validatorTable),
|
|
144
|
+
updateSchema: deriveUpdateSchema(validatorTable)
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
return candidates;
|
|
148
|
+
}
|
|
149
|
+
/** Atomically publish prepared metadata as the final schema transition. */
|
|
150
|
+
function publishSchema(raw, candidates, schemaName) {
|
|
151
|
+
const publications = [...raw.values()].map((table) => {
|
|
152
|
+
const candidate = candidates.get(table.name);
|
|
153
|
+
if (!candidate) throw new SchemaBuildError(`Table "${table.name}" was not prepared for finalization`);
|
|
154
|
+
return {
|
|
155
|
+
table,
|
|
156
|
+
candidate
|
|
157
|
+
};
|
|
158
|
+
});
|
|
159
|
+
const tables = nullRecord();
|
|
160
|
+
const engine = nullRecord();
|
|
161
|
+
for (const { table, candidate } of publications) {
|
|
162
|
+
Object.defineProperties(table.handle, {
|
|
163
|
+
$name: { value: table.name },
|
|
164
|
+
$schemaName: { value: schemaName },
|
|
165
|
+
$columns: { value: candidate.columns },
|
|
166
|
+
$engine: { value: candidate.engine },
|
|
167
|
+
$relations: { value: candidate.relations },
|
|
168
|
+
$insertSchema: { value: candidate.insertSchema },
|
|
169
|
+
$updateSchema: { value: candidate.updateSchema }
|
|
170
|
+
});
|
|
171
|
+
const finalized = Object.freeze(table.handle);
|
|
172
|
+
tables[table.name] = finalized;
|
|
173
|
+
engine[table.name] = candidate.engine;
|
|
174
|
+
}
|
|
175
|
+
const schema = {
|
|
176
|
+
$schemaName: schemaName,
|
|
177
|
+
$tables: Object.freeze(tables),
|
|
178
|
+
$engine: Object.freeze(engine)
|
|
179
|
+
};
|
|
180
|
+
Object.defineProperty(schema, FINALIZED_SCHEMA, { value: true });
|
|
181
|
+
return Object.freeze(schema);
|
|
182
|
+
}
|
|
183
|
+
/** @internal Reject values that were not finalized by `defineSchema()`. */
|
|
184
|
+
function assertFinalizedSchema(value) {
|
|
185
|
+
if (value === null || typeof value !== "object" || value[FINALIZED_SCHEMA] !== true) throw new TypeError("Expected a finalized AppKit database schema");
|
|
186
|
+
}
|
|
187
|
+
function defineSchema(builder, options) {
|
|
188
|
+
const schemaName = options?.schemaName ?? "public";
|
|
189
|
+
if (!schemaName) throw new SchemaBuildError("Schema name cannot be empty");
|
|
190
|
+
const state = {
|
|
191
|
+
raw: /* @__PURE__ */ new Map(),
|
|
192
|
+
handleNames: /* @__PURE__ */ new Map()
|
|
193
|
+
};
|
|
194
|
+
validateReturnedTables(builder(createBuilderContext(state)), state);
|
|
195
|
+
validateHandles(state.raw);
|
|
196
|
+
validatePrimaryKeys(state.raw);
|
|
197
|
+
resolveForeignKeys(state.raw);
|
|
198
|
+
validateLiteralDefaults(state.raw.values());
|
|
199
|
+
const relations = buildRelations(state.raw);
|
|
200
|
+
validateRelationKeys(state.raw, relations);
|
|
201
|
+
const candidates = prepareTables(state.raw, schemaName, relations);
|
|
202
|
+
return publishSchema(state.raw, candidates, schemaName);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
//#endregion
|
|
206
|
+
export { assertFinalizedSchema, defineSchema };
|
|
207
|
+
//# sourceMappingURL=define-schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"define-schema.js","names":[],"sources":["../../../src/database/schema-builder/define-schema.ts"],"sourcesContent":["import { ColumnBuilder, enumColumn, validateLiteralDefaults } from \"./columns\";\nimport { buildEngineTables } from \"./engine/tables\";\nimport { resolveForeignKeys } from \"./fk\";\nimport { buildRelations } from \"./relations\";\nimport {\n type AppKitTable,\n type ColumnMeta,\n type ColumnRef,\n type DefineSchemaOptions,\n type MutableColumnMeta,\n type ResolvedRelation,\n type Schema,\n SchemaBuildError,\n type TableHandle,\n} from \"./types\";\nimport { deriveInsertSchema, deriveUpdateSchema } from \"./validators\";\n\ninterface RawTable {\n readonly name: string;\n readonly metas: Record<string, MutableColumnMeta>;\n readonly handle: Record<string, ColumnRef>;\n}\n\ninterface FinalizedTableCandidate {\n readonly columns: Readonly<Record<string, ColumnMeta>>;\n readonly engine: Schema[\"$engine\"][string];\n readonly relations: readonly ResolvedRelation[];\n readonly insertSchema: unknown;\n readonly updateSchema: unknown;\n}\n\ninterface DeclarationState {\n readonly raw: Map<string, RawTable>;\n readonly handleNames: Map<object, string>;\n}\n\nexport interface SchemaBuilderContext {\n table<C extends Record<string, ColumnBuilder>>(\n name: string,\n columns: C,\n ): TableHandle<C>;\n enum(name: string, values: readonly string[]): ColumnBuilder;\n}\n\nconst RESERVED_OBJECT_KEYS = new Set([\"__proto__\", \"prototype\", \"constructor\"]);\nconst RESERVED_DATABASE_EXPORT_KEYS = new Set([\"sql\", \"transaction\"]);\n// A global symbol lets typegen recognize schemas loaded through another AppKit instance.\nconst FINALIZED_SCHEMA = Symbol.for(\"@databricks/appkit.database.schema\");\nconst TABLE_METADATA_KEYS = [\n \"$name\",\n \"$schemaName\",\n \"$columns\",\n \"$engine\",\n \"$relations\",\n \"$insertSchema\",\n \"$updateSchema\",\n] as const;\n\nfunction nullRecord<T>(): Record<string, T> {\n return Object.create(null) as Record<string, T>;\n}\n\nfunction assertRecord(value: unknown, label: string): asserts value is object {\n if (value === null || typeof value !== \"object\" || Array.isArray(value)) {\n throw new SchemaBuildError(`${label} must be an object`);\n }\n}\n\nfunction assertName(value: string, label: string): void {\n if (!value || RESERVED_OBJECT_KEYS.has(value)) {\n throw new SchemaBuildError(`${label} \"${value}\" is reserved`);\n }\n}\n\nfunction assertTableName(value: string): void {\n assertName(value, \"Table name\");\n if (RESERVED_DATABASE_EXPORT_KEYS.has(value)) {\n throw new SchemaBuildError(`Table name \"${value}\" is reserved`);\n }\n}\n\nfunction finalizeColumn(meta: MutableColumnMeta): ColumnMeta {\n if (!meta.engineColumn) {\n throw new SchemaBuildError(\n `Engine column \"${meta.columnName}\" is missing during finalization`,\n );\n }\n const { fkRef: _fkRef, ...published } = meta;\n return Object.freeze({\n ...published,\n enumValues: meta.enumValues\n ? Object.freeze([...meta.enumValues])\n : undefined,\n fk: meta.fk ? Object.freeze({ ...meta.fk }) : undefined,\n engineColumn: meta.engineColumn,\n }) as ColumnMeta;\n}\n\nfunction finalizeRelations(\n relations: readonly ResolvedRelation[],\n): readonly ResolvedRelation[] {\n return Object.freeze(\n relations.map((relation) => Object.freeze({ ...relation })),\n );\n}\n\n/** Clone builders into per-table metadata and create stable column handles. */\nfunction declareTable<C extends Record<string, ColumnBuilder>>(\n state: DeclarationState,\n name: string,\n columns: C,\n): TableHandle<C> {\n assertTableName(name);\n if (state.raw.has(name)) {\n throw new SchemaBuildError(`Duplicate table \"${name}\"`);\n }\n assertRecord(columns, `Columns for table \"${name}\"`);\n\n const metas = nullRecord<MutableColumnMeta>();\n const handle = Object.create(null) as Record<string, ColumnRef>;\n for (const [key, column] of Object.entries(columns)) {\n assertName(key, `Column name on table \"${name}\"`);\n if (key.startsWith(\"$\") || key === \"and\" || key === \"or\") {\n throw new SchemaBuildError(\n `Column \"${name}.${key}\" collides with AppKit runtime metadata`,\n );\n }\n if (!(column instanceof ColumnBuilder)) {\n throw new SchemaBuildError(\n `Column \"${name}.${key}\" was not created by an AppKit column builder`,\n );\n }\n\n const meta = column._cloneMeta();\n meta.name = key;\n meta.columnName = key;\n metas[key] = meta;\n\n const reference: ColumnRef = Object.freeze({\n __isColumnRef: true,\n tableName: name,\n columnName: key,\n });\n Object.defineProperty(handle, key, {\n enumerable: true,\n value: reference,\n });\n }\n\n state.raw.set(name, { name, metas, handle });\n state.handleNames.set(handle, name);\n return handle as unknown as TableHandle<C>;\n}\n\nfunction createBuilderContext(state: DeclarationState): SchemaBuilderContext {\n return {\n table(name, columns) {\n return declareTable(state, name, columns);\n },\n enum(name, values) {\n return enumColumn(name, values);\n },\n };\n}\n\n/** Require every exact table handle once under its declared identity. */\nfunction validateReturnedTables(\n returned: unknown,\n state: DeclarationState,\n): void {\n assertRecord(returned, \"defineSchema() return value\");\n const returnedHandles = new Set<object>();\n for (const [key, value] of Object.entries(returned)) {\n const name =\n value !== null && typeof value === \"object\"\n ? state.handleNames.get(value)\n : undefined;\n if (!name) {\n throw new SchemaBuildError(\n `defineSchema returned a value for \"${key}\" that was not produced by ctx.table()`,\n );\n }\n if (key !== name) {\n throw new SchemaBuildError(\n `defineSchema returned table \"${name}\" under key \"${key}\"; aliases are not supported`,\n );\n }\n if (returnedHandles.has(value)) {\n throw new SchemaBuildError(`Table \"${name}\" was returned more than once`);\n }\n returnedHandles.add(value);\n }\n if (returnedHandles.size !== state.raw.size) {\n const omitted = [...state.raw.values()]\n .filter((table) => !returnedHandles.has(table.handle))\n .map((table) => table.name);\n throw new SchemaBuildError(\n `defineSchema omitted declared table${omitted.length === 1 ? \"\" : \"s\"}: ${omitted.join(\", \")}`,\n );\n }\n}\n\n/** Detect declaration-handle tampering before metadata publication. */\nfunction validateHandles(raw: ReadonlyMap<string, RawTable>): void {\n for (const table of raw.values()) {\n const ownKeys = Reflect.ownKeys(table.handle);\n const hasOnlyDeclaredColumns =\n ownKeys.length === Object.keys(table.metas).length &&\n ownKeys.every(\n (key) => typeof key === \"string\" && Object.hasOwn(table.metas, key),\n );\n const hasMetadataCollision = TABLE_METADATA_KEYS.some((key) =>\n Object.hasOwn(table.handle, key),\n );\n if (\n Object.getPrototypeOf(table.handle) !== null ||\n !Object.isExtensible(table.handle) ||\n !hasOnlyDeclaredColumns ||\n hasMetadataCollision\n ) {\n throw new SchemaBuildError(\n `Table handle \"${table.name}\" was modified during schema declaration`,\n );\n }\n }\n}\n\n/** Reject composite primary keys, which keyed operations cannot represent. */\nfunction validatePrimaryKeys(raw: ReadonlyMap<string, RawTable>): void {\n for (const table of raw.values()) {\n const primaryKeys = Object.values(table.metas).filter(\n (meta) => meta.primaryKey,\n );\n if (primaryKeys.length > 1) {\n throw new SchemaBuildError(\n `Table \"${table.name}\" declares multiple primary-key columns; composite primary keys are not supported`,\n );\n }\n }\n}\n\n/** Reject table names that collide with generated Drizzle relation keys. */\nfunction validateRelationKeys(\n raw: ReadonlyMap<string, RawTable>,\n relations: ReadonlyMap<string, readonly ResolvedRelation[]>,\n): void {\n for (const [name, tableRelations] of relations) {\n if (tableRelations.length > 0 && raw.has(`${name}Relations`)) {\n throw new SchemaBuildError(\n `Table \"${name}Relations\" collides with generated relation metadata for \"${name}\"`,\n );\n }\n }\n}\n\n/** Prepare every engine object and validator without mutating handles. */\nfunction prepareTables(\n raw: ReadonlyMap<string, RawTable>,\n schemaName: string,\n relations: ReadonlyMap<string, readonly ResolvedRelation[]>,\n): Map<string, FinalizedTableCandidate> {\n const built = buildEngineTables(raw.values(), schemaName);\n const candidates = new Map<string, FinalizedTableCandidate>();\n for (const table of raw.values()) {\n const builtTable = built.get(table.name);\n if (!builtTable) {\n throw new SchemaBuildError(\n `Engine table \"${table.name}\" was not constructed`,\n );\n }\n const columns = nullRecord<ColumnMeta>();\n for (const [key, meta] of Object.entries(builtTable.columns)) {\n columns[key] = finalizeColumn(meta);\n }\n Object.freeze(columns);\n const tableRelations = finalizeRelations(relations.get(table.name) ?? []);\n const validatorTable = { $columns: columns } as AppKitTable;\n candidates.set(table.name, {\n columns,\n engine: builtTable.engine,\n relations: tableRelations,\n insertSchema: deriveInsertSchema(validatorTable),\n updateSchema: deriveUpdateSchema(validatorTable),\n });\n }\n return candidates;\n}\n\n/** Atomically publish prepared metadata as the final schema transition. */\nfunction publishSchema(\n raw: ReadonlyMap<string, RawTable>,\n candidates: ReadonlyMap<string, FinalizedTableCandidate>,\n schemaName: string,\n): Schema {\n const publications = [...raw.values()].map((table) => {\n const candidate = candidates.get(table.name);\n if (!candidate) {\n throw new SchemaBuildError(\n `Table \"${table.name}\" was not prepared for finalization`,\n );\n }\n return { table, candidate };\n });\n\n const tables = nullRecord<AppKitTable>();\n const engine = nullRecord<Schema[\"$engine\"][string]>();\n for (const { table, candidate } of publications) {\n Object.defineProperties(table.handle, {\n $name: { value: table.name },\n $schemaName: { value: schemaName },\n $columns: { value: candidate.columns },\n $engine: { value: candidate.engine },\n $relations: { value: candidate.relations },\n $insertSchema: { value: candidate.insertSchema },\n $updateSchema: { value: candidate.updateSchema },\n });\n const finalized = Object.freeze(table.handle) as unknown as AppKitTable;\n tables[table.name] = finalized;\n engine[table.name] = candidate.engine;\n }\n\n const schema = {\n $schemaName: schemaName,\n $tables: Object.freeze(tables),\n $engine: Object.freeze(engine),\n };\n Object.defineProperty(schema, FINALIZED_SCHEMA, { value: true });\n return Object.freeze(schema);\n}\n\n/** @internal Reject values that were not finalized by `defineSchema()`. */\nexport function assertFinalizedSchema(value: unknown): asserts value is Schema {\n if (\n value === null ||\n typeof value !== \"object\" ||\n (value as Record<PropertyKey, unknown>)[FINALIZED_SCHEMA] !== true\n ) {\n throw new TypeError(\"Expected a finalized AppKit database schema\");\n }\n}\n\nexport function defineSchema(\n builder: (context: SchemaBuilderContext) => Record<string, AppKitTable>,\n options?: DefineSchemaOptions,\n): Schema {\n const schemaName = options?.schemaName ?? \"public\";\n if (!schemaName) throw new SchemaBuildError(\"Schema name cannot be empty\");\n\n const state: DeclarationState = {\n raw: new Map(),\n handleNames: new Map(),\n };\n const returned = builder(createBuilderContext(state));\n\n validateReturnedTables(returned, state);\n validateHandles(state.raw);\n validatePrimaryKeys(state.raw);\n resolveForeignKeys(state.raw);\n // FK literals are checked against the inherited target storage, not the placeholder.\n validateLiteralDefaults(state.raw.values());\n\n const relations = buildRelations(state.raw);\n validateRelationKeys(state.raw, relations);\n const candidates = prepareTables(state.raw, schemaName, relations);\n return publishSchema(state.raw, candidates, schemaName);\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { SchemaBuildError } from "../types.js";
|
|
2
|
+
import { relations } from "drizzle-orm";
|
|
3
|
+
|
|
4
|
+
//#region src/database/schema-builder/engine/relations.ts
|
|
5
|
+
function columnOf(table, name) {
|
|
6
|
+
const column = table.$columns[name]?.engineColumn;
|
|
7
|
+
if (!column) throw new SchemaBuildError(`Engine relation column "${table.$name}.${name}" is not finalized`);
|
|
8
|
+
return column;
|
|
9
|
+
}
|
|
10
|
+
/** Adapt finalized relation metadata to Drizzle's relation registration shape. */
|
|
11
|
+
function buildEngineRelations(tables) {
|
|
12
|
+
const byName = /* @__PURE__ */ new Map();
|
|
13
|
+
for (const table of Object.values(tables)) byName.set(table.$name, table);
|
|
14
|
+
const out = Object.create(null);
|
|
15
|
+
for (const table of Object.values(tables)) {
|
|
16
|
+
if (table.$relations.length === 0) continue;
|
|
17
|
+
const localEngine = table.$engine;
|
|
18
|
+
out[`${table.$name}Relations`] = relations(localEngine, ({ one, many }) => {
|
|
19
|
+
const config = Object.create(null);
|
|
20
|
+
for (const relation of table.$relations) {
|
|
21
|
+
const target = byName.get(relation.targetTable);
|
|
22
|
+
if (!target) throw new SchemaBuildError(`Engine relation target "${relation.targetTable}" is not finalized`);
|
|
23
|
+
const targetEngine = target.$engine;
|
|
24
|
+
config[relation.name] = relation.cardinality === "toOne" ? one(targetEngine, {
|
|
25
|
+
fields: [columnOf(table, relation.localColumn)],
|
|
26
|
+
references: [columnOf(target, relation.targetColumn)]
|
|
27
|
+
}) : many(targetEngine);
|
|
28
|
+
}
|
|
29
|
+
return config;
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
return out;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
//#endregion
|
|
36
|
+
export { buildEngineRelations };
|
|
37
|
+
//# sourceMappingURL=relations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relations.js","names":[],"sources":["../../../../src/database/schema-builder/engine/relations.ts"],"sourcesContent":["import { type Relation, relations } from \"drizzle-orm\";\nimport type { AnyPgColumn, PgTable } from \"drizzle-orm/pg-core\";\n\nimport { type AppKitTable, SchemaBuildError } from \"../types\";\n\nfunction columnOf(table: AppKitTable, name: string): AnyPgColumn {\n const column = table.$columns[name]?.engineColumn;\n if (!column) {\n throw new SchemaBuildError(\n `Engine relation column \"${table.$name}.${name}\" is not finalized`,\n );\n }\n return column as unknown as AnyPgColumn;\n}\n\n/** Adapt finalized relation metadata to Drizzle's relation registration shape. */\nexport function buildEngineRelations(\n tables: Record<string, AppKitTable>,\n): Record<string, unknown> {\n const byName = new Map<string, AppKitTable>();\n for (const table of Object.values(tables)) byName.set(table.$name, table);\n\n const out: Record<string, unknown> = Object.create(null);\n\n for (const table of Object.values(tables)) {\n if (table.$relations.length === 0) continue;\n\n const localEngine = table.$engine as unknown as PgTable;\n out[`${table.$name}Relations`] = relations(localEngine, ({ one, many }) => {\n const config: Record<string, Relation> = Object.create(null);\n for (const relation of table.$relations) {\n const target = byName.get(relation.targetTable);\n if (!target) {\n throw new SchemaBuildError(\n `Engine relation target \"${relation.targetTable}\" is not finalized`,\n );\n }\n const targetEngine = target.$engine as unknown as PgTable;\n config[relation.name] =\n relation.cardinality === \"toOne\"\n ? one(targetEngine, {\n fields: [columnOf(table, relation.localColumn)],\n references: [columnOf(target, relation.targetColumn)],\n })\n : many(targetEngine);\n }\n return config;\n });\n }\n return out;\n}\n"],"mappings":";;;;AAKA,SAAS,SAAS,OAAoB,MAA2B;CAC/D,MAAM,SAAS,MAAM,SAAS,OAAO;AACrC,KAAI,CAAC,OACH,OAAM,IAAI,iBACR,2BAA2B,MAAM,MAAM,GAAG,KAAK,oBAChD;AAEH,QAAO;;;AAIT,SAAgB,qBACd,QACyB;CACzB,MAAM,yBAAS,IAAI,KAA0B;AAC7C,MAAK,MAAM,SAAS,OAAO,OAAO,OAAO,CAAE,QAAO,IAAI,MAAM,OAAO,MAAM;CAEzE,MAAM,MAA+B,OAAO,OAAO,KAAK;AAExD,MAAK,MAAM,SAAS,OAAO,OAAO,OAAO,EAAE;AACzC,MAAI,MAAM,WAAW,WAAW,EAAG;EAEnC,MAAM,cAAc,MAAM;AAC1B,MAAI,GAAG,MAAM,MAAM,cAAc,UAAU,cAAc,EAAE,KAAK,WAAW;GACzE,MAAM,SAAmC,OAAO,OAAO,KAAK;AAC5D,QAAK,MAAM,YAAY,MAAM,YAAY;IACvC,MAAM,SAAS,OAAO,IAAI,SAAS,YAAY;AAC/C,QAAI,CAAC,OACH,OAAM,IAAI,iBACR,2BAA2B,SAAS,YAAY,oBACjD;IAEH,MAAM,eAAe,OAAO;AAC5B,WAAO,SAAS,QACd,SAAS,gBAAgB,UACrB,IAAI,cAAc;KAChB,QAAQ,CAAC,SAAS,OAAO,SAAS,YAAY,CAAC;KAC/C,YAAY,CAAC,SAAS,QAAQ,SAAS,aAAa,CAAC;KACtD,CAAC,GACF,KAAK,aAAa;;AAE1B,UAAO;IACP;;AAEJ,QAAO"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { SchemaBuildError } from "../types.js";
|
|
2
|
+
import { bigint, boolean, integer, jsonb, pgEnum, pgSchema, pgTable, text, timestamp, uuid, varchar } from "drizzle-orm/pg-core";
|
|
3
|
+
|
|
4
|
+
//#region src/database/schema-builder/engine/tables.ts
|
|
5
|
+
function sameValues(left, right) {
|
|
6
|
+
return left.length === right.length && left.every((value, index) => value === right[index]);
|
|
7
|
+
}
|
|
8
|
+
function getEnum(registry, schemaName, name, values) {
|
|
9
|
+
const existing = registry.get(name);
|
|
10
|
+
if (existing) {
|
|
11
|
+
if (!sameValues(existing.enumValues, values)) throw new SchemaBuildError(`Enum "${name}" is declared with conflicting values`);
|
|
12
|
+
return existing;
|
|
13
|
+
}
|
|
14
|
+
const tuple = values;
|
|
15
|
+
const created = schemaName === "public" ? pgEnum(name, tuple) : pgSchema(schemaName).enum(name, tuple);
|
|
16
|
+
registry.set(name, created);
|
|
17
|
+
return created;
|
|
18
|
+
}
|
|
19
|
+
/** Map resolved storage metadata to its Drizzle column builder. */
|
|
20
|
+
function baseColumn(meta, schemaName, enums) {
|
|
21
|
+
const name = meta.columnName;
|
|
22
|
+
let builder;
|
|
23
|
+
switch (meta.storageKind) {
|
|
24
|
+
case "id":
|
|
25
|
+
case "integer":
|
|
26
|
+
builder = integer(name);
|
|
27
|
+
break;
|
|
28
|
+
case "bigid":
|
|
29
|
+
case "bigint":
|
|
30
|
+
builder = bigint(name, { mode: "bigint" });
|
|
31
|
+
break;
|
|
32
|
+
case "text":
|
|
33
|
+
builder = text(name);
|
|
34
|
+
break;
|
|
35
|
+
case "varchar":
|
|
36
|
+
builder = varchar(name, { length: meta.varcharLength ?? 255 });
|
|
37
|
+
break;
|
|
38
|
+
case "boolean":
|
|
39
|
+
builder = boolean(name);
|
|
40
|
+
break;
|
|
41
|
+
case "uuid":
|
|
42
|
+
builder = uuid(name);
|
|
43
|
+
break;
|
|
44
|
+
case "timestamp":
|
|
45
|
+
builder = timestamp(name, {
|
|
46
|
+
mode: "string",
|
|
47
|
+
withTimezone: meta.withTimezone ?? false
|
|
48
|
+
});
|
|
49
|
+
break;
|
|
50
|
+
case "jsonb":
|
|
51
|
+
builder = jsonb(name);
|
|
52
|
+
break;
|
|
53
|
+
case "enum":
|
|
54
|
+
if (!meta.enumName || !meta.enumValues?.length) throw new SchemaBuildError(`Enum column "${meta.columnName}" has no enum definition`);
|
|
55
|
+
builder = getEnum(enums, schemaName, meta.enumName, meta.enumValues)(name);
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
return builder;
|
|
59
|
+
}
|
|
60
|
+
function buildColumn(meta, schemaName, enums, resolveTarget) {
|
|
61
|
+
let column = baseColumn(meta, schemaName, enums);
|
|
62
|
+
if (meta.serverGenerated) column = column.generatedByDefaultAsIdentity();
|
|
63
|
+
if (meta.primaryKey) column = column.primaryKey();
|
|
64
|
+
else if (meta.notNull) column = column.notNull();
|
|
65
|
+
if (meta.unique) column = column.unique();
|
|
66
|
+
if (!meta.serverGenerated) {
|
|
67
|
+
if (meta.defaultNow) column = column.defaultNow();
|
|
68
|
+
else if (meta.defaultRandom) column = column.defaultRandom();
|
|
69
|
+
else if (Object.hasOwn(meta, "defaultValue")) column = column.default(meta.defaultValue);
|
|
70
|
+
}
|
|
71
|
+
if (meta.fk) {
|
|
72
|
+
const target = meta.fk;
|
|
73
|
+
column = column.references(() => resolveTarget(target.targetTable, target.targetColumn), {
|
|
74
|
+
onDelete: target.onDelete,
|
|
75
|
+
onUpdate: target.onUpdate
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
return column;
|
|
79
|
+
}
|
|
80
|
+
const PG_TIMESTAMP = /^(\d{4}-\d{2}-\d{2})[ T](\d{2}:\d{2}:\d{2}(?:\.\d+)?)(?:([+-]\d{2})(?::?(\d{2}))?)?$/;
|
|
81
|
+
function isoTimestamp(value) {
|
|
82
|
+
if (typeof value !== "string") return value;
|
|
83
|
+
const parts = PG_TIMESTAMP.exec(value);
|
|
84
|
+
if (!parts) return value;
|
|
85
|
+
const [, date, time, offsetHours, offsetMinutes] = parts;
|
|
86
|
+
return `${date}T${time}${offsetHours === void 0 ? "" : `${offsetHours}:${offsetMinutes ?? "00"}`}`;
|
|
87
|
+
}
|
|
88
|
+
function buildTable(name, schemaName, metas, enums, resolveTarget) {
|
|
89
|
+
const columnBuilders = Object.create(null);
|
|
90
|
+
for (const [key, meta] of Object.entries(metas)) columnBuilders[key] = buildColumn(meta, schemaName, enums, resolveTarget);
|
|
91
|
+
const engine = schemaName === "public" ? pgTable(name, columnBuilders) : pgSchema(schemaName).table(name, columnBuilders);
|
|
92
|
+
for (const [key, meta] of Object.entries(metas)) {
|
|
93
|
+
const engineColumn = engine[key];
|
|
94
|
+
if (!engineColumn) throw new SchemaBuildError(`Engine column "${name}.${key}" was not constructed`);
|
|
95
|
+
if (meta.storageKind === "timestamp") engineColumn.mapFromDriverValue = isoTimestamp;
|
|
96
|
+
meta.engineColumn = engineColumn;
|
|
97
|
+
}
|
|
98
|
+
return {
|
|
99
|
+
engine,
|
|
100
|
+
columns: metas
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
/** Build all Drizzle tables only after declaration validation has succeeded. */
|
|
104
|
+
function buildEngineTables(raw, schemaName) {
|
|
105
|
+
const entries = [...raw];
|
|
106
|
+
const builtEngine = /* @__PURE__ */ new Map();
|
|
107
|
+
const resolveTarget = (table, column) => {
|
|
108
|
+
const target = builtEngine.get(table)?.[column];
|
|
109
|
+
if (!target) throw new SchemaBuildError(`Cannot resolve FK target "${table}.${column}"`);
|
|
110
|
+
return target;
|
|
111
|
+
};
|
|
112
|
+
const enums = /* @__PURE__ */ new Map();
|
|
113
|
+
const tables = /* @__PURE__ */ new Map();
|
|
114
|
+
for (const { name, metas } of entries) {
|
|
115
|
+
const built = buildTable(name, schemaName, metas, enums, resolveTarget);
|
|
116
|
+
builtEngine.set(name, built.engine);
|
|
117
|
+
tables.set(name, built);
|
|
118
|
+
}
|
|
119
|
+
return tables;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
//#endregion
|
|
123
|
+
export { buildEngineTables };
|
|
124
|
+
//# sourceMappingURL=tables.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tables.js","names":["pgInteger","pgBigint","pgText","pgVarchar","pgBoolean","pgUuid","pgTimestamp","pgJsonb"],"sources":["../../../../src/database/schema-builder/engine/tables.ts"],"sourcesContent":["import {\n type AnyPgColumn,\n type PgColumnBuilderBase,\n type PgEnum,\n bigint as pgBigint,\n boolean as pgBoolean,\n pgEnum,\n integer as pgInteger,\n jsonb as pgJsonb,\n pgSchema,\n pgTable,\n text as pgText,\n timestamp as pgTimestamp,\n uuid as pgUuid,\n varchar as pgVarchar,\n} from \"drizzle-orm/pg-core\";\n\nimport {\n type EngineTable,\n type MutableColumnMeta,\n type ReferentialAction,\n SchemaBuildError,\n} from \"../types\";\n\ntype AnyColumnBuilder = PgColumnBuilderBase & {\n primaryKey(): AnyColumnBuilder;\n notNull(): AnyColumnBuilder;\n unique(): AnyColumnBuilder;\n default(value: unknown): AnyColumnBuilder;\n defaultNow(): AnyColumnBuilder;\n defaultRandom(): AnyColumnBuilder;\n generatedByDefaultAsIdentity(): AnyColumnBuilder;\n references(\n ref: () => AnyPgColumn,\n actions?: { onDelete?: ReferentialAction; onUpdate?: ReferentialAction },\n ): AnyColumnBuilder;\n};\n\ntype PgEnumValues = PgEnum<[string, ...string[]]>;\n/** Reuse one Drizzle enum object for each enum name in this schema. */\ntype EnumRegistry = Map<string, PgEnumValues>;\n\ninterface BuiltEngineTable {\n readonly engine: EngineTable;\n readonly columns: Record<string, MutableColumnMeta>;\n}\n\nfunction sameValues(\n left: readonly string[],\n right: readonly string[],\n): boolean {\n return (\n left.length === right.length &&\n left.every((value, index) => value === right[index])\n );\n}\n\nfunction getEnum(\n registry: EnumRegistry,\n schemaName: string,\n name: string,\n values: readonly string[],\n): PgEnumValues {\n const existing = registry.get(name);\n if (existing) {\n if (!sameValues(existing.enumValues, values)) {\n throw new SchemaBuildError(\n `Enum \"${name}\" is declared with conflicting values`,\n );\n }\n return existing;\n }\n\n const tuple = values as [string, ...string[]];\n const created =\n schemaName === \"public\"\n ? pgEnum(name, tuple)\n : pgSchema(schemaName).enum(name, tuple);\n registry.set(name, created as PgEnumValues);\n return created as PgEnumValues;\n}\n\n/** Map resolved storage metadata to its Drizzle column builder. */\nfunction baseColumn(\n meta: MutableColumnMeta,\n schemaName: string,\n enums: EnumRegistry,\n): AnyColumnBuilder {\n const name = meta.columnName;\n let builder: PgColumnBuilderBase;\n switch (meta.storageKind) {\n case \"id\":\n case \"integer\":\n builder = pgInteger(name);\n break;\n case \"bigid\":\n case \"bigint\":\n builder = pgBigint(name, { mode: \"bigint\" });\n break;\n case \"text\":\n builder = pgText(name);\n break;\n case \"varchar\":\n builder = pgVarchar(name, { length: meta.varcharLength ?? 255 });\n break;\n case \"boolean\":\n builder = pgBoolean(name);\n break;\n case \"uuid\":\n builder = pgUuid(name);\n break;\n case \"timestamp\":\n builder = pgTimestamp(name, {\n mode: \"string\",\n withTimezone: meta.withTimezone ?? false,\n });\n break;\n case \"jsonb\":\n builder = pgJsonb(name);\n break;\n case \"enum\": {\n if (!meta.enumName || !meta.enumValues?.length) {\n throw new SchemaBuildError(\n `Enum column \"${meta.columnName}\" has no enum definition`,\n );\n }\n builder = getEnum(\n enums,\n schemaName,\n meta.enumName,\n meta.enumValues,\n )(name);\n break;\n }\n }\n return builder as AnyColumnBuilder;\n}\n\nfunction buildColumn(\n meta: MutableColumnMeta,\n schemaName: string,\n enums: EnumRegistry,\n resolveTarget: (table: string, column: string) => AnyPgColumn,\n): PgColumnBuilderBase {\n let column = baseColumn(meta, schemaName, enums);\n if (meta.serverGenerated) column = column.generatedByDefaultAsIdentity();\n if (meta.primaryKey) column = column.primaryKey();\n else if (meta.notNull) column = column.notNull();\n if (meta.unique) column = column.unique();\n\n if (!meta.serverGenerated) {\n if (meta.defaultNow) column = column.defaultNow();\n else if (meta.defaultRandom) column = column.defaultRandom();\n else if (Object.hasOwn(meta, \"defaultValue\")) {\n column = column.default(meta.defaultValue);\n }\n }\n\n if (meta.fk) {\n const target = meta.fk;\n // Drizzle resolves this thunk after all referenced tables are registered.\n column = column.references(\n () => resolveTarget(target.targetTable, target.targetColumn),\n { onDelete: target.onDelete, onUpdate: target.onUpdate },\n );\n }\n return column;\n}\n\n// PostgreSQL renders a timestamp as `2026-06-29 19:05:19.051709+00` over the\n// text protocol but as ISO-8601 inside the JSON aggregates Drizzle builds for\n// relations, so one column reaches callers in two shapes depending on whether\n// it was included. Both shapes are declared `string`, and only ISO-8601 parses\n// per the ECMAScript grammar, so normalize to it.\nconst PG_TIMESTAMP =\n /^(\\d{4}-\\d{2}-\\d{2})[ T](\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?)(?:([+-]\\d{2})(?::?(\\d{2}))?)?$/;\n\nfunction isoTimestamp(value: unknown): unknown {\n if (typeof value !== \"string\") return value;\n const parts = PG_TIMESTAMP.exec(value);\n // Leave `infinity`, `-infinity`, and anything unrecognized untouched.\n if (!parts) return value;\n const [, date, time, offsetHours, offsetMinutes] = parts;\n const offset =\n offsetHours === undefined ? \"\" : `${offsetHours}:${offsetMinutes ?? \"00\"}`;\n return `${date}T${time}${offset}`;\n}\n\nfunction buildTable(\n name: string,\n schemaName: string,\n metas: Record<string, MutableColumnMeta>,\n enums: EnumRegistry,\n resolveTarget: (table: string, column: string) => AnyPgColumn,\n): BuiltEngineTable {\n const columnBuilders: Record<string, PgColumnBuilderBase> =\n Object.create(null);\n for (const [key, meta] of Object.entries(metas)) {\n columnBuilders[key] = buildColumn(meta, schemaName, enums, resolveTarget);\n }\n\n const engine =\n schemaName === \"public\"\n ? pgTable(name, columnBuilders)\n : pgSchema(schemaName).table(name, columnBuilders);\n for (const [key, meta] of Object.entries(metas)) {\n const engineColumn = (engine as unknown as Record<string, AnyPgColumn>)[\n key\n ];\n if (!engineColumn) {\n throw new SchemaBuildError(\n `Engine column \"${name}.${key}\" was not constructed`,\n );\n }\n if (meta.storageKind === \"timestamp\") {\n // Drizzle routes every read path through this decoder, so overriding it\n // covers direct selects, relation includes, and mutation RETURNING alike.\n (engineColumn as unknown as Record<string, unknown>).mapFromDriverValue =\n isoTimestamp;\n }\n meta.engineColumn =\n engineColumn as unknown as MutableColumnMeta[\"engineColumn\"];\n }\n return { engine: engine as unknown as EngineTable, columns: metas };\n}\n\n/** Build all Drizzle tables only after declaration validation has succeeded. */\nexport function buildEngineTables(\n raw: Iterable<{ name: string; metas: Record<string, MutableColumnMeta> }>,\n schemaName: string,\n): Map<string, BuiltEngineTable> {\n const entries = [...raw];\n const builtEngine = new Map<string, Record<string, AnyPgColumn>>();\n const resolveTarget = (table: string, column: string): AnyPgColumn => {\n const target = builtEngine.get(table)?.[column];\n if (!target) {\n throw new SchemaBuildError(\n `Cannot resolve FK target \"${table}.${column}\"`,\n );\n }\n return target;\n };\n\n const enums: EnumRegistry = new Map();\n const tables = new Map<string, BuiltEngineTable>();\n for (const { name, metas } of entries) {\n const built = buildTable(name, schemaName, metas, enums, resolveTarget);\n builtEngine.set(\n name,\n built.engine as unknown as Record<string, AnyPgColumn>,\n );\n tables.set(name, built);\n }\n return tables;\n}\n"],"mappings":"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"}
|