@domain.js/main 1.0.0-arpha.7 → 1.0.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.
- package/dist/defaults.d.ts +2 -2
- package/dist/defaults.js +2 -2
- package/dist/deps/aes/index.js +55 -68
- package/dist/deps/cache/index.d.ts +4 -0
- package/dist/deps/cache/index.js +1 -0
- package/dist/deps/defines.d.ts +2 -0
- package/dist/deps/defines.js +2 -0
- package/dist/deps/request/index.d.ts +34 -0
- package/dist/deps/request/index.js +72 -0
- package/package.json +30 -18
package/dist/defaults.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as ajv from "ajv";
|
|
2
2
|
import * as ajvFormats from "ajv-formats";
|
|
3
3
|
import ajvKeywords from "ajv-keywords";
|
|
4
|
-
import
|
|
4
|
+
import { CronExpressionParser } from "cron-parser";
|
|
5
5
|
import humanInterval from "human-interval";
|
|
6
6
|
import IORedis from "ioredis";
|
|
7
7
|
import LRU from "lru-cache";
|
|
@@ -27,7 +27,7 @@ export interface Defaults {
|
|
|
27
27
|
* It includes support for timezones and DST transitions.
|
|
28
28
|
* @link https://www.npmjs.com/package/cron-parser
|
|
29
29
|
*/
|
|
30
|
-
cronParser: typeof
|
|
30
|
+
cronParser: typeof CronExpressionParser;
|
|
31
31
|
/**
|
|
32
32
|
* Human-readable interval parser for Javascript.
|
|
33
33
|
* @link https://www.npmjs.com/package/human-interval
|
package/dist/defaults.js
CHANGED
|
@@ -40,7 +40,7 @@ exports.defaults = void 0;
|
|
|
40
40
|
const ajv = __importStar(require("ajv"));
|
|
41
41
|
const ajvFormats = __importStar(require("ajv-formats"));
|
|
42
42
|
const ajv_keywords_1 = __importDefault(require("ajv-keywords"));
|
|
43
|
-
const
|
|
43
|
+
const cron_parser_1 = require("cron-parser");
|
|
44
44
|
const human_interval_1 = __importDefault(require("human-interval"));
|
|
45
45
|
const ioredis_1 = __importDefault(require("ioredis"));
|
|
46
46
|
const lru_cache_1 = __importDefault(require("lru-cache"));
|
|
@@ -52,7 +52,7 @@ exports.defaults = {
|
|
|
52
52
|
ajv,
|
|
53
53
|
ajvFormats,
|
|
54
54
|
ajvKeywords: ajv_keywords_1.default,
|
|
55
|
-
cronParser,
|
|
55
|
+
cronParser: cron_parser_1.CronExpressionParser,
|
|
56
56
|
humanInterval: human_interval_1.default,
|
|
57
57
|
IORedis: ioredis_1.default,
|
|
58
58
|
LRU: lru_cache_1.default,
|
package/dist/deps/aes/index.js
CHANGED
|
@@ -1,81 +1,68 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
3
|
exports.Main = Main;
|
|
37
|
-
const
|
|
4
|
+
const node_crypto_1 = require("node:crypto");
|
|
5
|
+
const OPENSSL_MAGIC = Buffer.from("Salted__", "ascii");
|
|
6
|
+
const SALT_LEN = 8;
|
|
7
|
+
const KEY_LEN = 32;
|
|
8
|
+
const IV_LEN = 16;
|
|
9
|
+
/**
|
|
10
|
+
* EVP_BytesToKey compatible with OpenSSL / crypto-js:
|
|
11
|
+
* MD5, one iteration, D_i = MD5(D_{i-1} || password || salt); key then iv.
|
|
12
|
+
*/
|
|
13
|
+
function evpBytesToKey(password, salt) {
|
|
14
|
+
let keyLen = KEY_LEN;
|
|
15
|
+
let ivLen = IV_LEN;
|
|
16
|
+
const key = Buffer.alloc(KEY_LEN);
|
|
17
|
+
const iv = Buffer.alloc(IV_LEN);
|
|
18
|
+
let block = Buffer.alloc(0);
|
|
19
|
+
while (keyLen > 0 || ivLen > 0) {
|
|
20
|
+
const h = (0, node_crypto_1.createHash)("md5");
|
|
21
|
+
h.update(block);
|
|
22
|
+
h.update(password);
|
|
23
|
+
h.update(salt);
|
|
24
|
+
block = h.digest();
|
|
25
|
+
let used = 0;
|
|
26
|
+
if (keyLen > 0) {
|
|
27
|
+
const toCopy = Math.min(keyLen, block.length);
|
|
28
|
+
block.copy(key, KEY_LEN - keyLen, 0, toCopy);
|
|
29
|
+
used = toCopy;
|
|
30
|
+
keyLen -= toCopy;
|
|
31
|
+
}
|
|
32
|
+
if (used < block.length && ivLen > 0) {
|
|
33
|
+
const toCopy = Math.min(ivLen, block.length - used);
|
|
34
|
+
block.copy(iv, IV_LEN - ivLen, used, used + toCopy);
|
|
35
|
+
ivLen -= toCopy;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return { key, iv };
|
|
39
|
+
}
|
|
38
40
|
function Main() {
|
|
39
|
-
// aes-256-cbc encrypt
|
|
41
|
+
// aes-256-cbc encrypt (OpenSSL / crypto-js compatible: Salted__ + salt + ciphertext, base64)
|
|
40
42
|
const encrypt = (message, key) => {
|
|
41
|
-
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
cipher.setAutoPadding(true);
|
|
48
|
-
// 加密
|
|
49
|
-
let encrypted = cipher.update(message, "utf8", "hex");
|
|
50
|
-
encrypted += cipher.final("hex");
|
|
51
|
-
// 返回 IV + 加密数据的组合
|
|
52
|
-
const result = iv.toString("hex") + ":" + encrypted;
|
|
53
|
-
return result;
|
|
43
|
+
const salt = (0, node_crypto_1.randomBytes)(SALT_LEN);
|
|
44
|
+
const pass = Buffer.from(key, "utf8");
|
|
45
|
+
const { key: keyBuf, iv } = evpBytesToKey(pass, salt);
|
|
46
|
+
const cipher = (0, node_crypto_1.createCipheriv)("aes-256-cbc", keyBuf, iv);
|
|
47
|
+
const ciphertext = Buffer.concat([cipher.update(message, "utf8"), cipher.final()]);
|
|
48
|
+
return Buffer.concat([OPENSSL_MAGIC, salt, ciphertext]).toString("base64");
|
|
54
49
|
};
|
|
55
50
|
// aes-256-cbc decrypt
|
|
56
51
|
const decrypt = (message, key) => {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
if (parts.length !== 2) {
|
|
61
|
-
throw new Error("Invalid encrypted message format");
|
|
62
|
-
}
|
|
63
|
-
const iv = Buffer.from(parts[0], "hex");
|
|
64
|
-
const encrypted = parts[1];
|
|
65
|
-
// 使用相同的 PBKDF2 生成密钥
|
|
66
|
-
const derivedKey = crypto.pbkdf2Sync(key, "salt", 1000, 32, "sha256");
|
|
67
|
-
// 创建解密器
|
|
68
|
-
const decipher = crypto.createDecipheriv("aes-256-cbc", derivedKey, iv);
|
|
69
|
-
decipher.setAutoPadding(true);
|
|
70
|
-
// 解密
|
|
71
|
-
let decrypted = decipher.update(encrypted, "hex", "utf8");
|
|
72
|
-
decrypted += decipher.final("utf8");
|
|
73
|
-
return decrypted;
|
|
52
|
+
const raw = Buffer.from(message, "base64");
|
|
53
|
+
if (raw.length < OPENSSL_MAGIC.length + SALT_LEN) {
|
|
54
|
+
throw new Error("Invalid ciphertext: too short");
|
|
74
55
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
throw new Error("
|
|
56
|
+
const magic = raw.subarray(0, OPENSSL_MAGIC.length);
|
|
57
|
+
if (!magic.equals(OPENSSL_MAGIC)) {
|
|
58
|
+
throw new Error("Invalid ciphertext: missing OpenSSL Salted__ prefix");
|
|
78
59
|
}
|
|
60
|
+
const salt = raw.subarray(OPENSSL_MAGIC.length, OPENSSL_MAGIC.length + SALT_LEN);
|
|
61
|
+
const ciphertext = raw.subarray(OPENSSL_MAGIC.length + SALT_LEN);
|
|
62
|
+
const pass = Buffer.from(key, "utf8");
|
|
63
|
+
const { key: keyBuf, iv } = evpBytesToKey(pass, salt);
|
|
64
|
+
const decipher = (0, node_crypto_1.createDecipheriv)("aes-256-cbc", keyBuf, iv);
|
|
65
|
+
return decipher.update(ciphertext).toString("utf8") + decipher.final("utf8");
|
|
79
66
|
};
|
|
80
67
|
return Object.freeze({
|
|
81
68
|
encrypt,
|
|
@@ -16,6 +16,10 @@ export interface DepsDef {
|
|
|
16
16
|
}
|
|
17
17
|
export interface Cache extends LRUCache<{}, {}, unknown> {
|
|
18
18
|
caching: <T extends (...args: any[]) => Promise<any>>(func: T, life: number, getKey: (...args: Parameters<T>) => string, hit?: (hited: boolean) => void) => T;
|
|
19
|
+
/**
|
|
20
|
+
* @deprecated use delete instead of del
|
|
21
|
+
*/
|
|
22
|
+
del: (key: string) => boolean;
|
|
19
23
|
hitCount: () => {
|
|
20
24
|
hits: number;
|
|
21
25
|
misseds: number;
|
package/dist/deps/cache/index.js
CHANGED
package/dist/deps/defines.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ import * as logger from "./logger";
|
|
|
9
9
|
import * as myCia from "./myCia";
|
|
10
10
|
import * as parallel from "./parallel";
|
|
11
11
|
import * as redis from "./redis";
|
|
12
|
+
import * as request from "./request";
|
|
12
13
|
import * as rest from "./rest";
|
|
13
14
|
import * as schema from "./schema";
|
|
14
15
|
import * as sequelize from "./sequelize";
|
|
@@ -25,6 +26,7 @@ declare const _default: {
|
|
|
25
26
|
myCia: typeof myCia;
|
|
26
27
|
parallel: typeof parallel;
|
|
27
28
|
redis: typeof redis;
|
|
29
|
+
request: typeof request;
|
|
28
30
|
rest: typeof rest;
|
|
29
31
|
schema: typeof schema;
|
|
30
32
|
sequelize: typeof sequelize;
|
package/dist/deps/defines.js
CHANGED
|
@@ -44,6 +44,7 @@ const logger = __importStar(require("./logger"));
|
|
|
44
44
|
const myCia = __importStar(require("./myCia"));
|
|
45
45
|
const parallel = __importStar(require("./parallel"));
|
|
46
46
|
const redis = __importStar(require("./redis"));
|
|
47
|
+
const request = __importStar(require("./request"));
|
|
47
48
|
const rest = __importStar(require("./rest"));
|
|
48
49
|
const schema = __importStar(require("./schema"));
|
|
49
50
|
const sequelize = __importStar(require("./sequelize"));
|
|
@@ -60,6 +61,7 @@ module.exports = {
|
|
|
60
61
|
myCia: myCia,
|
|
61
62
|
parallel: parallel,
|
|
62
63
|
redis: redis,
|
|
64
|
+
request: request,
|
|
63
65
|
rest: rest,
|
|
64
66
|
schema: schema,
|
|
65
67
|
sequelize: sequelize,
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import axios, { AxiosInstance } from "axios";
|
|
2
|
+
import { Main as Logger } from "../logger";
|
|
3
|
+
interface Cnf {
|
|
4
|
+
/** axios config */
|
|
5
|
+
axios?: {
|
|
6
|
+
/** auto record log methods list */
|
|
7
|
+
loggers?: string[];
|
|
8
|
+
/** auto retry methods list */
|
|
9
|
+
retrys?: string[];
|
|
10
|
+
/** retry max times */
|
|
11
|
+
retryTimes?: number;
|
|
12
|
+
/** retry interval millisecond */
|
|
13
|
+
retryIntervalMS?: number;
|
|
14
|
+
/** axios.create the first argument */
|
|
15
|
+
conf?: Parameters<typeof axios.create>[0];
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
interface Deps {
|
|
19
|
+
logger: ReturnType<typeof Logger>;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* axios module
|
|
23
|
+
* @link https://www.npmjs.com/package/axios
|
|
24
|
+
*
|
|
25
|
+
* @param cnf module initialize config
|
|
26
|
+
* @param deps module initalize dependents
|
|
27
|
+
* @returns returns of axios.create
|
|
28
|
+
*/
|
|
29
|
+
export declare function Main(cnf: Cnf, deps: Deps): AxiosInstance & {
|
|
30
|
+
/** Original Axios module */
|
|
31
|
+
origin?: typeof axios;
|
|
32
|
+
};
|
|
33
|
+
export declare const Deps: string[];
|
|
34
|
+
export {};
|
|
@@ -0,0 +1,72 @@
|
|
|
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.Deps = void 0;
|
|
7
|
+
exports.Main = Main;
|
|
8
|
+
const axios_1 = __importDefault(require("axios"));
|
|
9
|
+
const utils_1 = require("../../utils");
|
|
10
|
+
/**
|
|
11
|
+
* axios module
|
|
12
|
+
* @link https://www.npmjs.com/package/axios
|
|
13
|
+
*
|
|
14
|
+
* @param cnf module initialize config
|
|
15
|
+
* @param deps module initalize dependents
|
|
16
|
+
* @returns returns of axios.create
|
|
17
|
+
*/
|
|
18
|
+
function Main(cnf, deps) {
|
|
19
|
+
const axiosError = (e) => (() => {
|
|
20
|
+
if (!e.response)
|
|
21
|
+
return ["no-response", e.message];
|
|
22
|
+
const r = e.response;
|
|
23
|
+
if (!r.data)
|
|
24
|
+
return [r.status, r.statusText];
|
|
25
|
+
const d = r.data;
|
|
26
|
+
if (typeof d === "string")
|
|
27
|
+
return [r.status, d];
|
|
28
|
+
return [d.code || r.status, d.message || JSON.stringify(d)];
|
|
29
|
+
})().join("\t");
|
|
30
|
+
if (!cnf.axios)
|
|
31
|
+
cnf.axios = {};
|
|
32
|
+
const { loggers, retrys, retryTimes = 3, retryIntervalMS = 3000, conf } = cnf.axios;
|
|
33
|
+
const { logger } = deps;
|
|
34
|
+
const retryAble = (fn, times, interval) => {
|
|
35
|
+
const exec = async (args, no) => {
|
|
36
|
+
try {
|
|
37
|
+
const res = await fn(...args);
|
|
38
|
+
return res;
|
|
39
|
+
}
|
|
40
|
+
catch (e) {
|
|
41
|
+
if (e.code === "ETIMEDOUT") {
|
|
42
|
+
if (interval)
|
|
43
|
+
await (0, utils_1.sleep)(interval);
|
|
44
|
+
if (times <= no)
|
|
45
|
+
throw e;
|
|
46
|
+
return exec(args, no + 1);
|
|
47
|
+
}
|
|
48
|
+
throw e;
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
return ((...args) => exec(args, 1));
|
|
52
|
+
};
|
|
53
|
+
const instance = axios_1.default.create(conf);
|
|
54
|
+
instance.origin = axios_1.default;
|
|
55
|
+
if (loggers) {
|
|
56
|
+
for (const x of loggers) {
|
|
57
|
+
if (typeof instance[x] !== "function")
|
|
58
|
+
continue;
|
|
59
|
+
const method = logger.logger(instance[x], `axios.${x}`, true, (res) => res.data, axiosError);
|
|
60
|
+
instance[x] = method;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (retrys) {
|
|
64
|
+
for (const x of retrys) {
|
|
65
|
+
if (typeof instance[x] !== "function")
|
|
66
|
+
continue;
|
|
67
|
+
instance[x] = retryAble(instance[x], retryTimes, retryIntervalMS);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return instance;
|
|
71
|
+
}
|
|
72
|
+
exports.Deps = ["logger"];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@domain.js/main",
|
|
3
|
-
"version": "1.0.0
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "DDD framework",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -16,9 +16,20 @@
|
|
|
16
16
|
},
|
|
17
17
|
"author": "Redstone Zhao",
|
|
18
18
|
"license": "MIT",
|
|
19
|
+
"prettier": {
|
|
20
|
+
"printWidth": 100,
|
|
21
|
+
"trailingComma": "all"
|
|
22
|
+
},
|
|
23
|
+
"lint-staged": {
|
|
24
|
+
"src/**/*.{js,ts}": [
|
|
25
|
+
"prettier --write",
|
|
26
|
+
"eslint --fix"
|
|
27
|
+
]
|
|
28
|
+
},
|
|
19
29
|
"devDependencies": {
|
|
20
30
|
"@babel/eslint-parser": "^7.28.6",
|
|
21
31
|
"@eslint/js": "^10.0.1",
|
|
32
|
+
"@fastify/multipart": "^9.4.0",
|
|
22
33
|
"@types/async": "^3.2.25",
|
|
23
34
|
"@types/jest": "^30.0.0",
|
|
24
35
|
"@types/lodash": "^4.17.24",
|
|
@@ -27,6 +38,8 @@
|
|
|
27
38
|
"@types/ws": "^8.18.1",
|
|
28
39
|
"@typescript-eslint/eslint-plugin": "^8.56.0",
|
|
29
40
|
"@typescript-eslint/parser": "^8.56.0",
|
|
41
|
+
"async": "^3.2.6",
|
|
42
|
+
"axios": "^1.13.5",
|
|
30
43
|
"eslint": "^10.0.1",
|
|
31
44
|
"eslint-config-airbnb": "^19.0.4",
|
|
32
45
|
"eslint-config-alloy": "^5.1.2",
|
|
@@ -37,42 +50,41 @@
|
|
|
37
50
|
"eslint-plugin-react": "^7.37.5",
|
|
38
51
|
"eslint-plugin-simple-import-sort": "^12.1.1",
|
|
39
52
|
"eslint-plugin-unused-imports": "^4.4.1",
|
|
53
|
+
"fastify": "^5.7.4",
|
|
40
54
|
"husky": "^9.1.7",
|
|
55
|
+
"ioredis": "^5.9.3",
|
|
41
56
|
"jest": "^30.2.0",
|
|
42
57
|
"lint-staged": "^16.2.7",
|
|
58
|
+
"lodash": "^4.17.23",
|
|
59
|
+
"mysql2": "^3.17.4",
|
|
43
60
|
"prettier": "^3.8.1",
|
|
61
|
+
"sequelize": "^6.37.5",
|
|
62
|
+
"socket.io": "^4.8.3",
|
|
44
63
|
"ts-jest": "^29.4.6",
|
|
45
64
|
"ts-node": "^10.9.2",
|
|
46
65
|
"typescript": "^5.9.3"
|
|
47
66
|
},
|
|
48
|
-
"prettier": {
|
|
49
|
-
"printWidth": 100,
|
|
50
|
-
"trailingComma": "all"
|
|
51
|
-
},
|
|
52
|
-
"lint-staged": {
|
|
53
|
-
"src/**/*.{js,ts}": [
|
|
54
|
-
"prettier --write",
|
|
55
|
-
"eslint --fix"
|
|
56
|
-
]
|
|
57
|
-
},
|
|
58
67
|
"dependencies": {
|
|
59
|
-
"@fastify/multipart": "^9.4.0",
|
|
60
68
|
"ajv": "^8.18.0",
|
|
61
69
|
"ajv-formats": "^3.0.1",
|
|
62
70
|
"ajv-keywords": "^5.1.0",
|
|
63
|
-
"async": "^3.2.6",
|
|
64
71
|
"cron-parser": "^5.5.0",
|
|
65
72
|
"csv-stringify": "^6.6.0",
|
|
66
73
|
"dayjs": "^1.11.19",
|
|
67
|
-
"fastify": "^5.7.4",
|
|
68
74
|
"fastify-socket.io": "^5.1.0",
|
|
69
75
|
"human-interval": "^2.0.1",
|
|
76
|
+
"lru-cache": "^11.2.6",
|
|
77
|
+
"xlsx": "^0.18.5"
|
|
78
|
+
},
|
|
79
|
+
"peerDependencies": {
|
|
80
|
+
"@fastify/multipart": "^9.4.0",
|
|
81
|
+
"async": "^3.2.6",
|
|
82
|
+
"axios": "^1.13.5",
|
|
83
|
+
"fastify": "^5.7.4",
|
|
70
84
|
"ioredis": "^5.9.3",
|
|
71
85
|
"lodash": "^4.17.23",
|
|
72
|
-
"lru-cache": "^11.2.6",
|
|
73
86
|
"mysql2": "^3.17.4",
|
|
74
|
-
"sequelize": "^6.37.
|
|
75
|
-
"socket.io": "^4.8.3"
|
|
76
|
-
"xlsx": "^0.18.5"
|
|
87
|
+
"sequelize": "^6.37.5",
|
|
88
|
+
"socket.io": "^4.8.3"
|
|
77
89
|
}
|
|
78
90
|
}
|