@ghom/orm 1.6.0 → 1.7.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.
@@ -33,6 +33,7 @@ const path_1 = __importDefault(require("path"));
33
33
  const handler_1 = require("@ghom/handler");
34
34
  const knex_1 = __importDefault(require("knex"));
35
35
  const table_js_1 = require("./table.js");
36
+ const defaultBackupDir = path_1.default.join(process.cwd(), "backup");
36
37
  const pack = JSON.parse(fs_1.default.readFileSync(path_1.default.join(process.cwd(), "package.json"), "utf8"));
37
38
  const isCJS = pack.type === "commonjs" || pack.type == void 0;
38
39
  class ORM {
@@ -86,55 +87,8 @@ class ORM {
86
87
  await table.make();
87
88
  }
88
89
  }
89
- async raw(sql) {
90
+ raw(sql) {
90
91
  return this.database.raw(sql);
91
92
  }
92
- /**
93
- * Extract the database to a CSV file.
94
- */
95
- async extract(dir = process.cwd()) {
96
- const tables = [...this.handler.elements.values()];
97
- for (const table of tables) {
98
- await this.database
99
- .select()
100
- .from(table.options.name)
101
- .then((rows) => {
102
- const csv = rows.map((row) => Object.values(row).join(",")).join("\n");
103
- fs_1.default.writeFileSync(path_1.default.join(dir, `${table.options.name}.csv`), csv, "utf8");
104
- });
105
- }
106
- }
107
- /**
108
- * Import a CSV file to the database.
109
- */
110
- async import(dir = process.cwd()) {
111
- const tables = [...this.handler.elements.values()].sort((a, b) => (b.options.priority ?? 0) - (a.options.priority ?? 0));
112
- for (const table of tables) {
113
- const columnInfo = await table.getColumns();
114
- let csv;
115
- try {
116
- csv = fs_1.default.readFileSync(path_1.default.join(dir, `${table.options.name}.csv`), "utf8");
117
- }
118
- catch (error) {
119
- continue;
120
- }
121
- if (csv.trim().length === 0)
122
- continue;
123
- const rows = csv
124
- .split("\n")
125
- .map((row) => row.split(","))
126
- .map((row) => {
127
- const data = {};
128
- let index = 0;
129
- for (const [name, info] of Object.entries(columnInfo)) {
130
- data[name] =
131
- info.type === "integer" ? Number(row[index]) : row[index];
132
- index++;
133
- }
134
- return data;
135
- });
136
- await this.database(table.options.name).insert(rows);
137
- }
138
- }
139
93
  }
140
94
  exports.ORM = ORM;
@@ -4,6 +4,7 @@ import path from "path";
4
4
  import { Handler } from "@ghom/handler";
5
5
  import { default as knex } from "knex";
6
6
  import { Table } from "./table.js";
7
+ const defaultBackupDir = path.join(process.cwd(), "backup");
7
8
  const pack = JSON.parse(fs.readFileSync(path.join(process.cwd(), "package.json"), "utf8"));
8
9
  const isCJS = pack.type === "commonjs" || pack.type == void 0;
9
10
  export class ORM {
@@ -60,54 +61,7 @@ export class ORM {
60
61
  await table.make();
61
62
  }
62
63
  }
63
- async raw(sql) {
64
+ raw(sql) {
64
65
  return this.database.raw(sql);
65
66
  }
66
- /**
67
- * Extract the database to a CSV file.
68
- */
69
- async extract(dir = process.cwd()) {
70
- const tables = [...this.handler.elements.values()];
71
- for (const table of tables) {
72
- await this.database
73
- .select()
74
- .from(table.options.name)
75
- .then((rows) => {
76
- const csv = rows.map((row) => Object.values(row).join(",")).join("\n");
77
- fs.writeFileSync(path.join(dir, `${table.options.name}.csv`), csv, "utf8");
78
- });
79
- }
80
- }
81
- /**
82
- * Import a CSV file to the database.
83
- */
84
- async import(dir = process.cwd()) {
85
- const tables = [...this.handler.elements.values()].sort((a, b) => (b.options.priority ?? 0) - (a.options.priority ?? 0));
86
- for (const table of tables) {
87
- const columnInfo = await table.getColumns();
88
- let csv;
89
- try {
90
- csv = fs.readFileSync(path.join(dir, `${table.options.name}.csv`), "utf8");
91
- }
92
- catch (error) {
93
- continue;
94
- }
95
- if (csv.trim().length === 0)
96
- continue;
97
- const rows = csv
98
- .split("\n")
99
- .map((row) => row.split(","))
100
- .map((row) => {
101
- const data = {};
102
- let index = 0;
103
- for (const [name, info] of Object.entries(columnInfo)) {
104
- data[name] =
105
- info.type === "integer" ? Number(row[index]) : row[index];
106
- index++;
107
- }
108
- return data;
109
- });
110
- await this.database(table.options.name).insert(rows);
111
- }
112
- }
113
67
  }
