sedentary 0.0.17 → 0.0.18
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/index.d.ts +3 -3
- package/index.js +103 -10
- package/lib/db.d.ts +14 -0
- package/lib/minidb.js +18 -15
- package/package.json +1 -1
package/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { DB, Entry, Meta, Natural, Type } from "./lib/db";
|
|
2
|
-
export { Entry, Natural, Type } from "./lib/db";
|
|
1
|
+
import { DB, Entry, ForeignKeyOptions, Meta, Natural, Type } from "./lib/db";
|
|
2
|
+
export { Entry, ForeignKeyActions, ForeignKeyOptions, Natural, Type } from "./lib/db";
|
|
3
3
|
export declare type TypeDefinition<N extends Natural, E> = (() => Type<N, E>) | Type<N, E>;
|
|
4
4
|
export interface AttributeOptions<N extends Natural, E> {
|
|
5
5
|
defaultValue?: N;
|
|
@@ -73,7 +73,7 @@ export declare class Sedentary {
|
|
|
73
73
|
private models;
|
|
74
74
|
constructor(filename: string, options?: SedentaryOptions);
|
|
75
75
|
DATETIME(): Type<Date, unknown>;
|
|
76
|
-
FKEY<N extends Natural, E extends Entry>(attribute: Type<N, E
|
|
76
|
+
FKEY<N extends Natural, E extends Entry>(attribute: Type<N, E>, options?: ForeignKeyOptions): Type<N, E>;
|
|
77
77
|
INT(size?: number): Type<number, unknown>;
|
|
78
78
|
INT8(): Type<string, unknown>;
|
|
79
79
|
VARCHAR(size?: number): Type<string, unknown>;
|
package/index.js
CHANGED
|
@@ -37,9 +37,9 @@ class Sedentary {
|
|
|
37
37
|
DATETIME() {
|
|
38
38
|
return new db_1.Type({ base: Date, type: "DATETIME" });
|
|
39
39
|
}
|
|
40
|
-
FKEY(attribute) {
|
|
40
|
+
FKEY(attribute, options) {
|
|
41
41
|
const { attributeName, base, fieldName, size, tableName, type } = attribute;
|
|
42
|
-
return new db_1.Type({ base, foreignKey: { attributeName, fieldName, tableName }, size, type });
|
|
42
|
+
return new db_1.Type({ base, foreignKey: { attributeName, fieldName, options, tableName }, size, type });
|
|
43
43
|
}
|
|
44
44
|
INT(size) {
|
|
45
45
|
const message = "Sedentary.INT: 'size' argument: Wrong value, expected 2 or 4";
|
|
@@ -107,6 +107,7 @@ class Sedentary {
|
|
|
107
107
|
const pk = aarray[0];
|
|
108
108
|
if (methods && !(methods instanceof Object))
|
|
109
109
|
throw new Error(`Sedentary.model: '${modelName}' model: 'methods' option: Wrong type, expected 'Object'`);
|
|
110
|
+
const originalMethods = methods;
|
|
110
111
|
if (parent) {
|
|
111
112
|
try {
|
|
112
113
|
if (!parent.isModel())
|
|
@@ -174,6 +175,23 @@ class Sedentary {
|
|
|
174
175
|
}
|
|
175
176
|
return ret;
|
|
176
177
|
})();
|
|
178
|
+
if (foreignKey) {
|
|
179
|
+
if (!foreignKey.options)
|
|
180
|
+
foreignKey.options = {};
|
|
181
|
+
if (!(foreignKey.options instanceof Object))
|
|
182
|
+
throw new Error(`Sedentary.FKEY: '${modelName}' model: '${attributeName}' attribute: Wrong options type, expected 'Object'`);
|
|
183
|
+
for (const k in foreignKey.options)
|
|
184
|
+
if (!["onDelete", "onUpdate"].includes(k))
|
|
185
|
+
throw new Error(`Sedentary.FKEY: '${modelName}' model: '${attributeName}' attribute: Unknown option '${k}'`);
|
|
186
|
+
for (const onChange of ["onDelete", "onUpdate"]) {
|
|
187
|
+
const actions = ["cascade", "no action", "restrict", "set default", "set null"];
|
|
188
|
+
let action = foreignKey.options[onChange];
|
|
189
|
+
if (!action)
|
|
190
|
+
action = foreignKey.options[onChange] = "no action";
|
|
191
|
+
if (action && !actions.includes(action))
|
|
192
|
+
throw new Error(`Sedentary.FKEY: '${modelName}' model: '${attributeName}' attribute: '${onChange}' option: Wrong value, expected ${actions.map(_ => `'${_}'`).join(" | ")}`);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
177
195
|
if (primaryKey === attributeName) {
|
|
178
196
|
notNull = true;
|
|
179
197
|
unique = true;
|
|
@@ -249,9 +267,6 @@ class Sedentary {
|
|
|
249
267
|
}
|
|
250
268
|
: parent.init
|
|
251
269
|
: options.init;
|
|
252
|
-
const flds = {};
|
|
253
|
-
for (const key in attributes)
|
|
254
|
-
flds[key] = null;
|
|
255
270
|
class Class {
|
|
256
271
|
constructor() {
|
|
257
272
|
if (init)
|
|
@@ -271,13 +286,65 @@ class Sedentary {
|
|
|
271
286
|
reject(new Error("boh"));
|
|
272
287
|
}, 10));
|
|
273
288
|
Object.defineProperty(load, "name", { value: modelName + ".load" });
|
|
274
|
-
const
|
|
289
|
+
const metaAttributes = aarray.reduce((ret, curr) => {
|
|
290
|
+
ret[curr.attributeName] = curr;
|
|
291
|
+
return ret;
|
|
292
|
+
}, {});
|
|
293
|
+
const metaForeignKeys = aarray
|
|
294
|
+
.filter(_ => _.foreignKey)
|
|
295
|
+
.reduce((ret, curr) => {
|
|
296
|
+
ret[curr.attributeName] = curr;
|
|
297
|
+
return ret;
|
|
298
|
+
}, {});
|
|
299
|
+
const meta = new db_1.Meta({ base: Number, attributes: metaAttributes, foreignKeys: metaForeignKeys, modelName, parent: parent, type: "meta", tableName, primaryKey, init, methods });
|
|
300
|
+
for (const foreignKey in metaForeignKeys) {
|
|
301
|
+
if (foreignKey + "Load" in metaAttributes)
|
|
302
|
+
throw new Error(`Sedentary.model: '${modelName}' model: '${foreignKey}' attribute: '${foreignKey}Load' inferred methods conflicts with an attribute`);
|
|
303
|
+
if (originalMethods && foreignKey + "Load" in originalMethods)
|
|
304
|
+
throw new Error(`Sedentary.model: '${modelName}' model: '${foreignKey}' attribute: '${foreignKey}Load' inferred methods conflicts with a method`);
|
|
305
|
+
}
|
|
306
|
+
if (originalMethods)
|
|
307
|
+
for (const method in originalMethods)
|
|
308
|
+
if (method in metaAttributes)
|
|
309
|
+
throw new Error(`Sedentary.model: '${modelName}' model: '${method}' method: conflicts with an attribute`);
|
|
310
|
+
const checkParent = (parent) => {
|
|
311
|
+
if (!parent)
|
|
312
|
+
return;
|
|
313
|
+
for (const attribute in metaAttributes) {
|
|
314
|
+
if (attribute in parent.attributes)
|
|
315
|
+
throw new Error(`Sedentary.model: '${modelName}' model: '${attribute}' attribute: conflicts with an attribute of '${parent.modelName}' model`);
|
|
316
|
+
if (parent.methods && attribute in parent.methods)
|
|
317
|
+
throw new Error(`Sedentary.model: '${modelName}' model: '${attribute}' attribute: conflicts with a method of '${parent.modelName}' model`);
|
|
318
|
+
for (const foreignKey in parent.foreignKeys)
|
|
319
|
+
if (attribute === foreignKey + "Load")
|
|
320
|
+
throw new Error(`Sedentary.model: '${modelName}' model: '${attribute}' attribute: conflicts with an inferred methods of '${parent.modelName}' model`);
|
|
321
|
+
}
|
|
322
|
+
for (const foreignKey in metaForeignKeys) {
|
|
323
|
+
if (foreignKey + "Load" in parent.attributes)
|
|
324
|
+
throw new Error(`Sedentary.model: '${modelName}' model: '${foreignKey}' attribute: '${foreignKey}Load' inferred methods conflicts with an attribute of '${parent.modelName}' model`);
|
|
325
|
+
if (parent.methods && foreignKey + "Load" in parent.methods)
|
|
326
|
+
throw new Error(`Sedentary.model: '${modelName}' model: '${foreignKey}' attribute: '${foreignKey}Load' inferred methods conflicts with a method of '${parent.modelName}' model`);
|
|
327
|
+
}
|
|
328
|
+
if (originalMethods) {
|
|
329
|
+
for (const method in originalMethods) {
|
|
330
|
+
if (method in parent.attributes)
|
|
331
|
+
throw new Error(`Sedentary.model: '${modelName}' model: '${method}' method: conflicts with an attribute of '${parent.modelName}' model`);
|
|
332
|
+
for (const foreignKey in parent.foreignKeys)
|
|
333
|
+
if (foreignKey + "Load" === method)
|
|
334
|
+
throw new Error(`Sedentary.model: '${modelName}' model: '${method}' method: conflicts with an inferred methods of '${parent.modelName}' model`);
|
|
335
|
+
if (parent.methods && method in parent.methods)
|
|
336
|
+
throw new Error(`Sedentary.model: '${modelName}' model: '${method}' method: conflicts with a method of '${parent.modelName}' model`);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
checkParent(parent.parent);
|
|
340
|
+
};
|
|
341
|
+
checkParent(parent);
|
|
275
342
|
Object.defineProperty(Class, "isModel", { value: () => true });
|
|
276
343
|
Object.defineProperty(Class, "load", { value: load });
|
|
277
|
-
Object.defineProperty(Class, "meta", { value:
|
|
344
|
+
Object.defineProperty(Class, "meta", { value: meta });
|
|
278
345
|
Object.defineProperty(Class, "name", { value: modelName });
|
|
279
346
|
Object.defineProperty(Class.prototype.save, "name", { value: modelName + ".save" });
|
|
280
|
-
Object.assign(Class,
|
|
347
|
+
Object.assign(Class, meta);
|
|
281
348
|
Object.assign(Class.prototype, methods);
|
|
282
349
|
for (const attribute of aarray)
|
|
283
350
|
Object.defineProperty(Class, attribute.attributeName, { value: attribute });
|
|
@@ -340,9 +407,9 @@ class Current extends db.model("Current", { b: { type: db.FKEY(Next), unique: tr
|
|
|
340
407
|
}
|
|
341
408
|
}) {
|
|
342
409
|
}
|
|
343
|
-
class Last extends db.model("Last", {
|
|
410
|
+
class Last extends db.model("Last", { c: db.FKEY(Current.b) }, {
|
|
344
411
|
init: function () {
|
|
345
|
-
this.
|
|
412
|
+
this.c = 24;
|
|
346
413
|
},
|
|
347
414
|
parent: Next
|
|
348
415
|
}) {
|
|
@@ -358,3 +425,29 @@ class Last extends db.model("Last", { b: db.FKEY(Current.b) }, {
|
|
|
358
425
|
}
|
|
359
426
|
return true;
|
|
360
427
|
})();
|
|
428
|
+
/*
|
|
429
|
+
export let factory = () => {
|
|
430
|
+
class Foo {
|
|
431
|
+
a = 3;
|
|
432
|
+
b = 'bar'
|
|
433
|
+
c?: boolean
|
|
434
|
+
}
|
|
435
|
+
return Foo as (new () => { [key in keyof Foo]: Foo[key] })
|
|
436
|
+
};
|
|
437
|
+
|
|
438
|
+
export const FooConstr = factory()
|
|
439
|
+
export type TypeExtractor<T> = T extends (new() => infer E) ? E : never;
|
|
440
|
+
export type FooType = TypeExtractor<typeof FooConstr>;
|
|
441
|
+
|
|
442
|
+
const foo = new FooConstr()
|
|
443
|
+
|
|
444
|
+
function rino(a:FooType){
|
|
445
|
+
if(a instanceof FooConstr){console.log("sisi")}
|
|
446
|
+
if(a instanceof FooType){console.log("sisi")}
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
rino(foo);
|
|
450
|
+
|
|
451
|
+
|
|
452
|
+
B.prototype instanceof A
|
|
453
|
+
*/
|
package/lib/db.d.ts
CHANGED
|
@@ -3,6 +3,11 @@ export declare class Entry {
|
|
|
3
3
|
init(): void;
|
|
4
4
|
save(): Promise<boolean>;
|
|
5
5
|
}
|
|
6
|
+
export declare type ForeignKeyActions = "cascade" | "no action" | "restrict" | "set default" | "set null";
|
|
7
|
+
export interface ForeignKeyOptions {
|
|
8
|
+
onDelete?: ForeignKeyActions;
|
|
9
|
+
onUpdate?: ForeignKeyActions;
|
|
10
|
+
}
|
|
6
11
|
export declare class Type<N extends Natural, E> {
|
|
7
12
|
base: unknown;
|
|
8
13
|
entry?: E;
|
|
@@ -12,16 +17,25 @@ export declare class Type<N extends Natural, E> {
|
|
|
12
17
|
foreignKey?: {
|
|
13
18
|
attributeName: string;
|
|
14
19
|
fieldName: string;
|
|
20
|
+
options?: ForeignKeyOptions;
|
|
15
21
|
tableName: string;
|
|
16
22
|
};
|
|
17
23
|
constructor(from: Type<N, E>);
|
|
18
24
|
}
|
|
19
25
|
export declare class Meta<N extends Natural, E> extends Type<N, E> {
|
|
26
|
+
attributes: {
|
|
27
|
+
[key: string]: unknown;
|
|
28
|
+
};
|
|
29
|
+
foreignKeys: {
|
|
30
|
+
[key: string]: unknown;
|
|
31
|
+
};
|
|
20
32
|
init: () => void;
|
|
21
33
|
isModel?: () => boolean;
|
|
22
34
|
methods: {
|
|
23
35
|
[key: string]: () => unknown;
|
|
24
36
|
};
|
|
37
|
+
modelName: string;
|
|
38
|
+
parent?: Meta<Natural, E>;
|
|
25
39
|
primaryKey: string;
|
|
26
40
|
tableName: string;
|
|
27
41
|
constructor(from: Meta<N, E>);
|
package/lib/minidb.js
CHANGED
|
@@ -23,7 +23,10 @@ class MiniDB extends db_1.DB {
|
|
|
23
23
|
async dropConstraints(table) {
|
|
24
24
|
const { constraints } = this.body.tables[table.tableName] || { constraints: { f: {}, u: {} } };
|
|
25
25
|
for (const constraint of Object.keys(constraints.f).sort()) {
|
|
26
|
-
|
|
26
|
+
const arr = table.constraints.filter(({ constraintName, type }) => constraintName === constraint && type === "f");
|
|
27
|
+
const dbOptions = arr.length ? arr[0].attribute.foreignKey.options : { onDelete: "delete", onUpdate: "delete" };
|
|
28
|
+
const inOptions = constraints.f[constraint].options;
|
|
29
|
+
if (dbOptions.onDelete !== inOptions.onDelete || dbOptions.onUpdate !== inOptions.onUpdate) {
|
|
27
30
|
this.syncLog(`'${table.tableName}': Removing foreign key: '${constraint}'`);
|
|
28
31
|
if (this.sync)
|
|
29
32
|
delete constraints.f[constraint];
|
|
@@ -31,7 +34,7 @@ class MiniDB extends db_1.DB {
|
|
|
31
34
|
}
|
|
32
35
|
for (const constraint of Object.keys(constraints.u).sort()) {
|
|
33
36
|
if (!table.constraints.filter(({ constraintName, type }) => constraintName === constraint && type === "u").length) {
|
|
34
|
-
this.syncLog(`'${table.tableName}': Removing unique constraint from field: '${constraints.u[constraint].
|
|
37
|
+
this.syncLog(`'${table.tableName}': Removing unique constraint from field: '${constraints.u[constraint].on}'`);
|
|
35
38
|
if (this.sync)
|
|
36
39
|
delete constraints.u[constraint];
|
|
37
40
|
}
|
|
@@ -70,20 +73,20 @@ class MiniDB extends db_1.DB {
|
|
|
70
73
|
async syncConstraints(table) {
|
|
71
74
|
const { constraints } = this.body.tables[table.tableName] || { constraints: { f: {}, u: {} } };
|
|
72
75
|
for (const constraint of table.constraints) {
|
|
73
|
-
const { constraintName, type } = constraint;
|
|
74
|
-
const { fieldName, foreignKey } = constraint.attribute;
|
|
76
|
+
const { attribute, constraintName, type } = constraint;
|
|
75
77
|
if (!constraints[type][constraintName]) {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
78
|
+
if (type === "f") {
|
|
79
|
+
const { fieldName, options, tableName } = attribute.foreignKey;
|
|
80
|
+
const onDelete = options.onDelete !== "no action" ? ` on delete ${options.onDelete}` : "";
|
|
81
|
+
const onUpdate = options.onUpdate !== "no action" ? ` on update ${options.onUpdate}` : "";
|
|
82
|
+
this.syncLog(`'${table.tableName}': Adding foreign key '${constraint.constraintName}' on field: '${attribute.fieldName}' references '${tableName}(${fieldName})'${onDelete}${onUpdate}`);
|
|
83
|
+
if (this.sync)
|
|
84
|
+
constraints[type][constraintName] = { on: attribute.fieldName, options, fieldName, tableName };
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
this.syncLog(`'${table.tableName}': Adding unique constraint on field: '${attribute.fieldName}'`);
|
|
88
|
+
if (this.sync)
|
|
89
|
+
constraints[type][constraintName] = { on: attribute.fieldName };
|
|
87
90
|
}
|
|
88
91
|
}
|
|
89
92
|
}
|
package/package.json
CHANGED