source: trip-planner-front/node_modules/@angular/cli/models/parser.js@ 84d0fbb

Last change on this file since 84d0fbb was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 13.2 KB
Line 
1"use strict";
2/**
3 * @license
4 * Copyright Google LLC All Rights Reserved.
5 *
6 * Use of this source code is governed by an MIT-style license that can be
7 * found in the LICENSE file at https://angular.io/license
8 */
9Object.defineProperty(exports, "__esModule", { value: true });
10exports.parseArguments = exports.parseFreeFormArguments = exports.ParseArgumentException = void 0;
11const core_1 = require("@angular-devkit/core");
12const interface_1 = require("./interface");
13class ParseArgumentException extends core_1.BaseException {
14 constructor(comments, parsed, ignored) {
15 super(`One or more errors occurred while parsing arguments:\n ${comments.join('\n ')}`);
16 this.comments = comments;
17 this.parsed = parsed;
18 this.ignored = ignored;
19 }
20}
21exports.ParseArgumentException = ParseArgumentException;
22function _coerceType(str, type, v) {
23 switch (type) {
24 case interface_1.OptionType.Any:
25 if (Array.isArray(v)) {
26 return v.concat(str || '');
27 }
28 return _coerceType(str, interface_1.OptionType.Boolean, v) !== undefined
29 ? _coerceType(str, interface_1.OptionType.Boolean, v)
30 : _coerceType(str, interface_1.OptionType.Number, v) !== undefined
31 ? _coerceType(str, interface_1.OptionType.Number, v)
32 : _coerceType(str, interface_1.OptionType.String, v);
33 case interface_1.OptionType.String:
34 return str || '';
35 case interface_1.OptionType.Boolean:
36 switch (str) {
37 case 'false':
38 return false;
39 case undefined:
40 case '':
41 case 'true':
42 return true;
43 default:
44 return undefined;
45 }
46 case interface_1.OptionType.Number:
47 if (str === undefined) {
48 return 0;
49 }
50 else if (str === '') {
51 return undefined;
52 }
53 else if (Number.isFinite(+str)) {
54 return +str;
55 }
56 else {
57 return undefined;
58 }
59 case interface_1.OptionType.Array:
60 return Array.isArray(v)
61 ? v.concat(str || '')
62 : v === undefined
63 ? [str || '']
64 : [v + '', str || ''];
65 default:
66 return undefined;
67 }
68}
69function _coerce(str, o, v) {
70 if (!o) {
71 return _coerceType(str, interface_1.OptionType.Any, v);
72 }
73 else {
74 const types = o.types || [o.type];
75 // Try all the types one by one and pick the first one that returns a value contained in the
76 // enum. If there's no enum, just return the first one that matches.
77 for (const type of types) {
78 const maybeResult = _coerceType(str, type, v);
79 if (maybeResult !== undefined && (!o.enum || o.enum.includes(maybeResult))) {
80 return maybeResult;
81 }
82 }
83 return undefined;
84 }
85}
86function _getOptionFromName(name, options) {
87 const camelName = /(-|_)/.test(name) ? core_1.strings.camelize(name) : name;
88 for (const option of options) {
89 if (option.name === name || option.name === camelName) {
90 return option;
91 }
92 if (option.aliases.some((x) => x === name || x === camelName)) {
93 return option;
94 }
95 }
96 return undefined;
97}
98function _removeLeadingDashes(key) {
99 const from = key.startsWith('--') ? 2 : key.startsWith('-') ? 1 : 0;
100 return key.substr(from);
101}
102function _assignOption(arg, nextArg, { options, parsedOptions, leftovers, ignored, errors, warnings, }) {
103 const from = arg.startsWith('--') ? 2 : 1;
104 let consumedNextArg = false;
105 let key = arg.substr(from);
106 let option = null;
107 let value = '';
108 const i = arg.indexOf('=');
109 // If flag is --no-abc AND there's no equal sign.
110 if (i == -1) {
111 if (key.startsWith('no')) {
112 // Only use this key if the option matching the rest is a boolean.
113 const from = key.startsWith('no-') ? 3 : 2;
114 const maybeOption = _getOptionFromName(core_1.strings.camelize(key.substr(from)), options);
115 if (maybeOption && maybeOption.type == 'boolean') {
116 value = 'false';
117 option = maybeOption;
118 }
119 }
120 if (option === null) {
121 // Set it to true if it's a boolean and the next argument doesn't match true/false.
122 const maybeOption = _getOptionFromName(key, options);
123 if (maybeOption) {
124 value = nextArg;
125 let shouldShift = true;
126 if (value && value.startsWith('-') && _coerce(undefined, maybeOption) !== undefined) {
127 // Verify if not having a value results in a correct parse, if so don't shift.
128 shouldShift = false;
129 }
130 // Only absorb it if it leads to a better value.
131 if (shouldShift && _coerce(value, maybeOption) !== undefined) {
132 consumedNextArg = true;
133 }
134 else {
135 value = '';
136 }
137 option = maybeOption;
138 }
139 }
140 }
141 else {
142 key = arg.substring(0, i);
143 option = _getOptionFromName(_removeLeadingDashes(key), options) || null;
144 if (option) {
145 value = arg.substring(i + 1);
146 }
147 }
148 if (option === null) {
149 if (nextArg && !nextArg.startsWith('-')) {
150 leftovers.push(arg, nextArg);
151 consumedNextArg = true;
152 }
153 else {
154 leftovers.push(arg);
155 }
156 }
157 else {
158 const v = _coerce(value, option, parsedOptions[option.name]);
159 if (v !== undefined) {
160 if (parsedOptions[option.name] !== v) {
161 if (parsedOptions[option.name] !== undefined && option.type !== interface_1.OptionType.Array) {
162 warnings.push(`Option ${JSON.stringify(option.name)} was already specified with value ` +
163 `${JSON.stringify(parsedOptions[option.name])}. The new value ${JSON.stringify(v)} ` +
164 `will override it.`);
165 }
166 parsedOptions[option.name] = v;
167 }
168 }
169 else {
170 let error = `Argument ${key} could not be parsed using value ${JSON.stringify(value)}.`;
171 if (option.enum) {
172 error += ` Valid values are: ${option.enum.map((x) => JSON.stringify(x)).join(', ')}.`;
173 }
174 else {
175 error += `Valid type(s) is: ${(option.types || [option.type]).join(', ')}`;
176 }
177 errors.push(error);
178 ignored.push(arg);
179 }
180 if (/^[a-z]+[A-Z]/.test(key)) {
181 warnings.push('Support for camel case arguments has been deprecated and will be removed in a future major version.\n' +
182 `Use '--${core_1.strings.dasherize(key)}' instead of '--${key}'.`);
183 }
184 }
185 return consumedNextArg;
186}
187/**
188 * Parse the arguments in a consistent way, but without having any option definition. This tries
189 * to assess what the user wants in a free form. For example, using `--name=false` will set the
190 * name properties to a boolean type.
191 * This should only be used when there's no schema available or if a schema is "true" (anything is
192 * valid).
193 *
194 * @param args Argument list to parse.
195 * @returns An object that contains a property per flags from the args.
196 */
197function parseFreeFormArguments(args) {
198 const parsedOptions = {};
199 const leftovers = [];
200 for (let arg = args.shift(); arg !== undefined; arg = args.shift()) {
201 if (arg == '--') {
202 leftovers.push(...args);
203 break;
204 }
205 if (arg.startsWith('--')) {
206 const eqSign = arg.indexOf('=');
207 let name;
208 let value;
209 if (eqSign !== -1) {
210 name = arg.substring(2, eqSign);
211 value = arg.substring(eqSign + 1);
212 }
213 else {
214 name = arg.substr(2);
215 value = args.shift();
216 }
217 const v = _coerce(value, null, parsedOptions[name]);
218 if (v !== undefined) {
219 parsedOptions[name] = v;
220 }
221 }
222 else if (arg.startsWith('-')) {
223 arg.split('').forEach((x) => (parsedOptions[x] = true));
224 }
225 else {
226 leftovers.push(arg);
227 }
228 }
229 if (leftovers.length) {
230 parsedOptions['--'] = leftovers;
231 }
232 return parsedOptions;
233}
234exports.parseFreeFormArguments = parseFreeFormArguments;
235/**
236 * Parse the arguments in a consistent way, from a list of standardized options.
237 * The result object will have a key per option name, with the `_` key reserved for positional
238 * arguments, and `--` will contain everything that did not match. Any key that don't have an
239 * option will be pushed back in `--` and removed from the object. If you need to validate that
240 * there's no additionalProperties, you need to check the `--` key.
241 *
242 * @param args The argument array to parse.
243 * @param options List of supported options. {@see Option}.
244 * @param logger Logger to use to warn users.
245 * @returns An object that contains a property per option.
246 */
247function parseArguments(args, options, logger) {
248 if (options === null) {
249 options = [];
250 }
251 const leftovers = [];
252 const positionals = [];
253 const parsedOptions = {};
254 const ignored = [];
255 const errors = [];
256 const warnings = [];
257 const state = { options, parsedOptions, positionals, leftovers, ignored, errors, warnings };
258 for (let argIndex = 0; argIndex < args.length; argIndex++) {
259 const arg = args[argIndex];
260 let consumedNextArg = false;
261 if (arg == '--') {
262 // If we find a --, we're done.
263 leftovers.push(...args.slice(argIndex + 1));
264 break;
265 }
266 if (arg.startsWith('--')) {
267 consumedNextArg = _assignOption(arg, args[argIndex + 1], state);
268 }
269 else if (arg.startsWith('-')) {
270 // Argument is of form -abcdef. Starts at 1 because we skip the `-`.
271 for (let i = 1; i < arg.length; i++) {
272 const flag = arg[i];
273 // If the next character is an '=', treat it as a long flag.
274 if (arg[i + 1] == '=') {
275 const f = '-' + flag + arg.slice(i + 1);
276 consumedNextArg = _assignOption(f, args[argIndex + 1], state);
277 break;
278 }
279 // Treat the last flag as `--a` (as if full flag but just one letter). We do this in
280 // the loop because it saves us a check to see if the arg is just `-`.
281 if (i == arg.length - 1) {
282 const arg = '-' + flag;
283 consumedNextArg = _assignOption(arg, args[argIndex + 1], state);
284 }
285 else {
286 const maybeOption = _getOptionFromName(flag, options);
287 if (maybeOption) {
288 const v = _coerce(undefined, maybeOption, parsedOptions[maybeOption.name]);
289 if (v !== undefined) {
290 parsedOptions[maybeOption.name] = v;
291 }
292 }
293 }
294 }
295 }
296 else {
297 positionals.push(arg);
298 }
299 if (consumedNextArg) {
300 argIndex++;
301 }
302 }
303 // Deal with positionals.
304 // TODO(hansl): this is by far the most complex piece of code in this file. Try to refactor it
305 // simpler.
306 if (positionals.length > 0) {
307 let pos = 0;
308 for (let i = 0; i < positionals.length;) {
309 let found = false;
310 let incrementPos = false;
311 let incrementI = true;
312 // We do this with a found flag because more than 1 option could have the same positional.
313 for (const option of options) {
314 // If any option has this positional and no value, AND fit the type, we need to remove it.
315 if (option.positional === pos) {
316 const coercedValue = _coerce(positionals[i], option, parsedOptions[option.name]);
317 if (parsedOptions[option.name] === undefined && coercedValue !== undefined) {
318 parsedOptions[option.name] = coercedValue;
319 found = true;
320 }
321 else {
322 incrementI = false;
323 }
324 incrementPos = true;
325 }
326 }
327 if (found) {
328 positionals.splice(i--, 1);
329 }
330 if (incrementPos) {
331 pos++;
332 }
333 if (incrementI) {
334 i++;
335 }
336 }
337 }
338 if (positionals.length > 0 || leftovers.length > 0) {
339 parsedOptions['--'] = [...positionals, ...leftovers];
340 }
341 if (warnings.length > 0 && logger) {
342 warnings.forEach((message) => logger.warn(message));
343 }
344 if (errors.length > 0) {
345 throw new ParseArgumentException(errors, parsedOptions, ignored);
346 }
347 return parsedOptions;
348}
349exports.parseArguments = parseArguments;
Note: See TracBrowser for help on using the repository browser.