@@ -3,8 +3,9 @@ import { Knex } from "knex";
3
3
  import { Table } from "./table.js";
4
4
  import { Color } from "chalk";
5
5
  export interface ILogger {
6
- log: (...message: string[]) => void;
7
- error: (error: Error | string) => void;
6
+ log: (message: string) => void;
7
+ error: (error: string | Error) => void;
8
+ warn: (warning: string) => void;
8
9
  }
9
10
  export interface ORMConfig {
10
11
  /**
@@ -41,13 +42,5 @@ export declare class ORM {
41
42
  * Handle the table files and create the tables in the database.
42
43
  */
43
44
  init(): Promise<void>;
44
- raw(sql: Knex.Value): Promise<Knex.Raw>;
45
- /**
46
- * Extract the database to a CSV file.
47
- */
48
- extract(dir?: string): Promise<void>;
49
- /**
50
- * Import a CSV file to the database.
51
- */
52
- import(dir?: string): Promise<void>;
45
+ raw(sql: Knex.Value): Knex.Raw;
53
46
  }
@@ -28,10 +28,10 @@ export declare class Table<Type extends object = object> {
28
28
  _unionProps: never;
29
29
  }[]>;
30
30
  count(where?: string): Promise<number>;
31
- hasColumn(name: keyof Type): Promise<boolean>;
32
- getColumn(name: keyof Type): Promise<Knex.ColumnInfo>;
33
- getColumns(): Promise<Record<keyof Type, Knex.ColumnInfo>>;
34
- getColumnNames(): Promise<Array<keyof Type>>;
31
+ hasColumn(name: keyof Type & string): Promise<boolean>;
32
+ getColumn(name: keyof Type & string): Promise<Knex.ColumnInfo>;
33
+ getColumns(): Promise<Record<keyof Type & string, Knex.ColumnInfo>>;
34
+ getColumnNames(): Promise<Array<keyof Type & string>>;
35
35
  isEmpty(): Promise<boolean>;
36
36
  make(): Promise<this>;
37
37
  private migrate;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ghom/orm",
3
- "version": "1.6.0",
3
+ "version": "1.7.0",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "main": "dist/esm/index.js",
@@ -20,20 +20,20 @@
20
20
  "prepublishOnly": "npm run format && npm test"
21
21
  },
22
22
  "devDependencies": {
23
- "@types/jest": "^29.5.1",
24
- "@types/node": "^18.16.3",
25
- "dotenv": "^16.0.3",
26
- "jest": "^29.5.0",
27
- "prettier": "^2.8.8",
28
- "typescript": "^5.0.4"
23
+ "@types/jest": "^29.5.6",
24
+ "@types/node": "^20.8.9",
25
+ "dotenv": "^16.3.1",
26
+ "jest": "^29.7.0",
27
+ "prettier": "^3.0.3",
28
+ "typescript": "^5.2.2"
29
29
  },
30
30
  "optionalDependencies": {
31
- "mysql2": "^3.2.4",
32
- "pg": "^8.10.0",
31
+ "mysql2": "^3.6.2",
32
+ "pg": "^8.11.3",
33
33
  "sqlite3": "^5.1.6"
34
34
  },
35
35
  "dependencies": {
36
36
  "@ghom/handler": "^2.0.0",
37
- "knex": "^2.4.2"
37
+ "knex": "^3.0.1"
38
38
  }
39
39
  }
package/src/app/orm.ts CHANGED
@@ -4,16 +4,19 @@ import path from "path"
4
4
  import { Handler } from "@ghom/handler"
5
5
  import { Knex, default as knex } from "knex"
6
6
  import { MigrationData, Table } from "./table.js"
7
- import { Color } from "chalk"
7
+ import chalk, { Color } from "chalk"
8
+
9
+ const defaultBackupDir = path.join(process.cwd(), "backup")
8
10
 
9
11
  const pack = JSON.parse(
10
- fs.readFileSync(path.join(process.cwd(), "package.json"), "utf8")
12
+ fs.readFileSync(path.join(process.cwd(), "package.json"), "utf8"),
11
13
  )
