@axium/server 0.36.5 → 0.37.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.
@@ -0,0 +1,268 @@
1
+ import type { Expand, MutableRecursive, ReadonlyRecursive } from 'utilium';
2
+ import * as z from 'zod';
3
+ import raw from './schema.json';
4
+ import { Table, type Column, type TableValue } from './data.js';
5
+ import * as delta from './delta.js';
6
+ export * from './data.js';
7
+ export declare const SchemaDecl: z.ZodObject<{
8
+ tables: z.ZodRecord<z.ZodString, z.ZodObject<{
9
+ columns: z.ZodRecord<z.ZodString, z.ZodObject<{
10
+ type: z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodLiteral<"bigint" | "boolean" | "uuid" | "date" | "binary" | "integer" | "int2" | "int4" | "int8" | "smallint" | "real" | "double precision" | "float4" | "float8" | "decimal" | "numeric" | "serial" | "bigserial" | "bool" | "varchar" | "char" | "text" | "datetime" | "time" | "timetz" | "timestamp" | "timestamptz" | "bytea" | "varbinary" | "blob" | "int4range" | "numrange" | "tsrange" | "tstzrange" | "daterange" | "int4multirange" | "int8multirange" | "nummultirange" | "tsmultirange" | "tstzmultirange" | "datemultirange" | "json" | "jsonb">, z.ZodTemplateLiteral<`binary(${number})` | `varchar(${number})` | `char(${number})` | `datetime(${number})` | `time(${number})` | `timetz(${number})` | `timestamp(${number})` | `timestamptz(${number})` | `varbinary(${number})`>, z.ZodTemplateLiteral<`decimal(${number},${number})` | `decimal(${number}, ${number})` | `numeric(${number},${number})` | `numeric(${number}, ${number})`>]>, z.ZodTemplateLiteral<"bigint[]" | "boolean[]" | "uuid[]" | "date[]" | "binary[]" | "integer[]" | "int2[]" | "int4[]" | "int8[]" | "smallint[]" | "real[]" | "double precision[]" | "float4[]" | "float8[]" | "decimal[]" | "numeric[]" | "serial[]" | "bigserial[]" | "bool[]" | "varchar[]" | "char[]" | "text[]" | "datetime[]" | "time[]" | "timetz[]" | "timestamp[]" | "timestamptz[]" | "bytea[]" | "varbinary[]" | "blob[]" | "int4range[]" | "numrange[]" | "tsrange[]" | "tstzrange[]" | "daterange[]" | "int4multirange[]" | "int8multirange[]" | "nummultirange[]" | "tsmultirange[]" | "tstzmultirange[]" | "datemultirange[]" | "json[]" | "jsonb[]" | `binary(${number})[]` | `varchar(${number})[]` | `char(${number})[]` | `datetime(${number})[]` | `time(${number})[]` | `timetz(${number})[]` | `timestamp(${number})[]` | `timestamptz(${number})[]` | `varbinary(${number})[]` | `decimal(${number},${number})[]` | `decimal(${number}, ${number})[]` | `numeric(${number},${number})[]` | `numeric(${number}, ${number})[]` | `bigint[${number}]` | `boolean[${number}]` | `uuid[${number}]` | `date[${number}]` | `binary[${number}]` | `integer[${number}]` | `int2[${number}]` | `int4[${number}]` | `int8[${number}]` | `smallint[${number}]` | `real[${number}]` | `double precision[${number}]` | `float4[${number}]` | `float8[${number}]` | `decimal[${number}]` | `numeric[${number}]` | `serial[${number}]` | `bigserial[${number}]` | `bool[${number}]` | `varchar[${number}]` | `char[${number}]` | `text[${number}]` | `datetime[${number}]` | `time[${number}]` | `timetz[${number}]` | `timestamp[${number}]` | `timestamptz[${number}]` | `bytea[${number}]` | `varbinary[${number}]` | `blob[${number}]` | `int4range[${number}]` | `numrange[${number}]` | `tsrange[${number}]` | `tstzrange[${number}]` | `daterange[${number}]` | `int4multirange[${number}]` | `int8multirange[${number}]` | `nummultirange[${number}]` | `tsmultirange[${number}]` | `tstzmultirange[${number}]` | `datemultirange[${number}]` | `json[${number}]` | `jsonb[${number}]` | `binary(${number})[${number}]` | `varchar(${number})[${number}]` | `char(${number})[${number}]` | `datetime(${number})[${number}]` | `time(${number})[${number}]` | `timetz(${number})[${number}]` | `timestamp(${number})[${number}]` | `timestamptz(${number})[${number}]` | `varbinary(${number})[${number}]` | `decimal(${number},${number})[${number}]` | `decimal(${number}, ${number})[${number}]` | `numeric(${number},${number})[${number}]` | `numeric(${number}, ${number})[${number}]`>]>;
11
+ required: z.ZodDefault<z.ZodBoolean>;
12
+ unique: z.ZodDefault<z.ZodBoolean>;
13
+ primary: z.ZodDefault<z.ZodBoolean>;
14
+ references: z.ZodOptional<z.ZodString>;
15
+ onDelete: z.ZodOptional<z.ZodEnum<{
16
+ cascade: "cascade";
17
+ restrict: "restrict";
18
+ "no action": "no action";
19
+ "set null": "set null";
20
+ "set default": "set default";
21
+ }>>;
22
+ default: z.ZodOptional<z.ZodAny>;
23
+ check: z.ZodOptional<z.ZodString>;
24
+ }, z.core.$strict>>;
25
+ constraints: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodDiscriminatedUnion<[z.ZodObject<{
26
+ type: z.ZodLiteral<"primary_key">;
27
+ on: z.ZodArray<z.ZodString>;
28
+ }, z.core.$strict>, z.ZodObject<{
29
+ type: z.ZodLiteral<"foreign_key">;
30
+ on: z.ZodArray<z.ZodString>;
31
+ target: z.ZodString;
32
+ references: z.ZodArray<z.ZodString>;
33
+ }, z.core.$strict>, z.ZodObject<{
34
+ type: z.ZodLiteral<"unique">;
35
+ on: z.ZodArray<z.ZodString>;
36
+ nulls_not_distinct: z.ZodOptional<z.ZodBoolean>;
37
+ }, z.core.$strict>, z.ZodObject<{
38
+ type: z.ZodLiteral<"check">;
39
+ check: z.ZodString;
40
+ }, z.core.$strict>], "type">>>>;
41
+ }, z.core.$strict>>;
42
+ indexes: z.ZodRecord<z.ZodString, z.ZodObject<{
43
+ on: z.ZodString;
44
+ columns: z.ZodArray<z.ZodString>;
45
+ }, z.core.$strict>>;
46
+ }, z.core.$strict>;
47
+ export interface SchemaDecl extends z.infer<typeof SchemaDecl> {
48
+ }
49
+ export declare const SchemaFile: z.ZodObject<{
50
+ format: z.ZodLiteral<1>;
51
+ versions: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
52
+ tables: z.ZodRecord<z.ZodString, z.ZodObject<{
53
+ columns: z.ZodRecord<z.ZodString, z.ZodObject<{
54
+ type: z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodLiteral<"bigint" | "boolean" | "uuid" | "date" | "binary" | "integer" | "int2" | "int4" | "int8" | "smallint" | "real" | "double precision" | "float4" | "float8" | "decimal" | "numeric" | "serial" | "bigserial" | "bool" | "varchar" | "char" | "text" | "datetime" | "time" | "timetz" | "timestamp" | "timestamptz" | "bytea" | "varbinary" | "blob" | "int4range" | "numrange" | "tsrange" | "tstzrange" | "daterange" | "int4multirange" | "int8multirange" | "nummultirange" | "tsmultirange" | "tstzmultirange" | "datemultirange" | "json" | "jsonb">, z.ZodTemplateLiteral<`binary(${number})` | `varchar(${number})` | `char(${number})` | `datetime(${number})` | `time(${number})` | `timetz(${number})` | `timestamp(${number})` | `timestamptz(${number})` | `varbinary(${number})`>, z.ZodTemplateLiteral<`decimal(${number},${number})` | `decimal(${number}, ${number})` | `numeric(${number},${number})` | `numeric(${number}, ${number})`>]>, z.ZodTemplateLiteral<"bigint[]" | "boolean[]" | "uuid[]" | "date[]" | "binary[]" | "integer[]" | "int2[]" | "int4[]" | "int8[]" | "smallint[]" | "real[]" | "double precision[]" | "float4[]" | "float8[]" | "decimal[]" | "numeric[]" | "serial[]" | "bigserial[]" | "bool[]" | "varchar[]" | "char[]" | "text[]" | "datetime[]" | "time[]" | "timetz[]" | "timestamp[]" | "timestamptz[]" | "bytea[]" | "varbinary[]" | "blob[]" | "int4range[]" | "numrange[]" | "tsrange[]" | "tstzrange[]" | "daterange[]" | "int4multirange[]" | "int8multirange[]" | "nummultirange[]" | "tsmultirange[]" | "tstzmultirange[]" | "datemultirange[]" | "json[]" | "jsonb[]" | `binary(${number})[]` | `varchar(${number})[]` | `char(${number})[]` | `datetime(${number})[]` | `time(${number})[]` | `timetz(${number})[]` | `timestamp(${number})[]` | `timestamptz(${number})[]` | `varbinary(${number})[]` | `decimal(${number},${number})[]` | `decimal(${number}, ${number})[]` | `numeric(${number},${number})[]` | `numeric(${number}, ${number})[]` | `bigint[${number}]` | `boolean[${number}]` | `uuid[${number}]` | `date[${number}]` | `binary[${number}]` | `integer[${number}]` | `int2[${number}]` | `int4[${number}]` | `int8[${number}]` | `smallint[${number}]` | `real[${number}]` | `double precision[${number}]` | `float4[${number}]` | `float8[${number}]` | `decimal[${number}]` | `numeric[${number}]` | `serial[${number}]` | `bigserial[${number}]` | `bool[${number}]` | `varchar[${number}]` | `char[${number}]` | `text[${number}]` | `datetime[${number}]` | `time[${number}]` | `timetz[${number}]` | `timestamp[${number}]` | `timestamptz[${number}]` | `bytea[${number}]` | `varbinary[${number}]` | `blob[${number}]` | `int4range[${number}]` | `numrange[${number}]` | `tsrange[${number}]` | `tstzrange[${number}]` | `daterange[${number}]` | `int4multirange[${number}]` | `int8multirange[${number}]` | `nummultirange[${number}]` | `tsmultirange[${number}]` | `tstzmultirange[${number}]` | `datemultirange[${number}]` | `json[${number}]` | `jsonb[${number}]` | `binary(${number})[${number}]` | `varchar(${number})[${number}]` | `char(${number})[${number}]` | `datetime(${number})[${number}]` | `time(${number})[${number}]` | `timetz(${number})[${number}]` | `timestamp(${number})[${number}]` | `timestamptz(${number})[${number}]` | `varbinary(${number})[${number}]` | `decimal(${number},${number})[${number}]` | `decimal(${number}, ${number})[${number}]` | `numeric(${number},${number})[${number}]` | `numeric(${number}, ${number})[${number}]`>]>;
55
+ required: z.ZodDefault<z.ZodBoolean>;
56
+ unique: z.ZodDefault<z.ZodBoolean>;
57
+ primary: z.ZodDefault<z.ZodBoolean>;
58
+ references: z.ZodOptional<z.ZodString>;
59
+ onDelete: z.ZodOptional<z.ZodEnum<{
60
+ cascade: "cascade";
61
+ restrict: "restrict";
62
+ "no action": "no action";
63
+ "set null": "set null";
64
+ "set default": "set default";
65
+ }>>;
66
+ default: z.ZodOptional<z.ZodAny>;
67
+ check: z.ZodOptional<z.ZodString>;
68
+ }, z.core.$strict>>;
69
+ constraints: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodDiscriminatedUnion<[z.ZodObject<{
70
+ type: z.ZodLiteral<"primary_key">;
71
+ on: z.ZodArray<z.ZodString>;
72
+ }, z.core.$strict>, z.ZodObject<{
73
+ type: z.ZodLiteral<"foreign_key">;
74
+ on: z.ZodArray<z.ZodString>;
75
+ target: z.ZodString;
76
+ references: z.ZodArray<z.ZodString>;
77
+ }, z.core.$strict>, z.ZodObject<{
78
+ type: z.ZodLiteral<"unique">;
79
+ on: z.ZodArray<z.ZodString>;
80
+ nulls_not_distinct: z.ZodOptional<z.ZodBoolean>;
81
+ }, z.core.$strict>, z.ZodObject<{
82
+ type: z.ZodLiteral<"check">;
83
+ check: z.ZodString;
84
+ }, z.core.$strict>], "type">>>>;
85
+ }, z.core.$strict>>;
86
+ indexes: z.ZodRecord<z.ZodString, z.ZodObject<{
87
+ on: z.ZodString;
88
+ columns: z.ZodArray<z.ZodString>;
89
+ }, z.core.$strict>>;
90
+ delta: z.ZodLiteral<false>;
91
+ }, z.core.$strict>, z.ZodObject<{
92
+ delta: z.ZodLiteral<true>;
93
+ add_tables: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
94
+ columns: z.ZodRecord<z.ZodString, z.ZodObject<{
95
+ type: z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodLiteral<"bigint" | "boolean" | "uuid" | "date" | "binary" | "integer" | "int2" | "int4" | "int8" | "smallint" | "real" | "double precision" | "float4" | "float8" | "decimal" | "numeric" | "serial" | "bigserial" | "bool" | "varchar" | "char" | "text" | "datetime" | "time" | "timetz" | "timestamp" | "timestamptz" | "bytea" | "varbinary" | "blob" | "int4range" | "numrange" | "tsrange" | "tstzrange" | "daterange" | "int4multirange" | "int8multirange" | "nummultirange" | "tsmultirange" | "tstzmultirange" | "datemultirange" | "json" | "jsonb">, z.ZodTemplateLiteral<`binary(${number})` | `varchar(${number})` | `char(${number})` | `datetime(${number})` | `time(${number})` | `timetz(${number})` | `timestamp(${number})` | `timestamptz(${number})` | `varbinary(${number})`>, z.ZodTemplateLiteral<`decimal(${number},${number})` | `decimal(${number}, ${number})` | `numeric(${number},${number})` | `numeric(${number}, ${number})`>]>, z.ZodTemplateLiteral<"bigint[]" | "boolean[]" | "uuid[]" | "date[]" | "binary[]" | "integer[]" | "int2[]" | "int4[]" | "int8[]" | "smallint[]" | "real[]" | "double precision[]" | "float4[]" | "float8[]" | "decimal[]" | "numeric[]" | "serial[]" | "bigserial[]" | "bool[]" | "varchar[]" | "char[]" | "text[]" | "datetime[]" | "time[]" | "timetz[]" | "timestamp[]" | "timestamptz[]" | "bytea[]" | "varbinary[]" | "blob[]" | "int4range[]" | "numrange[]" | "tsrange[]" | "tstzrange[]" | "daterange[]" | "int4multirange[]" | "int8multirange[]" | "nummultirange[]" | "tsmultirange[]" | "tstzmultirange[]" | "datemultirange[]" | "json[]" | "jsonb[]" | `binary(${number})[]` | `varchar(${number})[]` | `char(${number})[]` | `datetime(${number})[]` | `time(${number})[]` | `timetz(${number})[]` | `timestamp(${number})[]` | `timestamptz(${number})[]` | `varbinary(${number})[]` | `decimal(${number},${number})[]` | `decimal(${number}, ${number})[]` | `numeric(${number},${number})[]` | `numeric(${number}, ${number})[]` | `bigint[${number}]` | `boolean[${number}]` | `uuid[${number}]` | `date[${number}]` | `binary[${number}]` | `integer[${number}]` | `int2[${number}]` | `int4[${number}]` | `int8[${number}]` | `smallint[${number}]` | `real[${number}]` | `double precision[${number}]` | `float4[${number}]` | `float8[${number}]` | `decimal[${number}]` | `numeric[${number}]` | `serial[${number}]` | `bigserial[${number}]` | `bool[${number}]` | `varchar[${number}]` | `char[${number}]` | `text[${number}]` | `datetime[${number}]` | `time[${number}]` | `timetz[${number}]` | `timestamp[${number}]` | `timestamptz[${number}]` | `bytea[${number}]` | `varbinary[${number}]` | `blob[${number}]` | `int4range[${number}]` | `numrange[${number}]` | `tsrange[${number}]` | `tstzrange[${number}]` | `daterange[${number}]` | `int4multirange[${number}]` | `int8multirange[${number}]` | `nummultirange[${number}]` | `tsmultirange[${number}]` | `tstzmultirange[${number}]` | `datemultirange[${number}]` | `json[${number}]` | `jsonb[${number}]` | `binary(${number})[${number}]` | `varchar(${number})[${number}]` | `char(${number})[${number}]` | `datetime(${number})[${number}]` | `time(${number})[${number}]` | `timetz(${number})[${number}]` | `timestamp(${number})[${number}]` | `timestamptz(${number})[${number}]` | `varbinary(${number})[${number}]` | `decimal(${number},${number})[${number}]` | `decimal(${number}, ${number})[${number}]` | `numeric(${number},${number})[${number}]` | `numeric(${number}, ${number})[${number}]`>]>;
96
+ required: z.ZodDefault<z.ZodBoolean>;
97
+ unique: z.ZodDefault<z.ZodBoolean>;
98
+ primary: z.ZodDefault<z.ZodBoolean>;
99
+ references: z.ZodOptional<z.ZodString>;
100
+ onDelete: z.ZodOptional<z.ZodEnum<{
101
+ cascade: "cascade";
102
+ restrict: "restrict";
103
+ "no action": "no action";
104
+ "set null": "set null";
105
+ "set default": "set default";
106
+ }>>;
107
+ default: z.ZodOptional<z.ZodAny>;
108
+ check: z.ZodOptional<z.ZodString>;
109
+ }, z.core.$strict>>;
110
+ constraints: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodDiscriminatedUnion<[z.ZodObject<{
111
+ type: z.ZodLiteral<"primary_key">;
112
+ on: z.ZodArray<z.ZodString>;
113
+ }, z.core.$strict>, z.ZodObject<{
114
+ type: z.ZodLiteral<"foreign_key">;
115
+ on: z.ZodArray<z.ZodString>;
116
+ target: z.ZodString;
117
+ references: z.ZodArray<z.ZodString>;
118
+ }, z.core.$strict>, z.ZodObject<{
119
+ type: z.ZodLiteral<"unique">;
120
+ on: z.ZodArray<z.ZodString>;
121
+ nulls_not_distinct: z.ZodOptional<z.ZodBoolean>;
122
+ }, z.core.$strict>, z.ZodObject<{
123
+ type: z.ZodLiteral<"check">;
124
+ check: z.ZodString;
125
+ }, z.core.$strict>], "type">>>>;
126
+ }, z.core.$strict>>>>;
127
+ drop_tables: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString>>>;
128
+ alter_tables: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
129
+ add_columns: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
130
+ type: z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodLiteral<"bigint" | "boolean" | "uuid" | "date" | "binary" | "integer" | "int2" | "int4" | "int8" | "smallint" | "real" | "double precision" | "float4" | "float8" | "decimal" | "numeric" | "serial" | "bigserial" | "bool" | "varchar" | "char" | "text" | "datetime" | "time" | "timetz" | "timestamp" | "timestamptz" | "bytea" | "varbinary" | "blob" | "int4range" | "numrange" | "tsrange" | "tstzrange" | "daterange" | "int4multirange" | "int8multirange" | "nummultirange" | "tsmultirange" | "tstzmultirange" | "datemultirange" | "json" | "jsonb">, z.ZodTemplateLiteral<`binary(${number})` | `varchar(${number})` | `char(${number})` | `datetime(${number})` | `time(${number})` | `timetz(${number})` | `timestamp(${number})` | `timestamptz(${number})` | `varbinary(${number})`>, z.ZodTemplateLiteral<`decimal(${number},${number})` | `decimal(${number}, ${number})` | `numeric(${number},${number})` | `numeric(${number}, ${number})`>]>, z.ZodTemplateLiteral<"bigint[]" | "boolean[]" | "uuid[]" | "date[]" | "binary[]" | "integer[]" | "int2[]" | "int4[]" | "int8[]" | "smallint[]" | "real[]" | "double precision[]" | "float4[]" | "float8[]" | "decimal[]" | "numeric[]" | "serial[]" | "bigserial[]" | "bool[]" | "varchar[]" | "char[]" | "text[]" | "datetime[]" | "time[]" | "timetz[]" | "timestamp[]" | "timestamptz[]" | "bytea[]" | "varbinary[]" | "blob[]" | "int4range[]" | "numrange[]" | "tsrange[]" | "tstzrange[]" | "daterange[]" | "int4multirange[]" | "int8multirange[]" | "nummultirange[]" | "tsmultirange[]" | "tstzmultirange[]" | "datemultirange[]" | "json[]" | "jsonb[]" | `binary(${number})[]` | `varchar(${number})[]` | `char(${number})[]` | `datetime(${number})[]` | `time(${number})[]` | `timetz(${number})[]` | `timestamp(${number})[]` | `timestamptz(${number})[]` | `varbinary(${number})[]` | `decimal(${number},${number})[]` | `decimal(${number}, ${number})[]` | `numeric(${number},${number})[]` | `numeric(${number}, ${number})[]` | `bigint[${number}]` | `boolean[${number}]` | `uuid[${number}]` | `date[${number}]` | `binary[${number}]` | `integer[${number}]` | `int2[${number}]` | `int4[${number}]` | `int8[${number}]` | `smallint[${number}]` | `real[${number}]` | `double precision[${number}]` | `float4[${number}]` | `float8[${number}]` | `decimal[${number}]` | `numeric[${number}]` | `serial[${number}]` | `bigserial[${number}]` | `bool[${number}]` | `varchar[${number}]` | `char[${number}]` | `text[${number}]` | `datetime[${number}]` | `time[${number}]` | `timetz[${number}]` | `timestamp[${number}]` | `timestamptz[${number}]` | `bytea[${number}]` | `varbinary[${number}]` | `blob[${number}]` | `int4range[${number}]` | `numrange[${number}]` | `tsrange[${number}]` | `tstzrange[${number}]` | `daterange[${number}]` | `int4multirange[${number}]` | `int8multirange[${number}]` | `nummultirange[${number}]` | `tsmultirange[${number}]` | `tstzmultirange[${number}]` | `datemultirange[${number}]` | `json[${number}]` | `jsonb[${number}]` | `binary(${number})[${number}]` | `varchar(${number})[${number}]` | `char(${number})[${number}]` | `datetime(${number})[${number}]` | `time(${number})[${number}]` | `timetz(${number})[${number}]` | `timestamp(${number})[${number}]` | `timestamptz(${number})[${number}]` | `varbinary(${number})[${number}]` | `decimal(${number},${number})[${number}]` | `decimal(${number}, ${number})[${number}]` | `numeric(${number},${number})[${number}]` | `numeric(${number}, ${number})[${number}]`>]>;
131
+ required: z.ZodDefault<z.ZodBoolean>;
132
+ unique: z.ZodDefault<z.ZodBoolean>;
133
+ primary: z.ZodDefault<z.ZodBoolean>;
134
+ references: z.ZodOptional<z.ZodString>;
135
+ onDelete: z.ZodOptional<z.ZodEnum<{
136
+ cascade: "cascade";
137
+ restrict: "restrict";
138
+ "no action": "no action";
139
+ "set null": "set null";
140
+ "set default": "set default";
141
+ }>>;
142
+ default: z.ZodOptional<z.ZodAny>;
143
+ check: z.ZodOptional<z.ZodString>;
144
+ }, z.core.$strict>>>>;
145
+ drop_columns: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString>>>;
146
+ alter_columns: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
147
+ type: z.ZodOptional<z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodLiteral<"bigint" | "boolean" | "uuid" | "date" | "binary" | "integer" | "int2" | "int4" | "int8" | "smallint" | "real" | "double precision" | "float4" | "float8" | "decimal" | "numeric" | "serial" | "bigserial" | "bool" | "varchar" | "char" | "text" | "datetime" | "time" | "timetz" | "timestamp" | "timestamptz" | "bytea" | "varbinary" | "blob" | "int4range" | "numrange" | "tsrange" | "tstzrange" | "daterange" | "int4multirange" | "int8multirange" | "nummultirange" | "tsmultirange" | "tstzmultirange" | "datemultirange" | "json" | "jsonb">, z.ZodTemplateLiteral<`binary(${number})` | `varchar(${number})` | `char(${number})` | `datetime(${number})` | `time(${number})` | `timetz(${number})` | `timestamp(${number})` | `timestamptz(${number})` | `varbinary(${number})`>, z.ZodTemplateLiteral<`decimal(${number},${number})` | `decimal(${number}, ${number})` | `numeric(${number},${number})` | `numeric(${number}, ${number})`>]>, z.ZodTemplateLiteral<"bigint[]" | "boolean[]" | "uuid[]" | "date[]" | "binary[]" | "integer[]" | "int2[]" | "int4[]" | "int8[]" | "smallint[]" | "real[]" | "double precision[]" | "float4[]" | "float8[]" | "decimal[]" | "numeric[]" | "serial[]" | "bigserial[]" | "bool[]" | "varchar[]" | "char[]" | "text[]" | "datetime[]" | "time[]" | "timetz[]" | "timestamp[]" | "timestamptz[]" | "bytea[]" | "varbinary[]" | "blob[]" | "int4range[]" | "numrange[]" | "tsrange[]" | "tstzrange[]" | "daterange[]" | "int4multirange[]" | "int8multirange[]" | "nummultirange[]" | "tsmultirange[]" | "tstzmultirange[]" | "datemultirange[]" | "json[]" | "jsonb[]" | `binary(${number})[]` | `varchar(${number})[]` | `char(${number})[]` | `datetime(${number})[]` | `time(${number})[]` | `timetz(${number})[]` | `timestamp(${number})[]` | `timestamptz(${number})[]` | `varbinary(${number})[]` | `decimal(${number},${number})[]` | `decimal(${number}, ${number})[]` | `numeric(${number},${number})[]` | `numeric(${number}, ${number})[]` | `bigint[${number}]` | `boolean[${number}]` | `uuid[${number}]` | `date[${number}]` | `binary[${number}]` | `integer[${number}]` | `int2[${number}]` | `int4[${number}]` | `int8[${number}]` | `smallint[${number}]` | `real[${number}]` | `double precision[${number}]` | `float4[${number}]` | `float8[${number}]` | `decimal[${number}]` | `numeric[${number}]` | `serial[${number}]` | `bigserial[${number}]` | `bool[${number}]` | `varchar[${number}]` | `char[${number}]` | `text[${number}]` | `datetime[${number}]` | `time[${number}]` | `timetz[${number}]` | `timestamp[${number}]` | `timestamptz[${number}]` | `bytea[${number}]` | `varbinary[${number}]` | `blob[${number}]` | `int4range[${number}]` | `numrange[${number}]` | `tsrange[${number}]` | `tstzrange[${number}]` | `daterange[${number}]` | `int4multirange[${number}]` | `int8multirange[${number}]` | `nummultirange[${number}]` | `tsmultirange[${number}]` | `tstzmultirange[${number}]` | `datemultirange[${number}]` | `json[${number}]` | `jsonb[${number}]` | `binary(${number})[${number}]` | `varchar(${number})[${number}]` | `char(${number})[${number}]` | `datetime(${number})[${number}]` | `time(${number})[${number}]` | `timetz(${number})[${number}]` | `timestamp(${number})[${number}]` | `timestamptz(${number})[${number}]` | `varbinary(${number})[${number}]` | `decimal(${number},${number})[${number}]` | `decimal(${number}, ${number})[${number}]` | `numeric(${number},${number})[${number}]` | `numeric(${number}, ${number})[${number}]`>]>>;
148
+ default: z.ZodOptional<z.ZodString>;
149
+ ops: z.ZodOptional<z.ZodArray<z.ZodLiteral<"drop_default" | "set_required" | "drop_required">>>;
150
+ }, z.core.$strict>>>>;
151
+ add_constraints: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodDiscriminatedUnion<[z.ZodObject<{
152
+ type: z.ZodLiteral<"primary_key">;
153
+ on: z.ZodArray<z.ZodString>;
154
+ }, z.core.$strict>, z.ZodObject<{
155
+ type: z.ZodLiteral<"foreign_key">;
156
+ on: z.ZodArray<z.ZodString>;
157
+ target: z.ZodString;
158
+ references: z.ZodArray<z.ZodString>;
159
+ }, z.core.$strict>, z.ZodObject<{
160
+ type: z.ZodLiteral<"unique">;
161
+ on: z.ZodArray<z.ZodString>;
162
+ nulls_not_distinct: z.ZodOptional<z.ZodBoolean>;
163
+ }, z.core.$strict>, z.ZodObject<{
164
+ type: z.ZodLiteral<"check">;
165
+ check: z.ZodString;
166
+ }, z.core.$strict>], "type">>>>;
167
+ drop_constraints: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString>>>;
168
+ }, z.core.$strict>>>>;
169
+ add_indexes: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
170
+ on: z.ZodString;
171
+ columns: z.ZodArray<z.ZodString>;
172
+ }, z.core.$strict>>>>;
173
+ drop_indexes: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString>>>;
174
+ }, z.core.$strict>], "delta">>;
175
+ wipe: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString>>>;
176
+ latest: z.ZodOptional<z.ZodInt32>;
177
+ acl_tables: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>>;
178
+ }, z.core.$strip>;
179
+ export interface SchemaFile extends z.infer<typeof SchemaFile> {
180
+ }
181
+ export declare function getFiles(): Generator<[string, SchemaFile]>;
182
+ export type ApplyColumnDelta<C extends z.input<typeof Column>, D extends z.input<typeof delta.Column>> = Omit<C, 'type' | 'default' | 'required'> & {
183
+ type: D extends {
184
+ type: infer T;
185
+ } ? T : C['type'];
186
+ default: D extends {
187
+ ops: readonly any[];
188
+ } ? 'drop_default' extends D['ops'][number] ? undefined : D extends {
189
+ default: infer Def;
190
+ } ? Def : C['default'] : D extends {
191
+ default: infer Def;
192
+ } ? Def : C['default'];
193
+ required: D extends {
194
+ ops: readonly any[];
195
+ } ? 'set_required' extends D['ops'][number] ? true : 'drop_required' extends D['ops'][number] ? false : C['required'] : C['required'];
196
+ };
197
+ export type ApplyTableDelta<T extends z.input<typeof Table>, D extends z.input<typeof delta.Table>> = {
198
+ columns: {
199
+ [K in keyof T['columns'] as K extends (D extends {
200
+ drop_columns: any[];
201
+ } ? D['drop_columns'][number] : never) ? never : K]: K extends keyof (D extends {
202
+ alter_columns: any;
203
+ } ? D['alter_columns'] : {}) ? ApplyColumnDelta<T['columns'][K], (D['alter_columns'] & {})[K & keyof D['alter_columns']]> : T['columns'][K];
204
+ } & (D extends {
205
+ add_columns: infer A;
206
+ } ? A : {});
207
+ constraints: {
208
+ [K in keyof T['constraints'] as K extends (D extends {
209
+ drop_constraints: any[];
210
+ } ? D['drop_constraints'][number] : never) ? never : K]: T['constraints'][K];
211
+ } & (D extends {
212
+ add_constraints: infer A;
213
+ } ? A : {});
214
+ };
215
+ export type ApplySchemaDelta<S extends z.input<typeof SchemaDecl>, D extends z.input<typeof delta.Version>> = {
216
+ tables: {
217
+ [K in keyof S['tables'] as K extends (D extends {
218
+ drop_tables: any[];
219
+ } ? D['drop_tables'][number] : never) ? never : K]: K extends keyof (D extends {
220
+ alter_tables: any;
221
+ } ? D['alter_tables'] : {}) ? ApplyTableDelta<S['tables'][K], (D['alter_tables'] & {})[K & keyof D['alter_tables']]> : S['tables'][K];
222
+ } & (D extends {
223
+ add_tables: infer A;
224
+ } ? A : {});
225
+ indexes: {
226
+ [K in keyof S['indexes'] as K extends (D extends {
227
+ drop_indexes: any[];
228
+ } ? D['drop_indexes'][number] : never) ? never : K]: S['indexes'][K];
229
+ };
230
+ };
231
+ type ResolveVersions<V extends readonly any[], Current extends z.input<typeof SchemaDecl> = {
232
+ tables: {};
233
+ indexes: {};
234
+ }> = V extends readonly [
235
+ infer Head extends z.input<typeof delta.Version> | (z.input<typeof SchemaDecl> & {
236
+ delta: false;
237
+ }),
238
+ ...infer Tail extends (z.input<typeof delta.Version> | (z.input<typeof SchemaDecl> & {
239
+ delta: false;
240
+ }))[]
241
+ ] ? Head extends z.input<typeof delta.Version> ? ResolveVersions<Tail, ApplySchemaDelta<Current, Head>> : Head extends z.input<typeof SchemaDecl> ? ResolveVersions<Tail, Head> : never : Current;
242
+ export type FullSchema<S extends z.input<typeof SchemaFile>> = ResolveVersions<S['versions']>;
243
+ type _DBFromSchema<TBs extends Record<string, z.input<typeof Table>>> = {
244
+ [K in keyof TBs]: Expand<TableValue<TBs[K]>>;
245
+ };
246
+ /**
247
+ * Convert an entire schema definition file info the Kysely database schema type
248
+ */
249
+ export type FromFile<S extends ReadonlyRecursive<z.input<typeof SchemaFile>>> = _DBFromSchema<FullSchema<MutableRecursive<S>>['tables']>;
250
+ /**@deprecated use {@link FromFile} */
251
+ export type DatabaseFromSchemaFile<S extends ReadonlyRecursive<z.input<typeof SchemaFile>>> = FromFile<S>;
252
+ /** @internal @hidden */
253
+ export type Raw = FromFile<typeof raw>;
254
+ /**
255
+ * Get the active schema
256
+ */
257
+ export declare function getFull(opt?: {
258
+ exclude?: string[];
259
+ }): SchemaDecl & {
260
+ versions: Record<string, number>;
261
+ };
262
+ export declare function toSQL(schema: SchemaDecl): Generator<string>;
263
+ export declare function toGraph(schema: SchemaDecl): Generator<string>;
264
+ export declare const toIntrospected: {
265
+ boolean: string;
266
+ integer: string;
267
+ 'text[]': string;
268
+ };
@@ -0,0 +1,169 @@
1
+ import * as io from '@axium/core/node/io';
2
+ import { plugins } from '@axium/core/plugins';
3
+ import { sql } from 'kysely';
4
+ import * as z from 'zod';
5
+ import raw from './schema.json' with { type: 'json' };
6
+ import { database } from './connection.js';
7
+ import { buildColumn, Index, Table } from './data.js';
8
+ import * as delta from './delta.js';
9
+ export * from './data.js';
10
+ export const SchemaDecl = z.strictObject({
11
+ tables: z.record(z.string(), Table),
12
+ indexes: z.record(z.string(), Index),
13
+ });
14
+ export const SchemaFile = z.object({
15
+ format: z.literal(1),
16
+ versions: z.discriminatedUnion('delta', [SchemaDecl.extend({ delta: z.literal(false) }), delta.Version]).array(),
17
+ /** List of tables to wipe */
18
+ wipe: z.string().array().optional().default([]),
19
+ /** Set the latest version, defaults to the last one */
20
+ latest: z.int32().nonnegative().optional(),
21
+ /** Maps tables to their ACL tables, e.g. `"storage": "acl.storage"` */
22
+ acl_tables: z.record(z.string(), z.string()).optional().default({}),
23
+ });
24
+ const { data, error } = SchemaFile.safeParse(raw);
25
+ if (error)
26
+ io.error('Invalid base database schema:\n' + z.prettifyError(error));
27
+ const schema = data;
28
+ export function* getFiles() {
29
+ yield ['@axium/server', schema];
30
+ for (const [name, plugin] of plugins) {
31
+ if (!plugin._db)
32
+ continue;
33
+ try {
34
+ yield [name, SchemaFile.parse(plugin._db)];
35
+ }
36
+ catch (e) {
37
+ throw `Invalid database configuration for plugin "${name}":\n${io.errorText(e)}`;
38
+ }
39
+ }
40
+ }
41
+ /**
42
+ * Get the active schema
43
+ */
44
+ export function getFull(opt = {}) {
45
+ const fullSchema = { tables: {}, indexes: {}, versions: {} };
46
+ for (const [pluginName, file] of getFiles()) {
47
+ if (opt.exclude?.includes(pluginName))
48
+ continue;
49
+ file.latest ??= file.versions.length - 1;
50
+ let currentSchema = { tables: {}, indexes: {} };
51
+ fullSchema.versions[pluginName] = file.latest;
52
+ for (const [version, schema] of file.versions.entries()) {
53
+ if (!schema.delta)
54
+ currentSchema = schema;
55
+ else {
56
+ try {
57
+ delta.applyToSchema(currentSchema, schema);
58
+ }
59
+ catch (e) {
60
+ throw `Failed to apply version ${version - 1}->${version} delta to ${pluginName}: ${io.errorText(e)}`;
61
+ }
62
+ }
63
+ if (version === file.latest)
64
+ break;
65
+ }
66
+ for (const name of Object.keys(currentSchema.tables)) {
67
+ if (name in fullSchema.tables)
68
+ throw 'Duplicate table name in database schema: ' + name;
69
+ fullSchema.tables[name] = currentSchema.tables[name];
70
+ }
71
+ for (const index of Object.keys(currentSchema.indexes)) {
72
+ if (fullSchema.indexes[index])
73
+ throw 'Duplicate index in database schema: ' + index;
74
+ fullSchema.indexes[index] = currentSchema.indexes[index];
75
+ }
76
+ }
77
+ return fullSchema;
78
+ }
79
+ export function* toSQL(schema) {
80
+ for (const [tableName, table] of Object.entries(schema.tables)) {
81
+ let query = database.schema.createTable(tableName);
82
+ const columns = Object.entries(table.columns);
83
+ const pkColumns = columns.filter(([, column]) => column.primary).map(([name, column]) => ({ name, ...column }));
84
+ const needsSpecialConstraint = pkColumns.length > 1 || pkColumns.some(col => !col.required);
85
+ for (const [colName, column] of columns) {
86
+ query = query.addColumn(colName, sql.raw(column.type), buildColumn(column, !needsSpecialConstraint));
87
+ }
88
+ if (needsSpecialConstraint) {
89
+ query = query.addPrimaryKeyConstraint('PK_' + tableName.replaceAll('.', '_'), pkColumns.map(col => col.name));
90
+ }
91
+ yield query.compile().sql.replace('(', '(\n\t').replaceAll(', ', ',\n\t').replace(/\)$/, '\n);\n');
92
+ }
93
+ for (const [indexName, index] of Object.entries(schema.indexes)) {
94
+ const query = database.schema.createIndex(indexName).on(index.on).columns(index.columns).compile().sql;
95
+ yield query + ';\n';
96
+ }
97
+ }
98
+ export function* toGraph(schema) {
99
+ const esc = (s) => s.replaceAll('&', '&amp;').replaceAll('<', '&lt;').replaceAll('>', '&gt;').replaceAll('"', '&quot;');
100
+ const nodeId = (table) => table.replaceAll('.', '__');
101
+ const edges = [];
102
+ yield `digraph schema {
103
+ graph [
104
+ bgcolor="#111111",
105
+ overlap=false,
106
+ pad=0.5,
107
+ concentrate=true,
108
+ nodesep=1.0,
109
+ rankdir=LR,
110
+ size="16,9!",
111
+ ratio="fill"
112
+ ];
113
+ node [color="#c6c5fe",
114
+ fontcolor="#c6c5fe",
115
+ fontname=monospace,
116
+ fontsize="14px",
117
+ height=0,
118
+ label="\\N",
119
+ shape=plain,
120
+ style=rounded
121
+ ];
122
+ edge [color="#757575"];
123
+ `;
124
+ for (const [tableName, table] of Object.entries(schema.tables)) {
125
+ const id = nodeId(tableName);
126
+ for (const constraint of Object.values(table.constraints)) {
127
+ if (constraint.type !== 'foreign_key')
128
+ continue;
129
+ for (let i = 0; i < constraint.on.length; i++) {
130
+ edges.push({
131
+ fromTable: tableName,
132
+ fromCol: constraint.on[i],
133
+ toTable: constraint.target,
134
+ toCol: constraint.references[i],
135
+ });
136
+ }
137
+ }
138
+ yield `\t${id} [label=<\n`;
139
+ yield '\t\t<TABLE BORDER="1" CELLBORDER="0" CELLSPACING="0" CELLPADDING="4">\n';
140
+ yield `\t\t\t<TR><TD COLSPAN="3" BGCOLOR="#44C2C4"><B>${esc(tableName)}</B></TD></TR>\n`;
141
+ for (const [colName, column] of Object.entries(table.columns)) {
142
+ const nullable = !column.required ? '?' : '';
143
+ const typeText = esc(column.type) + nullable;
144
+ let label = `${esc(colName)}: ${column.references ? `<I>${typeText}</I>` : typeText}`;
145
+ if (column.primary)
146
+ label = `<B>${label}</B>`;
147
+ if (column.references) {
148
+ const [toTable, toCol] = column.references.split('.');
149
+ edges.push({ fromTable: tableName, fromCol: colName, toTable, toCol });
150
+ }
151
+ yield `\t\t\t<TR><TD PORT="${esc(colName)}_l" WIDTH="2"></TD><TD ALIGN="LEFT">${label}</TD><TD PORT="${esc(colName)}_r" WIDTH="2"></TD></TR>\n`;
152
+ }
153
+ yield '\t\t</TABLE>\n\t>];\n\n';
154
+ }
155
+ for (const { fromTable, fromCol, toTable, toCol } of edges) {
156
+ if (fromTable != toTable) {
157
+ yield `\t${nodeId(fromTable)}:${fromCol}_r -> ${nodeId(toTable)}:${toCol}_l;\n`;
158
+ continue;
159
+ }
160
+ const id = nodeId(fromTable);
161
+ yield `\t${id}:${fromCol}_l:w -> ${id}:${toCol}_l:w [constraint=false];\n`;
162
+ }
163
+ yield '}\n';
164
+ }
165
+ export const toIntrospected = {
166
+ boolean: 'bool',
167
+ integer: 'int4',
168
+ 'text[]': '_text',
169
+ };
@@ -1,6 +1,6 @@
1
1
  {
2
- "$schema": "../schemas/db.json",
3
- "format": 0,
2
+ "$schema": "../../schemas/db.json",
3
+ "format": 1,
4
4
  "versions": [
5
5
  {
6
6
  "delta": false,
@@ -64,7 +64,9 @@
64
64
  }
65
65
  }
66
66
  },
