sedentary 0.0.54 → 0.1.0
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 +47 -28
- package/package.json +5 -14
- package/dist/cjs/db.js +0 -179
- package/dist/cjs/index.js +0 -547
- package/dist/es/db.js +0 -172
- package/dist/es/index.js +0 -534
- package/dist/types/db.d.ts +0 -126
- package/dist/types/index.d.ts +0 -147
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# sedentary
|
|
2
2
|
|
|
3
3
|
[![Build Status][travis-badge]][travis-url]
|
|
4
|
-
[![Code
|
|
5
|
-
[![Test Coverage][cover-badge]][
|
|
4
|
+
[![Code Quality][qlty-badge]][qlty-url]
|
|
5
|
+
[![Test Coverage][cover-badge]][qlty-url]
|
|
6
6
|
|
|
7
7
|
[![NPM version][npm-badge]][npm-url]
|
|
8
8
|
[![NPM downloads][npm-downloads-badge]][npm-url]
|
|
@@ -13,27 +13,27 @@
|
|
|
13
13
|
[![Dependents][deps-badge]][npm-url]
|
|
14
14
|
[![Donate][donate-badge]][donate-url]
|
|
15
15
|
|
|
16
|
-
[
|
|
17
|
-
[
|
|
18
|
-
[
|
|
19
|
-
[deps-badge]: https://
|
|
16
|
+
[cover-badge]: https://qlty.sh/gh/iccicci/projects/sedentary/coverage.svg
|
|
17
|
+
[qlty-badge]: https://qlty.sh/gh/iccicci/projects/sedentary/maintainability.svg
|
|
18
|
+
[qlty-url]: https://qlty.sh/gh/iccicci/projects/sedentary
|
|
19
|
+
[deps-badge]: https://img.shields.io/librariesio/dependents/npm/sedentary?logo=npm
|
|
20
20
|
[doc-badge]: https://readthedocs.org/projects/sedentary/badge/?version=latest
|
|
21
21
|
[doc-url]: https://sedentary.readthedocs.io/
|
|
22
|
-
[donate-badge]: https://
|
|
22
|
+
[donate-badge]: https://img.shields.io/static/v1?label=donate&message=bitcoin&color=blue&logo=bitcoin
|
|
23
23
|
[donate-url]: https://blockchain.info/address/1Md9WFAHrXTb3yPBwQWmUfv2RmzrtbHioB
|
|
24
24
|
[github-url]: https://github.com/iccicci/sedentary
|
|
25
|
-
[npm-downloads-badge]: https://
|
|
26
|
-
[npm-badge]: https://
|
|
25
|
+
[npm-downloads-badge]: https://img.shields.io/npm/dw/sedentary?logo=npm
|
|
26
|
+
[npm-badge]: https://img.shields.io/npm/v/sedentary?color=green&logo=npm
|
|
27
27
|
[npm-url]: https://www.npmjs.com/package/sedentary
|
|
28
|
-
[stars-badge]: https://
|
|
29
|
-
[travis-badge]: https://
|
|
28
|
+
[stars-badge]: https://img.shields.io/github/stars/iccicci/sedentary?logo=github&style=flat&color=green
|
|
29
|
+
[travis-badge]: https://img.shields.io/travis/com/iccicci/sedentary?logo=travis
|
|
30
30
|
[travis-url]: https://app.travis-ci.com/github/iccicci/sedentary
|
|
31
|
-
[types-badge]: https://
|
|
32
|
-
|
|
33
|
-
# under development
|
|
31
|
+
[types-badge]: https://img.shields.io/static/v1?label=types&message=included&color=green&logo=typescript
|
|
34
32
|
|
|
35
33
|
# Description
|
|
36
34
|
|
|
35
|
+
This package contains the base logic and types for the Sedentary ORM. **It must not be used directly** because it does not implement any DB engine; use a dedicated extension such as [sedentary-pg](https://www.npmjs.com/package/sedentary-pg) instead.
|
|
36
|
+
|
|
37
37
|
An ORM which automatically syncs the DB schema on models change, no migrations between versions are required.
|
|
38
38
|
|
|
39
39
|
This package is designed **to make easy the process of applying changes to the database after model definition
|
|
@@ -46,19 +46,19 @@ changes to the models (or the database schema). This package tries to solve thes
|
|
|
46
46
|
# Usage
|
|
47
47
|
|
|
48
48
|
```javascript
|
|
49
|
-
import {
|
|
49
|
+
import { SedentaryPG } from "sedentary-pg";
|
|
50
50
|
|
|
51
|
-
const db = new
|
|
51
|
+
const db = new SedentaryPG({ database: "db", user: "user", password: "pass" });
|
|
52
52
|
|
|
53
|
-
|
|
54
|
-
num: db.
|
|
55
|
-
str: db.VarChar(30)
|
|
53
|
+
const Items = db.model("Item", {
|
|
54
|
+
num: db.Int(),
|
|
55
|
+
str: db.VarChar({ size: 30 })
|
|
56
56
|
});
|
|
57
57
|
|
|
58
58
|
(async function () {
|
|
59
59
|
await db.connect();
|
|
60
60
|
|
|
61
|
-
const item = Items
|
|
61
|
+
const item = new Items();
|
|
62
62
|
|
|
63
63
|
item.num = 0;
|
|
64
64
|
item.str = "0";
|
|
@@ -71,6 +71,22 @@ class Items extends db.model("Item", {
|
|
|
71
71
|
})();
|
|
72
72
|
```
|
|
73
73
|
|
|
74
|
+
With TypeScript the instance can be typed using `Entry<typeof Model>`:
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
import { Entry, SedentaryPG } from "sedentary-pg";
|
|
78
|
+
|
|
79
|
+
const db = new SedentaryPG({ database: "db", user: "user", password: "pass" });
|
|
80
|
+
|
|
81
|
+
const Items = db.model("Item", { num: db.Int(), str: db.VarChar({ size: 30 }) });
|
|
82
|
+
type Item = Entry<typeof Items>;
|
|
83
|
+
|
|
84
|
+
const item: Item = new Items();
|
|
85
|
+
|
|
86
|
+
item.num = 0;
|
|
87
|
+
item.str = "0";
|
|
88
|
+
```
|
|
89
|
+
|
|
74
90
|
# Installation
|
|
75
91
|
|
|
76
92
|
With [npm](https://www.npmjs.com/package/sedentary):
|
|
@@ -85,9 +101,9 @@ $ npm install --save sedentary
|
|
|
85
101
|
|
|
86
102
|
A _DB engine dedicated extension_ must be used:
|
|
87
103
|
|
|
88
|
-
- MySQL: planned
|
|
89
|
-
- PostgreSQL: [sedentary-pg](https://
|
|
90
|
-
- SQLite: planned
|
|
104
|
+
- MySQL: in todo, not yet planned
|
|
105
|
+
- PostgreSQL: [sedentary-pg](https://www.npmjs.com/package/sedentary-pg)
|
|
106
|
+
- SQLite: in todo, not yet planned
|
|
91
107
|
|
|
92
108
|
# Documentation
|
|
93
109
|
|
|
@@ -97,13 +113,13 @@ The full documentation is on [sedentary.readthedocs.io](https://sedentary.readth
|
|
|
97
113
|
|
|
98
114
|
Requires:
|
|
99
115
|
|
|
100
|
-
- Node.js: **
|
|
101
|
-
- TypeScript: **
|
|
116
|
+
- Node.js: **v20**
|
|
117
|
+
- TypeScript: **v5.7** (or none if used in a JavaScript project).
|
|
102
118
|
|
|
103
119
|
The package is tested under [all Node.js versions](https://app.travis-ci.com/github/iccicci/sedentary)
|
|
104
120
|
currently supported accordingly to [Node.js Release](https://github.com/nodejs/Release#readme).
|
|
105
121
|
|
|
106
|
-
To work with the package under Windows,
|
|
122
|
+
To work with the package under Windows, `bash.exe` can be configured as the _script-shell_.
|
|
107
123
|
|
|
108
124
|
```
|
|
109
125
|
> npm config set script-shell bash.exe
|
|
@@ -115,9 +131,12 @@ To work with the package under Windows, be sure to configure `bash.exe` as your
|
|
|
115
131
|
|
|
116
132
|
# Bugs
|
|
117
133
|
|
|
118
|
-
|
|
134
|
+
Bugs and inconsistencies can be reported [@github](https://github.com/iccicci/sedentary/issues).
|
|
119
135
|
|
|
120
136
|
# Donating
|
|
121
137
|
|
|
122
|
-
|
|
138
|
+
Satoshis can be donated to this bitcoin address if the package is found useful:
|
|
139
|
+
|
|
140
|
+
<!-- cSpell: disable -->
|
|
141
|
+
|
|
123
142
|
**1Md9WFAHrXTb3yPBwQWmUfv2RmzrtbHioB**
|
package/package.json
CHANGED
|
@@ -7,28 +7,23 @@
|
|
|
7
7
|
],
|
|
8
8
|
"description": "The ORM which never needs to migrate",
|
|
9
9
|
"engines": {
|
|
10
|
-
"node": ">=
|
|
10
|
+
"node": ">=20.19"
|
|
11
11
|
},
|
|
12
12
|
"funding": {
|
|
13
13
|
"url": "https://blockchain.info/address/1Md9WFAHrXTb3yPBwQWmUfv2RmzrtbHioB"
|
|
14
14
|
},
|
|
15
|
-
"homepage": "https://github.com/iccicci/sedentary/packages/sedentary#readme",
|
|
15
|
+
"homepage": "https://github.com/iccicci/sedentary/tree/master/packages/sedentary#readme",
|
|
16
16
|
"keywords": [
|
|
17
17
|
"DB",
|
|
18
18
|
"ORM",
|
|
19
19
|
"database",
|
|
20
20
|
"migration",
|
|
21
|
-
"
|
|
22
|
-
"postgresql",
|
|
23
|
-
"sqlite"
|
|
21
|
+
"postgresql"
|
|
24
22
|
],
|
|
25
23
|
"license": "MIT",
|
|
26
24
|
"main": "./dist/cjs/index.js",
|
|
27
25
|
"module": "./dist/es/index.js",
|
|
28
26
|
"name": "sedentary",
|
|
29
|
-
"optionalDependencies": {
|
|
30
|
-
"fsevents": "^2.3.3"
|
|
31
|
-
},
|
|
32
27
|
"readmeFilename": "README.md",
|
|
33
28
|
"repository": {
|
|
34
29
|
"type": "git",
|
|
@@ -36,12 +31,8 @@
|
|
|
36
31
|
},
|
|
37
32
|
"scripts": {
|
|
38
33
|
"build": "make build",
|
|
39
|
-
"coverage": "jest --coverage --no-cache --runInBand",
|
|
40
34
|
"deploy": "make deploy",
|
|
41
|
-
"
|
|
42
|
-
"preinstall": "if [ -f Makefile ] ; then make ; fi",
|
|
43
|
-
"pretest": "make pretest",
|
|
44
|
-
"test": "jest --no-cache --runInBand"
|
|
35
|
+
"preinstall": "if [ -f Makefile ] ; then make ; fi"
|
|
45
36
|
},
|
|
46
37
|
"tsd": {
|
|
47
38
|
"compilerOptions": {
|
|
@@ -61,5 +52,5 @@
|
|
|
61
52
|
}
|
|
62
53
|
},
|
|
63
54
|
"types": "./dist/types/index.d.ts",
|
|
64
|
-
"version": "0.0
|
|
55
|
+
"version": "0.1.0"
|
|
65
56
|
}
|
package/dist/cjs/db.js
DELETED
|
@@ -1,179 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.deepDiff = exports.deepCopy = exports.Transaction = exports.DB = exports.Table = exports.Attribute = exports.Type = exports.EntryBase = exports.transaction = exports.size = exports.loaded = exports.base = exports.actions = void 0;
|
|
4
|
-
exports.actions = Symbol("actions");
|
|
5
|
-
exports.base = Symbol("base");
|
|
6
|
-
exports.loaded = Symbol("loaded");
|
|
7
|
-
exports.size = Symbol("size");
|
|
8
|
-
exports.transaction = Symbol("transaction");
|
|
9
|
-
class EntryBase {
|
|
10
|
-
constructor(from) {
|
|
11
|
-
if (from === "load")
|
|
12
|
-
this.preLoad();
|
|
13
|
-
else {
|
|
14
|
-
if (from)
|
|
15
|
-
Object.assign(this, from);
|
|
16
|
-
this.construct();
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
construct() { }
|
|
20
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
21
|
-
postCommit(actions) { }
|
|
22
|
-
postLoad() { }
|
|
23
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
24
|
-
postRemove(deletedRecords) { }
|
|
25
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
26
|
-
postSave(savedRecords) { }
|
|
27
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
28
|
-
preCommit(actions) { }
|
|
29
|
-
preLoad() { }
|
|
30
|
-
preRemove() { }
|
|
31
|
-
preSave() { }
|
|
32
|
-
async remove() {
|
|
33
|
-
return false;
|
|
34
|
-
}
|
|
35
|
-
async save() {
|
|
36
|
-
return false;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
exports.EntryBase = EntryBase;
|
|
40
|
-
class Type {
|
|
41
|
-
constructor(from) {
|
|
42
|
-
Object.assign(this, from);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
exports.Type = Type;
|
|
46
|
-
class Attribute extends Type {
|
|
47
|
-
constructor(from) {
|
|
48
|
-
super(from);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
exports.Attribute = Attribute;
|
|
52
|
-
function autoImplement() {
|
|
53
|
-
return class {
|
|
54
|
-
constructor(defaults) {
|
|
55
|
-
Object.assign(this, defaults);
|
|
56
|
-
}
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
class Table extends autoImplement() {
|
|
60
|
-
findAttribute(name) {
|
|
61
|
-
return this.attributes.filter(_ => _.attributeName === name)[0];
|
|
62
|
-
}
|
|
63
|
-
findField(name) {
|
|
64
|
-
return this.attributes.filter(_ => _.fieldName === name)[0];
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
exports.Table = Table;
|
|
68
|
-
class DB {
|
|
69
|
-
constructor(log) {
|
|
70
|
-
this.tables = [];
|
|
71
|
-
this.sync = true;
|
|
72
|
-
this.log = log;
|
|
73
|
-
}
|
|
74
|
-
findTable(name) {
|
|
75
|
-
return this.tables.filter(_ => _.tableName === name)[0];
|
|
76
|
-
}
|
|
77
|
-
indexesEq(a, b) {
|
|
78
|
-
if (a.fields.length !== b.fields.length)
|
|
79
|
-
return false;
|
|
80
|
-
for (const i in a.fields)
|
|
81
|
-
if (a.fields[i] !== b.fields[i])
|
|
82
|
-
return false;
|
|
83
|
-
if (a.type !== b.type)
|
|
84
|
-
return false;
|
|
85
|
-
if (a.unique !== b.unique)
|
|
86
|
-
return false;
|
|
87
|
-
return true;
|
|
88
|
-
}
|
|
89
|
-
async syncDataBase() {
|
|
90
|
-
for (const table of this.tables) {
|
|
91
|
-
this.sync = table.sync;
|
|
92
|
-
await this.syncTable(table);
|
|
93
|
-
const indexes = await this.dropConstraints(table);
|
|
94
|
-
await this.dropIndexes(table, indexes);
|
|
95
|
-
await this.dropFields(table);
|
|
96
|
-
await this.syncFields(table);
|
|
97
|
-
await this.syncSequence(table);
|
|
98
|
-
await this.syncConstraints(table);
|
|
99
|
-
await this.syncIndexes(table);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
syncLog(message) {
|
|
103
|
-
this.log(this.sync ? message : "NOT SYNCING: " + message);
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
exports.DB = DB;
|
|
107
|
-
class Transaction {
|
|
108
|
-
constructor(log) {
|
|
109
|
-
this.entries = [];
|
|
110
|
-
this.log = log;
|
|
111
|
-
}
|
|
112
|
-
addEntry(entry) {
|
|
113
|
-
Object.defineProperty(entry, exports.transaction, { configurable: true, value: this });
|
|
114
|
-
this.entries.push(entry);
|
|
115
|
-
}
|
|
116
|
-
clean() {
|
|
117
|
-
const { entries } = this;
|
|
118
|
-
for (const entry of entries) {
|
|
119
|
-
Object.defineProperty(entry, exports.actions, { configurable: true, value: undefined });
|
|
120
|
-
Object.defineProperty(entry, exports.transaction, { configurable: true, value: undefined });
|
|
121
|
-
}
|
|
122
|
-
this.entries = [];
|
|
123
|
-
}
|
|
124
|
-
async commit() {
|
|
125
|
-
const { entries } = this;
|
|
126
|
-
for (const entry of entries)
|
|
127
|
-
if (entry[exports.actions])
|
|
128
|
-
entry.postCommit(entry[exports.actions]);
|
|
129
|
-
this.clean();
|
|
130
|
-
}
|
|
131
|
-
preCommit() {
|
|
132
|
-
const { entries } = this;
|
|
133
|
-
for (const entry of entries)
|
|
134
|
-
if (entry[exports.actions])
|
|
135
|
-
entry.preCommit(entry[exports.actions]);
|
|
136
|
-
}
|
|
137
|
-
async rollback() {
|
|
138
|
-
this.clean();
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
exports.Transaction = Transaction;
|
|
142
|
-
const sortedEntries = (obj) => Object.entries(obj).sort((entryA, entryB) => (entryA[0] > entryB[0] ? -1 : 1));
|
|
143
|
-
function deepCopy(o) {
|
|
144
|
-
if (!o || typeof o !== "object")
|
|
145
|
-
return o;
|
|
146
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
147
|
-
const [ret, entries] = o instanceof Array ? [new Array(o.length), o.entries()] : [{}, Object.entries(o)];
|
|
148
|
-
for (const [k, v] of entries)
|
|
149
|
-
ret[k] = deepCopy(v);
|
|
150
|
-
return ret;
|
|
151
|
-
}
|
|
152
|
-
exports.deepCopy = deepCopy;
|
|
153
|
-
function deepDiff(a, b) {
|
|
154
|
-
if (typeof a !== "object")
|
|
155
|
-
return a !== b;
|
|
156
|
-
if (typeof b !== "object")
|
|
157
|
-
return true;
|
|
158
|
-
if (a === null)
|
|
159
|
-
return b !== null;
|
|
160
|
-
if (b === null)
|
|
161
|
-
return true;
|
|
162
|
-
if (a instanceof Array) {
|
|
163
|
-
if (!(b instanceof Array))
|
|
164
|
-
return true;
|
|
165
|
-
for (const [i, value] of a.entries())
|
|
166
|
-
if (deepDiff(value, b[i]))
|
|
167
|
-
return true;
|
|
168
|
-
return false;
|
|
169
|
-
}
|
|
170
|
-
const entriesA = sortedEntries(a);
|
|
171
|
-
const entriesB = sortedEntries(b);
|
|
172
|
-
if (entriesA.length !== entriesB.length)
|
|
173
|
-
return true;
|
|
174
|
-
for (const [i, [key, value]] of entriesA.entries())
|
|
175
|
-
if (key !== entriesB[i][0] || deepDiff(value, entriesB[i][1]))
|
|
176
|
-
return true;
|
|
177
|
-
return false;
|
|
178
|
-
}
|
|
179
|
-
exports.deepDiff = deepDiff;
|