sedentary 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cjs/db.js CHANGED
@@ -109,9 +109,11 @@ class DB {
109
109
  }
110
110
  }
111
111
  exports.DB = DB;
112
+ const cleanProperties = { configurable: true, value: undefined };
112
113
  class Transaction {
113
114
  constructor(log) {
114
115
  this.entries = [];
116
+ this.closed = false;
115
117
  this.log = log;
116
118
  }
117
119
  addEntry(entry) {
@@ -121,8 +123,8 @@ class Transaction {
121
123
  clean() {
122
124
  const { entries } = this;
123
125
  for (const entry of entries) {
124
- Object.defineProperty(entry, exports.actions, { configurable: true, value: undefined });
125
- Object.defineProperty(entry, exports.transaction, { configurable: true, value: undefined });
126
+ Object.defineProperty(entry, exports.actions, cleanProperties);
127
+ Object.defineProperty(entry, exports.transaction, cleanProperties);
126
128
  }
127
129
  this.entries = [];
128
130
  }
@@ -135,12 +137,18 @@ class Transaction {
135
137
  return Promise.resolve();
136
138
  }
137
139
  preCommit() {
140
+ if (this.closed)
141
+ throw new Error("Transaction already closed");
142
+ this.closed = true;
138
143
  const { entries } = this;
139
144
  for (const entry of entries)
140
145
  if (entry[exports.actions])
141
146
  entry.preCommit(entry[exports.actions]);
142
147
  }
143
148
  rollback() {
149
+ if (this.closed)
150
+ throw new Error("Transaction already closed");
151
+ this.closed = true;
144
152
  this.clean();
145
153
  return Promise.resolve();
146
154
  }
package/dist/cjs/index.js CHANGED
@@ -19,7 +19,10 @@ Object.defineProperty(exports, "Type", { enumerable: true, get: function () { re
19
19
  const attributes = Symbol("attributes");
20
20
  const methods = Symbol("methods");
21
21
  const operators = ["=", ">", "<", ">=", "<=", "<>", "IN", "IS NULL", "LIKE", "NOT"];
22
- const allowedOption = ["indexes", "int8id", "parent", "primaryKey", "sync", "tableName"];
22
+ const allowedAttributeOptions = ["defaultValue", "fieldName", "notNull", "unique"];
23
+ const allowedAttributeOptionsSize = ["size", ...allowedAttributeOptions];
24
+ const allowedForeignKeyOptions = ["onDelete", "onUpdate", ...allowedAttributeOptions];
25
+ const allowedModelOptions = ["indexes", "int8id", "parent", "primaryKey", "sync", "tableName"];
23
26
  const reservedNames = [
24
27
  "attr2field",
25
28
  "attributeName",
@@ -49,6 +52,7 @@ const reservedNames = [
49
52
  "type",
50
53
  "unique"
51
54
  ];
55
+ const attributesWithSize = new Set(["VarChar", "Int", "Float"]);
52
56
  /** Model and attribute names: ASCII letters, digits, underscore; cannot start with digit. */
53
57
  const reModelAttributeName = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
54
58
  /** tableName and fieldName: ASCII lowercase letters, digits, underscore; cannot start with digit. */
@@ -93,18 +97,22 @@ class Sedentary {
93
97
  this.doSync = sync;
94
98
  }
95
99
  Boolean(options) {
100
+ this.checkOptions("Boolean", options);
96
101
  return new db_1.Type({ ...options, [db_1.base]: Boolean, type: "BOOLEAN" });
97
102
  }
98
103
  DateTime(options) {
104
+ this.checkOptions("DateTime", options);
99
105
  return new db_1.Type({ ...options, [db_1.base]: Date, type: "DATETIME" });
100
106
  }
101
107
  FKey(attribute, options) {
108
+ this.checkOptions("FKey", options);
102
109
  const { attributeName, fieldName, modelName, tableName, type, unique, [db_1.base]: _base, [db_1.size]: _size } = attribute;
103
110
  if (!unique)
104
111
  throw new Error(`Sedentary.FKey: '${modelName}' model: '${attributeName}' attribute: is not unique: can't be used as FKey target`);
105
- return new db_1.Type({ [db_1.base]: _base, foreignKey: { attributeName, fieldName, options, tableName }, [db_1.size]: _size, type });
112
+ return new db_1.Type({ ...options, [db_1.base]: _base, foreignKey: { attributeName, fieldName, options, tableName }, [db_1.size]: _size, type });
106
113
  }
107
114
  Float(options) {
115
+ this.checkOptions("Float", options);
108
116
  const sizeFloat = "Sedentary.Float: 'size' argument: Wrong value, expected 4 or 8";
109
117
  let storageSize;
110
118
  let rest;
@@ -116,6 +124,7 @@ class Sedentary {
116
124
  return new db_1.Type({ ...rest, [db_1.base]: Number, [db_1.size]: storageSize, type: "FLOAT" });
117
125
  }
118
126
  Int(options) {
127
+ this.checkOptions("Int", options);
119
128
  const sizeInt = "Sedentary.Int: 'size' argument: Wrong value, expected 2 or 4";
120
129
  let storageSize;
121
130
  let rest;
@@ -127,18 +136,23 @@ class Sedentary {
127
136
  return new db_1.Type({ ...rest, [db_1.base]: Number, [db_1.size]: storageSize, type: "INT" });
128
137
  }
129
138
  Int8(options) {
139
+ this.checkOptions("Int8", options);
130
140
  return new db_1.Type({ ...options, [db_1.base]: BigInt, [db_1.size]: 8, type: "INT8" });
131
141
  }
132
142
  JSON(options) {
143
+ this.checkOptions("JSON", options);
133
144
  return new db_1.Type({ ...options, [db_1.base]: Object, type: "JSON" });
134
145
  }
135
146
  Number(options) {
147
+ this.checkOptions("Number", options);
136
148
  return new db_1.Type({ ...options, [db_1.base]: Number, type: "NUMBER" });
137
149
  }
138
150
  None(options) {
151
+ this.checkOptions("None", options);
139
152
  return new db_1.Type({ ...options, [db_1.base]: undefined, type: "NONE" });
140
153
  }
141
154
  VarChar(options) {
155
+ this.checkOptions("VarChar", options);
142
156
  const message = "Sedentary.VarChar: 'size' argument: Wrong value, expected positive integer";
143
157
  const [maxSize, rest] = this.checkSize(message, options);
144
158
  return new db_1.Type({ ...rest, [db_1.base]: String, [db_1.size]: maxSize, type: "VARCHAR" });
@@ -147,6 +161,16 @@ class Sedentary {
147
161
  if (!this.db)
148
162
  throw new Error("Package sedentary can't be used directly. Please check: https://www.npmjs.com/package/sedentary#disclaimer");
149
163
  }
164
+ checkOptions(name, options) {
165
+ if (options === undefined)
166
+ return;
167
+ if (typeof options !== "object" || options === null)
168
+ throw new Error(`Sedentary.'${name}': Wrong options type, expected 'Object`);
169
+ const allowedOptions = name === "FKey" ? allowedForeignKeyOptions : attributesWithSize.has(name) ? allowedAttributeOptionsSize : allowedAttributeOptions;
170
+ for (const key in options)
171
+ if (!allowedOptions.includes(key))
172
+ throw new Error(`Sedentary.'${name}': Unknown option '${key}'`);
173
+ }
150
174
  checkOrderBy(order, attributes, modelName) {
151
175
  let array = [];
152
176
  if (!order)
@@ -302,7 +326,7 @@ class Sedentary {
302
326
  if (!(options instanceof Object))
303
327
  throw new Error(`Sedentary.model: '${modelName}' model: 'options' argument: Wrong type, expected 'Object'`);
304
328
  for (const k in options)
305
- if (!allowedOption.includes(k))
329
+ if (!allowedModelOptions.includes(k))
306
330
  throw new Error(`Sedentary.model: '${modelName}' model: 'options' argument: Unknown '${k}' option`);
307
331
  if (options.int8id && options.parent)
308
332
  throw new Error(`Sedentary.model: '${modelName}' model: 'int8id' and 'parent' options conflict each other`);
@@ -377,11 +401,6 @@ class Sedentary {
377
401
  })();
378
402
  if (foreignKey) {
379
403
  const options = foreignKey.options || {};
380
- if (foreignKey.options !== undefined && !(foreignKey.options instanceof Object))
381
- throw new Error(`Sedentary.FKey: '${modelName}' model: '${attributeName}' attribute: Wrong options type, expected 'Object'`);
382
- for (const k in options)
383
- if (!["onDelete", "onUpdate"].includes(k))
384
- throw new Error(`Sedentary.FKey: '${modelName}' model: '${attributeName}' attribute: Unknown option '${k}'`);
385
404
  for (const onChange of ["onDelete", "onUpdate"]) {
386
405
  const actions = ["cascade", "no action", "restrict", "set default", "set null"];
387
406
  let action = options[onChange];
@@ -1 +1 @@
1
- {\"type\":\"commonjs\"}
1
+ {"type":"commonjs"}
package/dist/es/db.js CHANGED
@@ -102,8 +102,10 @@ export class DB {
102
102
  this.log(this.sync ? message : `NOT SYNCING: ${message}`);
103
103
  }
104
104
  }
105
+ const cleanProperties = { configurable: true, value: undefined };
105
106
  export class Transaction {
106
107
  entries = [];
108
+ closed = false;
107
109
  log;
108
110
  constructor(log) {
109
111
  this.log = log;
@@ -115,8 +117,8 @@ export class Transaction {
115
117
  clean() {
116
118
  const { entries } = this;
117
119
  for (const entry of entries) {
118
- Object.defineProperty(entry, actions, { configurable: true, value: undefined });
119
- Object.defineProperty(entry, transaction, { configurable: true, value: undefined });
120
+ Object.defineProperty(entry, actions, cleanProperties);
121
+ Object.defineProperty(entry, transaction, cleanProperties);
120
122
  }
121
123
  this.entries = [];
122
124
  }
@@ -129,12 +131,18 @@ export class Transaction {
129
131
  return Promise.resolve();
130
132
  }
131
133
  preCommit() {
134
+ if (this.closed)
135
+ throw new Error("Transaction already closed");
136
+ this.closed = true;
132
137
  const { entries } = this;
133
138
  for (const entry of entries)
134
139
  if (entry[actions])
135
140
  entry.preCommit(entry[actions]);
136
141
  }
137
142
  rollback() {
143
+ if (this.closed)
144
+ throw new Error("Transaction already closed");
145
+ this.closed = true;
138
146
  this.clean();
139
147
  return Promise.resolve();
140
148
  }
package/dist/es/index.js CHANGED
@@ -3,7 +3,10 @@ export { Attribute, base, DB, deepCopy, deepDiff, EntryBase, loaded, size, Table
3
3
  const attributes = Symbol("attributes");
4
4
  const methods = Symbol("methods");
5
5
  const operators = ["=", ">", "<", ">=", "<=", "<>", "IN", "IS NULL", "LIKE", "NOT"];
6
- const allowedOption = ["indexes", "int8id", "parent", "primaryKey", "sync", "tableName"];
6
+ const allowedAttributeOptions = ["defaultValue", "fieldName", "notNull", "unique"];
7
+ const allowedAttributeOptionsSize = ["size", ...allowedAttributeOptions];
8
+ const allowedForeignKeyOptions = ["onDelete", "onUpdate", ...allowedAttributeOptions];
9
+ const allowedModelOptions = ["indexes", "int8id", "parent", "primaryKey", "sync", "tableName"];
7
10
  const reservedNames = [
8
11
  "attr2field",
9
12
  "attributeName",
@@ -33,6 +36,7 @@ const reservedNames = [
33
36
  "type",
34
37
  "unique"
35
38
  ];
39
+ const attributesWithSize = new Set(["VarChar", "Int", "Float"]);
36
40
  /** Model and attribute names: ASCII letters, digits, underscore; cannot start with digit. */
37
41
  const reModelAttributeName = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
38
42
  /** tableName and fieldName: ASCII lowercase letters, digits, underscore; cannot start with digit. */
@@ -80,18 +84,22 @@ export class Sedentary {
80
84
  this.doSync = sync;
81
85
  }
82
86
  Boolean(options) {
87
+ this.checkOptions("Boolean", options);
83
88
  return new Type({ ...options, [base]: Boolean, type: "BOOLEAN" });
84
89
  }
85
90
  DateTime(options) {
91
+ this.checkOptions("DateTime", options);
86
92
  return new Type({ ...options, [base]: Date, type: "DATETIME" });
87
93
  }
88
94
  FKey(attribute, options) {
95
+ this.checkOptions("FKey", options);
89
96
  const { attributeName, fieldName, modelName, tableName, type, unique, [base]: _base, [size]: _size } = attribute;
90
97
  if (!unique)
91
98
  throw new Error(`Sedentary.FKey: '${modelName}' model: '${attributeName}' attribute: is not unique: can't be used as FKey target`);
92
- return new Type({ [base]: _base, foreignKey: { attributeName, fieldName, options, tableName }, [size]: _size, type });
99
+ return new Type({ ...options, [base]: _base, foreignKey: { attributeName, fieldName, options, tableName }, [size]: _size, type });
93
100
  }
94
101
  Float(options) {
102
+ this.checkOptions("Float", options);
95
103
  const sizeFloat = "Sedentary.Float: 'size' argument: Wrong value, expected 4 or 8";
96
104
  let storageSize;
97
105
  let rest;
@@ -103,6 +111,7 @@ export class Sedentary {
103
111
  return new Type({ ...rest, [base]: Number, [size]: storageSize, type: "FLOAT" });
104
112
  }
105
113
  Int(options) {
114
+ this.checkOptions("Int", options);
106
115
  const sizeInt = "Sedentary.Int: 'size' argument: Wrong value, expected 2 or 4";
107
116
  let storageSize;
108
117
  let rest;
@@ -114,18 +123,23 @@ export class Sedentary {
114
123
  return new Type({ ...rest, [base]: Number, [size]: storageSize, type: "INT" });
115
124
  }
116
125
  Int8(options) {
126
+ this.checkOptions("Int8", options);
117
127
  return new Type({ ...options, [base]: BigInt, [size]: 8, type: "INT8" });
118
128
  }
119
129
  JSON(options) {
130
+ this.checkOptions("JSON", options);
120
131
  return new Type({ ...options, [base]: Object, type: "JSON" });
121
132
  }
122
133
  Number(options) {
134
+ this.checkOptions("Number", options);
123
135
  return new Type({ ...options, [base]: Number, type: "NUMBER" });
124
136
  }
125
137
  None(options) {
138
+ this.checkOptions("None", options);
126
139
  return new Type({ ...options, [base]: undefined, type: "NONE" });
127
140
  }
128
141
  VarChar(options) {
142
+ this.checkOptions("VarChar", options);
129
143
  const message = "Sedentary.VarChar: 'size' argument: Wrong value, expected positive integer";
130
144
  const [maxSize, rest] = this.checkSize(message, options);
131
145
  return new Type({ ...rest, [base]: String, [size]: maxSize, type: "VARCHAR" });
@@ -134,6 +148,16 @@ export class Sedentary {
134
148
  if (!this.db)
135
149
  throw new Error("Package sedentary can't be used directly. Please check: https://www.npmjs.com/package/sedentary#disclaimer");
136
150
  }
151
+ checkOptions(name, options) {
152
+ if (options === undefined)
153
+ return;
154
+ if (typeof options !== "object" || options === null)
155
+ throw new Error(`Sedentary.'${name}': Wrong options type, expected 'Object`);
156
+ const allowedOptions = name === "FKey" ? allowedForeignKeyOptions : attributesWithSize.has(name) ? allowedAttributeOptionsSize : allowedAttributeOptions;
157
+ for (const key in options)
158
+ if (!allowedOptions.includes(key))
159
+ throw new Error(`Sedentary.'${name}': Unknown option '${key}'`);
160
+ }
137
161
  checkOrderBy(order, attributes, modelName) {
138
162
  let array = [];
139
163
  if (!order)
@@ -289,7 +313,7 @@ export class Sedentary {
289
313
  if (!(options instanceof Object))
290
314
  throw new Error(`Sedentary.model: '${modelName}' model: 'options' argument: Wrong type, expected 'Object'`);
291
315
  for (const k in options)
292
- if (!allowedOption.includes(k))
316
+ if (!allowedModelOptions.includes(k))
293
317
  throw new Error(`Sedentary.model: '${modelName}' model: 'options' argument: Unknown '${k}' option`);
294
318
  if (options.int8id && options.parent)
295
319
  throw new Error(`Sedentary.model: '${modelName}' model: 'int8id' and 'parent' options conflict each other`);
@@ -364,11 +388,6 @@ export class Sedentary {
364
388
  })();
365
389
  if (foreignKey) {
366
390
  const options = foreignKey.options || {};
367
- if (foreignKey.options !== undefined && !(foreignKey.options instanceof Object))
368
- throw new Error(`Sedentary.FKey: '${modelName}' model: '${attributeName}' attribute: Wrong options type, expected 'Object'`);
369
- for (const k in options)
370
- if (!["onDelete", "onUpdate"].includes(k))
371
- throw new Error(`Sedentary.FKey: '${modelName}' model: '${attributeName}' attribute: Unknown option '${k}'`);
372
391
  for (const onChange of ["onDelete", "onUpdate"]) {
373
392
  const actions = ["cascade", "no action", "restrict", "set default", "set null"];
374
393
  let action = options[onChange];
@@ -117,6 +117,7 @@ export declare abstract class DB<T extends Transaction> {
117
117
  }
118
118
  export declare class Transaction {
119
119
  private entries;
120
+ private closed;
120
121
  protected log: (message: string) => void;
121
122
  constructor(log: (message: string) => void);
122
123
  addEntry(entry: EntryBase): void;
@@ -6,6 +6,7 @@ export interface AttributeOptions<T, N extends boolean> {
6
6
  notNull?: N;
7
7
  unique?: boolean;
8
8
  }
9
+ export type AttributeOptionsFKey<T, N extends boolean> = ForeignKeyOptions & AttributeOptions<T, N>;
9
10
  export interface AttributeOptionsSize<T, N extends boolean> extends AttributeOptions<T, N> {
10
11
  size?: number;
11
12
  }
@@ -123,7 +124,11 @@ export declare class Sedentary<D extends DB<T>, T extends Transaction> {
123
124
  constructor(options?: SedentaryOptions);
124
125
  Boolean<O extends AttributeOptions<boolean, boolean> | undefined = undefined>(options?: O): Type<boolean, NotNull<O>, unknown>;
125
126
  DateTime<O extends AttributeOptions<Date, boolean> | undefined = undefined>(options?: O): Type<Date, NotNull<O>, unknown>;
126
- FKey<T, E extends EntryBase>(attribute: Attribute<T, boolean, E>, options?: ForeignKeyOptions): Type<T, boolean, E>;
127
+ FKey<T, E extends EntryBase>(attribute: Attribute<T, boolean, E>): Type<T, false, E>;
128
+ FKey<T, E extends EntryBase>(attribute: Attribute<T, boolean, E>, options: {
129
+ notNull: true;
130
+ } & AttributeOptionsFKey<T, boolean>): Type<T, true, E>;
131
+ FKey<T, E extends EntryBase>(attribute: Attribute<T, boolean, E>, options: AttributeOptionsFKey<T, boolean>): Type<T, boolean, E>;
127
132
  Float<O extends AttributeOptionsSize<number, boolean> | undefined = undefined>(options?: O): Type<number, NotNull<O>, unknown>;
128
133
  Int<O extends AttributeOptionsSize<number, boolean> | undefined = undefined>(options?: O): Type<number, NotNull<O>, unknown>;
129
134
  Int8<O extends AttributeOptions<bigint, boolean> | undefined = undefined>(options?: O): Type<bigint, NotNull<O>, unknown>;
@@ -144,6 +149,7 @@ export declare class Sedentary<D extends DB<T>, T extends Transaction> {
144
149
  } & AttributeOptionsSize<S, boolean>): Type<S, true, unknown>;
145
150
  VarChar<S extends string = string>(options: AttributeOptionsSize<S, boolean>): Type<S, boolean, unknown>;
146
151
  private checkDB;
152
+ private checkOptions;
147
153
  private checkOrderBy;
148
154
  private checkSize;
149
155
  private createWhere;
package/package.json CHANGED
@@ -38,5 +38,5 @@
38
38
  "preinstall": "if [ -f Makefile ] ; then make ; fi"
39
39
  },
40
40
  "types": "./dist/types/index.d.ts",
41
- "version": "0.1.1"
41
+ "version": "0.1.3"
42
42
  }