12
14
  const isCJS = pack.type === "commonjs" || pack.type == void 0
13
15
 
14
16
  export interface ILogger {
15
- log: (...message: string[]) => void
16
- error: (error: Error | string) => void
17
+ log: (message: string) => void
18
+ error: (error: string | Error) => void
19
+ warn: (warning: string) => void
17
20
  }
18
21
 
19
22
  export interface ORMConfig {
@@ -54,13 +57,13 @@ export class ORM {
54
57
  connection: {
55
58
  filename: ":memory:",
56
59
  },
57
- }
60
+ },
58
61
  )
59
62
 
60
63
  this.handler = new Handler(config.location, {
61
64
  loader: (filepath) =>
62
65
  import(isCJS ? filepath : url.pathToFileURL(filepath).href).then(
63
- (file) => file.default
66
+ (file) => file.default,
64
67
  ),
65
68
  pattern: /\.js$/,
66
69
  })
@@ -105,81 +108,87 @@ export class ORM {
105
108
  await migration.make()
106
109
 
107
110
  for (const table of this.cachedTables.sort(
108
- (a, b) => (b.options.priority ?? 0) - (a.options.priority ?? 0)
111
+ (a, b) => (b.options.priority ?? 0) - (a.options.priority ?? 0),
109
112
  )) {
110
113
  table.orm = this
111
114
  await table.make()
112
115
  }
113
116
  }
114
117
 
115
- async raw(sql: Knex.Value): Promise<Knex.Raw> {
118
+ raw(sql: Knex.Value): Knex.Raw {
116
119
  return this.database.raw(sql)
117
120
  }
118
121
 
119
- /**
120
- * Extract the database to a CSV file.
121
- */
122
- async extract(dir = process.cwd()) {
123
- const tables = [...this.handler.elements.values()]
124
-
125
- for (const table of tables) {
126
- await this.database
127
- .select()
128
- .from(table.options.name)
129
- .then((rows) => {
130
- const csv = rows.map((row) => Object.values(row).join(",")).join("\n")
131
-
132
- fs.writeFileSync(
133
- path.join(dir, `${table.options.name}.csv`),
134
- csv,
135
- "utf8"
136
- )
137
- })
138
- }
139
- }
140
-
141
- /**
142
- * Import a CSV file to the database.
143
- */
144
- async import(dir = process.cwd()) {
145
- const tables = [...this.handler.elements.values()].sort(
146
- (a, b) => (b.options.priority ?? 0) - (a.options.priority ?? 0)
147
- )
148
-
149
- for (const table of tables) {
150
- const columnInfo = await table.getColumns()
151
-
152
- let csv: string
153
-
154
- try {
155
- csv = fs.readFileSync(
156
- path.join(dir, `${table.options.name}.csv`),
157
- "utf8"
158
- )
159
- } catch (error) {
160
- continue
161
- }
162
-
163
- if (csv.trim().length === 0) continue
164
-
165
- const rows = csv
166
- .split("\n")
167
- .map((row) => row.split(","))
168
- .map((row) => {
169
- const data: any = {}
170
-
171
- let index = 0
172
-
173
- for (const [name, info] of Object.entries(columnInfo)) {
174
- data[name] =
175
- info.type === "integer" ? Number(row[index]) : row[index]
176
- index++
177
- }
178
-
179
- return data
180
- })
181
-
182
- await this.database(table.options.name).insert(rows)
183
- }
184
- }
122
+ // /**
123
+ // * Extract the database to a CSV file for each table.
124
+ // */
125
+ // async createBackup(dir = defaultBackupDir) {
126
+ // const tables = [...this.handler.elements.values()]
127
+ //
128
+ // for (const table of tables) {
129
+ // await this.database
130
+ // .select()
131
+ // .from(table.options.name)
132
+ // .then(async (rows) => {
133
+ // const csv = rows.map((row) => Object.values(row).join(",")).join("\n")
134
+ //
135
+ // return fs.promises.writeFile(
136
+ // path.join(dir, `${table.options.name}.csv`),
137
+ // csv,
138
+ // "utf8",
139
+ // )
140
+ // })
141
+ // }
142
+ // }
143
+ //
144
+ // /**
145
+ // * Import a CSV file for each table to the database.
146
+ // */
147
+ // async restoreBackup(dir = defaultBackupDir) {
148
+ // const tables = [...this.handler.elements.values()].sort(
149
+ // (a, b) => (b.options.priority ?? 0) - (a.options.priority ?? 0),
150
+ // )
151
+ //
152
+ // for (const table of tables) {
153
+ // const columnInfo = await table.getColumns()
154
+ //
155
+ // let csv: string
156
+ //
157
+ // try {
158
+ // csv = await fs.promises.readFile(
159
+ // path.join(dir, `${table.options.name}.csv`),
160
+ // "utf8",
161
+ // )
162
+ // } catch (error) {
163
+ // this.config.logger?.warn(
164
+ // `missing backup file for table ${chalk[
165
+ // this.config.loggerColors?.highlight ?? "blueBright"
166
+ // ](table.options.name)}`,
167
+ // )
168
+ //
169
+ // continue
170
+ // }
171
+ //
172
+ // if (csv.trim().length === 0) continue
173
+ //
174
+ // const rows = csv
175
+ // .split("\n")
176
+ // .map((row) => row.split(","))
177
+ // .map((row) => {
178
+ // const data: any = {}
179
+ //
180
+ // let index = 0
181
+ //
182
+ // for (const [name, info] of Object.entries(columnInfo)) {
183
+ // data[name] =
184
+ // info.type === "integer" ? Number(row[index]) : row[index]
185
+ // index++
186
+ // }
187
+ //
188
+ // return data
189
+ // })
190
+ //
191
+ // await this.database(table.options.name).insert(rows)
192
+ // }
193
+ // }
185
194
  }
