ztechno_core 0.0.105 → 0.0.108
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/lib/core/crypto_service.d.ts +23 -0
- package/lib/core/crypto_service.js +100 -0
- package/lib/core/engine_base.d.ts +11 -0
- package/lib/core/engine_base.js +9 -0
- package/lib/core/index.d.ts +14 -0
- package/lib/core/index.js +101 -0
- package/lib/core/mail_service.d.ts +85 -0
- package/lib/core/mail_service.js +156 -0
- package/lib/core/orm/mail_blacklist_orm.d.ts +21 -0
- package/lib/core/orm/mail_blacklist_orm.js +79 -0
- package/lib/core/orm/orm.d.ts +27 -0
- package/lib/core/orm/orm.js +67 -0
- package/lib/core/sql_service.d.ts +195 -0
- package/lib/core/sql_service.js +333 -0
- package/lib/core/translate_service.d.ts +48 -0
- package/lib/core/translate_service.js +913 -0
- package/lib/core/types/crypto_types.d.ts +4 -0
- package/lib/core/types/crypto_types.js +2 -0
- package/lib/core/types/mail_types.d.ts +95 -0
- package/lib/core/types/mail_types.js +2 -0
- package/lib/core/types/site_config.d.ts +46 -0
- package/lib/core/types/site_config.js +2 -0
- package/lib/core/types/translate_types.d.ts +69 -0
- package/lib/core/types/translate_types.js +46 -0
- package/lib/core/types/user_types.d.ts +41 -0
- package/lib/core/types/user_types.js +2 -0
- package/lib/core/user_service.d.ts +87 -0
- package/lib/core/user_service.js +216 -0
- package/lib/express/index.d.ts +1 -0
- package/lib/express/index.js +18 -0
- package/lib/index.d.ts +17 -8
- package/lib/index.js +60 -16
- package/lib/mollie/index.d.ts +5 -0
- package/lib/mollie/index.js +62 -0
- package/lib/mollie/orm/customers_orm.d.ts +16 -0
- package/lib/mollie/orm/customers_orm.js +115 -0
- package/lib/mollie/orm/invoice_items_orm.d.ts +9 -0
- package/lib/mollie/orm/invoice_items_orm.js +71 -0
- package/lib/mollie/orm/invoice_payments_orm.d.ts +10 -0
- package/lib/mollie/orm/invoice_payments_orm.js +70 -0
- package/lib/mollie/orm/invoices_orm.d.ts +40 -0
- package/lib/mollie/orm/invoices_orm.js +172 -0
- package/lib/mollie/orm/subscription_items_orm.d.ts +9 -0
- package/lib/mollie/orm/subscription_items_orm.js +45 -0
- package/lib/mollie/orm/subscriptions_orm.d.ts +17 -0
- package/lib/mollie/orm/subscriptions_orm.js +122 -0
- package/lib/mollie/services/customer_service.d.ts +14 -0
- package/lib/mollie/services/customer_service.js +53 -0
- package/lib/mollie/services/invoice_service.d.ts +102 -0
- package/lib/mollie/services/invoice_service.js +866 -0
- package/lib/mollie/services/mollie_service.d.ts +42 -0
- package/lib/mollie/services/mollie_service.js +370 -0
- package/lib/mollie/services/subscription_service.d.ts +32 -0
- package/lib/mollie/services/subscription_service.js +134 -0
- package/lib/mollie/types/internal_types.d.ts +19 -0
- package/lib/mollie/types/internal_types.js +2 -0
- package/lib/mollie/types/mollie_types.d.ts +187 -0
- package/lib/mollie/types/mollie_types.js +3 -0
- package/lib/mollie/util/subscription_utils.d.ts +8 -0
- package/lib/mollie/util/subscription_utils.js +37 -0
- package/lib/schema/MySQLSchemaExtractor.d.ts +1 -1
- package/lib/schema/MySQLSchemaImporter.d.ts +1 -1
- package/package.json +3 -1
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
3
|
+
exports.ZOrm =
|
|
4
|
+
exports.toDatetimeFromDateOnly =
|
|
5
|
+
exports.formatDatetime =
|
|
6
|
+
exports.toDatetime =
|
|
7
|
+
exports.toJsonColumn =
|
|
8
|
+
void 0;
|
|
9
|
+
/**
|
|
10
|
+
* Safely converts a value to a JSON string for storage in a JSON column.
|
|
11
|
+
* Prevents the mysql driver from expanding plain objects into `key`=value pairs.
|
|
12
|
+
*/
|
|
13
|
+
function toJsonColumn(value) {
|
|
14
|
+
if (value == null) return null;
|
|
15
|
+
return typeof value === 'string' ? value : JSON.stringify(value);
|
|
16
|
+
}
|
|
17
|
+
exports.toJsonColumn = toJsonColumn;
|
|
18
|
+
/**
|
|
19
|
+
* Converts an ISO 8601 date string (e.g. from Mollie API) to MySQL DATETIME format.
|
|
20
|
+
* Accepts `2026-02-26T00:47:04+00:00` → `2026-02-26 00:47:04`
|
|
21
|
+
*/
|
|
22
|
+
function toDatetime(value) {
|
|
23
|
+
if (value == null) return null;
|
|
24
|
+
const d = new Date(value);
|
|
25
|
+
if (isNaN(d.getTime())) return null;
|
|
26
|
+
return d.toISOString().slice(0, 19).replace('T', ' ');
|
|
27
|
+
}
|
|
28
|
+
exports.toDatetime = toDatetime;
|
|
29
|
+
/**
|
|
30
|
+
* Converts a Date object to MySQL DATETIME format.
|
|
31
|
+
*/
|
|
32
|
+
function formatDatetime(value) {
|
|
33
|
+
return value.toISOString().slice(0, 19).replace('T', ' ');
|
|
34
|
+
}
|
|
35
|
+
exports.formatDatetime = formatDatetime;
|
|
36
|
+
/**
|
|
37
|
+
* Converts a date-only string (e.g. `2026-02-26`) to MySQL DATETIME format.
|
|
38
|
+
*/
|
|
39
|
+
function toDatetimeFromDateOnly(value) {
|
|
40
|
+
if (value == null) return null;
|
|
41
|
+
return toDatetime(`${value}T00:00:00Z`);
|
|
42
|
+
}
|
|
43
|
+
exports.toDatetimeFromDateOnly = toDatetimeFromDateOnly;
|
|
44
|
+
class ZOrm {
|
|
45
|
+
constructor(opt) {
|
|
46
|
+
this.alias = opt.alias;
|
|
47
|
+
this.sqlService = opt.sqlService;
|
|
48
|
+
}
|
|
49
|
+
async ensureTableExists() {
|
|
50
|
+
const exists = await this.checkTableExists();
|
|
51
|
+
if (!exists) {
|
|
52
|
+
await this.createTable();
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
async checkTableExists() {
|
|
56
|
+
const res = await this.sqlService.query(`
|
|
57
|
+
SELECT ENGINE, VERSION, CREATE_TIME FROM information_schema.tables
|
|
58
|
+
WHERE table_schema = '${this.sqlService.database}' AND table_name = '${this.alias}'
|
|
59
|
+
LIMIT 1
|
|
60
|
+
`);
|
|
61
|
+
return res.length > 0;
|
|
62
|
+
}
|
|
63
|
+
async createTable() {
|
|
64
|
+
throw new Error(`${this.alias} Create Table Statement Not Implemented!`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
exports.ZOrm = ZOrm;
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import * as mysql from 'mysql';
|
|
2
|
+
type ZOnErrorCallback = (err: mysql.MysqlError) => any;
|
|
3
|
+
type ZOnLogCallback = (log: string) => any;
|
|
4
|
+
export type ZSQLOptions = mysql.PoolConfig & {
|
|
5
|
+
dateStringTimezone?: string;
|
|
6
|
+
parseBooleans?: boolean;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* A scoped transaction handle passed to the `transaction()` callback.
|
|
10
|
+
* All queries executed through this handle run on the same connection
|
|
11
|
+
* inside a single BEGIN / COMMIT / ROLLBACK block.
|
|
12
|
+
*/
|
|
13
|
+
export interface ZTransaction {
|
|
14
|
+
/** Run a raw query inside the transaction (no type conversions). */
|
|
15
|
+
query<T = any>(
|
|
16
|
+
sql: string,
|
|
17
|
+
params?:
|
|
18
|
+
| any[]
|
|
19
|
+
| {
|
|
20
|
+
[key: string]: any;
|
|
21
|
+
},
|
|
22
|
+
): Promise<T[]>;
|
|
23
|
+
query(
|
|
24
|
+
sql: string,
|
|
25
|
+
params?:
|
|
26
|
+
| any[]
|
|
27
|
+
| {
|
|
28
|
+
[key: string]: any;
|
|
29
|
+
},
|
|
30
|
+
): Promise<{
|
|
31
|
+
insertId: number;
|
|
32
|
+
affectedRows: number;
|
|
33
|
+
}>;
|
|
34
|
+
/** Run a query with automatic date/boolean conversions inside the transaction. */
|
|
35
|
+
exec<T = any>(opt: {
|
|
36
|
+
query: string;
|
|
37
|
+
params?:
|
|
38
|
+
| any[]
|
|
39
|
+
| {
|
|
40
|
+
[key: string]: any;
|
|
41
|
+
};
|
|
42
|
+
}): Promise<T[]>;
|
|
43
|
+
exec(opt: {
|
|
44
|
+
query: string;
|
|
45
|
+
params?:
|
|
46
|
+
| any[]
|
|
47
|
+
| {
|
|
48
|
+
[key: string]: any;
|
|
49
|
+
};
|
|
50
|
+
}): Promise<{
|
|
51
|
+
insertId: number;
|
|
52
|
+
affectedRows: number;
|
|
53
|
+
}>;
|
|
54
|
+
}
|
|
55
|
+
export declare class ZSQLService {
|
|
56
|
+
private options;
|
|
57
|
+
private pool;
|
|
58
|
+
private defaultPoolconfig;
|
|
59
|
+
private listeners;
|
|
60
|
+
private databaseName;
|
|
61
|
+
get database(): string;
|
|
62
|
+
/**
|
|
63
|
+
* Creates a new ZSQLService instance with a MySQL connection pool.
|
|
64
|
+
* @param options - MySQL pool configuration options including custom dateStringTimezone and parseBooleans settings
|
|
65
|
+
*/
|
|
66
|
+
constructor(options: ZSQLOptions);
|
|
67
|
+
/**
|
|
68
|
+
* Registers an event listener for database errors or logs.
|
|
69
|
+
* @param eventName - The event type to listen for ('err' or 'log')
|
|
70
|
+
* @param listener - The callback function to execute when the event occurs
|
|
71
|
+
* @throws Error if the event name is not supported
|
|
72
|
+
*/
|
|
73
|
+
on(eventName: 'err', listener: ZOnErrorCallback): void;
|
|
74
|
+
on(eventName: 'log', listener: ZOnLogCallback): void;
|
|
75
|
+
private triggerEvent;
|
|
76
|
+
private getPoolConnection;
|
|
77
|
+
/**
|
|
78
|
+
* Executes a SQL query with automatic type conversion for dates and booleans.
|
|
79
|
+
* Converts TINYINT(1) columns to booleans if parseBooleans option is enabled.
|
|
80
|
+
* Converts date strings to Date objects if dateStringTimezone option is set.
|
|
81
|
+
* @template T - The expected result type
|
|
82
|
+
* @param opt - Query options containing the SQL query string and optional parameters
|
|
83
|
+
* @param opt.query - The SQL query string to execute
|
|
84
|
+
* @param opt.params - Optional query parameters (array for positional, object for named parameters)
|
|
85
|
+
* @returns Promise resolving to query results with type conversions applied
|
|
86
|
+
*/
|
|
87
|
+
exec(opt: {
|
|
88
|
+
query: string;
|
|
89
|
+
params?:
|
|
90
|
+
| any[]
|
|
91
|
+
| {
|
|
92
|
+
[key: string]: any;
|
|
93
|
+
};
|
|
94
|
+
}): Promise<{
|
|
95
|
+
insertId: number;
|
|
96
|
+
affectedRows: number;
|
|
97
|
+
}>;
|
|
98
|
+
exec<T = any>(opt: {
|
|
99
|
+
query: string;
|
|
100
|
+
params?:
|
|
101
|
+
| any[]
|
|
102
|
+
| {
|
|
103
|
+
[key: string]: any;
|
|
104
|
+
};
|
|
105
|
+
}): Promise<T[]>;
|
|
106
|
+
/**
|
|
107
|
+
* Legacy method to execute a SQL query. Uses uppercase property names for backwards compatibility.
|
|
108
|
+
* Applies date and boolean conversions if configured. Consider using exec() directly for new code.
|
|
109
|
+
* @template T - The expected result type
|
|
110
|
+
* @param opt - Query options
|
|
111
|
+
* @param opt.Query - The SQL query string to execute
|
|
112
|
+
* @param opt.Params - Named parameters for the query
|
|
113
|
+
* @returns Promise resolving to query results
|
|
114
|
+
*/
|
|
115
|
+
fetch<T = any>(opt: {
|
|
116
|
+
Query: string;
|
|
117
|
+
Params:
|
|
118
|
+
| {
|
|
119
|
+
[key: string]: any;
|
|
120
|
+
}
|
|
121
|
+
| any[];
|
|
122
|
+
}): Promise<T[]>;
|
|
123
|
+
fetch<T = any>(
|
|
124
|
+
query: string,
|
|
125
|
+
params:
|
|
126
|
+
| {
|
|
127
|
+
[key: string]: any;
|
|
128
|
+
}
|
|
129
|
+
| any[],
|
|
130
|
+
): Promise<T[]>;
|
|
131
|
+
/**
|
|
132
|
+
* Executes a SQL query without type conversions.
|
|
133
|
+
* Supports both positional (array) and named (object) parameters.
|
|
134
|
+
* @template T - The expected result type
|
|
135
|
+
* @param sql - The SQL query string to execute
|
|
136
|
+
* @param params - Optional query parameters (array for positional with ?, object for named with :key)
|
|
137
|
+
* @returns Promise resolving to query results or insert/update metadata
|
|
138
|
+
*/
|
|
139
|
+
query(
|
|
140
|
+
sql: string,
|
|
141
|
+
params?:
|
|
142
|
+
| any[]
|
|
143
|
+
| {
|
|
144
|
+
[key: string]: any;
|
|
145
|
+
},
|
|
146
|
+
): Promise<{
|
|
147
|
+
insertId: number;
|
|
148
|
+
affectedRows: number;
|
|
149
|
+
}>;
|
|
150
|
+
query<T = any>(
|
|
151
|
+
sql: string,
|
|
152
|
+
params?:
|
|
153
|
+
| any[]
|
|
154
|
+
| {
|
|
155
|
+
[key: string]: any;
|
|
156
|
+
},
|
|
157
|
+
): Promise<T[]>;
|
|
158
|
+
private queryWithFields;
|
|
159
|
+
private formatQueryParams;
|
|
160
|
+
private isSqlDate;
|
|
161
|
+
private beginTransaction;
|
|
162
|
+
private commitTransaction;
|
|
163
|
+
private rollbackTransaction;
|
|
164
|
+
private queryOnConnection;
|
|
165
|
+
private queryOnConnectionWithFields;
|
|
166
|
+
private buildExecOnConnection;
|
|
167
|
+
/**
|
|
168
|
+
* Executes a callback inside a database transaction.
|
|
169
|
+
* Automatically calls BEGIN before and COMMIT after the callback.
|
|
170
|
+
* If the callback throws, the transaction is rolled back and the error is re-thrown.
|
|
171
|
+
*
|
|
172
|
+
* @template T - The return type of the callback
|
|
173
|
+
* @param fn - An async function that receives a {@link ZTransaction} handle
|
|
174
|
+
* @returns The value returned by `fn`
|
|
175
|
+
*
|
|
176
|
+
* @example
|
|
177
|
+
* ```ts
|
|
178
|
+
* const result = await sqlService.transaction(async (trx) => {
|
|
179
|
+
* await trx.query('INSERT INTO orders (customer_id) VALUES (:id)', { id: 42 })
|
|
180
|
+
* await trx.query('UPDATE inventory SET stock = stock - 1 WHERE product_id = :pid', { pid: 7 })
|
|
181
|
+
* return 'done'
|
|
182
|
+
* })
|
|
183
|
+
* ```
|
|
184
|
+
*/
|
|
185
|
+
transaction<T = void>(fn: (trx: ZTransaction) => Promise<T>): Promise<T>;
|
|
186
|
+
/**
|
|
187
|
+
* Changes the active database by closing the current connection pool and creating a new one.
|
|
188
|
+
* All active connections will be gracefully closed before switching.
|
|
189
|
+
* @param newDatabase - The name of the database to switch to
|
|
190
|
+
* @returns Promise that resolves when the database has been changed successfully
|
|
191
|
+
* @throws Error if the pool cannot be closed or new pool cannot be created
|
|
192
|
+
*/
|
|
193
|
+
changeDatabase(newDatabase: string): Promise<void>;
|
|
194
|
+
}
|
|
195
|
+
export {};
|
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
var __createBinding =
|
|
3
|
+
(this && this.__createBinding) ||
|
|
4
|
+
(Object.create
|
|
5
|
+
? function (o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
+
if (!desc || ('get' in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
+
desc = {
|
|
10
|
+
enumerable: true,
|
|
11
|
+
get: function () {
|
|
12
|
+
return m[k];
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
Object.defineProperty(o, k2, desc);
|
|
17
|
+
}
|
|
18
|
+
: function (o, m, k, k2) {
|
|
19
|
+
if (k2 === undefined) k2 = k;
|
|
20
|
+
o[k2] = m[k];
|
|
21
|
+
});
|
|
22
|
+
var __setModuleDefault =
|
|
23
|
+
(this && this.__setModuleDefault) ||
|
|
24
|
+
(Object.create
|
|
25
|
+
? function (o, v) {
|
|
26
|
+
Object.defineProperty(o, 'default', { enumerable: true, value: v });
|
|
27
|
+
}
|
|
28
|
+
: function (o, v) {
|
|
29
|
+
o['default'] = v;
|
|
30
|
+
});
|
|
31
|
+
var __importStar =
|
|
32
|
+
(this && this.__importStar) ||
|
|
33
|
+
function (mod) {
|
|
34
|
+
if (mod && mod.__esModule) return mod;
|
|
35
|
+
var result = {};
|
|
36
|
+
if (mod != null)
|
|
37
|
+
for (var k in mod)
|
|
38
|
+
if (k !== 'default' && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
39
|
+
__setModuleDefault(result, mod);
|
|
40
|
+
return result;
|
|
41
|
+
};
|
|
42
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
43
|
+
exports.ZSQLService = void 0;
|
|
44
|
+
const mysql = __importStar(require('mysql'));
|
|
45
|
+
class ZSQLService {
|
|
46
|
+
get database() {
|
|
47
|
+
return this.databaseName;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Creates a new ZSQLService instance with a MySQL connection pool.
|
|
51
|
+
* @param options - MySQL pool configuration options including custom dateStringTimezone and parseBooleans settings
|
|
52
|
+
*/
|
|
53
|
+
constructor(options) {
|
|
54
|
+
this.options = options;
|
|
55
|
+
this.defaultPoolconfig = {
|
|
56
|
+
connectionLimit: 10,
|
|
57
|
+
timeout: 20000,
|
|
58
|
+
connectTimeout: 20000,
|
|
59
|
+
acquireTimeout: 20000,
|
|
60
|
+
};
|
|
61
|
+
this.listeners = { err: [], log: [] };
|
|
62
|
+
this.databaseName = options.database;
|
|
63
|
+
this.pool = mysql.createPool(Object.assign({}, this.defaultPoolconfig, options));
|
|
64
|
+
this.pool.on('connection', (connection) => {
|
|
65
|
+
// connection.config.queryFormat = function (query, values) {
|
|
66
|
+
// }
|
|
67
|
+
connection.on('error', (err) => {
|
|
68
|
+
this.triggerEvent('err', err);
|
|
69
|
+
});
|
|
70
|
+
connection.on('close', (err) => {
|
|
71
|
+
this.triggerEvent('err', err);
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
on(eventName, listener) {
|
|
76
|
+
if (!this.listeners.hasOwnProperty(eventName))
|
|
77
|
+
throw new Error(`EventName not supported for ZSqlService.on(${eventName}, ...)`);
|
|
78
|
+
this.listeners[eventName].push(listener);
|
|
79
|
+
}
|
|
80
|
+
triggerEvent(eventName, args) {
|
|
81
|
+
this.listeners[eventName].map((listener) => {
|
|
82
|
+
listener.apply(undefined, args);
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
getPoolConnection() {
|
|
86
|
+
return new Promise((resolve, reject) => {
|
|
87
|
+
this.pool.getConnection((err, con) => (err ? reject(err) : resolve(con)));
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
async exec(opt) {
|
|
91
|
+
const { results, fields } = await this.queryWithFields(opt.query, opt.params);
|
|
92
|
+
if (!Array.isArray(results)) {
|
|
93
|
+
return results;
|
|
94
|
+
}
|
|
95
|
+
if (!this.options.dateStringTimezone && !this.options.parseBooleans) {
|
|
96
|
+
return results;
|
|
97
|
+
}
|
|
98
|
+
// Build a set of column names that are TINYINT(1) for boolean conversion
|
|
99
|
+
const booleanColumns = new Set();
|
|
100
|
+
if (this.options.parseBooleans && fields) {
|
|
101
|
+
fields.forEach((field) => {
|
|
102
|
+
// Check if column is TINYINT(1) - type 1 is TINY, length 1 means TINYINT(1)
|
|
103
|
+
if (field.type === 1 && field.length === 1) {
|
|
104
|
+
booleanColumns.add(field.name);
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
return results.map((row) => {
|
|
109
|
+
Object.keys(row).map((key) => {
|
|
110
|
+
if (this.options.dateStringTimezone && this.isSqlDate(row[key])) {
|
|
111
|
+
row[key] = new Date(row[key] + this.options.dateStringTimezone);
|
|
112
|
+
}
|
|
113
|
+
if (this.options.parseBooleans && booleanColumns.has(key) && (row[key] === 0 || row[key] === 1)) {
|
|
114
|
+
row[key] = row[key] === 1;
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
return row;
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
async fetch(opt, params) {
|
|
121
|
+
if (typeof opt === 'string') {
|
|
122
|
+
return await this.exec({ query: opt, params });
|
|
123
|
+
}
|
|
124
|
+
return await this.exec({ query: opt.Query, params: opt.Params });
|
|
125
|
+
}
|
|
126
|
+
async query(sql, params) {
|
|
127
|
+
try {
|
|
128
|
+
const con = await this.getPoolConnection();
|
|
129
|
+
try {
|
|
130
|
+
const output = await new Promise((resolve, reject) => {
|
|
131
|
+
if (Array.isArray(params)) {
|
|
132
|
+
con.query(sql, params, (err, result) => (err ? reject(err) : resolve(result)));
|
|
133
|
+
} else {
|
|
134
|
+
sql = this.formatQueryParams(con, sql, params);
|
|
135
|
+
con.query(sql, (err, result) => (err ? reject(err) : resolve(result)));
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
con.release();
|
|
139
|
+
return output;
|
|
140
|
+
} catch (err) {
|
|
141
|
+
con.release();
|
|
142
|
+
throw err;
|
|
143
|
+
}
|
|
144
|
+
} catch (err) {
|
|
145
|
+
throw err;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
async queryWithFields(sql, params) {
|
|
149
|
+
try {
|
|
150
|
+
const con = await this.getPoolConnection();
|
|
151
|
+
try {
|
|
152
|
+
const output = await new Promise((resolve, reject) => {
|
|
153
|
+
if (Array.isArray(params)) {
|
|
154
|
+
con.query(sql, params, (err, results, fields) => {
|
|
155
|
+
if (err) {
|
|
156
|
+
reject(err);
|
|
157
|
+
} else {
|
|
158
|
+
resolve({ results, fields });
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
} else {
|
|
162
|
+
sql = this.formatQueryParams(con, sql, params);
|
|
163
|
+
con.query(sql, (err, results, fields) => {
|
|
164
|
+
if (err) {
|
|
165
|
+
reject(err);
|
|
166
|
+
} else {
|
|
167
|
+
resolve({ results, fields });
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
con.release();
|
|
173
|
+
return output;
|
|
174
|
+
} catch (err) {
|
|
175
|
+
con.release();
|
|
176
|
+
throw err;
|
|
177
|
+
}
|
|
178
|
+
} catch (err) {
|
|
179
|
+
throw err;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
formatQueryParams(con, query, values) {
|
|
183
|
+
if (!values) {
|
|
184
|
+
return query;
|
|
185
|
+
}
|
|
186
|
+
return query.replace(/\:(\w+)/g, (txt, key) => {
|
|
187
|
+
return values.hasOwnProperty(key) ? con.escape(values[key]) : txt;
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
isSqlDate(str) {
|
|
191
|
+
if (
|
|
192
|
+
str &&
|
|
193
|
+
typeof str === 'string' &&
|
|
194
|
+
str[4] === '-' &&
|
|
195
|
+
str[7] === '-' &&
|
|
196
|
+
str[10] === ' ' &&
|
|
197
|
+
str[13] === ':' &&
|
|
198
|
+
str[16] === ':'
|
|
199
|
+
) {
|
|
200
|
+
return true;
|
|
201
|
+
}
|
|
202
|
+
return false;
|
|
203
|
+
}
|
|
204
|
+
// ── Transaction helpers ────────────────────────────────────────────
|
|
205
|
+
beginTransaction(con) {
|
|
206
|
+
return new Promise((resolve, reject) => {
|
|
207
|
+
con.beginTransaction((err) => (err ? reject(err) : resolve()));
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
commitTransaction(con) {
|
|
211
|
+
return new Promise((resolve, reject) => {
|
|
212
|
+
con.commit((err) => (err ? reject(err) : resolve()));
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
rollbackTransaction(con) {
|
|
216
|
+
return new Promise((resolve, reject) => {
|
|
217
|
+
con.rollback(() => resolve()); // rollback should not throw
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
queryOnConnection(con, sql, params) {
|
|
221
|
+
return new Promise((resolve, reject) => {
|
|
222
|
+
if (Array.isArray(params)) {
|
|
223
|
+
con.query(sql, params, (err, result) => (err ? reject(err) : resolve(result)));
|
|
224
|
+
} else {
|
|
225
|
+
sql = this.formatQueryParams(con, sql, params);
|
|
226
|
+
con.query(sql, (err, result) => (err ? reject(err) : resolve(result)));
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
queryOnConnectionWithFields(con, sql, params) {
|
|
231
|
+
return new Promise((resolve, reject) => {
|
|
232
|
+
if (Array.isArray(params)) {
|
|
233
|
+
con.query(sql, params, (err, results, fields) => (err ? reject(err) : resolve({ results, fields })));
|
|
234
|
+
} else {
|
|
235
|
+
sql = this.formatQueryParams(con, sql, params);
|
|
236
|
+
con.query(sql, (err, results, fields) => (err ? reject(err) : resolve({ results, fields })));
|
|
237
|
+
}
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
buildExecOnConnection(con) {
|
|
241
|
+
const self = this;
|
|
242
|
+
return async function execOnConnection(opt) {
|
|
243
|
+
const { results, fields } = await self.queryOnConnectionWithFields(con, opt.query, opt.params);
|
|
244
|
+
if (!Array.isArray(results)) return results;
|
|
245
|
+
if (!self.options.dateStringTimezone && !self.options.parseBooleans) return results;
|
|
246
|
+
const booleanColumns = new Set();
|
|
247
|
+
if (self.options.parseBooleans && fields) {
|
|
248
|
+
fields.forEach((field) => {
|
|
249
|
+
if (field.type === 1 && field.length === 1) booleanColumns.add(field.name);
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
return results.map((row) => {
|
|
253
|
+
Object.keys(row).map((key) => {
|
|
254
|
+
if (self.options.dateStringTimezone && self.isSqlDate(row[key])) {
|
|
255
|
+
row[key] = new Date(row[key] + self.options.dateStringTimezone);
|
|
256
|
+
}
|
|
257
|
+
if (self.options.parseBooleans && booleanColumns.has(key) && (row[key] === 0 || row[key] === 1)) {
|
|
258
|
+
row[key] = row[key] === 1;
|
|
259
|
+
}
|
|
260
|
+
});
|
|
261
|
+
return row;
|
|
262
|
+
});
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Executes a callback inside a database transaction.
|
|
267
|
+
* Automatically calls BEGIN before and COMMIT after the callback.
|
|
268
|
+
* If the callback throws, the transaction is rolled back and the error is re-thrown.
|
|
269
|
+
*
|
|
270
|
+
* @template T - The return type of the callback
|
|
271
|
+
* @param fn - An async function that receives a {@link ZTransaction} handle
|
|
272
|
+
* @returns The value returned by `fn`
|
|
273
|
+
*
|
|
274
|
+
* @example
|
|
275
|
+
* ```ts
|
|
276
|
+
* const result = await sqlService.transaction(async (trx) => {
|
|
277
|
+
* await trx.query('INSERT INTO orders (customer_id) VALUES (:id)', { id: 42 })
|
|
278
|
+
* await trx.query('UPDATE inventory SET stock = stock - 1 WHERE product_id = :pid', { pid: 7 })
|
|
279
|
+
* return 'done'
|
|
280
|
+
* })
|
|
281
|
+
* ```
|
|
282
|
+
*/
|
|
283
|
+
async transaction(fn) {
|
|
284
|
+
const con = await this.getPoolConnection();
|
|
285
|
+
await this.beginTransaction(con);
|
|
286
|
+
const trx = {
|
|
287
|
+
query: (sql, params) => {
|
|
288
|
+
return this.queryOnConnection(con, sql, params);
|
|
289
|
+
},
|
|
290
|
+
exec: this.buildExecOnConnection(con),
|
|
291
|
+
};
|
|
292
|
+
try {
|
|
293
|
+
const result = await fn(trx);
|
|
294
|
+
await this.commitTransaction(con);
|
|
295
|
+
con.release();
|
|
296
|
+
return result;
|
|
297
|
+
} catch (err) {
|
|
298
|
+
await this.rollbackTransaction(con);
|
|
299
|
+
con.release();
|
|
300
|
+
throw err;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Changes the active database by closing the current connection pool and creating a new one.
|
|
305
|
+
* All active connections will be gracefully closed before switching.
|
|
306
|
+
* @param newDatabase - The name of the database to switch to
|
|
307
|
+
* @returns Promise that resolves when the database has been changed successfully
|
|
308
|
+
* @throws Error if the pool cannot be closed or new pool cannot be created
|
|
309
|
+
*/
|
|
310
|
+
async changeDatabase(newDatabase) {
|
|
311
|
+
return new Promise((resolve, reject) => {
|
|
312
|
+
this.pool.end((err) => {
|
|
313
|
+
if (err) {
|
|
314
|
+
reject(err);
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
this.databaseName = newDatabase;
|
|
318
|
+
const newOptions = { ...this.options, database: newDatabase };
|
|
319
|
+
this.pool = mysql.createPool(Object.assign({}, this.defaultPoolconfig, newOptions));
|
|
320
|
+
this.pool.on('connection', (connection) => {
|
|
321
|
+
connection.on('error', (err) => {
|
|
322
|
+
this.triggerEvent('err', err);
|
|
323
|
+
});
|
|
324
|
+
connection.on('close', (err) => {
|
|
325
|
+
this.triggerEvent('err', err);
|
|
326
|
+
});
|
|
327
|
+
});
|
|
328
|
+
resolve();
|
|
329
|
+
});
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
exports.ZSQLService = ZSQLService;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { TranslateData, dbTranslationRow, ATranslateLang, TranslateServiceOptions } from './types/translate_types';
|
|
2
|
+
export declare class ZTranslateService {
|
|
3
|
+
private opt;
|
|
4
|
+
private localCache;
|
|
5
|
+
private get sql();
|
|
6
|
+
surpressErrors: boolean;
|
|
7
|
+
private maxRetries;
|
|
8
|
+
private retryDelay;
|
|
9
|
+
private fallbackText;
|
|
10
|
+
getLanguages(): ATranslateLang[];
|
|
11
|
+
getSourceLang(): string;
|
|
12
|
+
getDefaultLang(): string;
|
|
13
|
+
constructor(opt: TranslateServiceOptions);
|
|
14
|
+
private codes;
|
|
15
|
+
getLang(cookies: { [key: string]: string }): string;
|
|
16
|
+
private sleep;
|
|
17
|
+
private logError;
|
|
18
|
+
private retryOperation;
|
|
19
|
+
translateText(langOrReq: string | any, text: string): Promise<string>;
|
|
20
|
+
private processHtmlEntities;
|
|
21
|
+
translateHtml(
|
|
22
|
+
html: string,
|
|
23
|
+
cookies: {
|
|
24
|
+
lang: string;
|
|
25
|
+
} & {
|
|
26
|
+
[key: string]: string;
|
|
27
|
+
},
|
|
28
|
+
): Promise<string>;
|
|
29
|
+
private translateHtmlRec;
|
|
30
|
+
update(
|
|
31
|
+
key: string,
|
|
32
|
+
lang: string,
|
|
33
|
+
data: TranslateData,
|
|
34
|
+
): Promise<{
|
|
35
|
+
insertId: number;
|
|
36
|
+
affectedRows: number;
|
|
37
|
+
}>;
|
|
38
|
+
private checkLocalCache;
|
|
39
|
+
private insertLocalCache;
|
|
40
|
+
private clearLocalCache;
|
|
41
|
+
private fetch;
|
|
42
|
+
private insert;
|
|
43
|
+
private fetchLang;
|
|
44
|
+
fetchAllGrouped(): Promise<{
|
|
45
|
+
[key: string]: dbTranslationRow[];
|
|
46
|
+
}>;
|
|
47
|
+
private fetchAll;
|
|
48
|
+
}
|