db-crud-wrapper 1.0.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.
- package/CHANGELOG.md +81 -0
- package/README.md +96 -0
- package/index.js +5 -0
- package/lib/builder.js +404 -0
- package/lib/config.js +287 -0
- package/lib/db-operations.js +426 -0
- package/lib/f.js +45 -0
- package/lib/factory.js +89 -0
- package/lib/log.js +21 -0
- package/lib/mssql.js +483 -0
- package/lib/mysql.js +532 -0
- package/lib/session-store.js +196 -0
- package/package.json +31 -0
package/lib/config.js
ADDED
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import * as f from './f.js';
|
|
4
|
+
import * as dbOpe from './db-operations.js';
|
|
5
|
+
|
|
6
|
+
export const config = {
|
|
7
|
+
servers: {
|
|
8
|
+
},
|
|
9
|
+
log: {
|
|
10
|
+
level: 0,
|
|
11
|
+
callback: undefined,
|
|
12
|
+
maxAsyncInstance: 50
|
|
13
|
+
},
|
|
14
|
+
session: {
|
|
15
|
+
tablePath: 'sessions'
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export class Server {
|
|
20
|
+
#_serverName = undefined;
|
|
21
|
+
|
|
22
|
+
// server can be the name (string) or object or an instance of Server class
|
|
23
|
+
constructor(server) {
|
|
24
|
+
if (typeof server === 'string') {
|
|
25
|
+
this.#_serverName = server;
|
|
26
|
+
if (!config.servers[server]) config.servers[server] = {};
|
|
27
|
+
}
|
|
28
|
+
else if (typeof server === 'object') {
|
|
29
|
+
if (server.constructor === Server) { // if server is an instance of Server class, we can use its toObject method to get the server object
|
|
30
|
+
this.#_serverName = server.name;
|
|
31
|
+
config.servers[this.#_serverName] = { name, ...structuredClone(server.toObject()) };
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
if (!server.name) throw new Error('server must have a name.');
|
|
35
|
+
this.#_serverName = server.name;
|
|
36
|
+
config.servers[server.name] = { name, ...structuredClone(server) };
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
else throw new Error('server must be a string or a server object.');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
get name() {
|
|
43
|
+
return this.#_serverName;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
instance(instance) {
|
|
47
|
+
if (typeof instance !== 'string') throw new Error('instance must be a string.');
|
|
48
|
+
config.servers[this.#_serverName].instance = instance;
|
|
49
|
+
return this;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
user(user) {
|
|
53
|
+
if (typeof user !== 'string') throw new Error('user must be a string.');
|
|
54
|
+
config.servers[this.#_serverName].user = user;
|
|
55
|
+
return this;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
password(password) {
|
|
59
|
+
if (typeof password !== 'string') throw new Error('password must be a string.');
|
|
60
|
+
config.servers[this.#_serverName].password = password;
|
|
61
|
+
return this;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
type(type) {
|
|
65
|
+
if (typeof type !== 'string' || !Object.values(dbOpe.serverType).includes(type)) throw new Error('invalid server type.');
|
|
66
|
+
config.servers[this.#_serverName].type = type;
|
|
67
|
+
return this;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
realName(realName) {
|
|
71
|
+
if (typeof realName !== 'string') throw new Error('realName must be a string.');
|
|
72
|
+
config.servers[this.#_serverName].realName = realName;
|
|
73
|
+
return this;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
options(options) {
|
|
77
|
+
if (typeof options !== 'object') throw new Error('options must be an object.');
|
|
78
|
+
config.servers[this.#_serverName].options = structuredClone(options);
|
|
79
|
+
return this;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
database(database) {
|
|
83
|
+
return new Database(database, this.#_serverName);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
toObject() {
|
|
87
|
+
const _return = structuredClone(config.servers[this.#_serverName]);
|
|
88
|
+
return _return;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export class Database {
|
|
93
|
+
#_dbName = undefined;
|
|
94
|
+
#_serverName = undefined;
|
|
95
|
+
|
|
96
|
+
// datbase can be the name (string) or object or an instance of Database class
|
|
97
|
+
constructor(database, serverName) {
|
|
98
|
+
if (typeof serverName !== 'string') throw new Error('server must be a string.');
|
|
99
|
+
this.#_serverName = serverName;
|
|
100
|
+
if (typeof database === 'string') {
|
|
101
|
+
this.#_dbName = database;
|
|
102
|
+
if (!config.servers[serverName]) config.servers[serverName] = {};
|
|
103
|
+
// note: I cannot use serverName in setDeep path because it can contain an IP address xx.xx.xx.xx
|
|
104
|
+
f.setDeep(config.servers[serverName], `databases.${database}`, {});
|
|
105
|
+
}
|
|
106
|
+
else if (typeof database === 'object') {
|
|
107
|
+
if (!database.name) throw new Error('database must have a name.');
|
|
108
|
+
this.#_dbName = database.name;
|
|
109
|
+
if (!config.servers[serverName]) config.servers[serverName] = {};
|
|
110
|
+
// note: I cannot use serverName in setDeep path because it can contain an IP address xx.xx.xx.xx
|
|
111
|
+
// if database is an instance of Database class, we can use its toObject method to get the database object
|
|
112
|
+
if (database.constructor === Database)
|
|
113
|
+
f.setDeep(config.servers[serverName], `databases.${database.name}`, { name, ...structuredClone(database.toObject()) });
|
|
114
|
+
else
|
|
115
|
+
f.setDeep(config.servers[serverName], `databases.${database.name}`, { name, ...structuredClone(database) });
|
|
116
|
+
}
|
|
117
|
+
else throw new Error('database must be a string or a database object.');
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
get name() {
|
|
121
|
+
return this.#_dbName;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
realName(realName) {
|
|
125
|
+
if (typeof realName !== 'string') throw new Error('realName must be a string.');
|
|
126
|
+
config.servers[this.#_serverName].databases[this.#_dbName].realName = realName;
|
|
127
|
+
return this;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
table(table) {
|
|
131
|
+
return new Table(table, this.#_dbName, this.#_serverName);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
toObject() {
|
|
135
|
+
const _return = structuredClone(config.servers[this.#_serverName].databases[this.#_dbName]);
|
|
136
|
+
return _return;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export class Table {
|
|
142
|
+
#_tableName = undefined;
|
|
143
|
+
#_dbName = undefined;
|
|
144
|
+
#_serverName = undefined;
|
|
145
|
+
|
|
146
|
+
// table can be a string or a table object or an instance of Table class
|
|
147
|
+
constructor(table, dbName, serverName) {
|
|
148
|
+
if (typeof serverName !== 'string') throw new Error('server must be a string.');
|
|
149
|
+
if (typeof dbName !== 'string') throw new Error('database must be a string.');
|
|
150
|
+
this.#_serverName = serverName;
|
|
151
|
+
this.#_dbName = dbName;
|
|
152
|
+
if (typeof table === 'string') {
|
|
153
|
+
this.#_tableName = table;
|
|
154
|
+
if (!config.servers[serverName]) config.servers[serverName] = {};
|
|
155
|
+
// note: I cannot use serverName in setDeep path because it can contain an IP address xx.xx.xx.xx
|
|
156
|
+
f.setDeep(config.servers[serverName], `databases.${dbName}.tables.${table}`, {});
|
|
157
|
+
}
|
|
158
|
+
else if (typeof table === 'object') {
|
|
159
|
+
if (!table.name) throw new Error('table must have a name.');
|
|
160
|
+
this.#_tableName = table.name;
|
|
161
|
+
if (!config.servers[serverName]) config.servers[serverName] = {};
|
|
162
|
+
// note: I cannot use serverName in setDeep path because it can contain an IP address xx.xx.xx.xx
|
|
163
|
+
// if table is an instance of Table class, we can use its toObject method to get the table object
|
|
164
|
+
if (table.constructor === Table)
|
|
165
|
+
f.setDeep(config.servers[serverName], `databases.${dbName}.tables.${table.name}`, { name, ...structuredClone(table.toObject()) });
|
|
166
|
+
else
|
|
167
|
+
f.setDeep(config.servers[serverName], `databases.${dbName}.tables.${table.name}`, { name, ...structuredClone(table) });
|
|
168
|
+
}
|
|
169
|
+
else throw new Error('table must be a string or a table object.');
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
get name() {
|
|
173
|
+
return this.#_tableName;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
realName(realName) {
|
|
177
|
+
if (typeof realName !== 'string') throw new Error('realName must be a string.');
|
|
178
|
+
config.servers[this.#_serverName].databases[this.#_dbName].tables[this.#_tableName].realName = realName;
|
|
179
|
+
return this;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
idField(idField) {
|
|
183
|
+
if (typeof idField !== 'string') throw new Error('idField must be a string.');
|
|
184
|
+
config.servers[this.#_serverName].databases[this.#_dbName].tables[this.#_tableName].idField = idField;
|
|
185
|
+
return this;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
autoId(autoId) {
|
|
189
|
+
if (typeof autoId !== 'boolean') throw new Error('autoId must be a boolean.');
|
|
190
|
+
config.servers[this.#_serverName].databases[this.#_dbName].tables[this.#_tableName].autoId = autoId;
|
|
191
|
+
return this;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
field(field) {
|
|
195
|
+
return new Field(field, this.#_tableName, this.#_dbName, this.#_serverName);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
toObject() {
|
|
199
|
+
const _return = structuredClone(config.servers[this.#_serverName].databases[this.#_dbName].tables[this.#_tableName]);
|
|
200
|
+
return _return;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
export class Field {
|
|
206
|
+
#_fieldName;
|
|
207
|
+
#_tableName;
|
|
208
|
+
#_dbName;
|
|
209
|
+
#_serverName;
|
|
210
|
+
|
|
211
|
+
// field can be a string or a field object
|
|
212
|
+
constructor(field, tableName, dbName, serverName) {
|
|
213
|
+
if (typeof serverName !== 'string') throw new Error('server must be a string.');
|
|
214
|
+
if (typeof dbName !== 'string') throw new Error('database must be a string.');
|
|
215
|
+
if (typeof tableName !== 'string') throw new Error('table must be a string.');
|
|
216
|
+
this.#_serverName = serverName;
|
|
217
|
+
this.#_dbName = dbName;
|
|
218
|
+
this.#_tableName = tableName;
|
|
219
|
+
if (typeof field === 'string') {
|
|
220
|
+
this.#_fieldName = field;
|
|
221
|
+
if (!config.servers[serverName]) config.servers[serverName] = {};
|
|
222
|
+
// note: I cannot use serverName in setDeep path because it can contain an IP address xx.xx.xx.xx
|
|
223
|
+
f.setDeep(config.servers[serverName], `databases.${dbName}.tables.${tableName}.fields.${field}`, {});
|
|
224
|
+
}
|
|
225
|
+
else if (typeof field === 'object') {
|
|
226
|
+
if (!field.name) throw new Error('field must have a name.');
|
|
227
|
+
this.#_fieldName = field.name;
|
|
228
|
+
if (!config.servers[serverName]) config.servers[serverName] = {};
|
|
229
|
+
// note: I cannot use serverName in setDeep path because it can contain an IP address xx.xx.xx.xx
|
|
230
|
+
f.setDeep(config.servers[serverName], `databases.${dbName}.tables.${tableName}.fields.${field}`, { name, ...structuredClone(field) });
|
|
231
|
+
}
|
|
232
|
+
else throw new Error('field must be a string or a field object.');
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
get name() {
|
|
236
|
+
return this.#_fieldName;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
type(type) {
|
|
240
|
+
if (typeof type !== 'string') throw new Error('type must be a string.');
|
|
241
|
+
config.servers[this.#_serverName].databases[this.#_dbName].tables[this.#_tableName].Database[this.#_fieldName].type = type;
|
|
242
|
+
return this;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
description(description) {
|
|
246
|
+
if (typeof description !== 'string') throw new Error('description must be a string.');
|
|
247
|
+
config.servers[this.#_serverName].databases[this.#_dbName].tables[this.#_tableName].Database[this.#_fieldName].description = description;
|
|
248
|
+
return this;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
toObject() {
|
|
252
|
+
const _return = structuredClone(config.servers[this.#_serverName].databases[this.#_dbName].tables[this.#_tableName].fields[this.#_fieldName]);
|
|
253
|
+
return _return;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
export class Log {
|
|
259
|
+
constructor() {
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
level(level) {
|
|
263
|
+
if (typeof level === 'number') {
|
|
264
|
+
config.log.level = level;
|
|
265
|
+
} else if (typeof level === 'string' && !isNaN(Number.parseInt(level))) {
|
|
266
|
+
config.log.level = Number.parseInt(level);
|
|
267
|
+
}
|
|
268
|
+
return this;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
callback(callback) {
|
|
272
|
+
if (typeof callback === 'function') {
|
|
273
|
+
config.log.callback = callback;
|
|
274
|
+
}
|
|
275
|
+
return this;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
maxAsyncInstances(maxAsyncInstances) {
|
|
279
|
+
if (typeof maxAsyncInstances === 'number') {
|
|
280
|
+
config.log.maxAsyncInstance = maxAsyncInstances;
|
|
281
|
+
} else if (typeof maxAsyncInstances === 'string' && !isNaN(Number.parseInt(maxAsyncInstances))) {
|
|
282
|
+
config.log.maxAsyncInstance = Number.parseInt(maxAsyncInstances);
|
|
283
|
+
}
|
|
284
|
+
return this;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
}
|