@clerc/parser 1.1.0 → 1.2.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/index.d.mts +46 -1
- package/dist/index.mjs +1 -302
- package/package.json +2 -2
package/dist/index.d.mts
CHANGED
|
@@ -172,4 +172,49 @@ declare function createParser<T extends FlagsDefinition>(options?: ParserOptions
|
|
|
172
172
|
};
|
|
173
173
|
declare const parse: <T extends FlagsDefinition>(args: string[], options?: ParserOptions<T>) => ParsedResult<InferFlags<T>>;
|
|
174
174
|
//#endregion
|
|
175
|
-
|
|
175
|
+
//#region src/utils.d.ts
|
|
176
|
+
/**
|
|
177
|
+
* Infers the implicit default value for a flag type based on its type
|
|
178
|
+
* constructor. This is useful for help output to show the default values of
|
|
179
|
+
* types that have built-in defaults.
|
|
180
|
+
*
|
|
181
|
+
* - Boolean: false
|
|
182
|
+
* - [Boolean] (Counter): 0
|
|
183
|
+
* - [T] (Array): []
|
|
184
|
+
* - Object: {}
|
|
185
|
+
* - Others: undefined (no implicit default)
|
|
186
|
+
*
|
|
187
|
+
* @param type The type value (constructor or array of constructor)
|
|
188
|
+
* @returns The inferred default value, or undefined if no implicit default
|
|
189
|
+
*/
|
|
190
|
+
declare function inferDefault(type: TypeValue): unknown;
|
|
191
|
+
/**
|
|
192
|
+
* Default value coercion for Object type. Converts "true" / "" to true, "false"
|
|
193
|
+
* to false, other values remain unchanged.
|
|
194
|
+
*
|
|
195
|
+
* @param value The raw string value from CLI
|
|
196
|
+
* @returns Coerced value (boolean or string)
|
|
197
|
+
*/
|
|
198
|
+
declare function coerceObjectValue(value: string): string | boolean;
|
|
199
|
+
/**
|
|
200
|
+
* Sets a value at a nested path in an object, creating intermediate objects as
|
|
201
|
+
* needed. Does NOT apply type conversion - value is set as-is. Overwrites
|
|
202
|
+
* existing values.
|
|
203
|
+
*
|
|
204
|
+
* @param obj The target object
|
|
205
|
+
* @param path Dot-separated path (e.g., "foo.bar.baz")
|
|
206
|
+
* @param value The value to set (used as-is, no type conversion)
|
|
207
|
+
*/
|
|
208
|
+
declare function setDotValues(obj: any, path: string, value: any): void;
|
|
209
|
+
/**
|
|
210
|
+
* Similar to setDotValues but handles duplicate keys by converting to arrays.
|
|
211
|
+
* Does NOT apply type conversion - value is set as-is. Useful for flags that
|
|
212
|
+
* can be specified multiple times.
|
|
213
|
+
*
|
|
214
|
+
* @param obj The target object
|
|
215
|
+
* @param path Dot-separated path (e.g., "foo.bar")
|
|
216
|
+
* @param value The value to set or append (used as-is, no type conversion)
|
|
217
|
+
*/
|
|
218
|
+
declare function appendDotValues(obj: any, path: string, value: any): void;
|
|
219
|
+
//#endregion
|
|
220
|
+
export { BaseFlagOptions, DOUBLE_DASH, FlagDefaultValue, FlagDefaultValueFunction, FlagDefinitionValue, FlagOptions, FlagsDefinition, IgnoreFunction, InferFlags, InvalidSchemaError, KNOWN_FLAG, ObjectInputType, PARAMETER, ParsedResult, ParserOptions, RawInputType, TypeFunction, TypeValue, UNKNOWN_FLAG, appendDotValues, coerceObjectValue, createParser, inferDefault, parse, setDotValues };
|
package/dist/index.mjs
CHANGED
|
@@ -1,302 +1 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
//#region src/errors.ts
|
|
4
|
-
var InvalidSchemaError = class extends Error {
|
|
5
|
-
constructor(message) {
|
|
6
|
-
super(`Invalid schema: ${message}`);
|
|
7
|
-
this.name = "InvalidSchemaError";
|
|
8
|
-
}
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
//#endregion
|
|
12
|
-
//#region src/iterator.ts
|
|
13
|
-
const KNOWN_FLAG = "known-flag";
|
|
14
|
-
const UNKNOWN_FLAG = "unknown-flag";
|
|
15
|
-
const PARAMETER = "parameter";
|
|
16
|
-
function iterateArgs(args, result, shouldProcessAsFlag, isKnownFlag, ignore, callback) {
|
|
17
|
-
let index = 0;
|
|
18
|
-
let stopped = false;
|
|
19
|
-
const argsLength = args.length;
|
|
20
|
-
const iterator = {
|
|
21
|
-
current: "",
|
|
22
|
-
index: 0,
|
|
23
|
-
hasNext: false,
|
|
24
|
-
next: "",
|
|
25
|
-
shouldIgnore: (arg) => {
|
|
26
|
-
if (ignore) return ignore(shouldProcessAsFlag(arg) ? isKnownFlag(arg) ? KNOWN_FLAG : UNKNOWN_FLAG : PARAMETER, arg);
|
|
27
|
-
return false;
|
|
28
|
-
},
|
|
29
|
-
eat: () => {
|
|
30
|
-
if (index + 1 >= argsLength) return;
|
|
31
|
-
const nextArg = args[index + 1];
|
|
32
|
-
if (iterator.shouldIgnore(nextArg)) {
|
|
33
|
-
iterator.exit();
|
|
34
|
-
return;
|
|
35
|
-
}
|
|
36
|
-
index++;
|
|
37
|
-
next();
|
|
38
|
-
return args[index];
|
|
39
|
-
},
|
|
40
|
-
exit: (push = true) => {
|
|
41
|
-
if (!stopped) {
|
|
42
|
-
if (push) result.ignored.push(...args.slice(index + 1));
|
|
43
|
-
stopped = true;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
};
|
|
47
|
-
function next() {
|
|
48
|
-
iterator.current = args[index];
|
|
49
|
-
iterator.index = index;
|
|
50
|
-
iterator.hasNext = index + 1 < argsLength;
|
|
51
|
-
iterator.next = iterator.hasNext ? args[index + 1] : "";
|
|
52
|
-
}
|
|
53
|
-
for (index = 0; index < argsLength; index++) {
|
|
54
|
-
if (stopped) break;
|
|
55
|
-
next();
|
|
56
|
-
callback(iterator);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
//#endregion
|
|
61
|
-
//#region src/config.ts
|
|
62
|
-
const defaultParserOptions = { delimiters: ["=", ":"] };
|
|
63
|
-
const resolveParserOptions = (options = {}) => ({
|
|
64
|
-
...defaultParserOptions,
|
|
65
|
-
...options
|
|
66
|
-
});
|
|
67
|
-
const normalizeConfig = (config) => typeof config === "function" || looseIsArray(config) ? { type: config } : config;
|
|
68
|
-
const BUILDTIN_DELIMITERS_RE = /[\s.]/;
|
|
69
|
-
function buildConfigsAndAliases(delimiters, flags) {
|
|
70
|
-
const configs = /* @__PURE__ */ new Map();
|
|
71
|
-
const aliases = /* @__PURE__ */ new Map();
|
|
72
|
-
const isNameInvalid = (name) => delimiters.some((char) => name.includes(char)) || BUILDTIN_DELIMITERS_RE.test(name);
|
|
73
|
-
function validateFlagOptions(name, options) {
|
|
74
|
-
const prefix = `Flag "${name}"`;
|
|
75
|
-
if (Array.isArray(options.type) && options.type.length > 1) throw new InvalidSchemaError(`${prefix} has an invalid type array. Only single-element arrays are allowed to denote multiple occurrences.`);
|
|
76
|
-
if (name.length < 2) throw new InvalidSchemaError(`${prefix} name must be at least 2 characters long.`);
|
|
77
|
-
const names = [name];
|
|
78
|
-
if (options.short) {
|
|
79
|
-
if (options.short.length !== 1) throw new InvalidSchemaError(`${prefix} short flag must be exactly 1 character long.`);
|
|
80
|
-
names.push(options.short);
|
|
81
|
-
}
|
|
82
|
-
if (names.some(isNameInvalid)) throw new InvalidSchemaError(`${prefix} contains reserved characters, which are used as delimiters.`);
|
|
83
|
-
if (options.required && options.default !== void 0) throw new InvalidSchemaError(`${prefix} cannot be both required and have a default value.`);
|
|
84
|
-
}
|
|
85
|
-
for (const [name, config] of Object.entries(flags)) {
|
|
86
|
-
const normalized = normalizeConfig(config);
|
|
87
|
-
validateFlagOptions(name, normalized);
|
|
88
|
-
configs.set(name, normalized);
|
|
89
|
-
aliases.set(name, name);
|
|
90
|
-
aliases.set(camelCase(name), name);
|
|
91
|
-
if (normalized.short) aliases.set(normalized.short, name);
|
|
92
|
-
}
|
|
93
|
-
return {
|
|
94
|
-
configs,
|
|
95
|
-
aliases
|
|
96
|
-
};
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
//#endregion
|
|
100
|
-
//#region src/utils.ts
|
|
101
|
-
const isArrayOfType = (arr, type) => Array.isArray(arr) && arr[0] === type;
|
|
102
|
-
/**
|
|
103
|
-
* Check if it's a letter (a-z: 97-122, A-Z: 65-90)
|
|
104
|
-
*/
|
|
105
|
-
const isLetter = (charCode) => charCode >= 65 && charCode <= 90 || charCode >= 97 && charCode <= 122;
|
|
106
|
-
/**
|
|
107
|
-
* Check if it's a digit (0-9: 48-57)
|
|
108
|
-
*/
|
|
109
|
-
const isDigit = (charCode) => charCode >= 48 && charCode <= 57;
|
|
110
|
-
function setValueByType(flags, key, value, config) {
|
|
111
|
-
const { type } = config;
|
|
112
|
-
if (looseIsArray(type)) if (isArrayOfType(type, Boolean)) flags[key] = (flags[key] ?? 0) + 1;
|
|
113
|
-
else (flags[key] ??= []).push(type[0](value));
|
|
114
|
-
else flags[key] = type(value);
|
|
115
|
-
}
|
|
116
|
-
function setDotValues(obj, path, value) {
|
|
117
|
-
const keys = path.split(".");
|
|
118
|
-
let current = obj;
|
|
119
|
-
for (let i = 0; i < keys.length - 1; i++) {
|
|
120
|
-
const key = keys[i];
|
|
121
|
-
current[key] ??= {};
|
|
122
|
-
current = current[key];
|
|
123
|
-
}
|
|
124
|
-
const lastKey = keys[keys.length - 1];
|
|
125
|
-
if (value === "true" || value === "") current[lastKey] = true;
|
|
126
|
-
else if (value === "false") current[lastKey] = false;
|
|
127
|
-
else current[lastKey] = value;
|
|
128
|
-
}
|
|
129
|
-
function splitNameAndValue(arg, delimiters) {
|
|
130
|
-
let sepIdx = -1;
|
|
131
|
-
let delimiterLen = 0;
|
|
132
|
-
for (const delimiter of delimiters) {
|
|
133
|
-
const idx = arg.indexOf(delimiter);
|
|
134
|
-
if (idx !== -1 && (sepIdx === -1 || idx < sepIdx)) {
|
|
135
|
-
sepIdx = idx;
|
|
136
|
-
delimiterLen = delimiter.length;
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
if (!(sepIdx !== -1)) return {
|
|
140
|
-
rawName: arg,
|
|
141
|
-
rawValue: void 0,
|
|
142
|
-
hasSep: false
|
|
143
|
-
};
|
|
144
|
-
return {
|
|
145
|
-
rawName: arg.slice(0, sepIdx),
|
|
146
|
-
rawValue: arg.slice(sepIdx + delimiterLen),
|
|
147
|
-
hasSep: true
|
|
148
|
-
};
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
//#endregion
|
|
152
|
-
//#region src/parse.ts
|
|
153
|
-
const DOUBLE_DASH = "--";
|
|
154
|
-
function createParser(options = {}) {
|
|
155
|
-
const { flags: flagsConfig = {}, delimiters, ignore } = resolveParserOptions(options);
|
|
156
|
-
const { configs, aliases } = buildConfigsAndAliases(delimiters, flagsConfig);
|
|
157
|
-
function resolve(name, isShortFlag = false) {
|
|
158
|
-
const dotIdx = name.indexOf(".");
|
|
159
|
-
const rootName = dotIdx === -1 ? name : name.slice(0, dotIdx);
|
|
160
|
-
let key = aliases.get(rootName);
|
|
161
|
-
if (!key) {
|
|
162
|
-
key = aliases.get(camelCase(rootName));
|
|
163
|
-
if (!key) return;
|
|
164
|
-
}
|
|
165
|
-
const config = configs.get(key);
|
|
166
|
-
if (!isShortFlag && config.short === rootName) return;
|
|
167
|
-
return {
|
|
168
|
-
key,
|
|
169
|
-
config,
|
|
170
|
-
path: dotIdx === -1 ? void 0 : name.slice(dotIdx + 1)
|
|
171
|
-
};
|
|
172
|
-
}
|
|
173
|
-
function resolveNegated(name) {
|
|
174
|
-
if (!name.startsWith("no")) return;
|
|
175
|
-
const possibleName = name[2] === "-" ? name.slice(3) : name.length > 2 && /[A-Z]/.test(name[2]) ? name[2].toLowerCase() + name.slice(3) : "";
|
|
176
|
-
if (possibleName) {
|
|
177
|
-
const possibleResolved = resolve(possibleName);
|
|
178
|
-
if (possibleResolved?.config.type === Boolean && possibleResolved.config.negatable !== false) return possibleResolved;
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
function shouldProcessAsFlag(arg) {
|
|
182
|
-
if (arg.charCodeAt(0) !== 45) return false;
|
|
183
|
-
const len = arg.length;
|
|
184
|
-
if (len < 2) return false;
|
|
185
|
-
const secondChar = arg.charCodeAt(1);
|
|
186
|
-
if (isLetter(secondChar)) return true;
|
|
187
|
-
if (isDigit(secondChar)) {
|
|
188
|
-
const isShortFlag = secondChar !== 45;
|
|
189
|
-
return !!resolve(isShortFlag ? arg[1] : arg.slice(2), isShortFlag);
|
|
190
|
-
}
|
|
191
|
-
if (secondChar === 45 && len > 2) return isLetter(arg.charCodeAt(2));
|
|
192
|
-
return false;
|
|
193
|
-
}
|
|
194
|
-
function isKnownFlag(arg) {
|
|
195
|
-
if (arg.charCodeAt(1) === 45) {
|
|
196
|
-
const { rawName } = splitNameAndValue(arg.slice(2), delimiters);
|
|
197
|
-
if (resolve(rawName, false)) return true;
|
|
198
|
-
if (resolveNegated(rawName)) return true;
|
|
199
|
-
return false;
|
|
200
|
-
}
|
|
201
|
-
const chars = arg.slice(1);
|
|
202
|
-
for (const char of chars) if (!resolve(char, true)) return false;
|
|
203
|
-
return true;
|
|
204
|
-
}
|
|
205
|
-
const parse$1 = (args) => {
|
|
206
|
-
const result = {
|
|
207
|
-
parameters: [],
|
|
208
|
-
doubleDash: [],
|
|
209
|
-
flags: {},
|
|
210
|
-
raw: args,
|
|
211
|
-
unknown: {},
|
|
212
|
-
ignored: [],
|
|
213
|
-
missingRequiredFlags: []
|
|
214
|
-
};
|
|
215
|
-
iterateArgs(args, result, shouldProcessAsFlag, isKnownFlag, ignore, ({ current, eat, exit, hasNext, index, next, shouldIgnore }) => {
|
|
216
|
-
if (current === DOUBLE_DASH) {
|
|
217
|
-
result.doubleDash.push(...args.slice(index + 1));
|
|
218
|
-
exit(false);
|
|
219
|
-
return;
|
|
220
|
-
}
|
|
221
|
-
if (shouldIgnore(current)) {
|
|
222
|
-
result.ignored.push(current);
|
|
223
|
-
exit();
|
|
224
|
-
return;
|
|
225
|
-
}
|
|
226
|
-
if (!shouldProcessAsFlag(current)) {
|
|
227
|
-
result.parameters.push(current);
|
|
228
|
-
return;
|
|
229
|
-
}
|
|
230
|
-
const isShortFlag = !current.startsWith(DOUBLE_DASH);
|
|
231
|
-
const chars = current.slice(isShortFlag ? 1 : 2);
|
|
232
|
-
if (isShortFlag) {
|
|
233
|
-
const charsLen = chars.length;
|
|
234
|
-
for (let j = 0; j < charsLen; j++) {
|
|
235
|
-
const char = chars[j];
|
|
236
|
-
const resolved = resolve(char, true);
|
|
237
|
-
if (!resolved) {
|
|
238
|
-
result.unknown[char] = true;
|
|
239
|
-
continue;
|
|
240
|
-
}
|
|
241
|
-
const { key, config } = resolved;
|
|
242
|
-
const configType = config.type;
|
|
243
|
-
if (configType === Boolean || isArrayOfType(configType, Boolean)) setValueByType(result.flags, key, "true", config);
|
|
244
|
-
else if (j + 1 < charsLen) {
|
|
245
|
-
setValueByType(result.flags, key, chars.slice(j + 1), config);
|
|
246
|
-
break;
|
|
247
|
-
} else {
|
|
248
|
-
const value = hasNext && !shouldProcessAsFlag(next) ? eat() ?? "" : "";
|
|
249
|
-
setValueByType(result.flags, key, value, config);
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
} else {
|
|
253
|
-
const { rawName, rawValue, hasSep } = splitNameAndValue(chars, delimiters);
|
|
254
|
-
let resolved = resolve(rawName);
|
|
255
|
-
let isNegated = false;
|
|
256
|
-
if (!resolved) {
|
|
257
|
-
const negated = resolveNegated(rawName);
|
|
258
|
-
if (negated) {
|
|
259
|
-
resolved = negated;
|
|
260
|
-
isNegated = true;
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
if (!resolved) {
|
|
264
|
-
const key$1 = camelCase(rawName);
|
|
265
|
-
if (hasSep) result.unknown[key$1] = rawValue;
|
|
266
|
-
else if (hasNext && !shouldProcessAsFlag(next)) {
|
|
267
|
-
const value = eat();
|
|
268
|
-
result.unknown[key$1] = value ?? true;
|
|
269
|
-
} else result.unknown[key$1] = true;
|
|
270
|
-
return;
|
|
271
|
-
}
|
|
272
|
-
const { key, config, path } = resolved;
|
|
273
|
-
if (path) {
|
|
274
|
-
if (config.type === Object) {
|
|
275
|
-
result.flags[key] ??= {};
|
|
276
|
-
const value = hasSep ? rawValue : hasNext && !shouldProcessAsFlag(next) ? eat() ?? "" : "";
|
|
277
|
-
setDotValues(result.flags[key], path, value);
|
|
278
|
-
}
|
|
279
|
-
} else if (config.type === Boolean) {
|
|
280
|
-
const value = hasSep ? rawValue !== "false" : true;
|
|
281
|
-
result.flags[key] = isNegated ? !value : value;
|
|
282
|
-
} else {
|
|
283
|
-
const value = hasSep ? rawValue : hasNext && !shouldProcessAsFlag(next) ? eat() ?? "" : "";
|
|
284
|
-
setValueByType(result.flags, key, value, config);
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
});
|
|
288
|
-
for (const [key, config] of configs.entries()) if (result.flags[key] === void 0) {
|
|
289
|
-
if (config.default !== void 0) result.flags[key] = resolveValue(config.default);
|
|
290
|
-
else if (Array.isArray(config.type)) result.flags[key] = isArrayOfType(config.type, Boolean) ? 0 : [];
|
|
291
|
-
else if (config.type === Object) result.flags[key] = {};
|
|
292
|
-
else if (config.type === Boolean) result.flags[key] = false;
|
|
293
|
-
else if (config.required) result.missingRequiredFlags.push(key);
|
|
294
|
-
}
|
|
295
|
-
return result;
|
|
296
|
-
};
|
|
297
|
-
return { parse: parse$1 };
|
|
298
|
-
}
|
|
299
|
-
const parse = (args, options = {}) => createParser(options).parse(args);
|
|
300
|
-
|
|
301
|
-
//#endregion
|
|
302
|
-
export { DOUBLE_DASH, InvalidSchemaError, KNOWN_FLAG, PARAMETER, UNKNOWN_FLAG, createParser, parse };
|
|
1
|
+
import{camelCase as e,hasOwn as t,looseIsArray as n,resolveValue as r}from"@clerc/utils";var i=class extends Error{constructor(e){super(`Invalid schema: ${e}`),this.name=`InvalidSchemaError`}};const a=`known-flag`,o=`unknown-flag`,s=`parameter`;function c(e,t,n,r,i,c){let l=0,u=!1,d=e.length,f={current:``,index:0,hasNext:!1,next:``,shouldIgnore:e=>i?i(n(e)?r(e)?a:o:s,e):!1,eat:()=>{if(l+1>=d)return;let t=e[l+1];if(f.shouldIgnore(t)){f.exit();return}return l++,p(),e[l]},exit:(n=!0)=>{u||=(n&&t.ignored.push(...e.slice(l+1)),!0)}};function p(){f.current=e[l],f.index=l,f.hasNext=l+1<d,f.next=f.hasNext?e[l+1]:``}for(l=0;l<d&&!u;l++)p(),c(f)}const l={delimiters:[`=`,`:`]},u=(e={})=>({...l,...e}),d=e=>typeof e==`function`||n(e)?{type:e}:e;function f(t,n){let r=new Map,a=new Map,o=e=>t.some(t=>e.includes(t))||e.includes(` `)||e.includes(`.`);function s(e,t){let n=`Flag "${e}"`;if(Array.isArray(t.type)&&t.type.length>1)throw new i(`${n} has an invalid type array. Only single-element arrays are allowed to denote multiple occurrences.`);if(e.length<2)throw new i(`${n} name must be at least 2 characters long.`);let r=[e];if(t.short){if(t.short.length!==1)throw new i(`${n} short flag must be exactly 1 character long.`);r.push(t.short)}if(r.some(o))throw new i(`${n} contains reserved characters, which are used as delimiters.`);if(t.required&&t.default!==void 0)throw new i(`${n} cannot be both required and have a default value.`)}for(let[t,i]of Object.entries(n)){let n=d(i);s(t,n),r.set(t,n),a.set(t,t),a.set(e(t),t),n.short&&a.set(n.short,t)}return{configs:r,aliases:a}}const p=(e,t)=>Array.isArray(e)&&e[0]===t;function m(e){if(n(e))return p(e,Boolean)?0:[];if(e===Boolean)return!1;if(e===Object)return{}}const h=e=>e>=65&&e<=90||e>=97&&e<=122,g=e=>e>=48&&e<=57;function _(e,t,r,i){let{type:a}=i;n(a)?p(a,Boolean)?e[t]=(e[t]??0)+1:(e[t]??=[]).push(a[0](r)):e[t]=a(r)}function v(e){return e===`true`||e===``?!0:e===`false`?!1:e}function y(e,t,n){let r=t.split(`.`),i=e;for(let e=0;e<r.length-1;e++){let t=r[e];i[t]??={},i=i[t]}let a=r[r.length-1];i[a]=n}function b(e,n,r){let i=n.split(`.`),a=e;for(let e=0;e<i.length-1;e++){let n=i[e];if(t(a,n)&&(typeof a[n]!=`object`||a[n]===null))return;a[n]??={},a=a[n]}let o=i[i.length-1];if(t(a,o)){let e=a[o];Array.isArray(e)?e.push(r):a[o]=[e,r]}else a[o]=r}function x(e,t){let n=-1,r=0;for(let i of t){let t=e.indexOf(i);t!==-1&&(n===-1||t<n)&&(n=t,r=i.length)}return n===-1?{rawName:e,rawValue:void 0,hasSep:!1}:{rawName:e.slice(0,n),rawValue:e.slice(n+r),hasSep:!0}}const S=`--`;function C(t={}){let{flags:n={},delimiters:i,ignore:a}=u(t),{configs:o,aliases:s}=f(i,n);function l(t,n=!1){let r=t.indexOf(`.`),i=r===-1?t:t.slice(0,r),a=s.get(i);if(!a&&(a=s.get(e(i)),!a))return;let c=o.get(a);if(!(!n&&c.short===i))return{key:a,config:c,path:r===-1?void 0:t.slice(r+1)}}function d(e){if(!e.startsWith(`no`))return;let t=e[2]===`-`?e.slice(3):e.length>2&&e.charCodeAt(2)>=65&&e.charCodeAt(2)<=90?e[2].toLowerCase()+e.slice(3):``;if(t){let e=l(t);if(e?.config.type===Boolean&&e.config.negatable!==!1)return e}}function y(e){if(e.charCodeAt(0)!==45)return!1;let t=e.length;if(t<2)return!1;let n=e.charCodeAt(1);if(h(n))return!0;if(g(n)){let t=n!==45;return!!l(t?e[1]:e.slice(2),t)}return n===45&&t>2?h(e.charCodeAt(2)):!1}function S(e){if(e.charCodeAt(1)===45){let{rawName:t}=x(e.slice(2),i);return!!(l(t,!1)||d(t))}let t=e.slice(1);for(let e of t)if(!l(e,!0))return!1;return!0}return{parse:t=>{let n={parameters:[],doubleDash:[],flags:{},raw:t,unknown:{},ignored:[],missingRequiredFlags:[]};c(t,n,y,S,a,({current:r,eat:a,exit:o,hasNext:s,index:c,next:u,shouldIgnore:f})=>{if(r===`--`){n.doubleDash.push(...t.slice(c+1)),o(!1);return}if(f(r)){n.ignored.push(r),o();return}if(!y(r)){n.parameters.push(r);return}let m=!r.startsWith(`--`),h=r.slice(m?1:2);if(m){let e=h.length;for(let t=0;t<e;t++){let r=h[t],i=l(r,!0);if(!i){n.unknown[r]=!0;continue}let{key:o,config:c}=i,d=c.type;if(d===Boolean||p(d,Boolean))_(n.flags,o,`true`,c);else if(t+1<e){_(n.flags,o,h.slice(t+1),c);break}else{let e=s&&!y(u)?a()??``:``;_(n.flags,o,e,c)}}}else{let{rawName:t,rawValue:r,hasSep:o}=x(h,i),c=l(t),f=!1;if(!c){let e=d(t);e&&(c=e,f=!0)}if(!c){let i=e(t);if(o)n.unknown[i]=r;else if(s&&!y(u)){let e=a();n.unknown[i]=e??!0}else n.unknown[i]=!0;return}let{key:p,config:m,path:g}=c;if(g){if(m.type===Object){n.flags[p]??={};let e=o?r:s&&!y(u)?a()??``:``;b(n.flags[p],g,v(e))}}else if(m.type===Boolean){let e=o?r!==`false`:!0;n.flags[p]=f?!e:e}else{let e=o?r:s&&!y(u)?a()??``:``;_(n.flags,p,e,m)}}});for(let[e,t]of o.entries())n.flags[e]===void 0&&(t.default===void 0?t.required?n.missingRequiredFlags.push(e):n.flags[e]=m(t.type):n.flags[e]=r(t.default));return n}}}const w=(e,t={})=>C(t).parse(e);export{S as DOUBLE_DASH,i as InvalidSchemaError,a as KNOWN_FLAG,s as PARAMETER,o as UNKNOWN_FLAG,b as appendDotValues,v as coerceObjectValue,C as createParser,m as inferDefault,w as parse,y as setDotValues};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@clerc/parser",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"author": "Ray <i@mk1.io> (https://github.com/so1ve)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Clerc parser",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"access": "public"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@clerc/utils": "1.
|
|
43
|
+
"@clerc/utils": "1.2.0"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@types/minimist": "^1.2.5",
|