67
- "indexes": ["sessions:id", "passkeys:userId"]
67
+ "indexes": {
68
+ "passkeys_userId": { "on": "passkeys", "columns": ["userId"] }
69
+ }
68
70
  },
69
71
  {
70
72
  "delta": true,
package/dist/main.js CHANGED
@@ -85,15 +85,15 @@ async function dbInitTables() {
85
85
  const env_2 = { stack: [], error: void 0, hasError: false };
86
86
  try {
87
87
  const info = db.getUpgradeInfo();
88
- const schema = db.getFullSchema({ exclude: Object.keys(info.current) });
89
- const delta = db.computeDelta({ tables: {}, indexes: [] }, schema);
90
- if (db.deltaIsEmpty(delta))
88
+ const schema = db.schema.getFull({ exclude: Object.keys(info.current) });
89
+ const delta = db.delta.compute({ tables: {}, indexes: {} }, schema);
90
+ if (db.delta.isEmpty(delta))
91
91
  return;
92
- for (const text of db.displayDelta(delta))
92
+ for (const text of db.delta.display(delta))
93
93
  console.log(text);
94
94
  await rlConfirm();
95
95
  const _ = __addDisposableResource(env_2, db.connect(), true);
96
- await db.applyDelta(delta);
96
+ await db.delta.apply(delta);
97
97
  Object.assign(info.current, schema.versions);
98
98
  db.setUpgradeInfo(info);
99
99
  }
@@ -248,7 +248,7 @@ try {
248
248
  .addOption(opts.force)
249
249
  .action(async (opt) => {
250
250
  const tables = new Map();
251
- for (const [plugin, schema] of db.getSchemaFiles()) {
251
+ for (const [plugin, schema] of db.schema.getFiles()) {
252
252
  for (const table of schema.wipe) {
253
253
  const maybePlugin = tables.get(table);
254
254
  tables.set(table, maybePlugin ? `${maybePlugin}, ${plugin}` : plugin);
@@ -309,7 +309,7 @@ try {
309
309
  io.start('Resolving database schemas');
310
310
  let schema;
311
311
  try {
312
- schema = db.getFullSchema();
312
+ schema = db.schema.getFull();
313
313
  io.done();
314
314
  }
315
315
  catch (e) {
@@ -350,12 +350,12 @@ try {
350
350
  .description('Generate a new password for the database user and update the config')
351
351
  .action(db.rotatePassword);
352
352
  axiumDB
353
- .command('schema')
353
+ .command('json-schema')
354
354
  .description('Get the JSON schema for the database configuration file')
355
355
  .option('-j, --json', 'values are JSON encoded')
356
356
  .action(opt => {
357
357
  try {
358
- const schema = z.toJSONSchema(db.SchemaFile, { io: 'input' });
358
+ const schema = z.toJSONSchema(db.schema.SchemaFile, { io: 'input' });
359
359
  console.log(opt.json ? JSON.stringify(schema, null, 4) : schema);
360
360
  }
361
361
  catch (e) {
@@ -373,7 +373,7 @@ try {
373
373
  const info = db.getUpgradeInfo();
374
374
  let empty = true;
375
375
  const from = {}, to = {};
376
- for (const [name, schema] of db.getSchemaFiles()) {
376
+ for (const [name, schema] of db.schema.getFiles()) {
377
377
  if (!(name in info.current))
378
378
  io.exit('Plugin is not initialized: ' + name);
379
379
  const currentVersion = info.current[name];
@@ -390,15 +390,15 @@ try {
390
390
  for (const [i, v] of versions.toReversed().entries()) {
391
391
  if (v.delta || v == v0)
392
392
  continue;
393
- versions = [db.computeDelta(v0, v), ...versions.slice(-i)];
393
+ versions = [db.delta.compute(v0, v), ...versions.slice(-i)];
394
394
  break;
395
395
  }
396
- const delta = db.collapseDeltas(versions);
396
+ const delta = db.delta.collapse(versions);
397
397
  deltas.push(delta);
398
398
  console.log('Upgrading', name, styleText('dim', currentVersion.toString() + '->') + styleText('blueBright', target.toString()) + ':');
399
- if (!db.deltaIsEmpty(delta))
399
+ if (!db.delta.isEmpty(delta))
400
400
  empty = false;
401
- for (const text of db.displayDelta(delta))
401
+ for (const text of db.delta.display(delta))
402
402
  console.log(text);
403
403
  }
404
404
  if (empty) {
@@ -412,7 +412,7 @@ try {
412
412
  io.start('Computing delta');
413
413
  let delta;
414
414
  try {
415
- delta = db.collapseDeltas(deltas);
415
+ delta = db.delta.collapse(deltas);
416
416
  io.done();
417
417
  }
418
418
  catch (e) {
@@ -420,14 +420,14 @@ try {
420
420
  }
421
421
  io.start('Validating delta');
422
422
  try {
423
- db.validateDelta(delta);
423
+ db.delta.validate(delta);
424
424
  io.done();
425
425
  }
426
426
  catch (e) {
427
427
  io.exit(e);
428
428
  }
429
429
  console.log('Applying delta.');
430
- await db.applyDelta(delta, opt.abort).catch(io.exit);
430
+ await db.delta.apply(delta, opt.abort).catch(io.exit);
431
431
  info.upgrades.push({ timestamp: new Date(), from, to });
432
432
  db.setUpgradeInfo(info);
433
433
  });
@@ -457,7 +457,7 @@ try {
457
457
  const entries = [
458
458
  { name: 'Name', current: 'Current', latest: 'Latest', available: 'Available' },
459
459
  ];
460
- for (const [name, file] of db.getSchemaFiles()) {
460
+ for (const [name, file] of db.schema.getFiles()) {
461
461
  const available = (file.versions.length - 1).toString();
462
462
  const latest = (file.latest ?? available).toString();
463
463
  const current = currentVersions[name]?.toString();
@@ -471,6 +471,20 @@ try {
471
471
  console.log(...['name', 'current', 'latest', 'available'].map(key => styleText(i === 0 ? ['whiteBright', 'underline'] : entry[key] === undefined ? 'reset' : [], entry[key].padStart(lengths[key]))));
472
472
  }
473
473
  });
474
+ axiumDB
475
+ .command('export-schema')
476
+ .description('Export the DB schema')
477
+ .addOption(new Option('-f, --format <format>', 'Output format').choices(['sql', 'graph']).default('sql'))
478
+ .option('-o, --output <file>', 'Output file path')
479
+ .action(opt => {
480
+ const schema = db.schema.getFull();
481
+ const it = opt.format == 'sql' ? db.schema.toSQL(schema) : db.schema.toGraph(schema);
482
+ const out = opt.output ? createWriteStream(opt.output) : process.stdout;
483
+ for (const data of it)
484
+ out.write(data);
485
+ if (opt.output)
486
+ out.close();
487
+ });
474
488
  axiumConfig = program
475
489
  .command('config')
476
490
  .description('Manage the configuration')
@@ -594,16 +608,16 @@ try {
594
608
  const exclude = Object.keys(info.current);
595
609
  if (exclude.includes(plugin.name))
596
610
  io.exit('Plugin is already initialized (database)');
597
- const schema = db.getFullSchema({ exclude });
598
- const delta = db.computeDelta({ tables: {}, indexes: [] }, schema);
599
- if (db.deltaIsEmpty(delta)) {
611
+ const schema = db.schema.getFull({ exclude });
612
+ const delta = db.delta.compute({ tables: {}, indexes: {} }, schema);
613
+ if (db.delta.isEmpty(delta)) {
600
614
  io.info('Plugin does not define any database schema.');
601
615
  return;
602
616
  }
603
- for (const text of db.displayDelta(delta))
617
+ for (const text of db.delta.display(delta))
604
618
  console.log(text);
605
619
  await rlConfirm();
606
- await db.applyDelta(delta);
620
+ await db.delta.apply(delta);
607
621
  Object.assign(info.current, schema.versions);
608
622
  db.setUpgradeInfo(info);
609
623
  }