sedentary 0.0.18 → 0.0.22
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/README.md +2 -3
- package/index.d.ts +63 -65
- package/index.js +69 -189
- package/lib/db.d.ts +17 -26
- package/lib/db.js +20 -13
- package/lib/minidb.js +2 -1
- package/lib/transaction.d.ts +2 -0
- package/lib/transaction.js +6 -0
- package/package.json +29 -7
- package/lib/log.d.ts +0 -4
- package/lib/log.js +0 -20
- package/lib/log.ts +0 -22
- package/requirements.txt +0 -2
package/README.md
CHANGED
|
@@ -81,10 +81,9 @@ $ npm install --save sedentary
|
|
|
81
81
|
|
|
82
82
|
# Disclaimer
|
|
83
83
|
|
|
84
|
-
**Do not use this package itself
|
|
85
|
-
purposes.**
|
|
84
|
+
**Do not use this package itself! It does not support any DB engine.**
|
|
86
85
|
|
|
87
|
-
|
|
86
|
+
A _DB engine dedicated extension_ must be used:
|
|
88
87
|
|
|
89
88
|
- MySQL: planned
|
|
90
89
|
- PostgreSQL: [sedentary-pg](https://github.com/iccicci/sedentary-pg#readme)
|
package/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { DB,
|
|
2
|
-
export {
|
|
1
|
+
import { Attribute, DB, EntryBase, ForeignKeyOptions, Natural, Type } from "./lib/db";
|
|
2
|
+
export { EntryBase, 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;
|
|
@@ -12,17 +12,13 @@ export declare type AttributeDefinition<N extends Natural, E> = TypeDefinition<N
|
|
|
12
12
|
export declare type AttributesDefinition = {
|
|
13
13
|
[key: string]: AttributeDefinition<Natural, unknown>;
|
|
14
14
|
};
|
|
15
|
-
declare type
|
|
16
|
-
declare type
|
|
17
|
-
[
|
|
18
|
-
}[keyof
|
|
19
|
-
declare type Methods<T> = {
|
|
20
|
-
[key: string]: (this: T) => unknown;
|
|
21
|
-
};
|
|
15
|
+
declare type ForeignKeysAttributes<T, k> = T extends AttributeDefinition<Natural, infer E> ? (E extends EntryBase ? k : never) : never;
|
|
16
|
+
declare type ForeignKeys<A extends AttributesDefinition> = {
|
|
17
|
+
[a in keyof A]?: ForeignKeysAttributes<A[a], a>;
|
|
18
|
+
}[keyof A];
|
|
22
19
|
declare type Native__<T> = T extends Type<infer N, unknown> ? N : never;
|
|
23
20
|
declare type Native_<T> = T extends () => Type<infer N, infer E> ? Native__<Type<N, E>> : Native__<T>;
|
|
24
21
|
declare type Native<T> = T extends AttributeOptions<infer N, infer E> ? Native__<Type<N, E>> : Native_<T>;
|
|
25
|
-
declare type Parent<T> = T extends Meta<Natural, infer E> ? E : never;
|
|
26
22
|
export declare type IndexAttributes = string[] | string;
|
|
27
23
|
export interface IndexOptions {
|
|
28
24
|
attributes: IndexAttributes;
|
|
@@ -33,34 +29,59 @@ export declare type IndexDefinition = IndexAttributes | IndexOptions;
|
|
|
33
29
|
export declare type IndexesDefinition = {
|
|
34
30
|
[key: string]: IndexDefinition;
|
|
35
31
|
};
|
|
36
|
-
|
|
32
|
+
interface BaseModelOptions {
|
|
37
33
|
indexes?: IndexesDefinition;
|
|
38
|
-
init?: (this: T) => void;
|
|
39
34
|
sync?: boolean;
|
|
40
35
|
tableName?: string;
|
|
41
|
-
}
|
|
42
|
-
export
|
|
36
|
+
}
|
|
37
|
+
export interface ModelOptions extends BaseModelOptions {
|
|
43
38
|
int8id?: boolean;
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
39
|
+
parent?: Type<Natural, EntryBase>;
|
|
40
|
+
primaryKey?: string;
|
|
41
|
+
}
|
|
42
|
+
declare type ConditionAttribute<N extends Natural> = N | [">" | "<" | ">=" | "<=" | "<>", N] | ["LIKE", string] | ["IN", ...N[]];
|
|
43
|
+
declare type ConditionBase<A extends AttributesDefinition> = string | {
|
|
44
|
+
[a in keyof A]?: ConditionAttribute<Native<A[a]>>;
|
|
47
45
|
};
|
|
48
|
-
declare type
|
|
49
|
-
declare type
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
declare type
|
|
46
|
+
declare type Condition<A extends AttributesDefinition> = ConditionBase<A> | ["NOT", Condition<A>] | ["AND", ...Condition<A>[]] | ["OR", ...Condition<A>[]];
|
|
47
|
+
declare type UnionToIntersection<U> = (U extends unknown ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
|
|
48
|
+
declare type IsUnion<T> = [T] extends [UnionToIntersection<T>] ? false : true;
|
|
49
|
+
declare type BaseKeyType<B extends boolean> = IsUnion<B> extends true ? number : B extends true ? string : number;
|
|
50
|
+
declare type KeyType<B extends boolean, P extends ModelStd> = P extends new () => EntryBase ? (P extends Attribute<infer T, EntryBase> ? T : never) : BaseKeyType<B>;
|
|
51
|
+
declare type ForeignKey<A> = A extends AttributeDefinition<Natural, infer E> ? () => Promise<E> : never;
|
|
52
|
+
declare type EntryBaseAttributes<A extends AttributesDefinition> = {
|
|
55
53
|
[a in keyof A]?: Native<A[a]>;
|
|
56
|
-
} & {
|
|
57
|
-
[a in Keys<A> & string as `${a}Load`]?: ForeignKey<A[a]>;
|
|
58
54
|
};
|
|
59
|
-
declare type
|
|
60
|
-
|
|
55
|
+
declare type EntryMethodsBase<P extends ModelStd> = P extends new () => EntryBase ? P["methods"] : EntryBase;
|
|
56
|
+
declare type EntryMethodsFK<A extends AttributesDefinition> = {
|
|
57
|
+
[a in ForeignKeys<A> & string as `${a}Load`]: ForeignKey<A[a]>;
|
|
58
|
+
};
|
|
59
|
+
declare type EntryMethods<A extends AttributesDefinition, P extends ModelStd> = keyof EntryMethodsFK<A> extends never ? EntryMethodsBase<P> : EntryMethodsBase<P> & EntryMethodsFK<A>;
|
|
60
|
+
declare type ModelAttributesIf<A extends AttributesDefinition, T> = keyof A extends never ? T : T & A;
|
|
61
|
+
declare type ModelAttributes<A extends AttributesDefinition, B extends boolean, K extends string, P extends ModelStd> = K extends keyof A ? A : ModelAttributesIf<A, P extends new () => EntryBase ? P["attributes"] : {
|
|
62
|
+
id: Type<BaseKeyType<B>, unknown>;
|
|
63
|
+
}>;
|
|
64
|
+
declare type ModelBase<N extends Natural, A extends AttributesDefinition, EA extends Record<string, Natural | undefined>, EM extends EntryBase, E extends EntryBase> = (new (from?: EA) => E) & Attribute<N, E> & {
|
|
65
|
+
attributes: A;
|
|
66
|
+
foreignKeys: Record<string, boolean>;
|
|
67
|
+
methods: EM;
|
|
68
|
+
parent?: ModelStd;
|
|
69
|
+
tableName: string;
|
|
70
|
+
load: (where?: Condition<A>) => Promise<E[]>;
|
|
61
71
|
} & {
|
|
62
|
-
|
|
63
|
-
}
|
|
72
|
+
[a in keyof A]: Attribute<Native<A[a]>, E>;
|
|
73
|
+
};
|
|
74
|
+
declare type Model<N extends Natural, A extends AttributesDefinition, EM extends EntryBase> = ModelBase<N, A, EntryBaseAttributes<A>, EM, EntryBaseAttributes<A> & EM>;
|
|
75
|
+
declare type ModelStd = Attribute<Natural, EntryBase> & {
|
|
76
|
+
attributes: AttributesDefinition;
|
|
77
|
+
foreignKeys: Record<string, boolean>;
|
|
78
|
+
methods: EntryBase;
|
|
79
|
+
parent?: ModelStd;
|
|
80
|
+
};
|
|
81
|
+
export declare type Entry<M> = M extends new () => infer E ? E : never;
|
|
82
|
+
export declare type Where<M> = M extends {
|
|
83
|
+
load: (where: infer T) => void;
|
|
84
|
+
} ? Exclude<T, undefined> : never;
|
|
64
85
|
export interface SedentaryOptions {
|
|
65
86
|
log?: ((message: string) => void) | null;
|
|
66
87
|
serverless?: boolean;
|
|
@@ -73,45 +94,22 @@ export declare class Sedentary {
|
|
|
73
94
|
private models;
|
|
74
95
|
constructor(filename: string, options?: SedentaryOptions);
|
|
75
96
|
DATETIME(): Type<Date, unknown>;
|
|
76
|
-
FKEY<N extends Natural, E extends
|
|
97
|
+
FKEY<N extends Natural, E extends EntryBase>(attribute: Attribute<N, E>, options?: ForeignKeyOptions): Type<N, E>;
|
|
77
98
|
INT(size?: number): Type<number, unknown>;
|
|
78
99
|
INT8(): Type<string, unknown>;
|
|
79
100
|
VARCHAR(size?: number): Type<string, unknown>;
|
|
101
|
+
checkSize(size: number, message: string): number;
|
|
80
102
|
connect(): Promise<void>;
|
|
81
103
|
end(): Promise<void>;
|
|
82
|
-
model<A extends AttributesDefinition,
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
primaryKey
|
|
91
|
-
}):
|
|
92
|
-
model<A extends AttributesDefinition, M extends Methods<T>, P extends Meta<Natural, Entry>, N extends P extends Meta<infer N, Entry> ? N : never, T extends Parent<P> & ModelWithMetods<A, M>>(modelName: string, attributes: A, options?: BaseModelOptions<T> & {
|
|
93
|
-
methods: M;
|
|
94
|
-
parent: P;
|
|
95
|
-
}): Ancestor<A, N, T>;
|
|
96
|
-
model<A extends AttributesDefinition, M extends Methods<T>, T extends Entry & {
|
|
97
|
-
id?: number;
|
|
98
|
-
} & ModelWithMetods<A, M>>(modelName: string, attributes: A, options?: BaseModelOptions<T> & {
|
|
99
|
-
methods: M;
|
|
100
|
-
}): Ancestor<A, number, T>;
|
|
101
|
-
model<A extends AttributesDefinition, T extends Entry & {
|
|
102
|
-
id?: string;
|
|
103
|
-
} & Model<A>>(modelName: string, attributes: A, options?: BaseModelOptions<T> & {
|
|
104
|
-
int8id: true;
|
|
105
|
-
}): Ancestor<A, string, T>;
|
|
106
|
-
model<A extends AttributesDefinition, K extends keyof A, N extends K extends keyof A ? Native<A[K]> : never, T extends Entry & Model<A>>(modelName: string, attributes: A, options?: BaseModelOptions<T> & {
|
|
107
|
-
primaryKey: K;
|
|
108
|
-
}): Ancestor<A, N, T>;
|
|
109
|
-
model<A extends AttributesDefinition, P extends Meta<Natural, Entry>, N extends P extends Meta<infer N, Entry> ? N : never, T extends Parent<P> & Model<A>>(modelName: string, attributes: A, options?: BaseModelOptions<T> & {
|
|
110
|
-
parent: P;
|
|
111
|
-
}): Ancestor<A, N, T>;
|
|
112
|
-
model<A extends AttributesDefinition, T extends Entry & {
|
|
113
|
-
id?: number;
|
|
114
|
-
} & Model<A>>(modelName: string, attributes: A, options?: BaseModelOptions<T>): Ancestor<A, number, T>;
|
|
115
|
-
checkSize(size: number, message: string): number;
|
|
104
|
+
model<A extends AttributesDefinition, B extends boolean, K extends string, P extends ModelStd, EM extends EntryMethods<A, P>>(modelName: string, attributes: A, options?: BaseModelOptions & {
|
|
105
|
+
int8id?: B;
|
|
106
|
+
parent?: P;
|
|
107
|
+
primaryKey?: K | keyof A;
|
|
108
|
+
}): Model<K extends keyof A ? Native<A[K]> : KeyType<B, P>, ModelAttributes<A, B, K, P>, EM>;
|
|
109
|
+
model<A extends AttributesDefinition, B extends boolean, K extends string, P extends ModelStd, EA extends EntryBaseAttributes<ModelAttributes<A, B, K, P>>, EM extends EntryMethods<A, P>, M extends Record<string, <S extends M>(this: EA & EM & S, ...args: any[]) => void>>(modelName: string, attributes: A, options: BaseModelOptions & {
|
|
110
|
+
int8id?: B;
|
|
111
|
+
parent?: P;
|
|
112
|
+
primaryKey?: K | keyof A;
|
|
113
|
+
}, methods: M & Record<keyof M, (this: EA & EM & M, ...args: any[]) => void>): Model<K extends keyof A ? Native<A[K]> : KeyType<B, P>, ModelAttributes<A, B, K, P>, EM & M>;
|
|
116
114
|
}
|
|
117
115
|
export declare const Package: typeof Sedentary;
|
package/index.js
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Package = exports.Sedentary = exports.Type = exports.
|
|
3
|
+
exports.Package = exports.Sedentary = exports.Type = exports.EntryBase = void 0;
|
|
4
4
|
const db_1 = require("./lib/db");
|
|
5
|
-
const log_1 = require("./lib/log");
|
|
6
5
|
const minidb_1 = require("./lib/minidb");
|
|
7
6
|
var db_2 = require("./lib/db");
|
|
8
|
-
Object.defineProperty(exports, "
|
|
7
|
+
Object.defineProperty(exports, "EntryBase", { enumerable: true, get: function () { return db_2.EntryBase; } });
|
|
9
8
|
Object.defineProperty(exports, "Type", { enumerable: true, get: function () { return db_2.Type; } });
|
|
10
|
-
const allowedOption = ["indexes", "
|
|
9
|
+
const allowedOption = ["indexes", "int8id", "parent", "primaryKey", "sync", "tableName"];
|
|
11
10
|
const reservedNames = [
|
|
12
|
-
...["attributeName", "base", "class", "constructor", "defaultValue", "entry", "fieldName", "
|
|
13
|
-
...["
|
|
11
|
+
...["attributeName", "attributes", "base", "class", "construct", "constructor", "defaultValue", "entry", "fieldName", "foreignKeys", "load"],
|
|
12
|
+
...["methods", "name", "postLoad", "postSave", "preLoad", "preSave", "primaryKey", "prototype", "save", "size", "tableName", "type"]
|
|
14
13
|
];
|
|
15
14
|
class Sedentary {
|
|
16
15
|
constructor(filename, options) {
|
|
@@ -30,7 +29,8 @@ class Sedentary {
|
|
|
30
29
|
throw new Error("new Sedentary: 'log' option: Wrong type, expected 'null' or 'Function'");
|
|
31
30
|
if (typeof sync !== "boolean")
|
|
32
31
|
throw new Error("new Sedentary: 'sync' option: Wrong type, expected 'boolean'");
|
|
33
|
-
|
|
32
|
+
// eslint-disable-next-line no-console
|
|
33
|
+
this.log = log ? log : log === null ? () => { } : console.log;
|
|
34
34
|
this.db = new minidb_1.MiniDB(filename, this.log);
|
|
35
35
|
this.sync = sync;
|
|
36
36
|
}
|
|
@@ -56,6 +56,13 @@ class Sedentary {
|
|
|
56
56
|
size = size ? this.checkSize(size, message) : undefined;
|
|
57
57
|
return new db_1.Type({ base: String, size, type: "VARCHAR" });
|
|
58
58
|
}
|
|
59
|
+
checkSize(size, message) {
|
|
60
|
+
const str = size.toString();
|
|
61
|
+
const parsed = parseInt(str, 10);
|
|
62
|
+
if (str !== parsed.toString())
|
|
63
|
+
throw new Error(message);
|
|
64
|
+
return parsed;
|
|
65
|
+
}
|
|
59
66
|
async connect() {
|
|
60
67
|
try {
|
|
61
68
|
this.log("Connecting...");
|
|
@@ -65,7 +72,7 @@ class Sedentary {
|
|
|
65
72
|
this.log("Synced");
|
|
66
73
|
}
|
|
67
74
|
catch (e) {
|
|
68
|
-
this.log("Connecting:"
|
|
75
|
+
this.log("Connecting: " + (e instanceof Error ? e.message : JSON.stringify(e)));
|
|
69
76
|
throw e;
|
|
70
77
|
}
|
|
71
78
|
}
|
|
@@ -74,7 +81,8 @@ class Sedentary {
|
|
|
74
81
|
await this.db.end();
|
|
75
82
|
this.log("Connection closed");
|
|
76
83
|
}
|
|
77
|
-
|
|
84
|
+
/* eslint-enable @typescript-eslint/no-explicit-any */
|
|
85
|
+
model(modelName, attributes, options, methods) {
|
|
78
86
|
if (typeof modelName !== "string")
|
|
79
87
|
throw new Error("Sedentary.model: 'name' argument: Wrong type, expected 'string'");
|
|
80
88
|
if (this.models[modelName])
|
|
@@ -98,26 +106,19 @@ class Sedentary {
|
|
|
98
106
|
throw new Error(`Sedentary.model: '${modelName}' model: 'parent' and 'primaryKey' options conflict each other`);
|
|
99
107
|
let autoIncrement = true;
|
|
100
108
|
const { indexes, int8id, parent, primaryKey, sync, tableName } = Object.assign({ sync: this.sync, tableName: modelName }, options);
|
|
101
|
-
let { methods } = options;
|
|
102
109
|
let aarray = int8id
|
|
103
110
|
? [new db_1.Attribute(Object.assign(Object.assign({}, this.INT8()), { attributeName: "id", fieldName: "id", modelName, notNull: true, tableName, unique: true }))]
|
|
104
111
|
: [new db_1.Attribute(Object.assign(Object.assign({}, this.INT(4)), { attributeName: "id", fieldName: "id", modelName, notNull: true, tableName, unique: true }))];
|
|
105
112
|
let constraints = [{ attribute: aarray[0], constraintName: `${tableName}_id_unique`, type: "u" }];
|
|
106
113
|
const iarray = [];
|
|
107
114
|
const pk = aarray[0];
|
|
108
|
-
if (
|
|
115
|
+
if (!methods)
|
|
116
|
+
methods = {};
|
|
117
|
+
if (!(methods instanceof Object))
|
|
109
118
|
throw new Error(`Sedentary.model: '${modelName}' model: 'methods' option: Wrong type, expected 'Object'`);
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
try {
|
|
113
|
-
if (!parent.isModel())
|
|
114
|
-
throw new Error();
|
|
115
|
-
}
|
|
116
|
-
catch (e) {
|
|
119
|
+
if (parent)
|
|
120
|
+
if (!parent.attributes)
|
|
117
121
|
throw new Error(`Sedentary.model: '${modelName}' model: 'parent' option: Wrong type, expected 'Model'`);
|
|
118
|
-
}
|
|
119
|
-
methods = (methods ? Object.assign(Object.assign({}, (parent.methods || {})), methods) : parent.methods);
|
|
120
|
-
}
|
|
121
122
|
if (primaryKey && typeof primaryKey !== "string")
|
|
122
123
|
throw new Error(`Sedentary.model: '${modelName}' model: 'primaryKey' option: Wrong type, expected 'string'`);
|
|
123
124
|
if (primaryKey && !Object.keys(attributes).includes(primaryKey))
|
|
@@ -176,21 +177,21 @@ class Sedentary {
|
|
|
176
177
|
return ret;
|
|
177
178
|
})();
|
|
178
179
|
if (foreignKey) {
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
if (!(foreignKey.options instanceof Object))
|
|
180
|
+
const options = foreignKey.options || {};
|
|
181
|
+
if (foreignKey.options !== undefined && !(foreignKey.options instanceof Object))
|
|
182
182
|
throw new Error(`Sedentary.FKEY: '${modelName}' model: '${attributeName}' attribute: Wrong options type, expected 'Object'`);
|
|
183
|
-
for (const k in
|
|
183
|
+
for (const k in options)
|
|
184
184
|
if (!["onDelete", "onUpdate"].includes(k))
|
|
185
185
|
throw new Error(`Sedentary.FKEY: '${modelName}' model: '${attributeName}' attribute: Unknown option '${k}'`);
|
|
186
186
|
for (const onChange of ["onDelete", "onUpdate"]) {
|
|
187
187
|
const actions = ["cascade", "no action", "restrict", "set default", "set null"];
|
|
188
|
-
let action =
|
|
188
|
+
let action = options[onChange];
|
|
189
189
|
if (!action)
|
|
190
|
-
action =
|
|
190
|
+
action = options[onChange] = "no action";
|
|
191
191
|
if (action && !actions.includes(action))
|
|
192
192
|
throw new Error(`Sedentary.FKEY: '${modelName}' model: '${attributeName}' attribute: '${onChange}' option: Wrong value, expected ${actions.map(_ => `'${_}'`).join(" | ")}`);
|
|
193
193
|
}
|
|
194
|
+
foreignKey.options = options;
|
|
194
195
|
}
|
|
195
196
|
if (primaryKey === attributeName) {
|
|
196
197
|
notNull = true;
|
|
@@ -259,195 +260,74 @@ class Sedentary {
|
|
|
259
260
|
}
|
|
260
261
|
this.db.tables.push(new db_1.Table({ autoIncrement, constraints, attributes: aarray, indexes: iarray, parent, sync, tableName }));
|
|
261
262
|
this.models[modelName] = true;
|
|
262
|
-
const
|
|
263
|
-
? options.init
|
|
264
|
-
? function () {
|
|
265
|
-
parent.init.call(this);
|
|
266
|
-
options.init.call(this);
|
|
267
|
-
}
|
|
268
|
-
: parent.init
|
|
269
|
-
: options.init;
|
|
270
|
-
class Class {
|
|
271
|
-
constructor() {
|
|
272
|
-
if (init)
|
|
273
|
-
init.call(this);
|
|
274
|
-
}
|
|
275
|
-
save() {
|
|
276
|
-
return new Promise((resolve, reject) => {
|
|
277
|
-
const save = () => reject(new Error("eh no"));
|
|
278
|
-
Object.defineProperty(save, "name", { value: modelName + ".save" });
|
|
279
|
-
setTimeout(save, 10);
|
|
280
|
-
});
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
const load = (boh) => new Promise((resolve, reject) => setTimeout(() => {
|
|
284
|
-
if (boh)
|
|
285
|
-
return resolve([new Class()]);
|
|
286
|
-
reject(new Error("boh"));
|
|
287
|
-
}, 10));
|
|
288
|
-
Object.defineProperty(load, "name", { value: modelName + ".load" });
|
|
289
|
-
const metaAttributes = aarray.reduce((ret, curr) => {
|
|
290
|
-
ret[curr.attributeName] = curr;
|
|
291
|
-
return ret;
|
|
292
|
-
}, {});
|
|
293
|
-
const metaForeignKeys = aarray
|
|
263
|
+
const foreignKeys = aarray
|
|
294
264
|
.filter(_ => _.foreignKey)
|
|
295
265
|
.reduce((ret, curr) => {
|
|
296
|
-
ret[curr.attributeName] =
|
|
266
|
+
ret[curr.attributeName] = true;
|
|
297
267
|
return ret;
|
|
298
268
|
}, {});
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
if (foreignKey + "Load" in metaAttributes)
|
|
269
|
+
for (const foreignKey in foreignKeys) {
|
|
270
|
+
if (foreignKey + "Load" in attributes)
|
|
302
271
|
throw new Error(`Sedentary.model: '${modelName}' model: '${foreignKey}' attribute: '${foreignKey}Load' inferred methods conflicts with an attribute`);
|
|
303
|
-
if (
|
|
272
|
+
if (foreignKey + "Load" in methods)
|
|
304
273
|
throw new Error(`Sedentary.model: '${modelName}' model: '${foreignKey}' attribute: '${foreignKey}Load' inferred methods conflicts with a method`);
|
|
305
274
|
}
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
throw new Error(`Sedentary.model: '${modelName}' model: '${method}' method: conflicts with an attribute`);
|
|
275
|
+
for (const method in methods)
|
|
276
|
+
if (method in attributes)
|
|
277
|
+
throw new Error(`Sedentary.model: '${modelName}' model: '${method}' method: conflicts with an attribute`);
|
|
310
278
|
const checkParent = (parent) => {
|
|
311
279
|
if (!parent)
|
|
312
280
|
return;
|
|
313
|
-
for (const attribute in
|
|
281
|
+
for (const attribute in attributes) {
|
|
314
282
|
if (attribute in parent.attributes)
|
|
315
283
|
throw new Error(`Sedentary.model: '${modelName}' model: '${attribute}' attribute: conflicts with an attribute of '${parent.modelName}' model`);
|
|
316
|
-
if (
|
|
284
|
+
if (attribute in parent.methods)
|
|
317
285
|
throw new Error(`Sedentary.model: '${modelName}' model: '${attribute}' attribute: conflicts with a method of '${parent.modelName}' model`);
|
|
318
286
|
for (const foreignKey in parent.foreignKeys)
|
|
319
287
|
if (attribute === foreignKey + "Load")
|
|
320
288
|
throw new Error(`Sedentary.model: '${modelName}' model: '${attribute}' attribute: conflicts with an inferred methods of '${parent.modelName}' model`);
|
|
321
289
|
}
|
|
322
|
-
for (const foreignKey in
|
|
290
|
+
for (const foreignKey in foreignKeys) {
|
|
323
291
|
if (foreignKey + "Load" in parent.attributes)
|
|
324
292
|
throw new Error(`Sedentary.model: '${modelName}' model: '${foreignKey}' attribute: '${foreignKey}Load' inferred methods conflicts with an attribute of '${parent.modelName}' model`);
|
|
325
|
-
if (
|
|
293
|
+
if (foreignKey + "Load" in parent.methods)
|
|
326
294
|
throw new Error(`Sedentary.model: '${modelName}' model: '${foreignKey}' attribute: '${foreignKey}Load' inferred methods conflicts with a method of '${parent.modelName}' model`);
|
|
327
295
|
}
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
throw new Error(`Sedentary.model: '${modelName}' model: '${method}' method: conflicts with a method of '${parent.modelName}' model`);
|
|
337
|
-
}
|
|
296
|
+
for (const method in methods) {
|
|
297
|
+
if (method in parent.attributes)
|
|
298
|
+
throw new Error(`Sedentary.model: '${modelName}' model: '${method}' method: conflicts with an attribute of '${parent.modelName}' model`);
|
|
299
|
+
for (const foreignKey in parent.foreignKeys)
|
|
300
|
+
if (foreignKey + "Load" === method)
|
|
301
|
+
throw new Error(`Sedentary.model: '${modelName}' model: '${method}' method: conflicts with an inferred methods of '${parent.modelName}' model`);
|
|
302
|
+
if (method in parent.methods)
|
|
303
|
+
throw new Error(`Sedentary.model: '${modelName}' model: '${method}' method: conflicts with a method of '${parent.modelName}' model`);
|
|
338
304
|
}
|
|
339
305
|
checkParent(parent.parent);
|
|
340
306
|
};
|
|
341
307
|
checkParent(parent);
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
308
|
+
const ret = class extends (parent || db_1.EntryBase) {
|
|
309
|
+
};
|
|
310
|
+
const load = (boh) => new Promise((resolve, reject) => setTimeout(() => {
|
|
311
|
+
if (boh)
|
|
312
|
+
return resolve([new ret()]);
|
|
313
|
+
reject(new Error("boh"));
|
|
314
|
+
}, 10));
|
|
315
|
+
Object.defineProperty(load, "name", { value: modelName + ".load" });
|
|
316
|
+
Object.defineProperty(ret, "name", { value: modelName });
|
|
317
|
+
Object.defineProperty(ret, "load", { value: load });
|
|
318
|
+
Object.defineProperty(ret, "attributes", { value: attributes });
|
|
319
|
+
Object.defineProperty(ret, "foreignKeys", { value: foreignKeys });
|
|
320
|
+
Object.defineProperty(ret, "methods", { value: methods });
|
|
321
|
+
Object.assign(ret.prototype, methods);
|
|
322
|
+
ret.prototype.save = function () {
|
|
323
|
+
return Promise.resolve(false);
|
|
324
|
+
};
|
|
349
325
|
for (const attribute of aarray)
|
|
350
|
-
Object.defineProperty(
|
|
351
|
-
for (const key of ["attributeName", "base", "fieldName", "modelName", "size", "type", "unique"])
|
|
352
|
-
Object.defineProperty(
|
|
353
|
-
return
|
|
354
|
-
}
|
|
355
|
-
checkSize(size, message) {
|
|
356
|
-
const str = size.toString();
|
|
357
|
-
const parsed = parseInt(str, 10);
|
|
358
|
-
if (str !== parsed.toString())
|
|
359
|
-
throw new Error(message);
|
|
360
|
-
return parsed;
|
|
326
|
+
Object.defineProperty(ret, attribute.attributeName, { value: attribute });
|
|
327
|
+
for (const key of ["attributeName", "base", "fieldName", "modelName", "size", "tableName", "type", "unique"])
|
|
328
|
+
Object.defineProperty(ret, key, { value: pk[key] });
|
|
329
|
+
return ret;
|
|
361
330
|
}
|
|
362
331
|
}
|
|
363
332
|
exports.Sedentary = Sedentary;
|
|
364
333
|
exports.Package = Sedentary;
|
|
365
|
-
const db = new Sedentary("gino");
|
|
366
|
-
const Users = db.model("User", { foo: db.INT(), bar: { type: db.VARCHAR(), unique: true } }, {});
|
|
367
|
-
class Item extends db.model("Item", {
|
|
368
|
-
num: db.FKEY(Users),
|
|
369
|
-
str: db.VARCHAR()
|
|
370
|
-
}, {
|
|
371
|
-
init: function () {
|
|
372
|
-
this.num = 0;
|
|
373
|
-
this.str = "0";
|
|
374
|
-
},
|
|
375
|
-
int8id: true,
|
|
376
|
-
methods: {
|
|
377
|
-
prova: () => "ok"
|
|
378
|
-
}
|
|
379
|
-
}) {
|
|
380
|
-
}
|
|
381
|
-
class Super extends db.model("Super", {
|
|
382
|
-
a: db.INT,
|
|
383
|
-
n: db.FKEY(Item),
|
|
384
|
-
s: db.FKEY(Users.bar)
|
|
385
|
-
}, {
|
|
386
|
-
parent: Item,
|
|
387
|
-
init: async function () {
|
|
388
|
-
this.n = "23";
|
|
389
|
-
this.id = "0";
|
|
390
|
-
this.num = 0;
|
|
391
|
-
const a = this.nLoad ? await this.nLoad() : { prova: () => null };
|
|
392
|
-
a.prova();
|
|
393
|
-
this.prova();
|
|
394
|
-
}
|
|
395
|
-
}) {
|
|
396
|
-
}
|
|
397
|
-
class Next extends db.model("Next", { a: db.INT, b: db.INT }, {
|
|
398
|
-
init: function () {
|
|
399
|
-
this.a = 23;
|
|
400
|
-
},
|
|
401
|
-
primaryKey: "a"
|
|
402
|
-
}) {
|
|
403
|
-
}
|
|
404
|
-
class Current extends db.model("Current", { b: { type: db.FKEY(Next), unique: true } }, {
|
|
405
|
-
init: function () {
|
|
406
|
-
this.b = 24;
|
|
407
|
-
}
|
|
408
|
-
}) {
|
|
409
|
-
}
|
|
410
|
-
class Last extends db.model("Last", { c: db.FKEY(Current.b) }, {
|
|
411
|
-
init: function () {
|
|
412
|
-
this.c = 24;
|
|
413
|
-
},
|
|
414
|
-
parent: Next
|
|
415
|
-
}) {
|
|
416
|
-
}
|
|
417
|
-
(async function () {
|
|
418
|
-
const item = new Super();
|
|
419
|
-
try {
|
|
420
|
-
await item.save();
|
|
421
|
-
}
|
|
422
|
-
catch (e) {
|
|
423
|
-
console.log(Item.load, item.save, await Item.load(true), item, e.message);
|
|
424
|
-
console.log(new Next(), Next.load, await Next.load(true), new Last(), item.prova());
|
|
425
|
-
}
|
|
426
|
-
return true;
|
|
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
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
export declare type Natural = Date | Record<string, unknown> | boolean | number | string;
|
|
2
|
-
export declare class
|
|
3
|
-
|
|
2
|
+
export declare class EntryBase {
|
|
3
|
+
constructor(from?: Partial<EntryBase> | "load");
|
|
4
|
+
construct(): void;
|
|
5
|
+
postLoad(): void;
|
|
6
|
+
postSave(): void;
|
|
7
|
+
preLoad(): void;
|
|
8
|
+
preSave(): void;
|
|
4
9
|
save(): Promise<boolean>;
|
|
5
10
|
}
|
|
6
11
|
export declare type ForeignKeyActions = "cascade" | "no action" | "restrict" | "set default" | "set null";
|
|
@@ -8,7 +13,7 @@ export interface ForeignKeyOptions {
|
|
|
8
13
|
onDelete?: ForeignKeyActions;
|
|
9
14
|
onUpdate?: ForeignKeyActions;
|
|
10
15
|
}
|
|
11
|
-
export
|
|
16
|
+
export interface Type<N extends Natural, E> {
|
|
12
17
|
base: unknown;
|
|
13
18
|
entry?: E;
|
|
14
19
|
native?: N;
|
|
@@ -20,27 +25,11 @@ export declare class Type<N extends Natural, E> {
|
|
|
20
25
|
options?: ForeignKeyOptions;
|
|
21
26
|
tableName: string;
|
|
22
27
|
};
|
|
23
|
-
constructor(from: Type<N, E>);
|
|
24
28
|
}
|
|
25
|
-
export declare class
|
|
26
|
-
|
|
27
|
-
[key: string]: unknown;
|
|
28
|
-
};
|
|
29
|
-
foreignKeys: {
|
|
30
|
-
[key: string]: unknown;
|
|
31
|
-
};
|
|
32
|
-
init: () => void;
|
|
33
|
-
isModel?: () => boolean;
|
|
34
|
-
methods: {
|
|
35
|
-
[key: string]: () => unknown;
|
|
36
|
-
};
|
|
37
|
-
modelName: string;
|
|
38
|
-
parent?: Meta<Natural, E>;
|
|
39
|
-
primaryKey: string;
|
|
40
|
-
tableName: string;
|
|
41
|
-
constructor(from: Meta<N, E>);
|
|
29
|
+
export declare class Type<N extends Natural, E> {
|
|
30
|
+
constructor(from: Type<N, E>);
|
|
42
31
|
}
|
|
43
|
-
export
|
|
32
|
+
export interface Attribute<N extends Natural, E> extends Type<N, E> {
|
|
44
33
|
attributeName: string;
|
|
45
34
|
defaultValue?: unknown;
|
|
46
35
|
fieldName: string;
|
|
@@ -48,6 +37,8 @@ export declare class Attribute<N extends Natural, E> extends Type<N, E> {
|
|
|
48
37
|
notNull: boolean;
|
|
49
38
|
tableName: string;
|
|
50
39
|
unique?: boolean;
|
|
40
|
+
}
|
|
41
|
+
export declare class Attribute<N extends Natural, E> extends Type<N, E> {
|
|
51
42
|
constructor(from: Attribute<N, E>);
|
|
52
43
|
}
|
|
53
44
|
export interface Constraint {
|
|
@@ -66,11 +57,11 @@ interface ITable {
|
|
|
66
57
|
autoIncrement: boolean;
|
|
67
58
|
constraints: Constraint[];
|
|
68
59
|
indexes: Index[];
|
|
69
|
-
parent:
|
|
60
|
+
parent: any;
|
|
70
61
|
sync: boolean;
|
|
71
62
|
tableName: string;
|
|
72
63
|
}
|
|
73
|
-
declare const Table_base: new (defaults?: ITable) => ITable;
|
|
64
|
+
declare const Table_base: new (defaults?: ITable | undefined) => ITable;
|
|
74
65
|
export declare class Table extends Table_base {
|
|
75
66
|
autoIncrementOwn?: boolean;
|
|
76
67
|
oid?: number;
|
|
@@ -78,7 +69,7 @@ export declare class Table extends Table_base {
|
|
|
78
69
|
}
|
|
79
70
|
export declare abstract class DB {
|
|
80
71
|
tables: Table[];
|
|
81
|
-
protected log: (
|
|
72
|
+
protected log: (message: string) => void;
|
|
82
73
|
protected sync: boolean;
|
|
83
74
|
abstract connect(): Promise<void>;
|
|
84
75
|
abstract end(): Promise<void>;
|
|
@@ -86,7 +77,7 @@ export declare abstract class DB {
|
|
|
86
77
|
findTable(name: string): Table;
|
|
87
78
|
protected indexesEq(a: Index, b: Index): boolean;
|
|
88
79
|
syncDataBase(): Promise<void>;
|
|
89
|
-
protected syncLog(
|
|
80
|
+
protected syncLog(message: string): void;
|
|
90
81
|
abstract dropConstraints(table: Table): Promise<number[]>;
|
|
91
82
|
abstract dropFields(table: Table): Promise<void>;
|
|
92
83
|
abstract dropIndexes(table: Table, constraintIndexes: number[]): Promise<void>;
|
package/lib/db.js
CHANGED
|
@@ -1,25 +1,32 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DB = exports.Table = exports.Attribute = exports.
|
|
4
|
-
class
|
|
5
|
-
|
|
3
|
+
exports.DB = exports.Table = exports.Attribute = exports.Type = exports.EntryBase = void 0;
|
|
4
|
+
class EntryBase {
|
|
5
|
+
constructor(from) {
|
|
6
|
+
if (from === "load")
|
|
7
|
+
this.preLoad();
|
|
8
|
+
else {
|
|
9
|
+
if (from)
|
|
10
|
+
Object.assign(this, from);
|
|
11
|
+
this.construct();
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
construct() { }
|
|
15
|
+
postLoad() { }
|
|
16
|
+
postSave() { }
|
|
17
|
+
preLoad() { }
|
|
18
|
+
preSave() { }
|
|
6
19
|
async save() {
|
|
7
20
|
return false;
|
|
8
21
|
}
|
|
9
22
|
}
|
|
10
|
-
exports.
|
|
23
|
+
exports.EntryBase = EntryBase;
|
|
11
24
|
class Type {
|
|
12
25
|
constructor(from) {
|
|
13
26
|
Object.assign(this, from);
|
|
14
27
|
}
|
|
15
28
|
}
|
|
16
29
|
exports.Type = Type;
|
|
17
|
-
class Meta extends Type {
|
|
18
|
-
constructor(from) {
|
|
19
|
-
super(from);
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
exports.Meta = Meta;
|
|
23
30
|
class Attribute extends Type {
|
|
24
31
|
constructor(from) {
|
|
25
32
|
super(from);
|
|
@@ -42,6 +49,7 @@ exports.Table = Table;
|
|
|
42
49
|
class DB {
|
|
43
50
|
constructor(log) {
|
|
44
51
|
this.tables = [];
|
|
52
|
+
this.sync = true;
|
|
45
53
|
this.log = log;
|
|
46
54
|
}
|
|
47
55
|
findTable(name) {
|
|
@@ -72,9 +80,8 @@ class DB {
|
|
|
72
80
|
await this.syncIndexes(table);
|
|
73
81
|
}
|
|
74
82
|
}
|
|
75
|
-
syncLog(
|
|
76
|
-
|
|
77
|
-
this.log(...args);
|
|
83
|
+
syncLog(message) {
|
|
84
|
+
this.log(this.sync ? message : "NOT SYNCING: " + message);
|
|
78
85
|
}
|
|
79
86
|
}
|
|
80
87
|
exports.DB = DB;
|
package/lib/minidb.js
CHANGED
package/package.json
CHANGED
|
@@ -1,20 +1,25 @@
|
|
|
1
1
|
{
|
|
2
2
|
"author": "Daniele Ricci <daniele.icc@gmail.com> (https://github.com/iccicci)",
|
|
3
3
|
"bugs": "https://github.com/iccicci/sedentary/issues",
|
|
4
|
+
"contributors": [
|
|
5
|
+
"Daniele Ricci <daniele.icc@gmail.com> (https://github.com/iccicci)",
|
|
6
|
+
"yossarian <sergiybiluk@gmail.com> (https://github.com/captain-yossarian)"
|
|
7
|
+
],
|
|
4
8
|
"dependencies": {},
|
|
5
9
|
"description": "The ORM which never needs to migrate",
|
|
6
10
|
"devDependencies": {
|
|
7
11
|
"@types/mocha": "9.0.0",
|
|
8
|
-
"@types/node": "
|
|
12
|
+
"@types/node": "17.0.5",
|
|
9
13
|
"@types/yamljs": "0.2.31",
|
|
10
|
-
"@typescript-eslint/eslint-plugin": "5.
|
|
11
|
-
"@typescript-eslint/parser": "5.
|
|
12
|
-
"eslint": "8.
|
|
14
|
+
"@typescript-eslint/eslint-plugin": "5.8.1",
|
|
15
|
+
"@typescript-eslint/parser": "5.8.1",
|
|
16
|
+
"eslint": "8.5.0",
|
|
13
17
|
"mocha": "9.1.3",
|
|
14
18
|
"nyc": "15.1.0",
|
|
15
|
-
"prettier": "2.5.
|
|
19
|
+
"prettier": "2.5.1",
|
|
16
20
|
"ts-node": "10.4.0",
|
|
17
|
-
"
|
|
21
|
+
"tsd": "0.19.0",
|
|
22
|
+
"typescript": "4.5.4",
|
|
18
23
|
"yamljs": "0.3.0"
|
|
19
24
|
},
|
|
20
25
|
"engines": {
|
|
@@ -55,6 +60,23 @@
|
|
|
55
60
|
"tsc": "tsc --declaration",
|
|
56
61
|
"version": "node -r ts-node/register utils.ts version"
|
|
57
62
|
},
|
|
63
|
+
"tsd": {
|
|
64
|
+
"compilerOptions": {
|
|
65
|
+
"alwaysStrict": true,
|
|
66
|
+
"declaration": true,
|
|
67
|
+
"esModuleInterop": true,
|
|
68
|
+
"module": "commonjs",
|
|
69
|
+
"noImplicitAny": true,
|
|
70
|
+
"noImplicitReturns": true,
|
|
71
|
+
"noImplicitThis": true,
|
|
72
|
+
"strict": true,
|
|
73
|
+
"strictBindCallApply": true,
|
|
74
|
+
"strictFunctionTypes": true,
|
|
75
|
+
"strictNullChecks": true,
|
|
76
|
+
"strictPropertyInitialization": true,
|
|
77
|
+
"target": "es2017"
|
|
78
|
+
}
|
|
79
|
+
},
|
|
58
80
|
"types": "index.d.ts",
|
|
59
|
-
"version": "0.0.
|
|
81
|
+
"version": "0.0.22"
|
|
60
82
|
}
|
package/lib/log.d.ts
DELETED
package/lib/log.js
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.createLogger = void 0;
|
|
4
|
-
const console_1 = require("console");
|
|
5
|
-
const stream_1 = require("stream");
|
|
6
|
-
class Logger extends stream_1.Writable {
|
|
7
|
-
constructor(log) {
|
|
8
|
-
super();
|
|
9
|
-
this.log = log;
|
|
10
|
-
}
|
|
11
|
-
_write(chunk, encoding, callback) {
|
|
12
|
-
this.log(chunk.toString());
|
|
13
|
-
callback();
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
function createLogger(log) {
|
|
17
|
-
// eslint-disable-next-line no-console
|
|
18
|
-
return log ? new console_1.Console(new Logger(log)).log : log === null ? () => { } : console.log;
|
|
19
|
-
}
|
|
20
|
-
exports.createLogger = createLogger;
|
package/lib/log.ts
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { Console } from "console";
|
|
2
|
-
import { Writable } from "stream";
|
|
3
|
-
|
|
4
|
-
class Logger extends Writable {
|
|
5
|
-
private log: (message: string) => void;
|
|
6
|
-
|
|
7
|
-
constructor(log: (message: string) => void) {
|
|
8
|
-
super();
|
|
9
|
-
|
|
10
|
-
this.log = log;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
_write(chunk: Buffer, encoding: string, callback: () => void) {
|
|
14
|
-
this.log(chunk.toString());
|
|
15
|
-
callback();
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export function createLogger(log: ((message: string) => void) | null | undefined) {
|
|
20
|
-
// eslint-disable-next-line no-console
|
|
21
|
-
return log ? new Console(new Logger(log)).log : log === null ? () => {} : console.log;
|
|
22
|
-
}
|
package/requirements.txt
DELETED