@contentstack/cli-utilities 2.0.0-beta.5 → 2.0.0-beta.7
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/contentstack-management-sdk.js +7 -3
- package/lib/contentstack-marketplace-sdk.d.ts +2 -2
- package/lib/fs-utility/core.js +0 -2
- package/lib/http-client/client.js +9 -6
- package/lib/http-client/http-response.d.ts +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/interfaces/index.d.ts +1 -1
- package/lib/logger/cli-error-handler.js +1 -1
- package/lib/logger/log.js +1 -1
- package/lib/logger/session-path.js +1 -1
- package/lib/progress-summary/summary-manager.js +1 -0
- package/lib/proxy-helper.d.ts +6 -6
- package/lib/proxy-helper.js +61 -51
- package/package.json +20 -21
|
@@ -19,12 +19,12 @@ class ManagementSDKInitiator {
|
|
|
19
19
|
const host = (0, proxy_helper_1.resolveRequestHost)(config);
|
|
20
20
|
// NO_PROXY has priority over HTTP_PROXY/HTTPS_PROXY and config-set proxy
|
|
21
21
|
const proxyConfig = (0, proxy_helper_1.getProxyConfigForHost)(host);
|
|
22
|
-
// When
|
|
23
|
-
if (
|
|
22
|
+
// When NO_PROXY matches, strip proxy env so SDK/axios cannot pick up HTTP_PROXY for this process.
|
|
23
|
+
if (host && (0, proxy_helper_1.shouldBypassProxy)(host)) {
|
|
24
24
|
(0, proxy_helper_1.clearProxyEnv)();
|
|
25
25
|
}
|
|
26
26
|
const option = {
|
|
27
|
-
host: config.host,
|
|
27
|
+
host: config.host || host || undefined,
|
|
28
28
|
maxContentLength: config.maxContentLength || 100000000,
|
|
29
29
|
maxBodyLength: config.maxBodyLength || 1000000000,
|
|
30
30
|
maxRequests: 10,
|
|
@@ -112,6 +112,10 @@ class ManagementSDKInitiator {
|
|
|
112
112
|
if (proxyConfig) {
|
|
113
113
|
option.proxy = proxyConfig;
|
|
114
114
|
}
|
|
115
|
+
else if (host && (0, proxy_helper_1.shouldBypassProxy)(host)) {
|
|
116
|
+
option.proxy = false;
|
|
117
|
+
}
|
|
118
|
+
// When host is in NO_PROXY, do not add proxy to option at all
|
|
115
119
|
if (config.endpoint) {
|
|
116
120
|
option.endpoint = config.endpoint;
|
|
117
121
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { App, AppData } from '@contentstack/marketplace-sdk/types/marketplace/app';
|
|
1
|
+
import type { App, AppData } from '@contentstack/marketplace-sdk/types/marketplace/app';
|
|
2
2
|
import { ContentstackConfig, ContentstackClient, ContentstackToken } from '@contentstack/marketplace-sdk';
|
|
3
|
-
import { Installation } from '@contentstack/marketplace-sdk/types/marketplace/installation';
|
|
3
|
+
import type { Installation } from '@contentstack/marketplace-sdk/types/marketplace/installation';
|
|
4
4
|
type ConfigType = Pick<ContentstackConfig, 'host' | 'endpoint' | 'retryDelay' | 'retryLimit'> & {
|
|
5
5
|
skipTokenValidity?: string;
|
|
6
6
|
};
|
package/lib/fs-utility/core.js
CHANGED
|
@@ -337,11 +337,9 @@ class FsUtility {
|
|
|
337
337
|
this.pageInfo.after = index || 0;
|
|
338
338
|
this.pageInfo.before = 1;
|
|
339
339
|
}
|
|
340
|
-
/* eslint-disable unicorn/consistent-destructuring */
|
|
341
340
|
if (!(0, isEmpty_1.default)(this.readIndexer[this.pageInfo.after + 1])) {
|
|
342
341
|
this.pageInfo.hasNextPage = true;
|
|
343
342
|
}
|
|
344
|
-
/* eslint-disable unicorn/consistent-destructuring */
|
|
345
343
|
if (!(0, isEmpty_1.default)(this.readIndexer[this.pageInfo.after - 1])) {
|
|
346
344
|
this.pageInfo.hasPreviousPage = true;
|
|
347
345
|
}
|
|
@@ -12,13 +12,13 @@ const proxy_helper_1 = require("../proxy-helper");
|
|
|
12
12
|
*/
|
|
13
13
|
function getRequestHost(baseURL, url) {
|
|
14
14
|
const toTry = [baseURL, url].filter(Boolean);
|
|
15
|
-
for (const
|
|
15
|
+
for (const u of toTry) {
|
|
16
16
|
try {
|
|
17
|
-
const parsed = new URL(
|
|
17
|
+
const parsed = new URL(u.startsWith('http') ? u : `https://${u}`);
|
|
18
18
|
return parsed.hostname || undefined;
|
|
19
19
|
}
|
|
20
20
|
catch (_a) {
|
|
21
|
-
//
|
|
21
|
+
// ignore
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
24
|
return undefined;
|
|
@@ -356,13 +356,16 @@ class HttpClient {
|
|
|
356
356
|
this.headers({ 'x-header-ea': Object.values(earlyAccessHeaders).join(',') });
|
|
357
357
|
}
|
|
358
358
|
}
|
|
359
|
-
// Configure proxy if available. NO_PROXY has priority
|
|
359
|
+
// Configure proxy if available. NO_PROXY has priority; fall back to region CMA for host resolution.
|
|
360
360
|
if (!this.request.proxy) {
|
|
361
|
-
const host = getRequestHost(this.request.baseURL, url);
|
|
362
|
-
const proxyConfig =
|
|
361
|
+
const host = getRequestHost(this.request.baseURL, url) || (0, proxy_helper_1.resolveRequestHost)({});
|
|
362
|
+
const proxyConfig = (0, proxy_helper_1.getProxyConfigForHost)(host);
|
|
363
363
|
if (proxyConfig) {
|
|
364
364
|
this.request.proxy = proxyConfig;
|
|
365
365
|
}
|
|
366
|
+
else if (host && (0, proxy_helper_1.shouldBypassProxy)(host)) {
|
|
367
|
+
this.request.proxy = false;
|
|
368
|
+
}
|
|
366
369
|
}
|
|
367
370
|
return await this.axiosInstance(Object.assign(Object.assign({ url,
|
|
368
371
|
method, withCredentials: true }, this.request), { data: this.prepareRequestPayload() }));
|
package/lib/index.d.ts
CHANGED
|
@@ -22,7 +22,7 @@ export * from './path-validator';
|
|
|
22
22
|
export { default as CLITable, TableFlags, TableHeader, TableOptions, TableData } from './cli-table';
|
|
23
23
|
export { App, AppData, Installation, marketplaceSDKClient, MarketplaceSDKInitiator, marketplaceSDKInitiator, ContentstackMarketplaceClient, ContentstackMarketplaceConfig, };
|
|
24
24
|
export { Args, CommandHelp, Config, Errors, Flags, loadHelpClass, Help, HelpBase, HelpSection, HelpSectionRenderer, HelpSectionKeyValueTable, Hook, Interfaces, Parser, Plugin, run, toStandardizedId, toConfiguredId, settings, Settings, flush, ux, execute, } from '@oclif/core';
|
|
25
|
-
export { FlagInput, ArgInput, FlagDefinition } from '@oclif/core/lib/interfaces/parser';
|
|
25
|
+
export type { FlagInput, ArgInput, FlagDefinition } from '@oclif/core/lib/interfaces/parser';
|
|
26
26
|
export { default as TablePrompt } from './inquirer-table-prompt';
|
|
27
27
|
export { loadChalk, getChalk } from './chalk';
|
|
28
28
|
export type { ChalkInstance } from './chalk';
|
|
@@ -17,7 +17,7 @@ export interface InquirePayload {
|
|
|
17
17
|
default?: any;
|
|
18
18
|
message: string;
|
|
19
19
|
choices?: Array<any>;
|
|
20
|
-
transformer?:
|
|
20
|
+
transformer?: (value: any) => any;
|
|
21
21
|
validate?(input: any, answers?: any): boolean | string | Promise<boolean | string>;
|
|
22
22
|
selectAll?: boolean;
|
|
23
23
|
pageSize?: number;
|
|
@@ -174,7 +174,7 @@ class CLIErrorHandler {
|
|
|
174
174
|
*/
|
|
175
175
|
extractErrorPayload(error) {
|
|
176
176
|
var _a, _b, _c, _d;
|
|
177
|
-
const { name, message, code, status, response, request, config, statusText } = error;
|
|
177
|
+
const { name, message: _message, code, status, response, request, config, statusText } = error;
|
|
178
178
|
const payload = {
|
|
179
179
|
name,
|
|
180
180
|
message: this.extractClearMessage(error),
|
package/lib/logger/log.js
CHANGED
|
@@ -44,7 +44,7 @@ function createSessionMetadataFile(sessionPath, metadata) {
|
|
|
44
44
|
try {
|
|
45
45
|
fs.writeFileSync(metadataPath, JSON.stringify(metadata, null, 2), 'utf8');
|
|
46
46
|
}
|
|
47
|
-
catch (
|
|
47
|
+
catch (_a) {
|
|
48
48
|
// Silently fail if metadata file cannot be created
|
|
49
49
|
// Logging here would cause circular dependency
|
|
50
50
|
// The session folder and logs will still be created
|
|
@@ -128,6 +128,7 @@ class SummaryManager {
|
|
|
128
128
|
const modulesWithFailures = Array.from(this.modules.values()).filter((m) => m.failures.length > 0);
|
|
129
129
|
if (modulesWithFailures.length === 0)
|
|
130
130
|
return;
|
|
131
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars -- kept for future session log path / totals UX
|
|
131
132
|
const totalFailures = modulesWithFailures.reduce((sum, m) => sum + m.failures.length, 0);
|
|
132
133
|
console.log('\n' + (0, chalk_1.getChalk)().bold.red('Failure Summary:'));
|
|
133
134
|
console.log((0, chalk_1.getChalk)().red('-'.repeat(50)));
|
package/lib/proxy-helper.d.ts
CHANGED
|
@@ -23,8 +23,9 @@ export declare function getNoProxyList(): string[];
|
|
|
23
23
|
*/
|
|
24
24
|
export declare function shouldBypassProxy(host: string): boolean;
|
|
25
25
|
/**
|
|
26
|
-
* Get proxy configuration.
|
|
27
|
-
* from `csdx config:set:proxy --host --port --protocol
|
|
26
|
+
* Get proxy configuration. Priority order (per spec):
|
|
27
|
+
* 1. Global CLI config from `csdx config:set:proxy --host <host> --port <port> --protocol <protocol>`
|
|
28
|
+
* 2. Environment variables (HTTPS_PROXY or HTTP_PROXY)
|
|
28
29
|
* For per-request use, prefer getProxyConfigForHost(host) so NO_PROXY overrides both sources.
|
|
29
30
|
* @returns ProxyConfig object or undefined if no proxy is configured
|
|
30
31
|
*/
|
|
@@ -39,10 +40,9 @@ export declare function getProxyConfig(): ProxyConfig | undefined;
|
|
|
39
40
|
*/
|
|
40
41
|
export declare function getProxyConfigForHost(host: string): ProxyConfig | undefined;
|
|
41
42
|
/**
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
* @returns Host string (hostname or empty)
|
|
43
|
+
* Hostname for NO_PROXY / proxy. Prefer `region.cma` when set so callers that pass a
|
|
44
|
+
* default SDK host (e.g. bulk-entries -> api.contentstack.io) still match rules like
|
|
45
|
+
* `.csnonprod.com` against the real API host (e.g. dev11-api.csnonprod.com).
|
|
46
46
|
*/
|
|
47
47
|
export declare function resolveRequestHost(config: {
|
|
48
48
|
host?: string;
|
package/lib/proxy-helper.js
CHANGED
|
@@ -87,40 +87,14 @@ function shouldBypassProxy(host) {
|
|
|
87
87
|
return false;
|
|
88
88
|
}
|
|
89
89
|
/**
|
|
90
|
-
* Get proxy configuration.
|
|
91
|
-
* from `csdx config:set:proxy --host --port --protocol
|
|
90
|
+
* Get proxy configuration. Priority order (per spec):
|
|
91
|
+
* 1. Global CLI config from `csdx config:set:proxy --host <host> --port <port> --protocol <protocol>`
|
|
92
|
+
* 2. Environment variables (HTTPS_PROXY or HTTP_PROXY)
|
|
92
93
|
* For per-request use, prefer getProxyConfigForHost(host) so NO_PROXY overrides both sources.
|
|
93
94
|
* @returns ProxyConfig object or undefined if no proxy is configured
|
|
94
95
|
*/
|
|
95
96
|
function getProxyConfig() {
|
|
96
|
-
// Priority 1:
|
|
97
|
-
const proxyUrl = process.env.HTTPS_PROXY || process.env.HTTP_PROXY;
|
|
98
|
-
if (proxyUrl) {
|
|
99
|
-
try {
|
|
100
|
-
const url = new URL(proxyUrl);
|
|
101
|
-
const defaultPort = url.protocol === 'https:' ? 443 : 80;
|
|
102
|
-
const port = url.port ? Number.parseInt(url.port, 10) : defaultPort;
|
|
103
|
-
if (!Number.isNaN(port) && port >= 1 && port <= 65535) {
|
|
104
|
-
const protocol = url.protocol.replace(':', '');
|
|
105
|
-
const proxyConfig = {
|
|
106
|
-
protocol: protocol,
|
|
107
|
-
host: url.hostname,
|
|
108
|
-
port: port,
|
|
109
|
-
};
|
|
110
|
-
if (url.username || url.password) {
|
|
111
|
-
proxyConfig.auth = {
|
|
112
|
-
username: url.username,
|
|
113
|
-
password: url.password,
|
|
114
|
-
};
|
|
115
|
-
}
|
|
116
|
-
return proxyConfig;
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
catch (_a) {
|
|
120
|
-
// Invalid URL, continue to check global config
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
// Priority 2: Global config (csdx config:set:proxy)
|
|
97
|
+
// Priority 1: Global config (csdx config:set:proxy)
|
|
124
98
|
const globalProxyConfig = config_handler_1.default.get('proxy');
|
|
125
99
|
if (globalProxyConfig) {
|
|
126
100
|
if (typeof globalProxyConfig === 'object') {
|
|
@@ -150,11 +124,38 @@ function getProxyConfig() {
|
|
|
150
124
|
return proxyConfig;
|
|
151
125
|
}
|
|
152
126
|
}
|
|
153
|
-
catch (
|
|
154
|
-
// Invalid URL,
|
|
127
|
+
catch (_a) {
|
|
128
|
+
// Invalid URL, continue to check environment
|
|
155
129
|
}
|
|
156
130
|
}
|
|
157
131
|
}
|
|
132
|
+
// Priority 2: Environment variables (HTTPS_PROXY or HTTP_PROXY)
|
|
133
|
+
const proxyUrl = process.env.HTTPS_PROXY || process.env.HTTP_PROXY;
|
|
134
|
+
if (proxyUrl) {
|
|
135
|
+
try {
|
|
136
|
+
const url = new URL(proxyUrl);
|
|
137
|
+
const defaultPort = url.protocol === 'https:' ? 443 : 80;
|
|
138
|
+
const port = url.port ? Number.parseInt(url.port, 10) : defaultPort;
|
|
139
|
+
if (!Number.isNaN(port) && port >= 1 && port <= 65535) {
|
|
140
|
+
const protocol = url.protocol.replace(':', '');
|
|
141
|
+
const proxyConfig = {
|
|
142
|
+
protocol: protocol,
|
|
143
|
+
host: url.hostname,
|
|
144
|
+
port: port,
|
|
145
|
+
};
|
|
146
|
+
if (url.username || url.password) {
|
|
147
|
+
proxyConfig.auth = {
|
|
148
|
+
username: url.username,
|
|
149
|
+
password: url.password,
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
return proxyConfig;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
catch (_b) {
|
|
156
|
+
// Invalid URL, return undefined
|
|
157
|
+
}
|
|
158
|
+
}
|
|
158
159
|
return undefined;
|
|
159
160
|
}
|
|
160
161
|
/**
|
|
@@ -170,30 +171,39 @@ function getProxyConfigForHost(host) {
|
|
|
170
171
|
return undefined;
|
|
171
172
|
return getProxyConfig();
|
|
172
173
|
}
|
|
174
|
+
function regionCmaHostname() {
|
|
175
|
+
var _a;
|
|
176
|
+
const cma = (_a = config_handler_1.default.get('region')) === null || _a === void 0 ? void 0 : _a.cma;
|
|
177
|
+
if (!cma || typeof cma !== 'string') {
|
|
178
|
+
return '';
|
|
179
|
+
}
|
|
180
|
+
if (cma.startsWith('http')) {
|
|
181
|
+
try {
|
|
182
|
+
const u = new URL(cma);
|
|
183
|
+
return u.hostname || cma;
|
|
184
|
+
}
|
|
185
|
+
catch (_b) {
|
|
186
|
+
return cma;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
return cma;
|
|
190
|
+
}
|
|
173
191
|
/**
|
|
174
|
-
*
|
|
175
|
-
*
|
|
176
|
-
*
|
|
177
|
-
* @returns Host string (hostname or empty)
|
|
192
|
+
* Hostname for NO_PROXY / proxy. Prefer `region.cma` when set so callers that pass a
|
|
193
|
+
* default SDK host (e.g. bulk-entries -> api.contentstack.io) still match rules like
|
|
194
|
+
* `.csnonprod.com` against the real API host (e.g. dev11-api.csnonprod.com).
|
|
178
195
|
*/
|
|
179
196
|
function resolveRequestHost(config) {
|
|
180
197
|
var _a;
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
return u.hostname || cma;
|
|
189
|
-
}
|
|
190
|
-
catch (_b) {
|
|
191
|
-
return cma;
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
return cma;
|
|
198
|
+
const fromRegion = regionCmaHostname();
|
|
199
|
+
if (fromRegion) {
|
|
200
|
+
return normalizeHost(fromRegion) || fromRegion;
|
|
201
|
+
}
|
|
202
|
+
const raw = ((_a = config.host) === null || _a === void 0 ? void 0 : _a.trim()) || '';
|
|
203
|
+
if (!raw) {
|
|
204
|
+
return '';
|
|
195
205
|
}
|
|
196
|
-
return
|
|
206
|
+
return normalizeHost(raw) || raw;
|
|
197
207
|
}
|
|
198
208
|
/**
|
|
199
209
|
* Temporarily clear proxy-related env vars so SDK/axios cannot use them.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentstack/cli-utilities",
|
|
3
|
-
"version": "2.0.0-beta.
|
|
3
|
+
"version": "2.0.0-beta.7",
|
|
4
4
|
"description": "Utilities for contentstack projects",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -9,14 +9,8 @@
|
|
|
9
9
|
"build": "pnpm compile",
|
|
10
10
|
"clean": "rm -rf ./lib ./node_modules tsconfig.tsbuildinfo",
|
|
11
11
|
"compile": "tsc -b tsconfig.json",
|
|
12
|
-
"test
|
|
13
|
-
"
|
|
14
|
-
"test": "nyc --extension .ts mocha --forbid-only \"test/**/*.test.ts\"",
|
|
15
|
-
"posttest": "npm run lint",
|
|
16
|
-
"lint": "eslint src/**/*.ts",
|
|
17
|
-
"format": "eslint src/**/*.ts --fix",
|
|
18
|
-
"test:unit": "mocha --forbid-only \"test/unit/**/*.test.ts\"",
|
|
19
|
-
"test:unit:report": "nyc --extension .ts mocha --forbid-only \"test/unit/**/*.test.ts\""
|
|
12
|
+
"test": "mocha \"test/unit/**/*.test.ts\"",
|
|
13
|
+
"lint": "eslint src/**/*.ts"
|
|
20
14
|
},
|
|
21
15
|
"repository": {
|
|
22
16
|
"type": "git",
|
|
@@ -33,10 +27,10 @@
|
|
|
33
27
|
"author": "contentstack",
|
|
34
28
|
"license": "MIT",
|
|
35
29
|
"dependencies": {
|
|
36
|
-
"@contentstack/management": "~1.
|
|
37
|
-
"@contentstack/marketplace-sdk": "^1.5.
|
|
38
|
-
"@oclif/core": "^4.
|
|
39
|
-
"axios": "^1.
|
|
30
|
+
"@contentstack/management": "~1.30.1",
|
|
31
|
+
"@contentstack/marketplace-sdk": "^1.5.1",
|
|
32
|
+
"@oclif/core": "^4.10.5",
|
|
33
|
+
"axios": "^1.15.0",
|
|
40
34
|
"chalk": "^5.6.2",
|
|
41
35
|
"cli-cursor": "^3.1.0",
|
|
42
36
|
"cli-progress": "^3.12.0",
|
|
@@ -49,37 +43,42 @@
|
|
|
49
43
|
"inquirer-search-list": "^1.2.6",
|
|
50
44
|
"js-yaml": "^4.1.1",
|
|
51
45
|
"klona": "^2.0.6",
|
|
52
|
-
"lodash": "^4.
|
|
46
|
+
"lodash": "^4.18.1",
|
|
53
47
|
"mkdirp": "^1.0.4",
|
|
54
48
|
"open": "^8.4.2",
|
|
55
49
|
"ora": "^5.4.1",
|
|
56
50
|
"papaparse": "^5.5.3",
|
|
57
|
-
"recheck": "~4.
|
|
51
|
+
"recheck": "~4.5.0",
|
|
58
52
|
"rxjs": "^6.6.7",
|
|
59
53
|
"traverse": "^0.6.11",
|
|
60
54
|
"tty-table": "^4.2.3",
|
|
61
55
|
"unique-string": "^2.0.0",
|
|
62
56
|
"uuid": "^9.0.1",
|
|
63
|
-
"winston": "^3.
|
|
57
|
+
"winston": "^3.19.0",
|
|
64
58
|
"xdg-basedir": "^4.0.0"
|
|
65
59
|
},
|
|
60
|
+
"overrides": {
|
|
61
|
+
"@oclif/core": {
|
|
62
|
+
"picomatch": "^4.0.4"
|
|
63
|
+
}
|
|
64
|
+
},
|
|
66
65
|
"devDependencies": {
|
|
67
66
|
"@types/chai": "^4.3.20",
|
|
68
|
-
"@types/inquirer": "^9.0.
|
|
67
|
+
"@types/inquirer": "^9.0.9",
|
|
69
68
|
"@types/mkdirp": "^1.0.2",
|
|
70
69
|
"@types/mocha": "^10.0.10",
|
|
71
|
-
"@types/node": "^18.
|
|
70
|
+
"@types/node": "^18.19.130",
|
|
72
71
|
"@types/sinon": "^21.0.0",
|
|
73
72
|
"@types/traverse": "^0.6.37",
|
|
74
73
|
"chai": "^4.5.0",
|
|
75
74
|
"eslint": "^8.57.1",
|
|
76
|
-
"eslint-config-oclif": "^6.0.
|
|
75
|
+
"eslint-config-oclif": "^6.0.157",
|
|
77
76
|
"eslint-config-oclif-typescript": "^3.1.14",
|
|
78
77
|
"fancy-test": "^2.0.42",
|
|
79
78
|
"mocha": "10.8.2",
|
|
80
79
|
"nyc": "^15.1.0",
|
|
81
|
-
"sinon": "^21.
|
|
80
|
+
"sinon": "^21.1.2",
|
|
82
81
|
"ts-node": "^10.9.2",
|
|
83
|
-
"typescript": "^5.
|
|
82
|
+
"typescript": "^5.9.3"
|
|
84
83
|
}
|
|
85
84
|
}
|