sedentary 0.0.22 → 0.0.23

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.
@@ -31,7 +31,7 @@ export declare class Type<N extends Natural, E> {
31
31
  }
32
32
  export interface Attribute<N extends Natural, E> extends Type<N, E> {
33
33
  attributeName: string;
34
- defaultValue?: unknown;
34
+ defaultValue?: Natural;
35
35
  fieldName: string;
36
36
  modelName: string;
37
37
  notNull: boolean;
@@ -57,7 +57,7 @@ interface ITable {
57
57
  autoIncrement: boolean;
58
58
  constraints: Constraint[];
59
59
  indexes: Index[];
60
- parent: any;
60
+ parent?: Attribute<Natural, unknown>;
61
61
  sync: boolean;
62
62
  tableName: string;
63
63
  }
@@ -78,6 +78,8 @@ export declare abstract class DB {
78
78
  protected indexesEq(a: Index, b: Index): boolean;
79
79
  syncDataBase(): Promise<void>;
80
80
  protected syncLog(message: string): void;
81
+ abstract escape(value: Natural): string;
82
+ abstract save(tableName: string, attributes: Attribute<Natural, unknown>[]): (this: Record<string, Natural>) => Promise<boolean>;
81
83
  abstract dropConstraints(table: Table): Promise<number[]>;
82
84
  abstract dropFields(table: Table): Promise<void>;
83
85
  abstract dropIndexes(table: Table, constraintIndexes: number[]): Promise<void>;
@@ -87,4 +89,6 @@ export declare abstract class DB {
87
89
  abstract syncSequence(table: Table): Promise<void>;
88
90
  abstract syncTable(table: Table): Promise<void>;
89
91
  }
92
+ export declare class Transaction {
93
+ }
90
94
  export {};
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DB = exports.Table = exports.Attribute = exports.Type = exports.EntryBase = void 0;
3
+ exports.Transaction = exports.DB = exports.Table = exports.Attribute = exports.Type = exports.EntryBase = void 0;
4
4
  class EntryBase {
5
5
  constructor(from) {
6
6
  if (from === "load")
@@ -85,3 +85,6 @@ class DB {
85
85
  }
86
86
  }
87
87
  exports.DB = DB;
88
+ class Transaction {
89
+ }
90
+ exports.Transaction = Transaction;
package/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { Attribute, DB, EntryBase, ForeignKeyOptions, Natural, Type } from "./lib/db";
2
- export { EntryBase, ForeignKeyActions, ForeignKeyOptions, Natural, Type } from "./lib/db";
1
+ import { Attribute, DB, EntryBase, ForeignKeyOptions, Natural, Type } from "./db";
2
+ export { EntryBase, ForeignKeyActions, ForeignKeyOptions, Natural, Type } from "./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;
@@ -36,10 +36,10 @@ interface BaseModelOptions {
36
36
  }
37
37
  export interface ModelOptions extends BaseModelOptions {
38
38
  int8id?: boolean;
39
- parent?: Type<Natural, EntryBase>;
39
+ parent?: Attribute<Natural, EntryBase>;
40
40
  primaryKey?: string;
41
41
  }
42
- declare type ConditionAttribute<N extends Natural> = N | [">" | "<" | ">=" | "<=" | "<>", N] | ["LIKE", string] | ["IN", ...N[]];
42
+ declare type ConditionAttribute<N extends Natural> = N | [">" | "<" | ">=" | "<=" | "<>", N] | ["IN", ...N[]] | ["IS NULL"] | ["LIKE", string];
43
43
  declare type ConditionBase<A extends AttributesDefinition> = string | {
44
44
  [a in keyof A]?: ConditionAttribute<Native<A[a]>>;
45
45
  };
@@ -83,24 +83,27 @@ export declare type Where<M> = M extends {
83
83
  load: (where: infer T) => void;
84
84
  } ? Exclude<T, undefined> : never;
85
85
  export interface SedentaryOptions {
86
+ autoSync?: boolean;
86
87
  log?: ((message: string) => void) | null;
87
- serverless?: boolean;
88
88
  sync?: boolean;
89
89
  }
90
90
  export declare class Sedentary {
91
+ protected autoSync: boolean;
91
92
  protected db: DB;
92
93
  protected log: (...data: unknown[]) => void;
93
94
  protected sync: boolean;
94
95
  private models;
95
- constructor(filename: string, options?: SedentaryOptions);
96
+ constructor(options?: SedentaryOptions);
96
97
  DATETIME(): Type<Date, unknown>;
97
98
  FKEY<N extends Natural, E extends EntryBase>(attribute: Attribute<N, E>, options?: ForeignKeyOptions): Type<N, E>;
98
99
  INT(size?: number): Type<number, unknown>;
99
100
  INT8(): Type<string, unknown>;
100
101
  VARCHAR(size?: number): Type<string, unknown>;
102
+ checkDB(): void;
101
103
  checkSize(size: number, message: string): number;
102
- connect(): Promise<void>;
104
+ connect(sync?: boolean): Promise<void>;
103
105
  end(): Promise<void>;
106
+ escape(value: Natural): string;
104
107
  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
108
  int8id?: B;
106
109
  parent?: P;
@@ -112,4 +115,3 @@ export declare class Sedentary {
112
115
  primaryKey?: K | keyof A;
113
116
  }, 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>;
114
117
  }
115
- export declare const Package: typeof Sedentary;
package/index.js CHANGED
@@ -1,37 +1,37 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Package = exports.Sedentary = exports.Type = exports.EntryBase = void 0;
4
- const db_1 = require("./lib/db");
5
- const minidb_1 = require("./lib/minidb");
6
- var db_2 = require("./lib/db");
3
+ exports.Sedentary = exports.Type = exports.EntryBase = void 0;
4
+ const db_1 = require("./db");
5
+ var db_2 = require("./db");
7
6
  Object.defineProperty(exports, "EntryBase", { enumerable: true, get: function () { return db_2.EntryBase; } });
8
7
  Object.defineProperty(exports, "Type", { enumerable: true, get: function () { return db_2.Type; } });
9
8
  const allowedOption = ["indexes", "int8id", "parent", "primaryKey", "sync", "tableName"];
10
9
  const reservedNames = [
11
10
  ...["attributeName", "attributes", "base", "class", "construct", "constructor", "defaultValue", "entry", "fieldName", "foreignKeys", "load"],
12
- ...["methods", "name", "postLoad", "postSave", "preLoad", "preSave", "primaryKey", "prototype", "save", "size", "tableName", "type"]
11
+ ...["loaded", "methods", "name", "postLoad", "postSave", "preLoad", "preSave", "primaryKey", "prototype", "save", "size", "tableName", "tx", "type"]
13
12
  ];
14
13
  class Sedentary {
15
- constructor(filename, options) {
14
+ constructor(options) {
16
15
  this.sync = true;
17
16
  this.models = {};
18
- if (typeof filename !== "string")
19
- throw new Error("new Sedentary: 'filename' argument: Wrong type, expected 'string'");
20
17
  if (!options)
21
18
  options = {};
22
19
  if (!(options instanceof Object))
23
20
  throw new Error("new Sedentary: 'options' argument: Wrong type, expected 'Object'");
24
21
  for (const k in options)
25
- if (!["log", "sync"].includes(k))
22
+ if (!["autoSync", "log", "sync"].includes(k))
26
23
  throw new Error(`new Sedentary: 'options' argument: Unknown '${k}' option`);
27
- const { log, sync } = Object.assign({ sync: true }, options);
24
+ const { autoSync, log, sync } = Object.assign({ autoSync: true, sync: true }, options);
25
+ if (typeof autoSync !== "boolean")
26
+ throw new Error("new Sedentary: 'autoSync' option: Wrong type, expected 'boolean'");
28
27
  if (log !== null && log !== undefined && !(log instanceof Function))
29
28
  throw new Error("new Sedentary: 'log' option: Wrong type, expected 'null' or 'Function'");
30
29
  if (typeof sync !== "boolean")
31
30
  throw new Error("new Sedentary: 'sync' option: Wrong type, expected 'boolean'");
31
+ this.autoSync = autoSync;
32
+ this.db = null;
32
33
  // eslint-disable-next-line no-console
33
34
  this.log = log ? log : log === null ? () => { } : console.log;
34
- this.db = new minidb_1.MiniDB(filename, this.log);
35
35
  this.sync = sync;
36
36
  }
37
37
  DATETIME() {
@@ -56,6 +56,10 @@ 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
+ checkDB() {
60
+ if (!this.db)
61
+ throw new Error("Package sedentary can't be used directly. Please check: https://www.npmjs.com/package/sedentary#disclaimer");
62
+ }
59
63
  checkSize(size, message) {
60
64
  const str = size.toString();
61
65
  const parsed = parseInt(str, 10);
@@ -63,13 +67,17 @@ class Sedentary {
63
67
  throw new Error(message);
64
68
  return parsed;
65
69
  }
66
- async connect() {
70
+ async connect(sync) {
67
71
  try {
72
+ this.checkDB();
68
73
  this.log("Connecting...");
69
74
  await this.db.connect();
70
- this.log("Connected, syncing...");
71
- await this.db.syncDataBase();
72
- this.log("Synced");
75
+ this.log("Connected");
76
+ if (this.autoSync || sync) {
77
+ this.log("Syncing...");
78
+ await this.db.syncDataBase();
79
+ this.log("Synced");
80
+ }
73
81
  }
74
82
  catch (e) {
75
83
  this.log("Connecting: " + (e instanceof Error ? e.message : JSON.stringify(e)));
@@ -81,8 +89,12 @@ class Sedentary {
81
89
  await this.db.end();
82
90
  this.log("Connection closed");
83
91
  }
92
+ escape(value) {
93
+ return this.db.escape(value);
94
+ }
84
95
  /* eslint-enable @typescript-eslint/no-explicit-any */
85
96
  model(modelName, attributes, options, methods) {
97
+ this.checkDB();
86
98
  if (typeof modelName !== "string")
87
99
  throw new Error("Sedentary.model: 'name' argument: Wrong type, expected 'string'");
88
100
  if (this.models[modelName])
@@ -319,9 +331,8 @@ class Sedentary {
319
331
  Object.defineProperty(ret, "foreignKeys", { value: foreignKeys });
320
332
  Object.defineProperty(ret, "methods", { value: methods });
321
333
  Object.assign(ret.prototype, methods);
322
- ret.prototype.save = function () {
323
- return Promise.resolve(false);
324
- };
334
+ ret.prototype.save = this.db.save(tableName, aarray);
335
+ Object.defineProperty(ret.prototype.save, "name", { value: modelName + ".save" });
325
336
  for (const attribute of aarray)
326
337
  Object.defineProperty(ret, attribute.attributeName, { value: attribute });
327
338
  for (const key of ["attributeName", "base", "fieldName", "modelName", "size", "tableName", "type", "unique"])
@@ -330,4 +341,3 @@ class Sedentary {
330
341
  }
331
342
  }
332
343
  exports.Sedentary = Sedentary;
333
- exports.Package = Sedentary;
package/package.json CHANGED
@@ -78,5 +78,5 @@
78
78
  }
79
79
  },
80
80
  "types": "index.d.ts",
81
- "version": "0.0.22"
81
+ "version": "0.0.23"
82
82
  }
package/lib/minidb.d.ts DELETED
@@ -1,17 +0,0 @@
1
- import { DB, Table } from "./db";
2
- export declare class MiniDB extends DB {
3
- private body;
4
- private file;
5
- constructor(filename: string, log: (message: string) => void);
6
- connect(): Promise<void>;
7
- dropConstraints(table: Table): Promise<number[]>;
8
- dropFields(table: Table): Promise<void>;
9
- dropIndexes(table: Table, constraintIndexes: number[]): Promise<void>;
10
- end(): Promise<void>;
11
- save(): Promise<void>;
12
- syncConstraints(table: Table): Promise<void>;
13
- syncIndexes(table: Table): Promise<void>;
14
- syncFields(table: Table): Promise<void>;
15
- syncSequence(table: Table): Promise<void>;
16
- syncTable(table: Table): Promise<void>;
17
- }
package/lib/minidb.js DELETED
@@ -1,191 +0,0 @@
1
- "use strict";
2
- /* eslint-disable @typescript-eslint/no-explicit-any */
3
- Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.MiniDB = void 0;
5
- const db_1 = require("./db");
6
- const fs_1 = require("fs");
7
- const { readFile, writeFile } = fs_1.promises;
8
- class MiniDB extends db_1.DB {
9
- constructor(filename, log) {
10
- super(log);
11
- this.file = filename;
12
- }
13
- async connect() {
14
- this.body = { next: {}, tables: {} };
15
- try {
16
- this.body = JSON.parse((await readFile(this.file)).toString());
17
- }
18
- catch (e) {
19
- const err = e;
20
- if (err.code !== "ENOENT")
21
- throw e;
22
- }
23
- }
24
- async dropConstraints(table) {
25
- const { constraints } = this.body.tables[table.tableName] || { constraints: { f: {}, u: {} } };
26
- for (const constraint of Object.keys(constraints.f).sort()) {
27
- const arr = table.constraints.filter(({ constraintName, type }) => constraintName === constraint && type === "f");
28
- const dbOptions = arr.length ? arr[0].attribute.foreignKey.options : { onDelete: "delete", onUpdate: "delete" };
29
- const inOptions = constraints.f[constraint].options;
30
- if (dbOptions.onDelete !== inOptions.onDelete || dbOptions.onUpdate !== inOptions.onUpdate) {
31
- this.syncLog(`'${table.tableName}': Removing foreign key: '${constraint}'`);
32
- if (this.sync)
33
- delete constraints.f[constraint];
34
- }
35
- }
36
- for (const constraint of Object.keys(constraints.u).sort()) {
37
- if (!table.constraints.filter(({ constraintName, type }) => constraintName === constraint && type === "u").length) {
38
- this.syncLog(`'${table.tableName}': Removing unique constraint from field: '${constraints.u[constraint].on}'`);
39
- if (this.sync)
40
- delete constraints.u[constraint];
41
- }
42
- }
43
- await this.save();
44
- return [];
45
- }
46
- async dropFields(table) {
47
- const { fields } = this.body.tables[table.tableName] || { fields: {} };
48
- for (const attribute of Object.keys(fields).sort()) {
49
- if (!table.findField(attribute)) {
50
- this.syncLog(`'${table.tableName}': Removing field: '${attribute}'`);
51
- if (this.sync)
52
- delete fields[attribute];
53
- }
54
- }
55
- await this.save();
56
- }
57
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
58
- async dropIndexes(table, constraintIndexes) {
59
- const { indexes } = this.body.tables[table.tableName] || { indexes: {} };
60
- for (const name of Object.keys(indexes).sort()) {
61
- const index = table.indexes.filter(_ => _.indexName === name);
62
- if (index.length === 0 || !this.indexesEq(indexes[name], index[0])) {
63
- this.syncLog(`'${table.tableName}': Removing index: '${name}'`);
64
- if (this.sync)
65
- delete indexes[name];
66
- }
67
- }
68
- await this.save();
69
- }
70
- async end() { }
71
- async save() {
72
- await writeFile(this.file, JSON.stringify(this.body));
73
- }
74
- async syncConstraints(table) {
75
- const { constraints } = this.body.tables[table.tableName] || { constraints: { f: {}, u: {} } };
76
- for (const constraint of table.constraints) {
77
- const { attribute, constraintName, type } = constraint;
78
- if (!constraints[type][constraintName]) {
79
- if (type === "f") {
80
- const { fieldName, options, tableName } = attribute.foreignKey;
81
- const onDelete = options.onDelete !== "no action" ? ` on delete ${options.onDelete}` : "";
82
- const onUpdate = options.onUpdate !== "no action" ? ` on update ${options.onUpdate}` : "";
83
- this.syncLog(`'${table.tableName}': Adding foreign key '${constraint.constraintName}' on field: '${attribute.fieldName}' references '${tableName}(${fieldName})'${onDelete}${onUpdate}`);
84
- if (this.sync)
85
- constraints[type][constraintName] = { on: attribute.fieldName, options, fieldName, tableName };
86
- }
87
- else {
88
- this.syncLog(`'${table.tableName}': Adding unique constraint on field: '${attribute.fieldName}'`);
89
- if (this.sync)
90
- constraints[type][constraintName] = { on: attribute.fieldName };
91
- }
92
- }
93
- }
94
- await this.save();
95
- }
96
- async syncIndexes(table) {
97
- const { indexes } = this.body.tables[table.tableName] || { indexes: {} };
98
- for (const index of table.indexes) {
99
- const { indexName } = index;
100
- if (!(indexName in indexes)) {
101
- this.syncLog(`'${table.tableName}': Adding index: '${indexName}' on (${index.fields.map(_ => `'${_}'`).join(", ")}) type '${index.type}'${index.unique ? " unique" : ""}`);
102
- if (this.sync)
103
- indexes[indexName] = index;
104
- }
105
- }
106
- await this.save();
107
- }
108
- async syncFields(table) {
109
- for (const attribute of table.attributes) {
110
- const { fields } = this.body.tables[table.tableName] || { fields: {} };
111
- const { defaultValue, fieldName, notNull, size, type } = attribute;
112
- let field = fields[fieldName];
113
- if (!field) {
114
- this.syncLog(`'${table.tableName}': Adding field: '${fieldName}' '${type}' '${size || ""}'`);
115
- if (this.sync)
116
- field = fields[fieldName] = { size, type };
117
- else
118
- field = {};
119
- }
120
- if (field.size !== size || field.type !== type) {
121
- this.syncLog(`'${table.tableName}': Changing field type: '${fieldName}' '${type}' '${size || ""}'`);
122
- if (this.sync)
123
- field = fields[fieldName] = Object.assign(Object.assign({}, field), { size, type });
124
- }
125
- if (field.default) {
126
- if (!defaultValue) {
127
- this.syncLog(`'${table.tableName}': Dropping default value for field: '${fieldName}'`);
128
- if (this.sync)
129
- delete field.default;
130
- }
131
- else if (field.default !== defaultValue) {
132
- this.syncLog(`'${table.tableName}': Changing default value to '${defaultValue}' for field: '${fieldName}'`);
133
- if (this.sync)
134
- field.default = defaultValue;
135
- }
136
- }
137
- else if (defaultValue) {
138
- this.syncLog(`'${table.tableName}': Setting default value '${defaultValue instanceof Date ? defaultValue.toISOString() : defaultValue}' for field: '${fieldName}'`);
139
- if (this.sync)
140
- field.default = defaultValue;
141
- }
142
- if (field.notNull) {
143
- if (!notNull) {
144
- this.syncLog(`'${table.tableName}': Dropping not null for field: '${fieldName}'`);
145
- if (this.sync)
146
- delete field.notNull;
147
- }
148
- }
149
- else if (notNull) {
150
- this.syncLog(`'${table.tableName}': Setting not null for field: '${fieldName}'`);
151
- if (this.sync)
152
- field.notNull = true;
153
- }
154
- }
155
- await this.save();
156
- }
157
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
158
- async syncSequence(table) { }
159
- async syncTable(table) {
160
- if (this.body.tables[table.tableName]) {
161
- (() => {
162
- if (table.parent) {
163
- if (this.body.tables[table.tableName].parent === table.parent.tableName)
164
- return;
165
- }
166
- else if (!this.body.tables[table.tableName].parent)
167
- return;
168
- this.syncLog(`Removing table: '${table.tableName}'`);
169
- if (this.sync)
170
- delete this.body.tables[table.tableName];
171
- })();
172
- }
173
- if (!this.body.tables[table.tableName]) {
174
- this.syncLog(`Adding table: '${table.tableName}'`);
175
- if (this.sync)
176
- this.body.tables[table.tableName] = { constraints: { f: {}, u: {} }, fields: {}, indexes: {} };
177
- if (table.parent) {
178
- this.syncLog(`Setting parent: '${table.parent.tableName}' - to table: '${table.tableName}'`);
179
- if (this.sync)
180
- this.body.tables[table.tableName].parent = table.parent.tableName;
181
- }
182
- if (table.autoIncrement && !this.body.next[table.tableName]) {
183
- this.syncLog(`Setting auto increment: '${table.tableName}'`);
184
- if (this.sync)
185
- this.body.next[table.tableName] = 1;
186
- }
187
- }
188
- await this.save();
189
- }
190
- }
191
- exports.MiniDB = MiniDB;
@@ -1,2 +0,0 @@
1
- export declare class Transaction {
2
- }
@@ -1,6 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Transaction = void 0;
4
- class Transaction {
5
- }
6
- exports.Transaction = Transaction;