@inflector/optima 1.0.0 → 1.0.1
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/dist/Qfluent.d.ts +40 -0
- package/dist/Qfluent.js +64 -0
- package/dist/database.d.ts +32 -0
- package/dist/database.js +240 -0
- package/dist/fluent.d.ts +13 -0
- package/dist/fluent.js +29 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/schema.d.ts +85 -0
- package/dist/schema.js +214 -0
- package/dist/table.d.ts +178 -0
- package/dist/table.js +617 -0
- package/package.json +10 -3
- package/src/Qfluent.ts +0 -179
- package/src/database.ts +0 -284
- package/src/fluent.ts +0 -55
- package/src/index.ts +0 -14
- package/src/schema.ts +0 -446
- package/src/table.ts +0 -926
- package/test/Schema.ts +0 -39
- package/test/index.ts +0 -16
- package/tsconfig.json +0 -15
package/src/schema.ts
DELETED
|
@@ -1,446 +0,0 @@
|
|
|
1
|
-
import * as z from "zod";
|
|
2
|
-
|
|
3
|
-
type DefaultConfig = { [K in keyof ColumnConfig]: false };
|
|
4
|
-
// Helper: Sets Key K to true in Config C
|
|
5
|
-
type SetFlag<C extends ColumnConfig, K extends keyof ColumnConfig> = Omit<
|
|
6
|
-
C,
|
|
7
|
-
K
|
|
8
|
-
> & { [P in K]: true };
|
|
9
|
-
|
|
10
|
-
export type Prettify<T> = {
|
|
11
|
-
[K in keyof T]: T[K];
|
|
12
|
-
} & {};
|
|
13
|
-
|
|
14
|
-
export type Restrict<K extends keyof ColumnConfig> = {
|
|
15
|
-
[P in keyof ColumnConfig]: P extends K ? true : false;
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
// Phantom type brand symbol
|
|
19
|
-
declare const __parentBrand: unique symbol;
|
|
20
|
-
type ParentBrand<Name extends string> = { [__parentBrand]: Name };
|
|
21
|
-
|
|
22
|
-
// Reference wrapper types for one-to-one and one-to-many relationships
|
|
23
|
-
// Using string literal type discrimination instead of symbols for cross-module compatibility
|
|
24
|
-
export type One<T> = T & { readonly __refKind: "one" };
|
|
25
|
-
export type Many<T> = T & { readonly __refKind: "many" };
|
|
26
|
-
|
|
27
|
-
// Helper functions for reference syntax
|
|
28
|
-
export const refHelpers = {
|
|
29
|
-
one: <T>(ref: T): One<T> => ref as One<T>,
|
|
30
|
-
many: <T>(ref: T): Many<T> => ref as Many<T>,
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
export type InferColumnType<T> = T extends ColumnBuilder<infer U, any, any>
|
|
34
|
-
? U
|
|
35
|
-
: never;
|
|
36
|
-
|
|
37
|
-
export type Infer<T extends Record<string, any>> = Prettify<
|
|
38
|
-
// 1. Handle Required Keys (notnull: true)
|
|
39
|
-
{
|
|
40
|
-
[K in keyof T as K extends `__${string}`
|
|
41
|
-
? never
|
|
42
|
-
: T[K] extends ColumnBuilder<any, infer C, any>
|
|
43
|
-
? C["notnull"] extends true
|
|
44
|
-
? K
|
|
45
|
-
: never
|
|
46
|
-
: never]: T[K] extends ColumnBuilder<infer U, any, any> ? U : never;
|
|
47
|
-
} & // 2. Handle Optional Keys (notnull: false)
|
|
48
|
-
{
|
|
49
|
-
[K in keyof T as K extends `__${string}`
|
|
50
|
-
? never
|
|
51
|
-
: T[K] extends ColumnBuilder<any, infer C, any>
|
|
52
|
-
? C["notnull"] extends true
|
|
53
|
-
? never
|
|
54
|
-
: K
|
|
55
|
-
: never]: T[K] extends ColumnBuilder<infer U, any, any>
|
|
56
|
-
? U | null
|
|
57
|
-
: never;
|
|
58
|
-
}
|
|
59
|
-
>;
|
|
60
|
-
export type InferAdd<T extends Record<string, any>> = Prettify<
|
|
61
|
-
// 1. Handle Required Keys (notnull: true)
|
|
62
|
-
{
|
|
63
|
-
[K in keyof T as K extends `__${string}`
|
|
64
|
-
? never
|
|
65
|
-
: T[K] extends ColumnBuilder<any, infer C, any>
|
|
66
|
-
? C["notnull"] extends true
|
|
67
|
-
? K
|
|
68
|
-
: never
|
|
69
|
-
: never]: T[K] extends ColumnBuilder<infer U, any, any> ? U : never;
|
|
70
|
-
} & // 2. Handle Optional Keys (notnull: false)
|
|
71
|
-
{
|
|
72
|
-
[K in keyof T as K extends `__${string}`
|
|
73
|
-
? never
|
|
74
|
-
: T[K] extends ColumnBuilder<any, infer C, any>
|
|
75
|
-
? C["notnull"] extends true
|
|
76
|
-
? never
|
|
77
|
-
: K
|
|
78
|
-
: never]?: T[K] extends ColumnBuilder<infer U, any, any>
|
|
79
|
-
? U | null
|
|
80
|
-
: never;
|
|
81
|
-
}
|
|
82
|
-
>;
|
|
83
|
-
|
|
84
|
-
export type ColumnConfig = {
|
|
85
|
-
SQlType: boolean;
|
|
86
|
-
primaryKey: boolean;
|
|
87
|
-
notnull: boolean;
|
|
88
|
-
unique: boolean;
|
|
89
|
-
default: boolean;
|
|
90
|
-
defaultNow: boolean;
|
|
91
|
-
reference: boolean;
|
|
92
|
-
validate: boolean;
|
|
93
|
-
transform: boolean;
|
|
94
|
-
deprecated: boolean;
|
|
95
|
-
STRUCTType: boolean;
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
export type ColumnBuilder<
|
|
99
|
-
Type,
|
|
100
|
-
Config extends ColumnConfig,
|
|
101
|
-
RefSchema = never
|
|
102
|
-
> = {
|
|
103
|
-
[K in keyof ColumnConfig as K extends "STRUCTType"
|
|
104
|
-
? never
|
|
105
|
-
: Config[K] extends true
|
|
106
|
-
? never
|
|
107
|
-
: K]: K extends "SQlType"
|
|
108
|
-
? (
|
|
109
|
-
val: string
|
|
110
|
-
) => ColumnBuilder<Type, SetFlag<Config, "SQlType">, RefSchema>
|
|
111
|
-
: K extends "primaryKey"
|
|
112
|
-
? () => ColumnBuilder<Type, SetFlag<Config, "primaryKey">, RefSchema>
|
|
113
|
-
: K extends "notnull"
|
|
114
|
-
? () => ColumnBuilder<Type, SetFlag<Config, "notnull">, RefSchema>
|
|
115
|
-
: K extends "unique"
|
|
116
|
-
? () => ColumnBuilder<Type, SetFlag<Config, "unique">, RefSchema>
|
|
117
|
-
: K extends "default"
|
|
118
|
-
? (
|
|
119
|
-
val: Type | (() => Type)
|
|
120
|
-
) => ColumnBuilder<Type, SetFlag<Config, "default">, RefSchema>
|
|
121
|
-
: K extends "defaultNow"
|
|
122
|
-
? () => ColumnBuilder<Type, SetFlag<Config, "defaultNow">, RefSchema>
|
|
123
|
-
: K extends "reference"
|
|
124
|
-
? <TRef>(
|
|
125
|
-
ref: (helpers: typeof refHelpers) => TRef
|
|
126
|
-
) => ColumnBuilder<Type, SetFlag<Config, "reference">, TRef>
|
|
127
|
-
: K extends "validate"
|
|
128
|
-
? (
|
|
129
|
-
fn: (val: Type) => boolean
|
|
130
|
-
) => ColumnBuilder<Type, SetFlag<Config, "validate">, RefSchema>
|
|
131
|
-
: K extends "transform"
|
|
132
|
-
? (
|
|
133
|
-
fn: (val: Type) => Type
|
|
134
|
-
) => ColumnBuilder<Type, SetFlag<Config, "transform">, RefSchema>
|
|
135
|
-
: K extends "deprecated"
|
|
136
|
-
? () => ColumnBuilder<Type, SetFlag<Config, "deprecated">, RefSchema>
|
|
137
|
-
: never;
|
|
138
|
-
};
|
|
139
|
-
|
|
140
|
-
class ColumnImpl<Type, RefSchema = never> {
|
|
141
|
-
public config: Partial<Record<keyof ColumnConfig, any>> = {};
|
|
142
|
-
|
|
143
|
-
constructor(config: Partial<Record<keyof ColumnConfig, any>> = {}) {
|
|
144
|
-
this.config = config;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
private next(key: keyof ColumnConfig, value: any = true): any {
|
|
148
|
-
return new ColumnImpl({ ...this.config, [key]: value });
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
SQlType(val: string) {
|
|
152
|
-
return this.next("SQlType", val);
|
|
153
|
-
}
|
|
154
|
-
primaryKey() {
|
|
155
|
-
return this.next("primaryKey");
|
|
156
|
-
}
|
|
157
|
-
notnull() {
|
|
158
|
-
return this.next("notnull");
|
|
159
|
-
}
|
|
160
|
-
unique() {
|
|
161
|
-
return this.next("unique");
|
|
162
|
-
}
|
|
163
|
-
default(val: Type | (() => Type)) {
|
|
164
|
-
return this.next("default", val);
|
|
165
|
-
}
|
|
166
|
-
defaultNow() {
|
|
167
|
-
return this.next("defaultNow");
|
|
168
|
-
}
|
|
169
|
-
reference<TRef>(c: (helpers: typeof refHelpers) => TRef) {
|
|
170
|
-
// Execute function with helpers to get the wrapped reference
|
|
171
|
-
const result = c(refHelpers) as any;
|
|
172
|
-
|
|
173
|
-
// Detect if it's a Many wrapper by checking the symbol
|
|
174
|
-
const isManyRef =
|
|
175
|
-
result?.[Symbol.for("__refType")] === "many" ||
|
|
176
|
-
(typeof result === "object" && result !== null && "__refType" in result);
|
|
177
|
-
|
|
178
|
-
// Unwrap the actual column reference
|
|
179
|
-
const actualRef = result;
|
|
180
|
-
|
|
181
|
-
let refName = "";
|
|
182
|
-
|
|
183
|
-
if (actualRef?.__parent && actualRef?.__fieldName) {
|
|
184
|
-
refName = `${actualRef.__parent}.${actualRef.__fieldName}`;
|
|
185
|
-
} else {
|
|
186
|
-
// Fallback: parse function string
|
|
187
|
-
const code = c.toString();
|
|
188
|
-
// Extract the reference from patterns like: one(Users.ID) or many(Users.ID)
|
|
189
|
-
const match = code.match(/(?:one|many)\s*\(\s*([^)]+)\s*\)/);
|
|
190
|
-
if (match && match[1]) {
|
|
191
|
-
const refPart = match[1].trim();
|
|
192
|
-
if (refPart.includes(".")) {
|
|
193
|
-
refName = refPart;
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
// Check if the TRef type is Many<...>
|
|
199
|
-
// At runtime we need a different check - look at the function body
|
|
200
|
-
const codeStr = c.toString();
|
|
201
|
-
const isMany = codeStr.includes("many(");
|
|
202
|
-
|
|
203
|
-
const nextConfig = { ...this.config, reference: { ref: refName, isMany } };
|
|
204
|
-
return new ColumnImpl(nextConfig);
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
validate(fn: (val: Type) => boolean) {
|
|
208
|
-
return this.next("validate", fn);
|
|
209
|
-
}
|
|
210
|
-
transform(fn: (val: any) => Type) {
|
|
211
|
-
return this.next("transform", fn);
|
|
212
|
-
}
|
|
213
|
-
deprecated() {
|
|
214
|
-
return this.next("deprecated");
|
|
215
|
-
}
|
|
216
|
-
STRUCTType(val: string) {
|
|
217
|
-
return this.next("STRUCTType", val);
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
const Column = <
|
|
222
|
-
Type,
|
|
223
|
-
Config extends ColumnConfig = DefaultConfig,
|
|
224
|
-
RefSchema = never
|
|
225
|
-
>(
|
|
226
|
-
conf?: Partial<Record<keyof ColumnConfig, any>>
|
|
227
|
-
): ColumnBuilder<Type, Config, RefSchema> => {
|
|
228
|
-
return new ColumnImpl<Type, RefSchema>(conf) as any;
|
|
229
|
-
};
|
|
230
|
-
|
|
231
|
-
export const Int = () =>
|
|
232
|
-
Column<number, Restrict<"defaultNow">>().SQlType("INTEGER");
|
|
233
|
-
export const BigInt = () =>
|
|
234
|
-
Column<bigint, Restrict<"defaultNow">>().SQlType("BIGINT");
|
|
235
|
-
export const Float = () =>
|
|
236
|
-
Column<number, Restrict<"defaultNow">>().SQlType("FLOAT");
|
|
237
|
-
export const Boolean = () =>
|
|
238
|
-
Column<boolean, Restrict<"defaultNow" | "primaryKey" | "unique">>().SQlType(
|
|
239
|
-
"BOOLEAN"
|
|
240
|
-
);
|
|
241
|
-
export const Text = () =>
|
|
242
|
-
Column<string, Restrict<"defaultNow">>().SQlType("VARCHAR");
|
|
243
|
-
export const Uuid = () =>
|
|
244
|
-
Column<string, Restrict<"defaultNow">>().SQlType("VARCHAR");
|
|
245
|
-
export const DateType = () =>
|
|
246
|
-
Column<Date, Restrict<"default">>().SQlType("DATE");
|
|
247
|
-
export const Timestamp = () =>
|
|
248
|
-
Column<Date, Restrict<"default">>().SQlType("TIMESTAMP");
|
|
249
|
-
export const Enum = <T extends string | number>(vals: readonly T[]) => {
|
|
250
|
-
const isString = typeof vals[0] === "string";
|
|
251
|
-
return Column<T, Restrict<"defaultNow">>()
|
|
252
|
-
.validate((v) => vals.includes(v))
|
|
253
|
-
.SQlType(isString ? "VARCHAR" : "INTEGER");
|
|
254
|
-
};
|
|
255
|
-
|
|
256
|
-
// --- RECURSIVE ZOD PARSER START ---
|
|
257
|
-
export * from "zod";
|
|
258
|
-
|
|
259
|
-
const zodToDuckDBType = (zodType: z.ZodTypeAny): string => {
|
|
260
|
-
const def: any = (zodType as any)?._def;
|
|
261
|
-
|
|
262
|
-
if (
|
|
263
|
-
def &&
|
|
264
|
-
(def.typeName === "ZodOptional" || def.typeName === "ZodNullable")
|
|
265
|
-
) {
|
|
266
|
-
return zodToDuckDBType(def.innerType);
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
if (def && def.typeName === "ZodDefault") {
|
|
270
|
-
return zodToDuckDBType(def.innerType);
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
if (zodType instanceof z.ZodString) return "VARCHAR";
|
|
274
|
-
if (zodType instanceof z.ZodNumber) return "INTEGER";
|
|
275
|
-
if (zodType instanceof z.ZodBoolean) return "BOOLEAN";
|
|
276
|
-
if (zodType instanceof z.ZodDate) return "TIMESTAMP";
|
|
277
|
-
if (zodType instanceof z.ZodBigInt) return "BIGINT";
|
|
278
|
-
|
|
279
|
-
if ("element" in (def ?? {})) {
|
|
280
|
-
const innerType = zodToDuckDBType(def.element);
|
|
281
|
-
return `${innerType}[]`;
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
if ("shape" in (def ?? {})) {
|
|
285
|
-
const shape: Record<string, z.ZodTypeAny> =
|
|
286
|
-
typeof def.shape === "function" ? def.shape() : def.shape;
|
|
287
|
-
const structParts = Object.entries(shape).map(([key, value]) => {
|
|
288
|
-
const fieldType = zodToDuckDBType(value as z.ZodTypeAny);
|
|
289
|
-
return `${key} ${fieldType}`;
|
|
290
|
-
});
|
|
291
|
-
return `STRUCT(${structParts.join(", ")})`;
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
return "VARCHAR";
|
|
295
|
-
};
|
|
296
|
-
|
|
297
|
-
export const Json = <T extends z.ZodRawShape>(obj: T) => {
|
|
298
|
-
const zodObj = z.object(obj);
|
|
299
|
-
const duckDBStructString = zodToDuckDBType(zodObj);
|
|
300
|
-
|
|
301
|
-
const col = Column<
|
|
302
|
-
z.infer<z.ZodObject<T>>,
|
|
303
|
-
Restrict<"defaultNow" | "primaryKey" | "unique">
|
|
304
|
-
>().SQlType("STRUCT");
|
|
305
|
-
|
|
306
|
-
return (col as any).STRUCTType(duckDBStructString) as typeof col;
|
|
307
|
-
};
|
|
308
|
-
|
|
309
|
-
export const Array = <T extends z.ZodTypeAny>(schema: T) => {
|
|
310
|
-
const innerType = zodToDuckDBType(schema);
|
|
311
|
-
|
|
312
|
-
const col = Column<
|
|
313
|
-
z.infer<T>[],
|
|
314
|
-
Restrict<"defaultNow" | "primaryKey" | "unique">
|
|
315
|
-
>().SQlType("LIST");
|
|
316
|
-
|
|
317
|
-
return (col as any).STRUCTType(`${innerType}[]`) as typeof col;
|
|
318
|
-
};
|
|
319
|
-
|
|
320
|
-
// ADD-ONS
|
|
321
|
-
export const Email = () =>
|
|
322
|
-
Column<string, Restrict<"defaultNow">>()
|
|
323
|
-
.SQlType("VARCHAR")
|
|
324
|
-
.validate((v) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(v));
|
|
325
|
-
export const Slug = () =>
|
|
326
|
-
Column<string, Restrict<"defaultNow">>()
|
|
327
|
-
.SQlType("VARCHAR")
|
|
328
|
-
.validate((v) => /^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(v));
|
|
329
|
-
export const Color = () =>
|
|
330
|
-
Column<string, Restrict<"defaultNow">>()
|
|
331
|
-
.SQlType("VARCHAR")
|
|
332
|
-
.validate((v) => /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/.test(v));
|
|
333
|
-
export const Bytes = () =>
|
|
334
|
-
Column<Uint8Array, Restrict<"defaultNow" | "primaryKey">>().SQlType("BLOB");
|
|
335
|
-
export const Password = () =>
|
|
336
|
-
Column<string, Restrict<"defaultNow" | "primaryKey" | "unique">>().SQlType(
|
|
337
|
-
"VARCHAR"
|
|
338
|
-
);
|
|
339
|
-
export const GeoPoint = () =>
|
|
340
|
-
Column<
|
|
341
|
-
{ latitude: number; longitude: number },
|
|
342
|
-
Restrict<"defaultNow" | "primaryKey">
|
|
343
|
-
>().SQlType("STRUCT");
|
|
344
|
-
export const GeoArea = () =>
|
|
345
|
-
Column<
|
|
346
|
-
{
|
|
347
|
-
latitude: number;
|
|
348
|
-
longitude: number;
|
|
349
|
-
radius: number;
|
|
350
|
-
},
|
|
351
|
-
Restrict<"defaultNow" | "primaryKey">
|
|
352
|
-
>().SQlType("STRUCT");
|
|
353
|
-
|
|
354
|
-
// ---------------------------------------------------------
|
|
355
|
-
// Column & Table Definitions
|
|
356
|
-
// ---------------------------------------------------------
|
|
357
|
-
|
|
358
|
-
export const Table = <
|
|
359
|
-
Name extends string,
|
|
360
|
-
T extends Record<string, ColumnBuilder<any, any>>
|
|
361
|
-
>(
|
|
362
|
-
name: Name,
|
|
363
|
-
fields: T
|
|
364
|
-
): T & { __tableName: Name } => {
|
|
365
|
-
// Runtime Metadata Injection
|
|
366
|
-
for (const [key, value] of Object.entries(fields)) {
|
|
367
|
-
Object.assign(value, { __parent: name, __fieldName: key });
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
return { ...fields, __tableName: name } as any;
|
|
371
|
-
};
|
|
372
|
-
|
|
373
|
-
const GetFieldConfig = (
|
|
374
|
-
f: ColumnBuilder<any, any>
|
|
375
|
-
): {
|
|
376
|
-
SQlType: string;
|
|
377
|
-
primaryKey: boolean;
|
|
378
|
-
notnull: boolean;
|
|
379
|
-
unique: boolean;
|
|
380
|
-
default: boolean;
|
|
381
|
-
defaultNow: boolean;
|
|
382
|
-
reference: boolean;
|
|
383
|
-
STRUCTType?: string;
|
|
384
|
-
} => {
|
|
385
|
-
return (f as any).config;
|
|
386
|
-
};
|
|
387
|
-
|
|
388
|
-
export class SQLBuilder {
|
|
389
|
-
static BuildField(name: string, f: ColumnBuilder<any, any>) {
|
|
390
|
-
const FieldConfig = GetFieldConfig(f);
|
|
391
|
-
let sql = `${name} ${FieldConfig.SQlType || "TEXT"}`;
|
|
392
|
-
|
|
393
|
-
if (
|
|
394
|
-
(FieldConfig.SQlType == "STRUCT" || FieldConfig.SQlType == "LIST") &&
|
|
395
|
-
FieldConfig.STRUCTType
|
|
396
|
-
) {
|
|
397
|
-
sql = `${name} ${FieldConfig.STRUCTType}`;
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
if (FieldConfig.primaryKey) sql += " PRIMARY KEY";
|
|
401
|
-
if (FieldConfig.notnull) sql += " NOT NULL";
|
|
402
|
-
if (FieldConfig.unique) sql += " UNIQUE";
|
|
403
|
-
if (FieldConfig.defaultNow) sql += ` DEFAULT CURRENT_TIMESTAMP`;
|
|
404
|
-
|
|
405
|
-
if (
|
|
406
|
-
FieldConfig.SQlType !== "STRUCT" &&
|
|
407
|
-
FieldConfig.SQlType !== "LIST" &&
|
|
408
|
-
FieldConfig.default !== false &&
|
|
409
|
-
FieldConfig.default !== undefined
|
|
410
|
-
) {
|
|
411
|
-
if (typeof FieldConfig.default !== "function") {
|
|
412
|
-
sql += ` DEFAULT ${
|
|
413
|
-
typeof FieldConfig.default === "string"
|
|
414
|
-
? `'${FieldConfig.default}'`
|
|
415
|
-
: JSON.stringify(FieldConfig.default)
|
|
416
|
-
}`;
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
|
|
420
|
-
if (
|
|
421
|
-
(FieldConfig.SQlType == "STRUCT" || FieldConfig.SQlType == "LIST") &&
|
|
422
|
-
FieldConfig.default !== false &&
|
|
423
|
-
FieldConfig.default !== undefined
|
|
424
|
-
) {
|
|
425
|
-
// Use split/join for compatibility with older JS/TS targets (replaceAll not supported)
|
|
426
|
-
sql += ` DEFAULT ${JSON.stringify(FieldConfig.default).split('"').join("'")}`;
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
return {
|
|
430
|
-
sql: sql.trim(),
|
|
431
|
-
// @ts-ignore
|
|
432
|
-
ref: FieldConfig.reference,
|
|
433
|
-
};
|
|
434
|
-
}
|
|
435
|
-
static BuildTable(name: string, t: Record<string, any>) {
|
|
436
|
-
const fieldDefs = Object.entries(t)
|
|
437
|
-
.filter(([key]) => key !== "__tableName")
|
|
438
|
-
.map(([fieldName, builder]) => {
|
|
439
|
-
const Result = this.BuildField(fieldName, builder);
|
|
440
|
-
return Result.sql;
|
|
441
|
-
});
|
|
442
|
-
return `CREATE TABLE IF NOT EXISTS ${name} (\n ${fieldDefs.join(
|
|
443
|
-
",\n "
|
|
444
|
-
)}\n);`;
|
|
445
|
-
}
|
|
446
|
-
}
|