@oclif/core 2.8.12 → 2.9.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/lib/interfaces/parser.d.ts +1 -2
- package/lib/parser/parse.d.ts +1 -4
- package/lib/parser/parse.js +110 -98
- package/lib/parser/validate.js +26 -33
- package/package.json +5 -2
|
@@ -48,7 +48,7 @@ export type Metadata = {
|
|
|
48
48
|
[key: string]: MetadataFlag;
|
|
49
49
|
};
|
|
50
50
|
};
|
|
51
|
-
type MetadataFlag = {
|
|
51
|
+
export type MetadataFlag = {
|
|
52
52
|
setFromDefault?: boolean;
|
|
53
53
|
defaultHelp?: unknown;
|
|
54
54
|
};
|
|
@@ -368,4 +368,3 @@ export type ArgInput<T extends ArgOutput = {
|
|
|
368
368
|
}> = {
|
|
369
369
|
[P in keyof T]: Arg<T[P]>;
|
|
370
370
|
};
|
|
371
|
-
export {};
|
package/lib/parser/parse.d.ts
CHANGED
|
@@ -6,17 +6,14 @@ export declare class Parser<T extends ParserInput, TFlags extends OutputFlags<T[
|
|
|
6
6
|
private readonly booleanFlags;
|
|
7
7
|
private readonly flagAliases;
|
|
8
8
|
private readonly context;
|
|
9
|
-
private readonly metaData;
|
|
10
9
|
private currentFlag?;
|
|
11
10
|
constructor(input: T);
|
|
12
11
|
parse(): Promise<ParserOutput<TFlags, BFlags, TArgs>>;
|
|
13
12
|
private _flags;
|
|
14
|
-
private _parseFlag;
|
|
15
|
-
private _validateOptions;
|
|
16
13
|
private _args;
|
|
17
14
|
private _debugOutput;
|
|
18
15
|
private _debugInput;
|
|
19
16
|
private get _argTokens();
|
|
20
|
-
private get _flagTokens();
|
|
21
17
|
private _setNames;
|
|
18
|
+
private mapAndValidateFlags;
|
|
22
19
|
}
|
package/lib/parser/parse.js
CHANGED
|
@@ -63,7 +63,6 @@ class Parser {
|
|
|
63
63
|
this.flagAliases = Object.fromEntries(Object.values(input.flags).flatMap(flag => {
|
|
64
64
|
return (flag.aliases ?? []).map(a => [a, flag]);
|
|
65
65
|
}));
|
|
66
|
-
this.metaData = {};
|
|
67
66
|
}
|
|
68
67
|
async parse() {
|
|
69
68
|
this._debugInput();
|
|
@@ -163,8 +162,7 @@ class Parser {
|
|
|
163
162
|
const arg = Object.keys(this.input.args)[this._argTokens.length];
|
|
164
163
|
this.raw.push({ type: 'arg', arg, input });
|
|
165
164
|
}
|
|
166
|
-
const { argv, args } = await this._args();
|
|
167
|
-
const flags = await this._flags();
|
|
165
|
+
const [{ argv, args }, { flags, metadata }] = await Promise.all([this._args(), this._flags()]);
|
|
168
166
|
this._debugOutput(argv, args, flags);
|
|
169
167
|
const unsortedArgv = (dashdash ? [...argv, ...nonExistentFlags, '--'] : [...argv, ...nonExistentFlags]);
|
|
170
168
|
return {
|
|
@@ -172,113 +170,118 @@ class Parser {
|
|
|
172
170
|
flags,
|
|
173
171
|
args: args,
|
|
174
172
|
raw: this.raw,
|
|
175
|
-
metadata
|
|
173
|
+
metadata,
|
|
176
174
|
nonExistentFlags,
|
|
177
175
|
};
|
|
178
176
|
}
|
|
179
|
-
// eslint-disable-next-line complexity
|
|
180
177
|
async _flags() {
|
|
181
|
-
const
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
if (flag.
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
flags[token.flag] = true;
|
|
178
|
+
const validateOptions = (flag, input) => {
|
|
179
|
+
if (flag.options && !flag.options.includes(input))
|
|
180
|
+
throw new errors_1.FlagInvalidOptionError(flag, input);
|
|
181
|
+
return input;
|
|
182
|
+
};
|
|
183
|
+
const parseFlagOrThrowError = async (input, flag, token, context = {}) => {
|
|
184
|
+
if (!flag.parse)
|
|
185
|
+
return input;
|
|
186
|
+
try {
|
|
187
|
+
if (flag.type === 'boolean') {
|
|
188
|
+
return await flag.parse(input, { ...context, token }, flag);
|
|
193
189
|
}
|
|
194
|
-
|
|
190
|
+
return await flag.parse(input, { ...context, token }, flag);
|
|
195
191
|
}
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
192
|
+
catch (error) {
|
|
193
|
+
error.message = `Parsing --${flag.name} \n\t${error.message}\nSee more help with --help`;
|
|
194
|
+
throw error;
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
/* Could add a valueFunction (if there is a value/env/default) and could metadata.
|
|
198
|
+
* Value function can be resolved later.
|
|
199
|
+
*/
|
|
200
|
+
const addValueFunction = (fws) => {
|
|
201
|
+
const tokenLength = fws.tokens?.length;
|
|
202
|
+
// user provided some input
|
|
203
|
+
if (tokenLength) {
|
|
204
|
+
// boolean
|
|
205
|
+
if (fws.inputFlag.flag.type === 'boolean' && fws.tokens?.at(-1)?.input) {
|
|
206
|
+
return { ...fws, valueFunction: async (i) => parseFlagOrThrowError(i.tokens?.at(-1)?.input !== `--no-${i.inputFlag.name}`, i.inputFlag.flag, i.tokens?.at(-1), this.context) };
|
|
207
207
|
}
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
flags[token.flag] = value;
|
|
217
|
-
}
|
|
208
|
+
// multiple with custom delimiter
|
|
209
|
+
if (fws.inputFlag.flag.type === 'option' && fws.inputFlag.flag.delimiter && fws.inputFlag.flag.multiple) {
|
|
210
|
+
return {
|
|
211
|
+
...fws, valueFunction: async (i) => (await Promise.all(((i.tokens ?? []).flatMap(token => token.input.split(i.inputFlag.flag.delimiter)))
|
|
212
|
+
// trim, and remove surrounding doubleQuotes (which would hav been needed if the elements contain spaces)
|
|
213
|
+
.map(v => v.trim().replace(/^"(.*)"$/, '$1').replace(/^'(.*)'$/, '$1'))
|
|
214
|
+
.map(async (v) => parseFlagOrThrowError(v, i.inputFlag.flag, { ...i.tokens?.at(-1), input: v }, this.context)))).map(v => validateOptions(i.inputFlag.flag, v)),
|
|
215
|
+
};
|
|
218
216
|
}
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
const flag = this.input.flags[k];
|
|
223
|
-
if (flags[k])
|
|
224
|
-
continue;
|
|
225
|
-
if (flag.env && Reflect.has(process.env, flag.env)) {
|
|
226
|
-
const input = process.env[flag.env];
|
|
227
|
-
if (flag.type === 'option') {
|
|
228
|
-
if (input) {
|
|
229
|
-
this._validateOptions(flag, input);
|
|
230
|
-
flags[k] = await this._parseFlag(input, flag);
|
|
231
|
-
}
|
|
217
|
+
// multiple in the oclif-core style
|
|
218
|
+
if (fws.inputFlag.flag.type === 'option' && fws.inputFlag.flag.multiple) {
|
|
219
|
+
return { ...fws, valueFunction: async (i) => Promise.all((fws.tokens ?? []).map(token => parseFlagOrThrowError(validateOptions(i.inputFlag.flag, token.input), i.inputFlag.flag, token, this.context))) };
|
|
232
220
|
}
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
221
|
+
// simple option flag
|
|
222
|
+
if (fws.inputFlag.flag.type === 'option') {
|
|
223
|
+
return { ...fws, valueFunction: async (i) => parseFlagOrThrowError(validateOptions(i.inputFlag.flag, fws.tokens?.at(-1)?.input), i.inputFlag.flag, fws.tokens?.at(-1), this.context) };
|
|
236
224
|
}
|
|
237
225
|
}
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
const
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
}
|
|
244
|
-
for (const k of Object.keys(this.input.flags)) {
|
|
245
|
-
if ((k in flags) && Reflect.has(this.input.flags[k], 'defaultHelp')) {
|
|
246
|
-
try {
|
|
247
|
-
const defaultHelpProperty = Reflect.get(this.input.flags[k], 'defaultHelp');
|
|
248
|
-
const defaultHelp = (typeof defaultHelpProperty === 'function' ? await defaultHelpProperty({
|
|
249
|
-
options: flags[k],
|
|
250
|
-
flags, ...this.context,
|
|
251
|
-
}) : defaultHelpProperty);
|
|
252
|
-
this.metaData.flags[k] = { ...this.metaData.flags[k], defaultHelp };
|
|
226
|
+
// no input: env flags
|
|
227
|
+
if (fws.inputFlag.flag.env && process.env[fws.inputFlag.flag.env]) {
|
|
228
|
+
const valueFromEnv = process.env[fws.inputFlag.flag.env];
|
|
229
|
+
if (fws.inputFlag.flag.type === 'option' && valueFromEnv) {
|
|
230
|
+
return { ...fws, valueFunction: async (i) => parseFlagOrThrowError(validateOptions(i.inputFlag.flag, valueFromEnv), i.inputFlag.flag, this.context) };
|
|
253
231
|
}
|
|
254
|
-
|
|
255
|
-
|
|
232
|
+
if (fws.inputFlag.flag.type === 'boolean') {
|
|
233
|
+
return { ...fws, valueFunction: async (i) => Promise.resolve((0, util_1.isTruthy)(process.env[i.inputFlag.flag.env] ?? 'false')) };
|
|
256
234
|
}
|
|
257
235
|
}
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
ctx.token = token;
|
|
267
|
-
if (flag.type === 'boolean') {
|
|
268
|
-
const ctx = this.context;
|
|
269
|
-
ctx.token = token;
|
|
270
|
-
return await flag.parse(input, ctx, flag);
|
|
236
|
+
// no input, but flag has default value
|
|
237
|
+
if (typeof fws.inputFlag.flag.default !== undefined) {
|
|
238
|
+
return {
|
|
239
|
+
...fws, metadata: { setFromDefault: true },
|
|
240
|
+
valueFunction: typeof fws.inputFlag.flag.default === 'function' ?
|
|
241
|
+
(i, allFlags = {}) => fws.inputFlag.flag.default({ options: i.inputFlag.flag, flags: allFlags }) :
|
|
242
|
+
async () => fws.inputFlag.flag.default,
|
|
243
|
+
};
|
|
271
244
|
}
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
245
|
+
// base case (no value function)
|
|
246
|
+
return fws;
|
|
247
|
+
};
|
|
248
|
+
const addHelpFunction = (fws) => {
|
|
249
|
+
if (fws.inputFlag.flag.type === 'option' && fws.inputFlag.flag.defaultHelp) {
|
|
250
|
+
return {
|
|
251
|
+
...fws, helpFunction: typeof fws.inputFlag.flag.defaultHelp === 'function' ?
|
|
252
|
+
// @ts-expect-error flag type isn't specific enough to know defaultHelp will definitely be there
|
|
253
|
+
(i, flags, ...context) => i.inputFlag.flag.defaultHelp({ options: i.inputFlag, flags }, ...context) :
|
|
254
|
+
// @ts-expect-error flag type isn't specific enough to know defaultHelp will definitely be there
|
|
255
|
+
(i) => i.inputFlag.flag.defaultHelp,
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
return fws;
|
|
259
|
+
};
|
|
260
|
+
const addDefaultHelp = async (fws) => {
|
|
261
|
+
const valueReferenceForHelp = fwsArrayToObject(flagsWithAllValues.filter(fws => !fws.metadata?.setFromDefault));
|
|
262
|
+
return Promise.all(fws.map(async (fws) => fws.helpFunction ? ({ ...fws, metadata: { ...fws.metadata, defaultHelp: await fws.helpFunction?.(fws, valueReferenceForHelp, this.context) } }) : fws));
|
|
263
|
+
};
|
|
264
|
+
const fwsArrayToObject = (fwsArray) => Object.fromEntries(fwsArray.map(fws => [fws.inputFlag.name, fws.value]));
|
|
265
|
+
const flagTokenMap = this.mapAndValidateFlags();
|
|
266
|
+
const flagsWithValues = await Promise.all(Object.entries(this.input.flags)
|
|
267
|
+
// we check them if they have a token, or might have env, default, or defaultHelp. Also include booleans so they get their default value
|
|
268
|
+
.filter(([name, flag]) => flag.type === 'boolean' || flag.env || flag.default || 'defaultHelp' in flag || flagTokenMap.has(name))
|
|
269
|
+
// match each possible flag to its token, if there is one
|
|
270
|
+
.map(([name, flag]) => ({ inputFlag: { name, flag }, tokens: flagTokenMap.get(name) }))
|
|
271
|
+
.map(fws => addValueFunction(fws))
|
|
272
|
+
.filter(fws => fws.valueFunction !== undefined)
|
|
273
|
+
.map(fws => addHelpFunction(fws))
|
|
274
|
+
// we can't apply the default values until all the other flags are resolved because `flag.default` can reference other flags
|
|
275
|
+
.map(async (fws) => (fws.metadata?.setFromDefault ? fws : { ...fws, value: await fws.valueFunction?.(fws) })));
|
|
276
|
+
const valueReference = fwsArrayToObject(flagsWithValues.filter(fws => !fws.metadata?.setFromDefault));
|
|
277
|
+
const flagsWithAllValues = await Promise.all(flagsWithValues
|
|
278
|
+
.map(async (fws) => (fws.metadata?.setFromDefault ? { ...fws, value: await fws.valueFunction?.(fws, valueReference) } : fws)));
|
|
279
|
+
const finalFlags = (flagsWithAllValues.some(fws => typeof fws.helpFunction === 'function')) ? await addDefaultHelp(flagsWithAllValues) : flagsWithAllValues;
|
|
280
|
+
return {
|
|
281
|
+
// @ts-ignore original version returned an any. Not sure how to get to the return type for `flags` prop
|
|
282
|
+
flags: fwsArrayToObject(finalFlags),
|
|
283
|
+
metadata: { flags: Object.fromEntries(finalFlags.filter(fws => fws.metadata).map(fws => [fws.inputFlag.name, fws.metadata])) },
|
|
284
|
+
};
|
|
282
285
|
}
|
|
283
286
|
async _args() {
|
|
284
287
|
const argv = [];
|
|
@@ -352,9 +355,6 @@ class Parser {
|
|
|
352
355
|
get _argTokens() {
|
|
353
356
|
return this.raw.filter(o => o.type === 'arg');
|
|
354
357
|
}
|
|
355
|
-
get _flagTokens() {
|
|
356
|
-
return this.raw.filter(o => o.type === 'flag');
|
|
357
|
-
}
|
|
358
358
|
_setNames() {
|
|
359
359
|
for (const k of Object.keys(this.input.flags)) {
|
|
360
360
|
this.input.flags[k].name = k;
|
|
@@ -363,5 +363,17 @@ class Parser {
|
|
|
363
363
|
this.input.args[k].name = k;
|
|
364
364
|
}
|
|
365
365
|
}
|
|
366
|
+
mapAndValidateFlags() {
|
|
367
|
+
const flagTokenMap = new Map();
|
|
368
|
+
for (const token of this.raw.filter(o => o.type === 'flag')) {
|
|
369
|
+
// fail fast if there are any invalid flags
|
|
370
|
+
if (!(token.flag in this.input.flags)) {
|
|
371
|
+
throw new errors_1.CLIError(`Unexpected flag ${token.flag}`);
|
|
372
|
+
}
|
|
373
|
+
const existing = flagTokenMap.get(token.flag) ?? [];
|
|
374
|
+
flagTokenMap.set(token.flag, [...existing, token]);
|
|
375
|
+
}
|
|
376
|
+
return flagTokenMap;
|
|
377
|
+
}
|
|
366
378
|
}
|
|
367
379
|
exports.Parser = Parser;
|
package/lib/parser/validate.js
CHANGED
|
@@ -4,6 +4,7 @@ exports.validate = void 0;
|
|
|
4
4
|
const errors_1 = require("./errors");
|
|
5
5
|
const util_1 = require("../config/util");
|
|
6
6
|
async function validate(parse) {
|
|
7
|
+
let cachedResolvedFlags;
|
|
7
8
|
function validateArgs() {
|
|
8
9
|
if (parse.output.nonExistentFlags?.length > 0) {
|
|
9
10
|
throw new errors_1.NonExistentFlagsError({ parse, flags: parse.output.nonExistentFlags });
|
|
@@ -33,25 +34,31 @@ async function validate(parse) {
|
|
|
33
34
|
}
|
|
34
35
|
}
|
|
35
36
|
async function validateFlags() {
|
|
36
|
-
const promises = Object.entries(parse.input.flags).
|
|
37
|
-
const results = [];
|
|
37
|
+
const promises = Object.entries(parse.input.flags).flatMap(([name, flag]) => {
|
|
38
38
|
if (parse.output.flags[name] !== undefined) {
|
|
39
|
-
|
|
39
|
+
return [
|
|
40
|
+
...flag.relationships ? validateRelationships(name, flag) : [],
|
|
41
|
+
...flag.dependsOn ? [validateDependsOn(name, flag.dependsOn)] : [],
|
|
42
|
+
...flag.exclusive ? [validateExclusive(name, flag.exclusive)] : [],
|
|
43
|
+
...flag.exactlyOne ? [validateExactlyOne(name, flag.exactlyOne)] : [],
|
|
44
|
+
];
|
|
40
45
|
}
|
|
41
|
-
|
|
42
|
-
|
|
46
|
+
if (flag.required) {
|
|
47
|
+
return [{ status: 'failed', name, validationFn: 'required', reason: `Missing required flag ${name}` }];
|
|
43
48
|
}
|
|
44
|
-
|
|
45
|
-
|
|
49
|
+
if (flag.exactlyOne && flag.exactlyOne.length > 0) {
|
|
50
|
+
return [validateAcrossFlags(flag)];
|
|
46
51
|
}
|
|
47
|
-
return
|
|
52
|
+
return [];
|
|
48
53
|
});
|
|
49
|
-
const results = (await Promise.all(promises))
|
|
54
|
+
const results = (await Promise.all(promises));
|
|
50
55
|
const failed = results.filter(r => r.status === 'failed');
|
|
51
56
|
if (failed.length > 0)
|
|
52
57
|
throw new errors_1.FailedFlagValidationError({ parse, failed });
|
|
53
58
|
}
|
|
54
59
|
async function resolveFlags(flags) {
|
|
60
|
+
if (cachedResolvedFlags)
|
|
61
|
+
return cachedResolvedFlags;
|
|
55
62
|
const promises = flags.map(async (flag) => {
|
|
56
63
|
if (typeof flag === 'string') {
|
|
57
64
|
return [flag, parse.output.flags[flag]];
|
|
@@ -60,15 +67,10 @@ async function validate(parse) {
|
|
|
60
67
|
return result ? [flag.name, parse.output.flags[flag.name]] : null;
|
|
61
68
|
});
|
|
62
69
|
const resolved = await Promise.all(promises);
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
function getPresentFlags(flags) {
|
|
66
|
-
return Object.keys(flags).reduce((acc, key) => {
|
|
67
|
-
if (flags[key] !== undefined)
|
|
68
|
-
acc.push(key);
|
|
69
|
-
return acc;
|
|
70
|
-
}, []);
|
|
70
|
+
cachedResolvedFlags = Object.fromEntries(resolved.filter(r => r !== null));
|
|
71
|
+
return cachedResolvedFlags;
|
|
71
72
|
}
|
|
73
|
+
const getPresentFlags = (flags) => Object.keys(flags).filter(key => key !== undefined);
|
|
72
74
|
function validateAcrossFlags(flag) {
|
|
73
75
|
const base = { name: flag.name, validationFn: 'validateAcrossFlags' };
|
|
74
76
|
const intersection = Object.entries(parse.input.flags)
|
|
@@ -131,30 +133,21 @@ async function validate(parse) {
|
|
|
131
133
|
}
|
|
132
134
|
return { ...base, status: 'success' };
|
|
133
135
|
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
return [];
|
|
137
|
-
const results = await Promise.all(flag.relationships.map(async (relationship) => {
|
|
138
|
-
const flags = relationship.flags ?? [];
|
|
139
|
-
const results = [];
|
|
136
|
+
function validateRelationships(name, flag) {
|
|
137
|
+
return ((flag.relationships ?? []).map(relationship => {
|
|
140
138
|
switch (relationship.type) {
|
|
141
139
|
case 'all':
|
|
142
|
-
|
|
143
|
-
break;
|
|
140
|
+
return validateDependsOn(name, relationship.flags);
|
|
144
141
|
case 'some':
|
|
145
|
-
|
|
146
|
-
break;
|
|
142
|
+
return validateSome(name, relationship.flags);
|
|
147
143
|
case 'none':
|
|
148
|
-
|
|
149
|
-
break;
|
|
144
|
+
return validateExclusive(name, relationship.flags);
|
|
150
145
|
default:
|
|
151
|
-
|
|
146
|
+
throw new Error(`Unknown relationship type: ${relationship.type}`);
|
|
152
147
|
}
|
|
153
|
-
return results;
|
|
154
148
|
}));
|
|
155
|
-
return results.flat();
|
|
156
149
|
}
|
|
157
150
|
validateArgs();
|
|
158
|
-
|
|
151
|
+
return validateFlags();
|
|
159
152
|
}
|
|
160
153
|
exports.validate = validate;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oclif/core",
|
|
3
3
|
"description": "base library for oclif CLIs",
|
|
4
|
-
"version": "2.
|
|
4
|
+
"version": "2.9.0",
|
|
5
5
|
"author": "Salesforce",
|
|
6
6
|
"bugs": "https://github.com/oclif/core/issues",
|
|
7
7
|
"dependencies": {
|
|
@@ -42,6 +42,7 @@
|
|
|
42
42
|
"@oclif/plugin-plugins": "^2.4.7",
|
|
43
43
|
"@oclif/test": "^2.3.15",
|
|
44
44
|
"@types/ansi-styles": "^3.2.1",
|
|
45
|
+
"@types/benchmark": "^2.1.2",
|
|
45
46
|
"@types/chai": "^4.3.4",
|
|
46
47
|
"@types/chai-as-promised": "^7.1.5",
|
|
47
48
|
"@types/clean-stack": "^2.1.1",
|
|
@@ -61,6 +62,7 @@
|
|
|
61
62
|
"@types/supports-color": "^8.1.1",
|
|
62
63
|
"@types/wordwrap": "^1.0.1",
|
|
63
64
|
"@types/wrap-ansi": "^3.0.0",
|
|
65
|
+
"benchmark": "^2.1.4",
|
|
64
66
|
"chai": "^4.3.7",
|
|
65
67
|
"chai-as-promised": "^7.1.1",
|
|
66
68
|
"commitlint": "^12.1.4",
|
|
@@ -114,7 +116,8 @@
|
|
|
114
116
|
"prepack": "yarn run build",
|
|
115
117
|
"test": "mocha --forbid-only \"test/**/*.test.ts\"",
|
|
116
118
|
"test:e2e": "mocha --forbid-only \"test/**/*.e2e.ts\" --timeout 1200000",
|
|
117
|
-
"pretest": "yarn build --noEmit && tsc -p test --noEmit --skipLibCheck"
|
|
119
|
+
"pretest": "yarn build --noEmit && tsc -p test --noEmit --skipLibCheck",
|
|
120
|
+
"test:perf": "ts-node test/perf/parser.perf.ts"
|
|
118
121
|
},
|
|
119
122
|
"types": "lib/index.d.ts"
|
|
120
123
|
}
|