@ghom/orm 1.1.2 → 1.2.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/dist/{app → cjs/app}/orm.js +0 -0
- package/dist/{app → cjs/app}/table.js +0 -0
- package/dist/{index.js → cjs/index.js} +0 -0
- package/dist/cjs/package.json +3 -0
- package/dist/esm/app/orm.js +49 -0
- package/dist/esm/app/table.js +90 -0
- package/dist/{index.d.ts → esm/index.js} +0 -0
- package/dist/esm/package.json +3 -0
- package/dist/{app → typings/app}/orm.d.ts +0 -0
- package/dist/{app → typings/app}/table.d.ts +0 -0
- package/dist/typings/index.d.ts +2 -0
- package/fixup.sh +11 -0
- package/package.json +9 -4
- package/tests/tables/a.js +1 -1
- package/tests/tables/b.js +1 -1
- package/tests/tables/c.js +1 -1
- package/tests/test.js +1 -1
- package/tsconfig-cjs.json +10 -0
- package/tsconfig-esm.json +8 -0
- package/tsconfig.json +1 -4
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { Handler } from "@ghom/handler";
|
|
2
|
+
import { default as knex } from "knex";
|
|
3
|
+
import { Table } from "./table";
|
|
4
|
+
export class ORM extends Handler {
|
|
5
|
+
db;
|
|
6
|
+
ormConfig;
|
|
7
|
+
/**
|
|
8
|
+
* @param ormConfig configuration for table handler or just tablePath (path to directory that contains js files of tables)
|
|
9
|
+
* @param knexConfig configuration for connect to database
|
|
10
|
+
*/
|
|
11
|
+
constructor(ormConfig, knexConfig = {
|
|
12
|
+
client: "sqlite3",
|
|
13
|
+
useNullAsDefault: true,
|
|
14
|
+
connection: {
|
|
15
|
+
filename: ":memory:",
|
|
16
|
+
},
|
|
17
|
+
}) {
|
|
18
|
+
super(typeof ormConfig === "string" ? ormConfig : ormConfig.tablePath);
|
|
19
|
+
this.ormConfig =
|
|
20
|
+
typeof ormConfig === "string" ? { tablePath: ormConfig } : ormConfig;
|
|
21
|
+
this.db = knex(knexConfig);
|
|
22
|
+
}
|
|
23
|
+
async init() {
|
|
24
|
+
this.once("finish", async (pathList) => {
|
|
25
|
+
const tables = await Promise.all(pathList.map(async (filepath) => {
|
|
26
|
+
return import(filepath).then((file) => file.default);
|
|
27
|
+
}));
|
|
28
|
+
const migration = new Table({
|
|
29
|
+
name: "migration",
|
|
30
|
+
priority: Infinity,
|
|
31
|
+
setup: (table) => {
|
|
32
|
+
table.string("table").unique().notNullable();
|
|
33
|
+
table.integer("version").notNullable();
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
migration.orm = this;
|
|
37
|
+
await migration.make();
|
|
38
|
+
for (const table of tables.sort((a, b) => (b.options.priority ?? 0) - (a.options.priority ?? 0))) {
|
|
39
|
+
table.orm = this;
|
|
40
|
+
await table.make();
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
try {
|
|
44
|
+
await this.db.raw("PRAGMA foreign_keys = ON;");
|
|
45
|
+
}
|
|
46
|
+
catch (error) { }
|
|
47
|
+
await this.load();
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
export class Table {
|
|
4
|
+
options;
|
|
5
|
+
orm;
|
|
6
|
+
constructor(options) {
|
|
7
|
+
this.options = options;
|
|
8
|
+
}
|
|
9
|
+
get filepath() {
|
|
10
|
+
if (!this.orm)
|
|
11
|
+
throw new Error("missing ORM");
|
|
12
|
+
return path.relative(process.cwd(), path.join(this.orm.ormConfig.tablePath, this.options.name + ".ts"));
|
|
13
|
+
}
|
|
14
|
+
get logger() {
|
|
15
|
+
if (!this.orm)
|
|
16
|
+
throw new Error("missing ORM");
|
|
17
|
+
return this.orm.ormConfig.logger;
|
|
18
|
+
}
|
|
19
|
+
get db() {
|
|
20
|
+
if (!this.orm)
|
|
21
|
+
throw new Error("missing ORM");
|
|
22
|
+
return this.orm.db;
|
|
23
|
+
}
|
|
24
|
+
get query() {
|
|
25
|
+
return this.db(this.options.name);
|
|
26
|
+
}
|
|
27
|
+
async hasColumn(name) {
|
|
28
|
+
return this.db.schema.hasColumn(this.options.name, name);
|
|
29
|
+
}
|
|
30
|
+
async isEmpty() {
|
|
31
|
+
return this.query
|
|
32
|
+
.select()
|
|
33
|
+
.limit(1)
|
|
34
|
+
.then((rows) => rows.length === 0);
|
|
35
|
+
}
|
|
36
|
+
async make() {
|
|
37
|
+
try {
|
|
38
|
+
await this.db.schema.createTable(this.options.name, this.options.setup);
|
|
39
|
+
this.logger?.log(`created table ${chalk.blueBright(this.options.name)}`);
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
if (error.toString().includes("syntax error")) {
|
|
43
|
+
this.logger?.error(`you need to implement the "setup" method in options of your ${chalk.blueBright(this.options.name)} table!`, this.filepath);
|
|
44
|
+
throw error;
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
this.logger?.log(`loaded table ${chalk.blueBright(this.options.name)}`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
try {
|
|
51
|
+
const migrated = await this.migrate();
|
|
52
|
+
if (migrated !== false) {
|
|
53
|
+
this.logger?.log(`migrated table ${chalk.blueBright(this.options.name)} to version ${chalk.magentaBright(migrated)}`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
this.logger?.error(error, this.filepath);
|
|
58
|
+
}
|
|
59
|
+
await this.options.then?.bind(this)(this);
|
|
60
|
+
return this;
|
|
61
|
+
}
|
|
62
|
+
async migrate() {
|
|
63
|
+
if (!this.options.migrations)
|
|
64
|
+
return false;
|
|
65
|
+
const migrations = new Map(Object.entries(this.options.migrations)
|
|
66
|
+
.sort((a, b) => Number(a[0]) - Number(b[0]))
|
|
67
|
+
.map((entry) => [Number(entry[0]), entry[1]]));
|
|
68
|
+
const fromDatabase = await this.db("migration")
|
|
69
|
+
.where("table", this.options.name)
|
|
70
|
+
.first();
|
|
71
|
+
const data = fromDatabase || {
|
|
72
|
+
table: this.options.name,
|
|
73
|
+
version: -Infinity,
|
|
74
|
+
};
|
|
75
|
+
const baseVersion = data.version;
|
|
76
|
+
await this.db.schema.alterTable(this.options.name, (builder) => {
|
|
77
|
+
migrations.forEach((migration, version) => {
|
|
78
|
+
if (version <= data.version)
|
|
79
|
+
return;
|
|
80
|
+
migration(builder);
|
|
81
|
+
data.version = version;
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
await this.db("migration")
|
|
85
|
+
.insert(data)
|
|
86
|
+
.onConflict("table")
|
|
87
|
+
.merge();
|
|
88
|
+
return baseVersion === data.version ? false : data.version;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/fixup.sh
ADDED
package/package.json
CHANGED
|
@@ -1,16 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ghom/orm",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"license": "MIT",
|
|
5
|
-
"main": "dist/index.js",
|
|
6
|
-
"
|
|
5
|
+
"main": "dist/cjs/index.js",
|
|
6
|
+
"module": "dist/esm/index.js",
|
|
7
|
+
"types": "dist/typings/index.d.ts",
|
|
7
8
|
"description": "TypeScript KnexJS ORM & handler",
|
|
8
9
|
"prettier": {
|
|
9
10
|
"semi": false
|
|
10
11
|
},
|
|
12
|
+
"exports": {
|
|
13
|
+
"import": "./dist/esm/index.js",
|
|
14
|
+
"require": "./dist/cjs/index.js"
|
|
15
|
+
},
|
|
11
16
|
"scripts": {
|
|
12
17
|
"format": "prettier --write src tsconfig.*",
|
|
13
|
-
"build": "tsc",
|
|
18
|
+
"build": "rm -fr dist/* && tsc -p tsconfig-esm.json && tsc -p tsconfig-cjs.json && fixup.sh",
|
|
14
19
|
"test": "npm run build && jest tests/test.js --detectOpenHandles",
|
|
15
20
|
"prepublishOnly": "npm run format && npm test"
|
|
16
21
|
},
|
package/tests/tables/a.js
CHANGED
package/tests/tables/b.js
CHANGED
package/tests/tables/c.js
CHANGED
package/tests/test.js
CHANGED
package/tsconfig.json
CHANGED
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"compilerOptions": {
|
|
3
3
|
"strict": true,
|
|
4
|
-
"outDir": "dist",
|
|
5
4
|
"rootDir": "src",
|
|
6
|
-
"module": "CommonJS",
|
|
7
5
|
"target": "es2020",
|
|
8
6
|
"lib": ["es2020", "dom"],
|
|
9
7
|
"moduleResolution": "Node",
|
|
10
|
-
"esModuleInterop": true
|
|
11
|
-
"declaration": true
|
|
8
|
+
"esModuleInterop": true
|
|
12
9
|
}
|
|
13
10
|
}
|