utilitas 1995.2.7 → 1995.2.9
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/README.md +5 -2
- package/dist/utilitas.lite.mjs +1 -1
- package/dist/utilitas.lite.mjs.map +1 -1
- package/lib/dbio.mjs +114 -38
- package/lib/manifest.mjs +10 -8
- package/lib/shot.mjs +1 -3
- package/lib/vision.mjs +45 -4
- package/package.json +10 -8
package/lib/dbio.mjs
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
assertSet, ensureArray, ensureString, log as _log, need,
|
|
3
|
+
} from './utilitas.mjs';
|
|
4
|
+
|
|
2
5
|
import { isPrimary } from './callosum.mjs';
|
|
3
6
|
|
|
4
|
-
const _NEED = ['mysql2'];
|
|
5
|
-
const
|
|
7
|
+
const _NEED = ['mysql2', 'pg'];
|
|
8
|
+
const [mysqlDefaultPort, postgresqlDefaultPort] = [3306, 5432];
|
|
6
9
|
const orders = { '+': 'ASC', '-': 'DESC' };
|
|
7
10
|
const [fieldId, fieldAny] = ['id', '*'];
|
|
8
11
|
const fieldCount = `COUNT(${fieldAny})`;
|
|
@@ -12,16 +15,47 @@ const log = (content) => _log(content, import.meta.url);
|
|
|
12
15
|
const defaultKey = (options) => options && options.key ? options.key : fieldId;
|
|
13
16
|
const queryOne = async (...args) => (await query(...args))[0];
|
|
14
17
|
const assertForce = op => assert(op?.force, "Option 'force' is required.", 500);
|
|
18
|
+
const [MYSQL, POSTGRESQL] = ['MYSQL', 'POSTGRESQL'];
|
|
19
|
+
const quote = name => `${bracket}${name}${bracket}`;
|
|
20
|
+
const join = elements => elements.join(', ');
|
|
15
21
|
|
|
16
|
-
let pool;
|
|
22
|
+
let [provider, pool, actExecute, bracket, actDuplicate] = [];
|
|
17
23
|
|
|
18
24
|
const init = async (options) => {
|
|
19
25
|
if (options) {
|
|
20
|
-
const
|
|
21
|
-
|
|
26
|
+
const _provider = ensureString(options?.provider, { case: 'UP' });
|
|
27
|
+
let port;
|
|
28
|
+
switch (_provider) {
|
|
29
|
+
case MYSQL:
|
|
30
|
+
case 'MARIA':
|
|
31
|
+
case 'MARIADB':
|
|
32
|
+
const mysql = await need('mysql2/promise');
|
|
33
|
+
delete options.provider;
|
|
34
|
+
[provider, pool, port, actExecute, bracket, actDuplicate] = [
|
|
35
|
+
MYSQL, mysql.createPool(options), mysqlDefaultPort,
|
|
36
|
+
'execute', '`', 'ON DUPLICATE KEY',
|
|
37
|
+
];
|
|
38
|
+
break;
|
|
39
|
+
case 'PG':
|
|
40
|
+
case 'POSTGRE':
|
|
41
|
+
case 'PSQL':
|
|
42
|
+
case POSTGRESQL:
|
|
43
|
+
// https://node-postgres.com/apis/pool
|
|
44
|
+
const { Pool } = await need('pg');
|
|
45
|
+
[provider, pool, port, actExecute, bracket, actDuplicate] = [
|
|
46
|
+
POSTGRESQL, new Pool(options), postgresqlDefaultPort,
|
|
47
|
+
'query', '', 'ON CONFLICT DO',
|
|
48
|
+
];
|
|
49
|
+
break;
|
|
50
|
+
default:
|
|
51
|
+
assert(
|
|
52
|
+
!options?.provider,
|
|
53
|
+
`Invalid database provider: '${options.provider}'.`, 400
|
|
54
|
+
);
|
|
55
|
+
}
|
|
22
56
|
isPrimary && !options.silent && log(
|
|
23
|
-
`Initialized:
|
|
24
|
-
+
|
|
57
|
+
`Initialized: ${_provider.toLowerCase()}://${options.user}@`
|
|
58
|
+
+ `${options.host}:${options.port || port}/${options.database}`
|
|
25
59
|
);
|
|
26
60
|
}
|
|
27
61
|
assert(pool, 'Database has not been initialized.', 501);
|
|
@@ -34,8 +68,9 @@ const end = async (options) => {
|
|
|
34
68
|
};
|
|
35
69
|
|
|
36
70
|
const logCommand = (args) => {
|
|
37
|
-
|
|
38
|
-
if (~~globalThis.debug >
|
|
71
|
+
const _args = ensureArray(args);
|
|
72
|
+
if (~~globalThis.debug > 0 && _args && _args[0]) { log(`SQL: ${_args[0]}`); }
|
|
73
|
+
if (~~globalThis.debug > 1 && _args && _args[1]) { console.log(_args[1]); };
|
|
39
74
|
};
|
|
40
75
|
|
|
41
76
|
const getComparison = (val) => Object.isObject(val)
|
|
@@ -61,16 +96,28 @@ const rawQuery = async (...args) => {
|
|
|
61
96
|
|
|
62
97
|
const rawExecute = async (...args) => {
|
|
63
98
|
const conn = await init();
|
|
99
|
+
console.log(args);
|
|
64
100
|
logCommand(...args);
|
|
65
|
-
return await conn
|
|
101
|
+
return await conn[actExecute](...args);
|
|
66
102
|
};
|
|
67
103
|
|
|
68
|
-
const
|
|
69
|
-
|
|
104
|
+
const handleResult = result => {
|
|
105
|
+
switch (provider) {
|
|
106
|
+
case MYSQL: return result[0];
|
|
107
|
+
case POSTGRESQL: return result.rows;
|
|
108
|
+
}
|
|
70
109
|
};
|
|
71
110
|
|
|
111
|
+
const query = async (...args) => handleResult(
|
|
112
|
+
await rawQuery(...distillArguments(...args))
|
|
113
|
+
);
|
|
114
|
+
|
|
72
115
|
const execute = async (...args) => {
|
|
73
|
-
|
|
116
|
+
const resp = await rawExecute(...distillArguments(...args));
|
|
117
|
+
switch (provider) {
|
|
118
|
+
case MYSQL: return resp[0];
|
|
119
|
+
case POSTGRESQL: return resp;
|
|
120
|
+
}
|
|
74
121
|
};
|
|
75
122
|
|
|
76
123
|
const assertTable = (table, message, status) =>
|
|
@@ -92,10 +139,10 @@ const assembleQuery = (table, options) => {
|
|
|
92
139
|
const fields = [];
|
|
93
140
|
ensureArray(options.fields).map((field) => {
|
|
94
141
|
fields.push(fieldNoQuote.includes(field) || options.noQuote
|
|
95
|
-
? field :
|
|
142
|
+
? field : quote(field));
|
|
96
143
|
});
|
|
97
144
|
if (!fields.length) { fields.push(fieldAny); }
|
|
98
|
-
return `SELECT ${
|
|
145
|
+
return `SELECT ${join(fields)} FROM ${quote(table)}`;
|
|
99
146
|
};
|
|
100
147
|
|
|
101
148
|
const rawAssembleKeyValue = (key, value, options) => {
|
|
@@ -106,7 +153,7 @@ const rawAssembleKeyValue = (key, value, options) => {
|
|
|
106
153
|
assert(value.length, 'Invalid array value.', 500);
|
|
107
154
|
express = 'IN (?)';
|
|
108
155
|
} else if (value === null) { express = 'IS ?'; }
|
|
109
|
-
return `${options.prefix || ''}
|
|
156
|
+
return `${options.prefix || ''}${quote(key)} ${express}`;
|
|
110
157
|
};
|
|
111
158
|
|
|
112
159
|
const assembleKeyValue = (key, value, options) => {
|
|
@@ -124,22 +171,26 @@ const assembleSet = (data, options) => {
|
|
|
124
171
|
const [isArray, result] = [options.asArray || Array.isArray(data), []];
|
|
125
172
|
ensureArray(data).map((item) => {
|
|
126
173
|
assert(Object.keys(item).length, 'Fields are required.', 500);
|
|
127
|
-
let [
|
|
174
|
+
let [keys, vals, values, dupSql] = [[], [], [], []];
|
|
128
175
|
for (let k in item) {
|
|
129
|
-
|
|
176
|
+
keys.push(k);
|
|
177
|
+
switch (provider) {
|
|
178
|
+
case MYSQL: vals.push('?'); break;
|
|
179
|
+
case POSTGRESQL: vals.push(`$${vals.length + 1}`); break;
|
|
180
|
+
}
|
|
130
181
|
pushValue(values, item[k]);
|
|
131
182
|
}
|
|
132
183
|
if (options.upsert) {
|
|
133
184
|
for (let k in item) {
|
|
134
|
-
dupSql.push(
|
|
185
|
+
dupSql.push(`${quote(k)} = ?`);
|
|
135
186
|
pushValue(values, item[k]);
|
|
136
187
|
}
|
|
137
|
-
dupSql = `
|
|
188
|
+
dupSql = ` ${actDuplicate} UPDATE ${join(dupSql)}`;
|
|
138
189
|
} else { dupSql = ''; }
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
});
|
|
190
|
+
const sql = `${options.prefix || ''}`
|
|
191
|
+
+ `(${join(keys.map(quote))}) VALUES (${join(vals)})${dupSql}`
|
|
192
|
+
+ `${options.subfix || ''}`
|
|
193
|
+
result.push({ sql, values, object: item });
|
|
143
194
|
});
|
|
144
195
|
return isArray ? result : result[0];
|
|
145
196
|
};
|
|
@@ -147,20 +198,20 @@ const assembleSet = (data, options) => {
|
|
|
147
198
|
const assembleInsert = (table, data, options) => {
|
|
148
199
|
options = options || {};
|
|
149
200
|
assertTable(table);
|
|
150
|
-
options.prefix = `INSERT INTO
|
|
201
|
+
options.prefix = `INSERT INTO ${quote(table)} `;
|
|
151
202
|
return assembleSet(data, options);
|
|
152
203
|
};
|
|
153
204
|
|
|
154
205
|
const assembleUpdate = (table, data, options) => {
|
|
155
206
|
options = options || {};
|
|
156
207
|
assertTable(table);
|
|
157
|
-
options.prefix = `UPDATE
|
|
208
|
+
options.prefix = `UPDATE ${quote(table)} `;
|
|
158
209
|
return assembleSet(data, options);
|
|
159
210
|
};
|
|
160
211
|
|
|
161
212
|
const assembleDelete = (table) => {
|
|
162
213
|
assertTable(table);
|
|
163
|
-
return `DELETE FROM
|
|
214
|
+
return `DELETE FROM ${quote(table)}`;
|
|
164
215
|
};
|
|
165
216
|
|
|
166
217
|
const assembleTail = (options) => {
|
|
@@ -168,15 +219,28 @@ const assembleTail = (options) => {
|
|
|
168
219
|
ensureArray(options?.order || []).map?.(x => {
|
|
169
220
|
const ord = Object.isObject(x) ? x : { [x]: '+' };
|
|
170
221
|
const key = Object.keys(ord)[0];
|
|
171
|
-
sort.push(
|
|
222
|
+
sort.push(`${quote(key)} ${getOrder(ord[key])}`);
|
|
172
223
|
});
|
|
173
|
-
return (sort.length ? ` ORDER BY ${
|
|
224
|
+
return (sort.length ? ` ORDER BY ${join(sort)}` : '')
|
|
174
225
|
+ (~~options?.limit ? ` LIMIT ${~~options.limit}` : '');
|
|
175
226
|
};
|
|
176
227
|
|
|
177
228
|
const tables = async (options) => {
|
|
178
|
-
|
|
179
|
-
|
|
229
|
+
let sql = '';
|
|
230
|
+
switch (provider) {
|
|
231
|
+
case MYSQL:
|
|
232
|
+
sql = 'SHOW TABLES';
|
|
233
|
+
break;
|
|
234
|
+
case POSTGRESQL:
|
|
235
|
+
sql = "SELECT * FROM information_schema.tables WHERE table_schema = 'public'";
|
|
236
|
+
}
|
|
237
|
+
const resp = await query(sql);
|
|
238
|
+
return options?.raw ? resp : resp.map(x => {
|
|
239
|
+
switch (provider) {
|
|
240
|
+
case MYSQL: return Object.values(x)[0];
|
|
241
|
+
case POSTGRESQL: return x.table_name;
|
|
242
|
+
}
|
|
243
|
+
});
|
|
180
244
|
};
|
|
181
245
|
|
|
182
246
|
const desc = async (table, options) => {
|
|
@@ -198,7 +262,7 @@ const indexes = async (table, options) => {
|
|
|
198
262
|
const drop = async (table, options) => {
|
|
199
263
|
assertTable(table);
|
|
200
264
|
assertForce(options);
|
|
201
|
-
return await query(
|
|
265
|
+
return await query('DROP TABLE IF EXISTS ??', [table]);
|
|
202
266
|
};
|
|
203
267
|
|
|
204
268
|
const queryAll = (table, options) =>
|
|
@@ -223,20 +287,32 @@ const insert = async (table, fields, options) => {
|
|
|
223
287
|
options = options || {};
|
|
224
288
|
let [isArray, key, ids, error, result]
|
|
225
289
|
= [Array.isArray(fields), defaultKey(options), [], [], []];
|
|
290
|
+
const subfix = provider === POSTGRESQL ? (options.skipEcho ? (
|
|
291
|
+
options.key ? ` RETURNING ${key}` : ''
|
|
292
|
+
) : ` RETURNING *`) : '';
|
|
226
293
|
for (let item of assembleInsert(
|
|
227
|
-
table, fields, { ...options, asArray: true }
|
|
228
|
-
)
|
|
294
|
+
table, fields, { ...options, asArray: true, subfix })
|
|
295
|
+
) {
|
|
229
296
|
try {
|
|
230
297
|
const resp = await execute(item.sql, item.values);
|
|
298
|
+
if (provider === POSTGRESQL) {
|
|
299
|
+
resp.affectedRows = resp.rowCount;
|
|
300
|
+
}
|
|
231
301
|
resp.key = key;
|
|
232
|
-
|
|
233
|
-
|
|
302
|
+
!resp.insertId && item.object[key]
|
|
303
|
+
&& (resp.insertId = item.object[key]);
|
|
234
304
|
result.push(resp);
|
|
235
305
|
ids.push(resp.insertId);
|
|
236
306
|
} catch (err) { error.push(err); }
|
|
237
307
|
}
|
|
238
308
|
if (!options.skipEcho && ids.length) {
|
|
239
|
-
|
|
309
|
+
switch (provider) {
|
|
310
|
+
case MYSQL:
|
|
311
|
+
result = await queryById(table, ids, options);
|
|
312
|
+
break;
|
|
313
|
+
case POSTGRESQL:
|
|
314
|
+
result = result.map(x => x.rows).flat();
|
|
315
|
+
}
|
|
240
316
|
}
|
|
241
317
|
if (!isArray) {
|
|
242
318
|
if (error.length) { throw error[0]; }
|
package/lib/manifest.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const manifest = {
|
|
2
2
|
"name": "utilitas",
|
|
3
3
|
"description": "Just another common utility for JavaScript.",
|
|
4
|
-
"version": "1995.2.
|
|
4
|
+
"version": "1995.2.9",
|
|
5
5
|
"private": false,
|
|
6
6
|
"homepage": "https://github.com/Leask/utilitas",
|
|
7
7
|
"main": "index.mjs",
|
|
@@ -28,7 +28,7 @@ const manifest = {
|
|
|
28
28
|
"@google-cloud/text-to-speech": "^5.0.1",
|
|
29
29
|
"@google-cloud/vision": "^4.0.2",
|
|
30
30
|
"@mozilla/readability": "^0.4.4",
|
|
31
|
-
"@sentry/node": "^7.
|
|
31
|
+
"@sentry/node": "^7.83.0",
|
|
32
32
|
"@waylaidwanderer/chatgpt-api": "^1.37.3",
|
|
33
33
|
"acme-client": "^5.0.0",
|
|
34
34
|
"browserify-fs": "^1.0.0",
|
|
@@ -37,24 +37,26 @@ const manifest = {
|
|
|
37
37
|
"fluent-ffmpeg": "^2.1.2",
|
|
38
38
|
"form-data": "^4.0.0",
|
|
39
39
|
"ioredis": "^5.3.2",
|
|
40
|
-
"jsdom": "^
|
|
40
|
+
"jsdom": "^23.0.0",
|
|
41
41
|
"lorem-ipsum": "^2.0.8",
|
|
42
42
|
"mailgun.js": "^9.3.0",
|
|
43
43
|
"mime-types": "^2.1.35",
|
|
44
|
-
"mysql2": "^3.6.
|
|
45
|
-
"node-mailjet": "^6.0.
|
|
44
|
+
"mysql2": "^3.6.5",
|
|
45
|
+
"node-mailjet": "^6.0.5",
|
|
46
46
|
"node-polyfill-webpack-plugin": "^2.0.1",
|
|
47
47
|
"office-text-extractor": "^3.0.2",
|
|
48
|
-
"openai": "^4.
|
|
48
|
+
"openai": "^4.20.1",
|
|
49
|
+
"pdfjs-dist": "^4.0.269",
|
|
50
|
+
"pg": "^8.11.3",
|
|
49
51
|
"ping": "^0.4.4",
|
|
50
52
|
"say": "^0.16.0",
|
|
51
|
-
"telegraf": "^4.15.
|
|
53
|
+
"telegraf": "^4.15.2",
|
|
52
54
|
"telesignsdk": "^2.2.3",
|
|
53
55
|
"tesseract.js": "^5.0.3",
|
|
54
56
|
"twilio": "^4.19.0",
|
|
55
57
|
"url": "github:Leask/node-url",
|
|
56
58
|
"webpack-cli": "^5.1.4",
|
|
57
|
-
"whisper-node": "^
|
|
59
|
+
"whisper-node": "^1.1.1",
|
|
58
60
|
"youtube-transcript": "^1.0.6"
|
|
59
61
|
}
|
|
60
62
|
};
|
package/lib/shot.mjs
CHANGED
|
@@ -122,14 +122,12 @@ const get = async (url, options) => {
|
|
|
122
122
|
case _JSON:
|
|
123
123
|
content = parseJson(buf2utf(buffer), null);
|
|
124
124
|
break;
|
|
125
|
-
case 'TEXT':
|
|
126
|
-
content = buf2utf(buffer);
|
|
127
|
-
break;
|
|
128
125
|
case _PARSED:
|
|
129
126
|
content = await distillHtml(buf2utf(buffer));
|
|
130
127
|
break;
|
|
131
128
|
default:
|
|
132
129
|
assert(!options.encode, 'Invalid encoding.', 400);
|
|
130
|
+
case 'TEXT':
|
|
133
131
|
content = buf2utf(buffer);
|
|
134
132
|
}
|
|
135
133
|
}
|
package/lib/vision.mjs
CHANGED
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
import { getApiKeyCredentials } from './encryption.mjs';
|
|
2
|
-
import get from './shot.mjs';
|
|
3
|
-
|
|
4
1
|
import {
|
|
5
2
|
convert, deleteOnCloud, downloadFromCloud, getIdByGs, uploadToCloud,
|
|
6
3
|
} from './storage.mjs';
|
|
@@ -9,7 +6,9 @@ import {
|
|
|
9
6
|
ensureArray, ignoreErrFunc, log as _log, need, throwError, trim,
|
|
10
7
|
} from './utilitas.mjs';
|
|
11
8
|
|
|
12
|
-
|
|
9
|
+
import { getApiKeyCredentials } from './encryption.mjs';
|
|
10
|
+
|
|
11
|
+
const _NEED = ['@google-cloud/vision', 'pdfjs-dist', 'tesseract.js'];
|
|
13
12
|
const [BASE64, BUFFER, FILE, DEFAULT_LANG] = ['BASE64', 'BUFFER', 'FILE', 'eng'];
|
|
14
13
|
const ceil = num => num.toFixed(4);
|
|
15
14
|
const errorMessage = 'Invalid image data.';
|
|
@@ -128,6 +127,12 @@ const see = async (image, options) => {
|
|
|
128
127
|
|
|
129
128
|
const read = async (image, options) => {
|
|
130
129
|
assert(client, 'Vision API has not been initialized.', 500);
|
|
130
|
+
if (options?.allPages) {
|
|
131
|
+
assert(options?.input === FILE, 'Only file input is supported.', 400);
|
|
132
|
+
if ((await getPdfInfo(image)).numPages > pages.length) {
|
|
133
|
+
return await readAll(image, options);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
131
136
|
const content = await convert(image, {
|
|
132
137
|
input: options?.input, expected: BASE64, errorMessage,
|
|
133
138
|
});
|
|
@@ -163,9 +168,45 @@ const readAll = async (image, options) => {
|
|
|
163
168
|
).flat();
|
|
164
169
|
};
|
|
165
170
|
|
|
171
|
+
const getPdfPage = async (doc, pageNum) => {
|
|
172
|
+
const page = await doc.getPage(pageNum);
|
|
173
|
+
const viewport = page.getViewport({ scale: 1.0 });
|
|
174
|
+
const result = {
|
|
175
|
+
pageNum: pageNum,
|
|
176
|
+
width: viewport.width,
|
|
177
|
+
height: viewport.height,
|
|
178
|
+
content: (await page.getTextContent()).items.map(x => x.str).join(' '),
|
|
179
|
+
};
|
|
180
|
+
page.cleanup();
|
|
181
|
+
return result
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
const getPdfPages = async (doc) => {
|
|
185
|
+
const result = [];
|
|
186
|
+
for (let i = 1; i <= doc.numPages; i++) { result.push(getPdfPage(doc, i)); }
|
|
187
|
+
return await Promise.all(result);
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
// https://github.com/mozilla/pdf.js/blob/master/examples/node/getinfo.mjs
|
|
191
|
+
const getPdfInfo = async (file, options) => {
|
|
192
|
+
const { getDocument } = await need('pdfjs-dist');
|
|
193
|
+
const doc = await getDocument(file).promise;
|
|
194
|
+
const data = await doc.getMetadata();
|
|
195
|
+
const result = {
|
|
196
|
+
numPages: doc.numPages,
|
|
197
|
+
info: data.info,
|
|
198
|
+
metadata: { ...data.metadata.getAll() },
|
|
199
|
+
pages: options?.withPages ? await getPdfPages(doc) : null,
|
|
200
|
+
};
|
|
201
|
+
return result;
|
|
202
|
+
};
|
|
203
|
+
|
|
166
204
|
export {
|
|
167
205
|
_NEED,
|
|
168
206
|
annotateImage,
|
|
207
|
+
getPdfInfo,
|
|
208
|
+
getPdfPage,
|
|
209
|
+
getPdfPages,
|
|
169
210
|
init,
|
|
170
211
|
ocrImage,
|
|
171
212
|
ocrImageGoogle,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "utilitas",
|
|
3
3
|
"description": "Just another common utility for JavaScript.",
|
|
4
|
-
"version": "1995.2.
|
|
4
|
+
"version": "1995.2.9",
|
|
5
5
|
"private": false,
|
|
6
6
|
"homepage": "https://github.com/Leask/utilitas",
|
|
7
7
|
"main": "index.mjs",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"@google-cloud/text-to-speech": "^5.0.1",
|
|
40
40
|
"@google-cloud/vision": "^4.0.2",
|
|
41
41
|
"@mozilla/readability": "^0.4.4",
|
|
42
|
-
"@sentry/node": "^7.
|
|
42
|
+
"@sentry/node": "^7.83.0",
|
|
43
43
|
"@waylaidwanderer/chatgpt-api": "^1.37.3",
|
|
44
44
|
"acme-client": "^5.0.0",
|
|
45
45
|
"browserify-fs": "^1.0.0",
|
|
@@ -48,24 +48,26 @@
|
|
|
48
48
|
"fluent-ffmpeg": "^2.1.2",
|
|
49
49
|
"form-data": "^4.0.0",
|
|
50
50
|
"ioredis": "^5.3.2",
|
|
51
|
-
"jsdom": "^
|
|
51
|
+
"jsdom": "^23.0.0",
|
|
52
52
|
"lorem-ipsum": "^2.0.8",
|
|
53
53
|
"mailgun.js": "^9.3.0",
|
|
54
54
|
"mime-types": "^2.1.35",
|
|
55
|
-
"mysql2": "^3.6.
|
|
56
|
-
"node-mailjet": "^6.0.
|
|
55
|
+
"mysql2": "^3.6.5",
|
|
56
|
+
"node-mailjet": "^6.0.5",
|
|
57
57
|
"node-polyfill-webpack-plugin": "^2.0.1",
|
|
58
58
|
"office-text-extractor": "^3.0.2",
|
|
59
|
-
"openai": "^4.
|
|
59
|
+
"openai": "^4.20.1",
|
|
60
|
+
"pdfjs-dist": "^4.0.269",
|
|
61
|
+
"pg": "^8.11.3",
|
|
60
62
|
"ping": "^0.4.4",
|
|
61
63
|
"say": "^0.16.0",
|
|
62
|
-
"telegraf": "^4.15.
|
|
64
|
+
"telegraf": "^4.15.2",
|
|
63
65
|
"telesignsdk": "^2.2.3",
|
|
64
66
|
"tesseract.js": "^5.0.3",
|
|
65
67
|
"twilio": "^4.19.0",
|
|
66
68
|
"url": "github:Leask/node-url",
|
|
67
69
|
"webpack-cli": "^5.1.4",
|
|
68
|
-
"whisper-node": "^
|
|
70
|
+
"whisper-node": "^1.1.1",
|
|
69
71
|
"youtube-transcript": "^1.0.6"
|
|
70
72
|
}
|
|
71
73
|
}
|