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 CHANGED
@@ -81,10 +81,9 @@ $ npm install --save sedentary
81
81
 
82
82
  # Disclaimer
83
83
 
84
- **Do not use this package itself in production! This package uses a simple self made JSON-DB engine just for testing
85
- purposes.**
84
+ **Do not use this package itself! It does not support any DB engine.**
86
85
 
87
- For a real environment a _DB engine dedicated extension_ must be used:
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, Entry, ForeignKeyOptions, Meta, Natural, Type } from "./lib/db";
2
- export { Entry, ForeignKeyActions, ForeignKeyOptions, Natural, Type } from "./lib/db";
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 KeysAttributes<T, k> = T extends AttributeDefinition<Natural, infer E> ? (E extends Entry ? k : never) : never;
16
- declare type Keys<F extends AttributesDefinition> = {
17
- [f in keyof F]?: KeysAttributes<F[f], f>;
18
- }[keyof F];
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
- declare type BaseModelOptions<T> = {
32
+ interface BaseModelOptions {
37
33
  indexes?: IndexesDefinition;
38
- init?: (this: T) => void;
39
34
  sync?: boolean;
40
35
  tableName?: string;
41
- };
42
- export declare type ModelOptions<K extends string, M extends Methods<T>, P extends Meta<Natural, Entry>, T extends Entry> = BaseModelOptions<T> & {
36
+ }
37
+ export interface ModelOptions extends BaseModelOptions {
43
38
  int8id?: boolean;
44
- methods?: M;
45
- parent?: P;
46
- primaryKey?: K;
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 ForeignKey<T> = T extends AttributeDefinition<Natural, infer E> ? () => Promise<E> : never;
49
- declare type ModelWithMetods<A extends AttributesDefinition, M> = {
50
- [a in keyof A]?: Native<A[a]>;
51
- } & {
52
- [a in Keys<A> & string as `${a}Load`]?: ForeignKey<A[a]>;
53
- } & M;
54
- declare type Model<A extends AttributesDefinition> = {
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 Ancestor<A, N extends Natural, T extends Entry> = (new () => T) & {
60
- [a in keyof A]?: Meta<Native<A[a]>, T>;
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
- load: (boh: boolean) => Promise<T[]>;
63
- } & Meta<N, T>;
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 Entry>(attribute: Type<N, E>, options?: ForeignKeyOptions): Type<N, E>;
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, M extends Methods<T>, T extends Entry & {
83
- id?: string;
84
- } & ModelWithMetods<A, M>>(modelName: string, attributes: A, options?: BaseModelOptions<T> & {
85
- int8id: true;
86
- methods: M;
87
- }): Ancestor<A, string, T>;
88
- model<A extends AttributesDefinition, K extends keyof A, M extends Methods<T>, N extends K extends keyof A ? Native<A[K]> : never, T extends Entry & ModelWithMetods<A, M>>(modelName: string, attributes: A, options?: BaseModelOptions<T> & {
89
- methods: M;
90
- primaryKey: K;
91
- }): Ancestor<A, N, T>;
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.Entry = void 0;
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, "Entry", { enumerable: true, get: function () { return db_2.Entry; } });
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", "init", "int8id", "methods", "parent", "primaryKey", "sync", "tableName", "type"];
9
+ const allowedOption = ["indexes", "int8id", "parent", "primaryKey", "sync", "tableName"];
11
10
  const reservedNames = [
12
- ...["attributeName", "base", "class", "constructor", "defaultValue", "entry", "fieldName", "init", "isModel"],
13
- ...["load", "meta", "methods", "name", "primaryKey", "prototype", "save", "size", "tableName", "type"]
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
- this.log = (0, log_1.createLogger)(log);
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:", e.message);
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
- model(modelName, attributes, options) {
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 (methods && !(methods instanceof Object))
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
- const originalMethods = methods;
111
- if (parent) {
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
- if (!foreignKey.options)
180
- foreignKey.options = {};
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 foreignKey.options)
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 = foreignKey.options[onChange];
188
+ let action = options[onChange];
189
189
  if (!action)
190
- action = foreignKey.options[onChange] = "no 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 init = parent
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] = curr;
266
+ ret[curr.attributeName] = true;
297
267
  return ret;
298
268
  }, {});
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)
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 (originalMethods && foreignKey + "Load" in originalMethods)
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
- 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`);
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 metaAttributes) {
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 (parent.methods && attribute in parent.methods)
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 metaForeignKeys) {
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 (parent.methods && foreignKey + "Load" in parent.methods)
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
- 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
- }
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
- Object.defineProperty(Class, "isModel", { value: () => true });
343
- Object.defineProperty(Class, "load", { value: load });
344
- Object.defineProperty(Class, "meta", { value: meta });
345
- Object.defineProperty(Class, "name", { value: modelName });
346
- Object.defineProperty(Class.prototype.save, "name", { value: modelName + ".save" });
347
- Object.assign(Class, meta);
348
- Object.assign(Class.prototype, methods);
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(Class, attribute.attributeName, { value: attribute });
351
- for (const key of ["attributeName", "base", "fieldName", "modelName", "size", "type", "unique"])
352
- Object.defineProperty(Class, key, { value: pk[key] });
353
- return Class;
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 Entry {
3
- init(): void;
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 declare class Type<N extends Natural, E> {
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 Meta<N extends Natural, E> extends Type<N, E> {
26
- attributes: {
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 declare class Attribute<N extends Natural, E> extends Type<N, E> {
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: Meta<Natural, unknown>;
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: (...data: unknown[]) => void;
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(...data: unknown[]): void;
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.Meta = exports.Type = exports.Entry = void 0;
4
- class Entry {
5
- init() { }
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.Entry = Entry;
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(...data) {
76
- const args = this.sync ? data : ["NOT SYNCING:", ...data];
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
@@ -16,7 +16,8 @@ class MiniDB extends db_1.DB {
16
16
  this.body = JSON.parse((await readFile(this.file)).toString());
17
17
  }
18
18
  catch (e) {
19
- if (e.code !== "ENOENT")
19
+ const err = e;
20
+ if (err.code !== "ENOENT")
20
21
  throw e;
21
22
  }
22
23
  }
@@ -0,0 +1,2 @@
1
+ export declare class Transaction {
2
+ }
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Transaction = void 0;
4
+ class Transaction {
5
+ }
6
+ exports.Transaction = Transaction;
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": "16.11.10",
12
+ "@types/node": "17.0.5",
9
13
  "@types/yamljs": "0.2.31",
10
- "@typescript-eslint/eslint-plugin": "5.4.0",
11
- "@typescript-eslint/parser": "5.4.0",
12
- "eslint": "8.3.0",
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.0",
19
+ "prettier": "2.5.1",
16
20
  "ts-node": "10.4.0",
17
- "typescript": "4.5.2",
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.18"
81
+ "version": "0.0.22"
60
82
  }
package/lib/log.d.ts DELETED
@@ -1,4 +0,0 @@
1
- export declare function createLogger(log: ((message: string) => void) | null | undefined): {
2
- (...data: any[]): void;
3
- (message?: any, ...optionalParams: any[]): void;
4
- };
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
@@ -1,2 +0,0 @@
1
- sphinx
2
- sphinx_rtd_theme