package/src/app/table.ts CHANGED
@@ -36,20 +36,22 @@ export class Table<Type extends object = object> {
36
36
  .then((rows) => (rows[0] as unknown as { total: number }).total)
37
37
  }
38
38
 
39
- async hasColumn(name: keyof Type): Promise<boolean> {
39
+ async hasColumn(name: keyof Type & string): Promise<boolean> {
40
40
  return this.db.schema.hasColumn(this.options.name, name as string)
41
41
  }
42
42
 
43
- async getColumn(name: keyof Type): Promise<Knex.ColumnInfo> {
43
+ async getColumn(name: keyof Type & string): Promise<Knex.ColumnInfo> {
44
44
  return this.db(this.options.name).columnInfo(name)
45
45
  }
46
46
 
47
- async getColumns(): Promise<Record<keyof Type, Knex.ColumnInfo>> {
47
+ async getColumns(): Promise<Record<keyof Type & string, Knex.ColumnInfo>> {
48
48
  return this.db(this.options.name).columnInfo()
49
49
  }
50
50
 
51
- async getColumnNames(): Promise<Array<keyof Type>> {
52
- return this.getColumns().then(Object.keys) as Promise<Array<keyof Type>>
51
+ async getColumnNames(): Promise<Array<keyof Type & string>> {
52
+ return this.getColumns().then(Object.keys) as Promise<
53
+ Array<keyof Type & string>
54
+ >
53
55
  }
54
56
 
55
57
  async isEmpty(): Promise<boolean> {
@@ -65,14 +67,14 @@ export class Table<Type extends object = object> {
65
67
  this.orm.config.logger?.log(
66
68
  `created table ${chalk[
67
69
  this.orm.config.loggerColors?.highlight ?? "blueBright"
68
- ](this.options.name)}`
70
+ ](this.options.name)}`,
69
71
  )
70
72
  } catch (error: any) {
71
73
  if (error.toString().includes("syntax error")) {
72
74
  this.orm.config.logger?.error(
73
75
  `you need to implement the "setup" method in options of your ${chalk[
74
76
  this.orm.config.loggerColors?.highlight ?? "blueBright"
75
- ](this.options.name)} table!`
77
+ ](this.options.name)} table!`,
76
78
  )
77
79
 
78
80
  throw error
@@ -80,7 +82,7 @@ export class Table<Type extends object = object> {
80
82
  this.orm.config.logger?.log(
81
83
  `loaded table ${chalk[
82
84
  this.orm.config.loggerColors?.highlight ?? "blueBright"
83
- ](this.options.name)}`
85
+ ](this.options.name)}`,
84
86
  )
85
87
  }
86
88
  }
@@ -94,7 +96,7 @@ export class Table<Type extends object = object> {
94
96
  this.orm.config.loggerColors?.highlight ?? "blueBright"
95
97
  ](this.options.name)} to version ${chalk[
96
98
  this.orm.config.loggerColors?.rawValue ?? "magentaBright"
97
- ](migrated)}`
99
+ ](migrated)}`,
98
100
  )
99
101
  }
100
102
  } catch (error: any) {
@@ -117,7 +119,7 @@ export class Table<Type extends object = object> {
117
119
  >(
118
120
  Object.entries(this.options.migrations)
119
121
  .sort((a, b) => Number(a[0]) - Number(b[0]))
120
- .map((entry) => [Number(entry[0]), entry[1]])
122
+ .map((entry) => [Number(entry[0]), entry[1]]),
121
123
  )
122
124
 
123
125
  const fromDatabase = await this.db<MigrationData>("migration")
package/tests/test.js CHANGED
@@ -54,7 +54,7 @@ describe("table column types", () => {
54
54
  await orm
55
55
  .database("a")
56
56
  .columnInfo("id")
57
- .then((info) => info.type)
57
+ .then((info) => info.type),
58
58
  ).toBe("integer")
59
59
  })
60
60
 
@@ -63,50 +63,50 @@ describe("table column types", () => {
63
63
  await orm
64
64
  .database("a")
65
65
  .columnInfo("b_id")
66
- .then((info) => info.type)
66
+ .then((info) => info.type),
67
67
  ).toBe("integer")
68
68
  })
69
69
  })
70
70
 
71
- describe("database migration", () => {
72
- beforeAll(async () => {
73
- await c.query.insert({ id: 0 })
74
- await b.query.insert({
75
- id: 0,
76
- c_id: 0,
77
- })
78
- await a.query.insert({
79
- id: 0,
80
- b_id: 0,
81
- })
82
- })
83
-
84
- test("extract CSV", async () => {
85
- await orm.extract()
86
-
87
- expect(fs.existsSync("a.csv")).toBeTruthy()
88
- expect(fs.existsSync("b.csv")).toBeTruthy()
89
- expect(fs.existsSync("c.csv")).toBeTruthy()
90
- })
91
-
92
- test("empty tables", async () => {
93
- await a.query.del()
94
- await b.query.del()
95
- await c.query.del()
96
-
97
- expect(await a.isEmpty()).toBeTruthy()
98
- expect(await b.isEmpty()).toBeTruthy()
99
- expect(await c.isEmpty()).toBeTruthy()
100
- })
101
-
102
- test("import CSV", async () => {
103
- await orm.import()
104
-
105
- expect(await a.isEmpty()).toBeFalsy()
106
- expect(await b.isEmpty()).toBeFalsy()
107
- expect(await c.isEmpty()).toBeFalsy()
108
- })
109
- })
71
+ // describe("database extraction", () => {
72
+ // beforeAll(async () => {
73
+ // await c.query.insert({ id: 0 })
74
+ // await b.query.insert({
75
+ // id: 0,
76
+ // c_id: 0,
77
+ // })
78
+ // await a.query.insert({
79
+ // id: 0,
80
+ // b_id: 0,
81
+ // })
82
+ // })
83
+ //
84
+ // test("extract CSV", async () => {
85
+ // await orm.extract()
86
+ //
87
+ // expect(fs.existsSync("a.csv")).toBeTruthy()
88
+ // expect(fs.existsSync("b.csv")).toBeTruthy()
89
+ // expect(fs.existsSync("c.csv")).toBeTruthy()
90
+ // })
91
+ //
92
+ // test("empty tables", async () => {
93
+ // await a.query.del()
94
+ // await b.query.del()
95
+ // await c.query.del()
96
+ //
97
+ // expect(await a.isEmpty()).toBeTruthy()
98
+ // expect(await b.isEmpty()).toBeTruthy()
99
+ // expect(await c.isEmpty()).toBeTruthy()
100
+ // })
101
+ //
102
+ // test("import CSV", async () => {
103
+ // await orm.import()
104
+ //
105
+ // expect(await a.isEmpty()).toBeFalsy()
106
+ // expect(await b.isEmpty()).toBeFalsy()
107
+ // expect(await c.isEmpty()).toBeFalsy()
108
+ // })
109
+ // })
110
110
 
111
111
  describe("table getters", () => {
112
112
  test("table info", async () => {
@@ -128,7 +128,7 @@ describe("table getters", () => {
128
128
 
129
129
  afterAll(async () => {
130
130
  await orm.database.destroy()
131
- fs.unlinkSync("a.csv")
132
- fs.unlinkSync("b.csv")
133
- fs.unlinkSync("c.csv")
131
+ // fs.unlinkSync("a.csv")
132
+ // fs.unlinkSync("b.csv")
133
+ // fs.unlinkSync("c.csv")
134
134
  })