@open-wa/wa-automate 4.23.15 → 4.24.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/api/Client.js +20 -11
- package/dist/api/model/chat.d.ts +57 -0
- package/dist/api/model/media.d.ts +8 -0
- package/dist/cli/collections.js +3 -2
- package/dist/cli/index.js +6 -0
- package/dist/cli/setup.js +5 -0
- package/dist/config/puppeteer.config.d.ts +1 -1
- package/dist/config/puppeteer.config.js +3 -3
- package/dist/controllers/browser.d.ts +1 -1
- package/dist/controllers/browser.js +50 -36
- package/dist/controllers/initializer.js +5 -2
- package/package.json +5 -3
package/dist/api/Client.js
CHANGED
@@ -355,7 +355,8 @@ class Client {
|
|
355
355
|
const START_TIME = Date.now();
|
356
356
|
spinner.info("Opening session in new tab");
|
357
357
|
const newTab = yield this._page.browser().newPage();
|
358
|
-
yield
|
358
|
+
yield browser_1.initPage(this.getSessionId(), this._createConfig, this._createConfig.customUserAgent, spinner, newTab, true);
|
359
|
+
// await newTab.goto(puppeteerConfig.WAUrl);
|
359
360
|
//Two promises. One that closes the previous page, one that sets up the new page
|
360
361
|
const closePageOnConflict = () => __awaiter(this, void 0, void 0, function* () {
|
361
362
|
const useHere = yield this._page.evaluate(() => WAPI.getUseHereString());
|
@@ -470,20 +471,28 @@ class Client {
|
|
470
471
|
const res = yield this._page.evaluate(pageFunction, ...args);
|
471
472
|
if (this._createConfig.onError && typeof res == "string" && (res.startsWith("Error") || res.startsWith("ERROR"))) {
|
472
473
|
const e = this._createConfig.onError;
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
if (e == model_1.OnError.LOG_AND_STRING) {
|
474
|
+
/**
|
475
|
+
* Log error
|
476
|
+
*/
|
477
|
+
if (e == model_1.OnError.LOG_AND_FALSE ||
|
478
|
+
e == model_1.OnError.LOG_AND_STRING ||
|
479
|
+
res.includes("get.openwa.dev"))
|
480
480
|
console.error(res);
|
481
|
+
/**
|
482
|
+
* Return res
|
483
|
+
*/
|
484
|
+
if (e == model_1.OnError.AS_STRING ||
|
485
|
+
e == model_1.OnError.NOTHING ||
|
486
|
+
e == model_1.OnError.LOG_AND_STRING)
|
481
487
|
return res;
|
482
|
-
|
488
|
+
/**
|
489
|
+
* Return false
|
490
|
+
*/
|
491
|
+
if (e == model_1.OnError.LOG_AND_FALSE ||
|
492
|
+
e == model_1.OnError.RETURN_FALSE)
|
493
|
+
return false;
|
483
494
|
if (e == model_1.OnError.RETURN_ERROR)
|
484
495
|
return new Error(res);
|
485
|
-
if (e == model_1.OnError.RETURN_FALSE)
|
486
|
-
return false;
|
487
496
|
if (e == model_1.OnError.THROW)
|
488
497
|
throw new Error(res);
|
489
498
|
}
|
package/dist/api/model/chat.d.ts
CHANGED
@@ -5,26 +5,83 @@ export interface Chat {
|
|
5
5
|
archive: boolean;
|
6
6
|
changeNumberNewJid: any;
|
7
7
|
changeNumberOldJid: any;
|
8
|
+
/**
|
9
|
+
* The contact related to this chat
|
10
|
+
*/
|
8
11
|
contact: Contact;
|
12
|
+
/**
|
13
|
+
* Group metadata for this chat
|
14
|
+
*/
|
9
15
|
groupMetadata: GroupMetadata;
|
16
|
+
/**
|
17
|
+
* The id of the chat
|
18
|
+
*/
|
10
19
|
id: ChatId;
|
20
|
+
/**
|
21
|
+
* If the chat is a group chat is restricted
|
22
|
+
*/
|
11
23
|
isAnnounceGrpRestrict: any;
|
24
|
+
/**
|
25
|
+
* The title of the chat
|
26
|
+
*/
|
12
27
|
formattedTitle?: string;
|
28
|
+
/**
|
29
|
+
* Whether your host account is able to send messages to this chat
|
30
|
+
*/
|
13
31
|
canSend?: boolean;
|
32
|
+
/**
|
33
|
+
* Whether the chat is a group chat
|
34
|
+
*/
|
14
35
|
isGroup: boolean;
|
36
|
+
/**
|
37
|
+
* Whether the chat is a group chat and the group is restricted
|
38
|
+
*/
|
15
39
|
isReadOnly: boolean;
|
16
40
|
kind: string;
|
41
|
+
/**
|
42
|
+
* The labels attached to this chat.
|
43
|
+
*/
|
17
44
|
labels: any;
|
45
|
+
/**
|
46
|
+
* The ID of the last message received in this chat
|
47
|
+
*/
|
18
48
|
lastReceivedKey: any;
|
19
49
|
modifyTag: number;
|
50
|
+
/**
|
51
|
+
* The messages in the chat
|
52
|
+
*/
|
20
53
|
msgs: any;
|
54
|
+
/**
|
55
|
+
* The expiration timestamp of the chat mute
|
56
|
+
*/
|
21
57
|
muteExpiration: number;
|
58
|
+
/**
|
59
|
+
* The name of the chat
|
60
|
+
*/
|
22
61
|
name: string;
|
62
|
+
/**
|
63
|
+
* Whether the chat is marked as spam
|
64
|
+
*/
|
23
65
|
notSpam: boolean;
|
66
|
+
/**
|
67
|
+
* Messages that are pending to be sent
|
68
|
+
*/
|
24
69
|
pendingMsgs: boolean;
|
70
|
+
/**
|
71
|
+
* Whether the chat is pinned
|
72
|
+
*/
|
25
73
|
pin: number;
|
74
|
+
/**
|
75
|
+
* The presence state of the chat participant
|
76
|
+
*/
|
26
77
|
presence: any;
|
78
|
+
/**
|
79
|
+
* The timestamp of the last interaction in the chat
|
80
|
+
*/
|
27
81
|
t: number;
|
82
|
+
/**
|
83
|
+
* The number of undread messages in this chat
|
84
|
+
*/
|
28
85
|
unreadCount: number;
|
29
86
|
ack?: any;
|
30
87
|
/**
|
@@ -44,6 +44,14 @@ export declare type StickerMetadata = {
|
|
44
44
|
* @default `attention`
|
45
45
|
*/
|
46
46
|
cropPosition?: 'top' | 'right top' | 'right' | 'right bottom' | 'bottom' | 'left bottom' | 'left' | 'left top' | 'north' | 'northeast' | 'east' | 'southeast' | 'south' | 'southwest' | 'west' | 'northwest' | 'center' | 'centre' | 'entropy' | 'attention';
|
47
|
+
/**
|
48
|
+
* The corner radius of the sticker when `stickerMetadata.circle` is set to true.
|
49
|
+
* @default `100`
|
50
|
+
* @minimum `1`
|
51
|
+
* @maximum `100`
|
52
|
+
* @multipleOf `1`
|
53
|
+
*/
|
54
|
+
cornerRadius?: number;
|
47
55
|
};
|
48
56
|
export declare type Mp4StickerConversionProcessOptions = {
|
49
57
|
/**
|
package/dist/cli/collections.js
CHANGED
@@ -37,7 +37,8 @@ const postman_2_swagger_1 = __importDefault(require("postman-2-swagger"));
|
|
37
37
|
const fs_extra_1 = require("fs-extra");
|
38
38
|
const typeconv_1 = require("typeconv");
|
39
39
|
const fs = __importStar(require("fs"));
|
40
|
-
const
|
40
|
+
const glob = require("tiny-glob");
|
41
|
+
const path = __importStar(require("path"));
|
41
42
|
exports.collections = {};
|
42
43
|
const generateCollections = (config, spinner) => __awaiter(void 0, void 0, void 0, function* () {
|
43
44
|
let swCol = null;
|
@@ -118,7 +119,7 @@ const getTypeSchemas = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
118
119
|
const { convert } = typeconv_1.makeConverter(reader, writer, {
|
119
120
|
simplify: true
|
120
121
|
});
|
121
|
-
const s = (yield Promise.all([...(yield
|
122
|
+
const s = (yield Promise.all([...(yield glob(path.resolve(__dirname, '../**/*.d.ts'))), ...(yield glob(path.resolve(__dirname, '../**/message.js'))), ...(yield glob(path.resolve(__dirname, '../**/chat.js')))])).filter(f => !f.includes('node_modules'));
|
122
123
|
const res = {};
|
123
124
|
yield Promise.all(s.map((x) => __awaiter(void 0, void 0, void 0, function* () {
|
124
125
|
var _a, _b;
|
package/dist/cli/index.js
CHANGED
@@ -20,6 +20,7 @@ const axios_1 = __importDefault(require("axios"));
|
|
20
20
|
const setup_1 = require("./setup");
|
21
21
|
const collections_1 = require("./collections");
|
22
22
|
const server_1 = require("./server");
|
23
|
+
const localtunnel_1 = __importDefault(require("localtunnel"));
|
23
24
|
let checkUrl = (s) => (typeof s === "string") && is_url_superb_1.default(s);
|
24
25
|
const ready = (config) => __awaiter(void 0, void 0, void 0, function* () {
|
25
26
|
if (process.send) {
|
@@ -176,6 +177,11 @@ function start() {
|
|
176
177
|
spinner.succeed(`\n• Listening on port ${PORT}!`);
|
177
178
|
yield ready(Object.assign(Object.assign(Object.assign(Object.assign({}, cliConfig), createConfig), client.getSessionInfo()), { hostAccountNumber: yield client.getHostNumber() }));
|
178
179
|
}));
|
180
|
+
if (cliConfig.tunnel) {
|
181
|
+
spinner.info(`\n• Setting up external tunnel`);
|
182
|
+
const tunnel = yield localtunnel_1.default({ port: PORT });
|
183
|
+
spinner.succeed(`\n\t${terminal_link_1.default('External address', tunnel.url)}`);
|
184
|
+
}
|
179
185
|
const apiDocsUrl = cliConfig.apiHost ? `${cliConfig.apiHost}/api-docs/ ` : `${cliConfig.host.includes('http') ? '' : 'http://'}${cliConfig.host}:${PORT}/api-docs/ `;
|
180
186
|
const link = terminal_link_1.default('API Explorer', apiDocsUrl);
|
181
187
|
if (cliConfig && cliConfig.generateApiDocs)
|
package/dist/cli/setup.js
CHANGED
@@ -251,6 +251,11 @@ const optionList = [{
|
|
251
251
|
type: Boolean,
|
252
252
|
description: "Don't validate webhook URLs. Enables use of non-FQDNs."
|
253
253
|
},
|
254
|
+
{
|
255
|
+
name: 'tunnel',
|
256
|
+
type: Boolean,
|
257
|
+
description: "Expose a tunnel to your EASY API session - this is for testing and it is unsecured."
|
258
|
+
},
|
254
259
|
{
|
255
260
|
name: 'help',
|
256
261
|
description: 'Print this usage guide.'
|
@@ -4,8 +4,8 @@ declare const puppeteerConfig: {
|
|
4
4
|
height: number;
|
5
5
|
chromiumArgs: string[];
|
6
6
|
};
|
7
|
-
export declare const useragent = "WhatsApp/2.2108.8 Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36";
|
8
7
|
export declare const createUserAgent: (waVersion: string) => string;
|
8
|
+
export declare const useragent: string;
|
9
9
|
export { puppeteerConfig };
|
10
10
|
export declare const width: number;
|
11
11
|
export declare const height: number;
|
@@ -1,6 +1,6 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.height = exports.width = exports.puppeteerConfig = exports.
|
3
|
+
exports.height = exports.width = exports.puppeteerConfig = exports.useragent = exports.createUserAgent = void 0;
|
4
4
|
const puppeteerConfig = {
|
5
5
|
WAUrl: 'https://web.whatsapp.com',
|
6
6
|
width: 1440,
|
@@ -52,8 +52,8 @@ const puppeteerConfig = {
|
|
52
52
|
]
|
53
53
|
};
|
54
54
|
exports.puppeteerConfig = puppeteerConfig;
|
55
|
-
|
56
|
-
const createUserAgent = (waVersion) => `WhatsApp/${waVersion} Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36`;
|
55
|
+
const createUserAgent = (waVersion) => `WhatsApp/${waVersion} Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36`;
|
57
56
|
exports.createUserAgent = createUserAgent;
|
57
|
+
exports.useragent = exports.createUserAgent('2.2144.11');
|
58
58
|
exports.width = puppeteerConfig.width;
|
59
59
|
exports.height = puppeteerConfig.height;
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import { Page } from 'puppeteer';
|
2
2
|
import { Spin } from './events';
|
3
3
|
import { ConfigObject } from '../api/model';
|
4
|
-
export declare function initPage(sessionId?: string, config?: ConfigObject, customUserAgent?: string, spinner?: Spin): Promise<Page>;
|
4
|
+
export declare function initPage(sessionId?: string, config?: ConfigObject, customUserAgent?: string, spinner?: Spin, _page?: Page, skipAuth?: boolean): Promise<Page>;
|
5
5
|
export declare const deleteSessionData: (config: ConfigObject) => boolean;
|
6
6
|
export declare const getSessionDataFilePath: (sessionId: string, config: ConfigObject) => string | boolean;
|
7
7
|
export declare const addScript: (page: Page, js: string) => Promise<unknown>;
|
@@ -42,7 +42,7 @@ const pico_s3_1 = require("pico-s3");
|
|
42
42
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
43
43
|
const puppeteer = require('puppeteer-extra');
|
44
44
|
let browser;
|
45
|
-
function initPage(sessionId, config, customUserAgent, spinner) {
|
45
|
+
function initPage(sessionId, config, customUserAgent, spinner, _page, skipAuth) {
|
46
46
|
var _a, _b, _c, _d, _e;
|
47
47
|
return __awaiter(this, void 0, void 0, function* () {
|
48
48
|
const setupPromises = [];
|
@@ -52,10 +52,13 @@ function initPage(sessionId, config, customUserAgent, spinner) {
|
|
52
52
|
const { default: stealth } = yield Promise.resolve().then(() => __importStar(require('puppeteer-extra-plugin-stealth')));
|
53
53
|
puppeteer.use(stealth());
|
54
54
|
}
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
55
|
+
let waPage = _page;
|
56
|
+
if (!waPage) {
|
57
|
+
spinner === null || spinner === void 0 ? void 0 : spinner.info('Launching Browser');
|
58
|
+
browser = yield initBrowser(sessionId, config);
|
59
|
+
waPage = yield getWAPage(browser);
|
60
|
+
}
|
61
|
+
spinner === null || spinner === void 0 ? void 0 : spinner.info('Setting Up Page');
|
59
62
|
if (config === null || config === void 0 ? void 0 : config.proxyServerCredentials) {
|
60
63
|
yield waPage.authenticate(config.proxyServerCredentials);
|
61
64
|
}
|
@@ -115,40 +118,51 @@ function initPage(sessionId, config, customUserAgent, spinner) {
|
|
115
118
|
request.continue();
|
116
119
|
}));
|
117
120
|
}
|
118
|
-
|
119
|
-
|
120
|
-
if (!sessionjson && sessionjson !== "" && config.sessionDataBucketAuth) {
|
121
|
-
try {
|
122
|
-
spinner === null || spinner === void 0 ? void 0 : spinner.info('Unable to find session data file locally, attempting to find session data in cloud storage..');
|
123
|
-
sessionjson = JSON.parse(Buffer.from(yield pico_s3_1.getTextFile(Object.assign(Object.assign({ directory: '_sessionData' }, JSON.parse(Buffer.from(config.sessionDataBucketAuth, 'base64').toString('ascii'))), { filename: `${config.sessionId || 'session'}.data.json` })), 'base64').toString('ascii'));
|
124
|
-
spinner === null || spinner === void 0 ? void 0 : spinner.succeed('Successfully downloaded session data file from cloud storage!');
|
125
|
-
}
|
126
|
-
catch (error) {
|
127
|
-
spinner === null || spinner === void 0 ? void 0 : spinner.fail(`${error instanceof pico_s3_1.FileNotFoundError ? 'The session data file was not found in the cloud storage bucket' : 'Something went wrong while fetching session data from cloud storage bucket'}. Continuing...`);
|
128
|
-
}
|
129
|
-
}
|
130
|
-
if (sessionjson) {
|
131
|
-
spinner === null || spinner === void 0 ? void 0 : spinner.info(config.multiDevice ? "multi-device enabled. Session data skipped..." : 'Existing session data detected. Injecting...');
|
132
|
-
if (!(config === null || config === void 0 ? void 0 : config.multiDevice))
|
133
|
-
yield waPage.evaluateOnNewDocument(session => {
|
134
|
-
localStorage.clear();
|
135
|
-
Object.keys(session).forEach(key => localStorage.setItem(key, session[key]));
|
136
|
-
}, sessionjson);
|
137
|
-
spinner === null || spinner === void 0 ? void 0 : spinner.succeed('Existing session data injected');
|
121
|
+
if (skipAuth) {
|
122
|
+
spinner.info("Skipping Authentication");
|
138
123
|
}
|
139
124
|
else {
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
}
|
125
|
+
/**
|
126
|
+
* AUTH
|
127
|
+
*/
|
128
|
+
spinner === null || spinner === void 0 ? void 0 : spinner.info('Loading session data');
|
129
|
+
let sessionjson = getSessionDataFromFile(sessionId, config, spinner);
|
130
|
+
if (!sessionjson && sessionjson !== "" && config.sessionDataBucketAuth) {
|
131
|
+
try {
|
132
|
+
spinner === null || spinner === void 0 ? void 0 : spinner.info('Unable to find session data file locally, attempting to find session data in cloud storage..');
|
133
|
+
sessionjson = JSON.parse(Buffer.from(yield pico_s3_1.getTextFile(Object.assign(Object.assign({ directory: '_sessionData' }, JSON.parse(Buffer.from(config.sessionDataBucketAuth, 'base64').toString('ascii'))), { filename: `${config.sessionId || 'session'}.data.json` })), 'base64').toString('ascii'));
|
134
|
+
spinner === null || spinner === void 0 ? void 0 : spinner.succeed('Successfully downloaded session data file from cloud storage!');
|
135
|
+
}
|
136
|
+
catch (error) {
|
137
|
+
spinner === null || spinner === void 0 ? void 0 : spinner.fail(`${error instanceof pico_s3_1.FileNotFoundError ? 'The session data file was not found in the cloud storage bucket' : 'Something went wrong while fetching session data from cloud storage bucket'}. Continuing...`);
|
138
|
+
}
|
139
|
+
}
|
140
|
+
if (sessionjson) {
|
141
|
+
spinner === null || spinner === void 0 ? void 0 : spinner.info(config.multiDevice ? "multi-device enabled. Session data skipped..." : 'Existing session data detected. Injecting...');
|
142
|
+
if (!(config === null || config === void 0 ? void 0 : config.multiDevice))
|
143
|
+
yield waPage.evaluateOnNewDocument(session => {
|
144
|
+
localStorage.clear();
|
145
|
+
Object.keys(session).forEach(key => localStorage.setItem(key, session[key]));
|
146
|
+
}, sessionjson);
|
147
|
+
spinner === null || spinner === void 0 ? void 0 : spinner.succeed('Existing session data injected');
|
148
|
+
}
|
149
|
+
else {
|
150
|
+
if (config === null || config === void 0 ? void 0 : config.multiDevice) {
|
151
|
+
spinner === null || spinner === void 0 ? void 0 : spinner.info("No session data detected. Opting in for MD.");
|
152
|
+
spinner === null || spinner === void 0 ? void 0 : spinner.info("Make sure to keep the session alive for at least 5 minutes after scanning the QR code before trying to restart a session!!");
|
153
|
+
yield waPage.evaluateOnNewDocument(session => {
|
154
|
+
localStorage.clear();
|
155
|
+
Object.keys(session).forEach(key => localStorage.setItem(key, session[key]));
|
156
|
+
}, {
|
157
|
+
"md-opted-in": "true",
|
158
|
+
"MdUpgradeWamFlag": "true",
|
159
|
+
"remember-me": "true"
|
160
|
+
});
|
161
|
+
}
|
151
162
|
}
|
163
|
+
/**
|
164
|
+
* END AUTH
|
165
|
+
*/
|
152
166
|
}
|
153
167
|
if ((config === null || config === void 0 ? void 0 : config.proxyServerCredentials) && !(config === null || config === void 0 ? void 0 : config.useNativeProxy)) {
|
154
168
|
yield proxy(waPage, proxyAddr);
|
@@ -158,7 +158,7 @@ function create(config = {}) {
|
|
158
158
|
* Check if the IGNORE folder exists, therefore, assume that the session is MD.
|
159
159
|
*/
|
160
160
|
const mdDir = config["userDataDir"] || `${(config === null || config === void 0 ? void 0 : config.inDocker) ? '/sessions' : (config === null || config === void 0 ? void 0 : config.sessionDataPath) || '.'}/_IGNORE_${(config === null || config === void 0 ? void 0 : config.sessionId) || 'session'}`;
|
161
|
-
if (fs.existsSync(mdDir) && !(config === null || config === void 0 ? void 0 : config.multiDevice)) {
|
161
|
+
if (process.env.AUTO_MD && fs.existsSync(mdDir) && !(config === null || config === void 0 ? void 0 : config.multiDevice)) {
|
162
162
|
spinner.info(`Multi-Device directory detected. multiDevice set to true.`);
|
163
163
|
config.multiDevice = true;
|
164
164
|
}
|
@@ -269,7 +269,10 @@ function create(config = {}) {
|
|
269
269
|
const race = [];
|
270
270
|
race.push(auth_1.smartQr(waPage, config, spinner));
|
271
271
|
if ((config === null || config === void 0 ? void 0 : config.qrTimeout) !== 0) {
|
272
|
-
|
272
|
+
let to = ((config === null || config === void 0 ? void 0 : config.qrTimeout) || 60) * 1000;
|
273
|
+
if (config === null || config === void 0 ? void 0 : config.multiDevice)
|
274
|
+
to = to * 2;
|
275
|
+
race.push(timeout(to));
|
273
276
|
}
|
274
277
|
const result = yield Promise.race(race);
|
275
278
|
if (result === "MULTI_DEVICE_DETECTED" && !(config === null || config === void 0 ? void 0 : config.multiDevice)) {
|
package/package.json
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
{
|
2
2
|
"name": "@open-wa/wa-automate",
|
3
|
-
"version": "4.
|
3
|
+
"version": "4.24.0",
|
4
4
|
"licenseCheckUrl": "https://openwa.dev/license-check",
|
5
5
|
"brokenMethodReportUrl": "https://openwa.dev/report-bm",
|
6
|
-
"patches": "
|
6
|
+
"patches": "http://127.0.0.1:5503/functions/patches.json",
|
7
7
|
"stickerUrl": "https://sticker-api.openwa.dev",
|
8
8
|
"description": " 💬 🤖 The most reliable NodeJS whatsapp library for chatbots with advanced features.",
|
9
9
|
"main": "dist/index.js",
|
@@ -69,6 +69,7 @@
|
|
69
69
|
"@types/express": "^4.17.11",
|
70
70
|
"@types/fs-extra": "^9.0.11",
|
71
71
|
"@types/line-reader": "0.0.34",
|
72
|
+
"@types/localtunnel": "^2.0.1",
|
72
73
|
"@types/marked": "^3.0.0",
|
73
74
|
"@types/mime-types": "^2.1.0",
|
74
75
|
"@types/node": "^16.0.0",
|
@@ -120,11 +121,11 @@
|
|
120
121
|
"find-up": "^5.0.0",
|
121
122
|
"fs-extra": "^10.0.0",
|
122
123
|
"get-port": "^5.1.1",
|
123
|
-
"glob-promise": "^4.2.2",
|
124
124
|
"hasha": "^5.2.0",
|
125
125
|
"image-type": "^4.1.0",
|
126
126
|
"is-url-superb": "^5.0.0",
|
127
127
|
"json5": "^2.2.0",
|
128
|
+
"localtunnel": "^2.0.2",
|
128
129
|
"lodash.uniq": "^4.5.0",
|
129
130
|
"meow": "^9.0.0",
|
130
131
|
"node-persist": "^3.1.0",
|
@@ -154,6 +155,7 @@
|
|
154
155
|
"swagger-ui-express": "^4.1.4",
|
155
156
|
"tcp-port-used": "^1.0.1",
|
156
157
|
"terminal-link": "^2.1.1",
|
158
|
+
"tiny-glob": "^0.2.9",
|
157
159
|
"tree-kill": "^1.2.2",
|
158
160
|
"ts-json-schema-generator": "^0.95.0",
|
159
161
|
"ts-morph": "^12.0.0",
|