@ghom/orm 1.1.1 → 1.2.1

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.
@@ -25,7 +25,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
25
25
  exports.ORM = void 0;
26
26
  const handler_1 = require("@ghom/handler");
27
27
  const knex_1 = __importDefault(require("knex"));
28
- const table_1 = require("./table");
28
+ const table_js_1 = require("./table.js");
29
29
  class ORM extends handler_1.Handler {
30
30
  /**
31
31
  * @param ormConfig configuration for table handler or just tablePath (path to directory that contains js files of tables)
@@ -48,7 +48,7 @@ class ORM extends handler_1.Handler {
48
48
  const tables = await Promise.all(pathList.map(async (filepath) => {
49
49
  return Promise.resolve().then(() => __importStar(require(filepath))).then((file) => file.default);
50
50
  }));
51
- const migration = new table_1.Table({
51
+ const migration = new table_js_1.Table({
52
52
  name: "migration",
53
53
  priority: Infinity,
54
54
  setup: (table) => {
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.Table = void 0;
7
+ const path_1 = __importDefault(require("path"));
8
+ const chalk_1 = __importDefault(require("chalk"));
9
+ class Table {
10
+ constructor(options) {
11
+ this.options = options;
12
+ }
13
+ get filepath() {
14
+ if (!this.orm)
15
+ throw new Error("missing ORM");
16
+ return path_1.default.relative(process.cwd(), path_1.default.join(this.orm.ormConfig.tablePath, this.options.name + ".ts"));
17
+ }
18
+ get logger() {
19
+ if (!this.orm)
20
+ throw new Error("missing ORM");
21
+ return this.orm.ormConfig.logger;
22
+ }
23
+ get db() {
24
+ if (!this.orm)
25
+ throw new Error("missing ORM");
26
+ return this.orm.db;
27
+ }
28
+ get query() {
29
+ return this.db(this.options.name);
30
+ }
31
+ async hasColumn(name) {
32
+ return this.db.schema.hasColumn(this.options.name, name);
33
+ }
34
+ async isEmpty() {
35
+ return this.query
36
+ .select()
37
+ .limit(1)
38
+ .then((rows) => rows.length === 0);
39
+ }
40
+ async make() {
41
+ try {
42
+ await this.db.schema.createTable(this.options.name, this.options.setup);
43
+ this.logger?.log(`created table ${chalk_1.default.blueBright(this.options.name)}`);
44
+ }
45
+ catch (error) {
46
+ if (error.toString().includes("syntax error")) {
47
+ this.logger?.error(`you need to implement the "setup" method in options of your ${chalk_1.default.blueBright(this.options.name)} table!`, this.filepath);
48
+ throw error;
49
+ }
50
+ else {
51
+ this.logger?.log(`loaded table ${chalk_1.default.blueBright(this.options.name)}`);
52
+ }
53
+ }
54
+ try {
55
+ const migrated = await this.migrate();
56
+ if (migrated !== false) {
57
+ this.logger?.log(`migrated table ${chalk_1.default.blueBright(this.options.name)} to version ${chalk_1.default.magentaBright(migrated)}`);
58
+ }
59
+ }
60
+ catch (error) {
61
+ this.logger?.error(error, this.filepath);
62
+ }
63
+ await this.options.then?.bind(this)(this);
64
+ return this;
65
+ }
66
+ async migrate() {
67
+ if (!this.options.migrations)
68
+ return false;
69
+ const migrations = new Map(Object.entries(this.options.migrations)
70
+ .sort((a, b) => Number(a[0]) - Number(b[0]))
71
+ .map((entry) => [Number(entry[0]), entry[1]]));
72
+ const fromDatabase = await this.db("migration")
73
+ .where("table", this.options.name)
74
+ .first();
75
+ const data = fromDatabase || {
76
+ table: this.options.name,
77
+ version: -Infinity,
78
+ };
79
+ const baseVersion = data.version;
80
+ await this.db.schema.alterTable(this.options.name, (builder) => {
81
+ migrations.forEach((migration, version) => {
82
+ if (version <= data.version)
83
+ return;
84
+ migration(builder);
85
+ data.version = version;
86
+ });
87
+ });
88
+ await this.db("migration")
89
+ .insert(data)
90
+ .onConflict("table")
91
+ .merge();
92
+ return baseVersion === data.version ? false : data.version;
93
+ }
94
+ }
95
+ exports.Table = Table;
@@ -10,5 +10,5 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
10
10
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
11
11
  };
12
12
  Object.defineProperty(exports, "__esModule", { value: true });
13
- __exportStar(require("./app/orm"), exports);
14
- __exportStar(require("./app/table"), exports);
13
+ __exportStar(require("./app/orm.js"), exports);
14
+ __exportStar(require("./app/table.js"), exports);
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "commonjs"
3
+ }
@@ -0,0 +1,49 @@
1
+ import { Handler } from "@ghom/handler";
2
+ import { default as knex } from "knex";
3
+ import { Table } from "./table.js";
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
+ }
@@ -1,14 +1,15 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Table = void 0;
4
- class Table {
1
+ import path from "path";
2
+ import chalk from "chalk";
3
+ export class Table {
4
+ options;
5
+ orm;
5
6
  constructor(options) {
6
7
  this.options = options;
7
8
  }
8
- get verbose() {
9
+ get filepath() {
9
10
  if (!this.orm)
10
11
  throw new Error("missing ORM");
11
- return !!this.orm.ormConfig.logger;
12
+ return path.relative(process.cwd(), path.join(this.orm.ormConfig.tablePath, this.options.name + ".ts"));
12
13
  }
13
14
  get logger() {
14
15
  if (!this.orm)
@@ -35,25 +36,25 @@ class Table {
35
36
  async make() {
36
37
  try {
37
38
  await this.db.schema.createTable(this.options.name, this.options.setup);
38
- this.logger?.log(`created table ${this.options.name}`);
39
+ this.logger?.log(`created table ${chalk.blueBright(this.options.name)}`);
39
40
  }
40
41
  catch (error) {
41
42
  if (error.toString().includes("syntax error")) {
42
- this.logger?.error(`you need to implement the "setup" method in options of your ${this.options.name} table!`);
43
+ this.logger?.error(`you need to implement the "setup" method in options of your ${chalk.blueBright(this.options.name)} table!`, this.filepath);
43
44
  throw error;
44
45
  }
45
46
  else {
46
- this.logger?.log("loaded table", this.options.name);
47
+ this.logger?.log(`loaded table ${chalk.blueBright(this.options.name)}`);
47
48
  }
48
49
  }
49
50
  try {
50
51
  const migrated = await this.migrate();
51
52
  if (migrated !== false) {
52
- this.logger?.log("migrated table", this.options.name, "to version", migrated);
53
+ this.logger?.log(`migrated table ${chalk.blueBright(this.options.name)} to version ${chalk.magentaBright(migrated)}`);
53
54
  }
54
55
  }
55
56
  catch (error) {
56
- this.logger?.error(error);
57
+ this.logger?.error(error, this.filepath);
57
58
  }
58
59
  await this.options.then?.bind(this)(this);
59
60
  return this;
@@ -87,4 +88,3 @@ class Table {
87
88
  return baseVersion === data.version ? false : data.version;
88
89
  }
89
90
  }
90
- exports.Table = Table;
@@ -0,0 +1,2 @@
1
+ export * from "./app/orm.js";
2
+ export * from "./app/table.js";
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "module"
3
+ }
@@ -1,8 +1,8 @@
1
1
  import { Handler } from "@ghom/handler";
2
2
  import { Knex } from "knex";
3
3
  export interface ORMLogger {
4
- log: (message: string | number, ...parts: (string | number)[]) => unknown;
5
- error: (err: Error | string | number, ...parts: (string | number)[]) => unknown;
4
+ log: (message: string, section?: string) => void;
5
+ error: (text: string | Error, _path: string, full?: boolean) => void;
6
6
  }
7
7
  /**
8
8
  * @property tablePath - path to directory that contains js files of tables
@@ -17,7 +17,7 @@ export declare class Table<Type> {
17
17
  readonly options: TableOptions<Type>;
18
18
  orm?: ORM;
19
19
  constructor(options: TableOptions<Type>);
20
- private get verbose();
20
+ private get filepath();
21
21
  private get logger();
22
22
  get db(): Knex<any, Record<string, any>[]>;
23
23
  get query(): Knex.QueryBuilder<Type, {
@@ -0,0 +1,2 @@
1
+ export * from "./app/orm.js";
2
+ export * from "./app/table.js";
package/fixup.sh ADDED
@@ -0,0 +1,11 @@
1
+ cat >dist/cjs/package.json <<!EOF
2
+ {
3
+ "type": "commonjs"
4
+ }
5
+ !EOF
6
+
7
+ cat >dist/esm/package.json <<!EOF
8
+ {
9
+ "type": "module"
10
+ }
11
+ !EOF
package/package.json CHANGED
@@ -1,16 +1,21 @@
1
1
  {
2
2
  "name": "@ghom/orm",
3
- "version": "1.1.1",
3
+ "version": "1.2.1",
4
4
  "license": "MIT",
5
- "main": "dist/index.js",
6
- "types": "dist/index.d.ts",
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
  },
@@ -24,6 +29,7 @@
24
29
  },
25
30
  "dependencies": {
26
31
  "@ghom/handler": "^1.1.0",
32
+ "chalk": "^4.1.2",
27
33
  "knex": "^1.0.3"
28
34
  }
29
35
  }
package/src/app/orm.ts CHANGED
@@ -1,13 +1,10 @@
1
1
  import { Handler } from "@ghom/handler"
2
2
  import { Knex, default as knex } from "knex"
3
- import { MigrationData, Table } from "./table"
3
+ import { MigrationData, Table } from "./table.js"
4
4
 
5
5
  export interface ORMLogger {
6
- log: (message: string | number, ...parts: (string | number)[]) => unknown
7
- error: (
8
- err: Error | string | number,
9
- ...parts: (string | number)[]
10
- ) => unknown
6
+ log: (message: string, section?: string) => void
7
+ error: (text: string | Error, _path: string, full?: boolean) => void
11
8
  }
12
9
 
13
10
  /**
package/src/app/table.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import path from "path"
2
+ import chalk from "chalk"
1
3
  import { Knex } from "knex"
2
4
  import { ORM } from "./orm.js"
3
5
 
@@ -19,9 +21,12 @@ export class Table<Type> {
19
21
 
20
22
  constructor(public readonly options: TableOptions<Type>) {}
21
23
 
22
- private get verbose() {
24
+ private get filepath() {
23
25
  if (!this.orm) throw new Error("missing ORM")
24
- return !!this.orm.ormConfig.logger
26
+ return path.relative(
27
+ process.cwd(),
28
+ path.join(this.orm.ormConfig.tablePath, this.options.name + ".ts")
29
+ )
25
30
  }
26
31
 
27
32
  private get logger() {
@@ -52,16 +57,19 @@ export class Table<Type> {
52
57
  async make(): Promise<this> {
53
58
  try {
54
59
  await this.db.schema.createTable(this.options.name, this.options.setup)
55
- this.logger?.log(`created table ${this.options.name}`)
60
+ this.logger?.log(`created table ${chalk.blueBright(this.options.name)}`)
56
61
  } catch (error: any) {
57
62
  if (error.toString().includes("syntax error")) {
58
63
  this.logger?.error(
59
- `you need to implement the "setup" method in options of your ${this.options.name} table!`
64
+ `you need to implement the "setup" method in options of your ${chalk.blueBright(
65
+ this.options.name
66
+ )} table!`,
67
+ this.filepath
60
68
  )
61
69
 
62
70
  throw error
63
71
  } else {
64
- this.logger?.log("loaded table", this.options.name)
72
+ this.logger?.log(`loaded table ${chalk.blueBright(this.options.name)}`)
65
73
  }
66
74
  }
67
75
 
@@ -70,14 +78,13 @@ export class Table<Type> {
70
78
 
71
79
  if (migrated !== false) {
72
80
  this.logger?.log(
73
- "migrated table",
74
- this.options.name,
75
- "to version",
76
- migrated
81
+ `migrated table ${chalk.blueBright(
82
+ this.options.name
83
+ )} to version ${chalk.magentaBright(migrated)}`
77
84
  )
78
85
  }
79
86
  } catch (error: any) {
80
- this.logger?.error(error)
87
+ this.logger?.error(error, this.filepath)
81
88
  }
82
89
 
83
90
  await this.options.then?.bind(this)(this)
package/src/index.ts CHANGED
@@ -1,2 +1,2 @@
1
- export * from "./app/orm"
2
- export * from "./app/table"
1
+ export * from "./app/orm.js"
2
+ export * from "./app/table.js"
package/tests/tables/a.js CHANGED
@@ -1,4 +1,4 @@
1
- const { Table } = require("../../dist/index")
1
+ const { Table } = require("../..")
2
2
 
3
3
  module.exports = new Table({
4
4
  name: "a",
package/tests/tables/b.js CHANGED
@@ -1,4 +1,4 @@
1
- const { Table } = require("../../dist/index")
1
+ const { Table } = require("../..")
2
2
 
3
3
  module.exports = new Table({
4
4
  name: "b",
package/tests/tables/c.js CHANGED
@@ -1,4 +1,4 @@
1
- const { Table } = require("../../dist/index")
1
+ const { Table } = require("../..")
2
2
 
3
3
  module.exports = new Table({
4
4
  name: "c",
package/tests/test.js CHANGED
@@ -1,6 +1,6 @@
1
1
  require("dotenv").config({ path: "./.env" })
2
2
  const path = require("path")
3
- const { ORM } = require("../dist/index")
3
+ const { ORM } = require("..")
4
4
  const a = require("./tables/a")
5
5
  const b = require("./tables/b")
6
6
  const c = require("./tables/c")
@@ -0,0 +1,10 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "compilerOptions": {
4
+ "outDir": "dist/cjs",
5
+ "module": "CommonJS",
6
+ "target": "es2020",
7
+ "declaration": true,
8
+ "declarationDir": "dist/typings"
9
+ }
10
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "compilerOptions": {
4
+ "outDir": "dist/esm",
5
+ "module": "esnext",
6
+ "target": "esnext",
7
+ }
8
+ }
package/tsconfig.json CHANGED
@@ -1,13 +1,11 @@
1
1
  {
2
2
  "compilerOptions": {
3
3
  "strict": true,
4
- "outDir": "dist",
5
4
  "rootDir": "src",
6
- "module": "CommonJS",
7
5
  "target": "es2020",
6
+ "module": "CommonJS",
8
7
  "lib": ["es2020", "dom"],
9
8
  "moduleResolution": "Node",
10
- "esModuleInterop": true,
11
- "declaration": true
9
+ "esModuleInterop": true
12
10
  }
13
11
  }
package/dist/index.d.ts DELETED
@@ -1,2 +0,0 @@
1
- export * from "./app/orm";
2
- export * from "./app/table";