@flowscripter/dynamic-cli-framework 1.2.2 → 1.3.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/README/core-service-providers.md +2 -2
- package/README/development.md +3 -6
- package/README/implementation-details.md +17 -17
- package/README/key-concepts.md +17 -17
- package/README.md +4 -4
- package/bun.lock +0 -2
- package/index.ts +22 -30
- package/package.json +19 -19
- package/src/api/argument/Argument.ts +1 -1
- package/src/api/argument/ArgumentValueTypes.ts +3 -10
- package/src/api/argument/ComplexOption.ts +5 -9
- package/src/api/command/GlobalCommand.ts +1 -4
- package/src/api/service/core/ArgumentPrompterService.ts +1 -3
- package/src/api/service/core/AsciiBannerGeneratorService.ts +1 -4
- package/src/api/service/core/CompletionService.ts +2 -6
- package/src/api/service/core/ImagePrinterService.ts +1 -2
- package/src/api/service/core/KeyValueService.ts +1 -2
- package/src/api/service/core/PrettyPrinterService.ts +1 -4
- package/src/api/service/core/PrinterService.ts +8 -9
- package/src/api/service/core/PrompterService.ts +4 -11
- package/src/api/service/core/ShutdownService.ts +1 -2
- package/src/api/service/core/SyntaxHighlighterService.ts +1 -5
- package/src/api/service/core/Table.ts +7 -25
- package/src/api/service/core/TreePrinterService.ts +1 -2
- package/src/cli/BaseCLI.ts +17 -47
- package/src/cli/DefaultRuntimeCLI.ts +1 -4
- package/src/command/CompletionCommand.ts +19 -45
- package/src/command/MultiCommandCliHelpCommand.ts +45 -92
- package/src/command/SingleCommandCliHelpCommand.ts +17 -28
- package/src/command/UsageCommand.ts +6 -12
- package/src/command/VersionCommand.ts +2 -6
- package/src/launcher.ts +4 -2
- package/src/runtime/DefaultContext.ts +2 -5
- package/src/runtime/argument/ArgumentTypeGuards.ts +1 -3
- package/src/runtime/command/CommandTypeGuards.ts +5 -14
- package/src/runtime/command/CommandValidator.ts +56 -118
- package/src/runtime/parser.ts +13 -17
- package/src/runtime/registry/CommandRegistry.ts +2 -7
- package/src/runtime/registry/DefaultCommandRegistry.ts +32 -84
- package/src/runtime/registry/DefaultServiceProviderRegistry.ts +3 -9
- package/src/runtime/runner.ts +103 -142
- package/src/runtime/scanner.ts +28 -46
- package/src/runtime/values/ValuePopulationResult.ts +1 -2
- package/src/runtime/values/argumentValueMerge.ts +16 -28
- package/src/runtime/values/argumentValueValidation.ts +21 -67
- package/src/runtime/values/globalCommandValuePopulation.ts +9 -18
- package/src/runtime/values/subCommandValuePopulation.ts +42 -65
- package/src/service/argumentPrompter/ArgumentPrompterServiceProvider.ts +3 -10
- package/src/service/argumentPrompter/DefaultArgumentPrompterService.ts +22 -59
- package/src/service/asciiBannerGenerator/AsciiBannerGeneratorServiceProvider.ts +5 -14
- package/src/service/asciiBannerGenerator/DefaultAsciiBannerGeneratorService.ts +59 -77
- package/src/service/banner/BannerServiceProvider.ts +13 -35
- package/src/service/banner/command/NoBannerCommand.ts +2 -8
- package/src/service/chiselAsciiBannerGenerator/ChiselFontAsciiBannerGeneratorService.ts +5 -10
- package/src/service/completion/CompletionServiceProvider.ts +20 -48
- package/src/service/completion/DefaultCompletionService.ts +17 -56
- package/src/service/completion/shell/ShellHandler.ts +1 -3
- package/src/service/completion/shell/fish.ts +1 -1
- package/src/service/completion/shell/powershell.ts +2 -12
- package/src/service/completion/shell/zsh.ts +1 -1
- package/src/service/configuration/ConfigurationServiceProvider.ts +40 -133
- package/src/service/configuration/DefaultKeyValueService.ts +6 -20
- package/src/service/configuration/DefaultSecretService.ts +10 -14
- package/src/service/configuration/command/ConfigCommand.ts +1 -4
- package/src/service/configuration/command/DumpConfigCommand.ts +9 -21
- package/src/service/dataDumpGenerator/DataDumpGeneratorServiceProvider.ts +5 -14
- package/src/service/dataDumpGenerator/DefaultDataDumpGeneratorService.ts +5 -12
- package/src/service/imagePrinter/DefaultImagePrinterService.ts +1 -5
- package/src/service/imagePrinter/ImagePrinterServiceProvider.ts +1 -4
- package/src/service/prettyPrinter/DefaultPrettyPrinterService.ts +4 -12
- package/src/service/prettyPrinter/PrettyPrinterServiceProvider.ts +3 -10
- package/src/service/printer/DefaultPrinterService.ts +20 -83
- package/src/service/printer/PrinterServiceProvider.ts +3 -11
- package/src/service/printer/command/DarkModeCommand.ts +3 -10
- package/src/service/printer/command/LogLevelCommand.ts +7 -26
- package/src/service/printer/command/NoColorCommand.ts +3 -10
- package/src/service/printer/command/NoHyperlinksCommand.ts +3 -10
- package/src/service/printer/terminal/Progress.ts +99 -90
- package/src/service/printer/terminal/Spinner.ts +7 -26
- package/src/service/prompter/DefaultPrompterService.ts +2 -6
- package/src/service/prompter/PrompterServiceProvider.ts +3 -11
- package/src/service/prompter/command/NoPromptCommand.ts +3 -10
- package/src/service/prompter/prompt/PromptContext.ts +5 -18
- package/src/service/prompter/prompt/promptMultiSelect.ts +6 -21
- package/src/service/prompter/prompt/promptOpenUrl.ts +7 -22
- package/src/service/prompter/prompt/promptSingleSelect.ts +6 -23
- package/src/service/prompter/prompt/promptText.ts +10 -27
- package/src/service/prompter/prompt/promptToggle.ts +8 -8
- package/src/service/shutdown/ShutdownServiceProvider.ts +3 -10
- package/src/service/syntaxHighlighter/DefaultSyntaxHighlighterService.ts +13 -26
- package/src/service/syntaxHighlighter/SyntaxHighlighterServiceProvider.ts +8 -21
- package/src/service/tableGenerator/DefaultTableGeneratorService.ts +44 -68
- package/src/service/tableGenerator/TableGeneratorServiceProvider.ts +7 -16
- package/src/service/treePrinter/DefaultTreePrinterService.ts +2 -7
- package/src/service/treePrinter/TreePrinterServiceProvider.ts +4 -12
- package/src/terminal/ImageRenderer.ts +35 -54
- package/src/terminal/PngDecoder.ts +10 -19
- package/src/terminal/TtyStyler.ts +11 -9
- package/src/terminal/TtyTerminal.ts +2 -10
- package/src/terminal/supportsHyperlinks.ts +4 -10
- package/src/util/configHelper.ts +3 -10
- package/src/util/envVarHelper.ts +50 -88
- package/src/util/helpHelper.ts +123 -193
- package/src/util/logger.ts +12 -42
- package/src/util/runnerHelper.ts +20 -61
- package/tests/cli/BaseCLI.test.ts +23 -80
- package/tests/command/CompletionCommand.test.ts +1 -6
- package/tests/command/MultiCommandCliHelpCommand.test.ts +51 -205
- package/tests/command/SingleCommandCliHelpCommand.test.ts +21 -103
- package/tests/command/UsageCommand.test.ts +4 -10
- package/tests/fixtures/Command.ts +87 -68
- package/tests/fixtures/CommandRegistry.ts +1 -3
- package/tests/fixtures/Context.ts +3 -11
- package/tests/fixtures/ServiceProviderRegistry.ts +1 -1
- package/tests/fixtures/prettierPluginFoo.ts +1 -1
- package/tests/fixtures/util.ts +2 -8
- package/tests/runtime/argument/ArgumentTypeGuards.test.ts +1 -3
- package/tests/runtime/command/CommandValidator.test.ts +881 -604
- package/tests/runtime/parser.test.ts +222 -246
- package/tests/runtime/registry/DefaultCommandRegistry.test.ts +15 -37
- package/tests/runtime/registry/DefaultServiceProviderRegistry.test.ts +2 -8
- package/tests/runtime/runner.test.ts +231 -281
- package/tests/runtime/scanner.test.ts +277 -475
- package/tests/runtime/values/argumentValueMerge.test.ts +133 -81
- package/tests/runtime/values/argumentValueValidation.test.ts +444 -588
- package/tests/runtime/values/globalCommandValuePopulation.test.ts +71 -253
- package/tests/runtime/values/subCommandValuePopulation.test.ts +1342 -1570
- package/tests/service/argumentPrompter/ArgumentPrompterServiceProvider.test.ts +3 -12
- package/tests/service/argumentPrompter/DefaultArgumentPrompterService.test.ts +36 -45
- package/tests/service/asciiBannerGenerator/AsciiBannerGeneratorServiceProvider.test.ts +2 -8
- package/tests/service/asciiBannerGenerator/DefaultAsciiBannerGeneratorService.test.ts +40 -62
- package/tests/service/banner/BannerServiceProvider.test.ts +5 -18
- package/tests/service/banner/command/NoBannerCommand.test.ts +1 -4
- package/tests/service/completion/CompletionServiceProvider.test.ts +145 -214
- package/tests/service/completion/DefaultCompletionService.test.ts +17 -79
- package/tests/service/completion/shell/fish.test.ts +1 -3
- package/tests/service/configuration/ConfigurationServiceProvider.test.ts +26 -75
- package/tests/service/configuration/DefaultKeyValueService.test.ts +9 -21
- package/tests/service/configuration/DefaultSecretService.test.ts +7 -15
- package/tests/service/configuration/command/DumpConfigCommand.test.ts +4 -13
- package/tests/service/dataDumpGenerator/DataDumpGeneratorServiceProvider.test.ts +6 -12
- package/tests/service/dataDumpGenerator/DefaultDataDumpGeneratorService.test.ts +1 -10
- package/tests/service/imagePrinter/DefaultImagePrinterService.test.ts +5 -70
- package/tests/service/prettyPrinter/DefaultPrettyPrinterService.test.ts +4 -11
- package/tests/service/prettyPrinter/PrettyPrinterServiceProvider.test.ts +2 -6
- package/tests/service/printer/DefaultPrinterService.test.ts +57 -255
- package/tests/service/printer/PrinterServiceProvider.test.ts +2 -8
- package/tests/service/printer/command/DarkModeCommand.test.ts +4 -12
- package/tests/service/printer/command/LogLevelCommand.test.ts +4 -17
- package/tests/service/printer/command/NoColorCommand.test.ts +4 -12
- package/tests/service/printer/command/NoHyperlinksCommand.test.ts +7 -21
- package/tests/service/printer/terminal/Progress.test.ts +1 -3
- package/tests/service/printer/terminal/Spinner.test.ts +2 -8
- package/tests/service/prompter/DefaultPrompterService.test.ts +52 -69
- package/tests/service/prompter/PrompterServiceProvider.test.ts +2 -8
- package/tests/service/shutdown/ShutdownServiceProvider.test.ts +1 -3
- package/tests/service/syntaxHighlighter/DefaultSyntaxHighlighterService.test.ts +13 -99
- package/tests/service/syntaxHighlighter/SyntaxHighlighterServiceProvider.test.ts +2 -7
- package/tests/service/tableGenerator/DefaultTableGeneratorService.test.ts +12 -33
- package/tests/service/tableGenerator/TableGeneratorServiceProvider.test.ts +2 -2
- package/tests/service/treePrinter/DefaultTreePrinterService.test.ts +4 -6
- package/tests/service/treePrinter/TreePrinterServiceProvider.test.ts +4 -8
- package/tests/terminal/ImageRenderer.test.ts +2 -11
- package/tests/terminal/PngDecoder.test.ts +2 -6
- package/tests/util/configHelper.test.ts +55 -137
- package/tests/util/envVarHelper.test.ts +46 -110
package/src/util/envVarHelper.ts
CHANGED
|
@@ -10,9 +10,7 @@ import {
|
|
|
10
10
|
type ProcessEnv = NodeJS.ProcessEnv;
|
|
11
11
|
|
|
12
12
|
import type SubCommandArgument from "../api/argument/SubCommandArgument.ts";
|
|
13
|
-
import {
|
|
14
|
-
MAXIMUM_ARGUMENT_ARRAY_SIZE,
|
|
15
|
-
} from "../api/argument/SubCommandArgument.ts";
|
|
13
|
+
import { MAXIMUM_ARGUMENT_ARRAY_SIZE } from "../api/argument/SubCommandArgument.ts";
|
|
16
14
|
import type Option from "../api/argument/Option.ts";
|
|
17
15
|
import type GlobalCommandArgument from "../api/argument/GlobalCommandArgument.ts";
|
|
18
16
|
import type GlobalCommand from "../api/command/GlobalCommand.ts";
|
|
@@ -35,9 +33,9 @@ function getSubCommandArgumentKeyPrefix(
|
|
|
35
33
|
if (subCommandArgument.configurationKey) {
|
|
36
34
|
return subCommandArgument.configurationKey;
|
|
37
35
|
}
|
|
38
|
-
return `${getKeySegment(cliConfig.name)}_${getKeySegment(command.name)}_${
|
|
39
|
-
|
|
40
|
-
}`;
|
|
36
|
+
return `${getKeySegment(cliConfig.name)}_${getKeySegment(command.name)}_${getKeySegment(
|
|
37
|
+
subCommandArgument.name,
|
|
38
|
+
)}`;
|
|
41
39
|
}
|
|
42
40
|
|
|
43
41
|
function getGlobalArgumentKeyPrefix(
|
|
@@ -68,14 +66,9 @@ export function getGlobalCommandValueFromEnvVars(
|
|
|
68
66
|
}
|
|
69
67
|
|
|
70
68
|
// simple check for a specific env var name
|
|
71
|
-
let envVarValue = process.env[
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
if (
|
|
75
|
-
(envVarValue != undefined) &&
|
|
76
|
-
(argument.type === ArgumentValueTypeName.BOOLEAN)
|
|
77
|
-
) {
|
|
78
|
-
envVarValue = (envVarValue.length > 0) ? "true" : "false";
|
|
69
|
+
let envVarValue = process.env[getGlobalArgumentKeyPrefix(cliConfig, command, argument)];
|
|
70
|
+
if (envVarValue != undefined && argument.type === ArgumentValueTypeName.BOOLEAN) {
|
|
71
|
+
envVarValue = envVarValue.length > 0 ? "true" : "false";
|
|
79
72
|
}
|
|
80
73
|
|
|
81
74
|
return envVarValue;
|
|
@@ -92,10 +85,7 @@ function getOptionValuesFromEnvVars(
|
|
|
92
85
|
return;
|
|
93
86
|
}
|
|
94
87
|
|
|
95
|
-
if (
|
|
96
|
-
option.name === "__proto__" || option.name === "constructor" ||
|
|
97
|
-
option.name === "prototype"
|
|
98
|
-
) {
|
|
88
|
+
if (option.name === "__proto__" || option.name === "constructor" || option.name === "prototype") {
|
|
99
89
|
throw new Error(
|
|
100
90
|
`Unsafe key name in use: ${option.name}, CodeQL Rule ID: js/prototype-polluting-assignment`,
|
|
101
91
|
);
|
|
@@ -105,7 +95,7 @@ function getOptionValuesFromEnvVars(
|
|
|
105
95
|
envVarNamePrefix = `${envVarNamePrefix}_`;
|
|
106
96
|
|
|
107
97
|
const matches = potentialEnvVarNames.filter((envVarName) =>
|
|
108
|
-
envVarName.startsWith(envVarNamePrefix)
|
|
98
|
+
envVarName.startsWith(envVarNamePrefix),
|
|
109
99
|
);
|
|
110
100
|
matches.forEach((match) => {
|
|
111
101
|
const path = match.substring(envVarNamePrefix.length);
|
|
@@ -123,14 +113,12 @@ function getOptionValuesFromEnvVars(
|
|
|
123
113
|
let index: number;
|
|
124
114
|
try {
|
|
125
115
|
index = parseInt(indexString);
|
|
126
|
-
} catch
|
|
116
|
+
} catch {
|
|
127
117
|
throw new Error(`Unable to parse array index from env var: ${match}`);
|
|
128
118
|
}
|
|
129
119
|
if (index !== undefined) {
|
|
130
120
|
if (index > MAXIMUM_ARGUMENT_ARRAY_SIZE) {
|
|
131
|
-
throw new Error(
|
|
132
|
-
`Maximum array size exceeded: ${index} in env var: ${match}`,
|
|
133
|
-
);
|
|
121
|
+
throw new Error(`Maximum array size exceeded: ${index} in env var: ${match}`);
|
|
134
122
|
}
|
|
135
123
|
if (envVarValues[option.name] === undefined) {
|
|
136
124
|
envVarValues[option.name] = [];
|
|
@@ -138,21 +126,17 @@ function getOptionValuesFromEnvVars(
|
|
|
138
126
|
if (suffix.length > 0) {
|
|
139
127
|
if (option.type === ComplexValueTypeName.COMPLEX) {
|
|
140
128
|
if (
|
|
141
|
-
(envVarValues[option.name] as Array<
|
|
142
|
-
|
|
143
|
-
>)[index] === undefined
|
|
129
|
+
(envVarValues[option.name] as Array<PopulatedArgumentSingleValueType>)[index] ===
|
|
130
|
+
undefined
|
|
144
131
|
) {
|
|
145
|
-
(envVarValues[option.name] as Array<PopulatedArgumentValues>)[
|
|
146
|
-
|
|
147
|
-
|
|
132
|
+
(envVarValues[option.name] as Array<PopulatedArgumentValues>)[index] = Object.create(
|
|
133
|
+
null,
|
|
134
|
+
) as PopulatedArgumentValues;
|
|
148
135
|
}
|
|
149
136
|
(option as ComplexOption).properties.forEach((property) => {
|
|
150
|
-
const propertySegment = property.configurationKey ||
|
|
151
|
-
getKeySegment(property.name);
|
|
137
|
+
const propertySegment = property.configurationKey || getKeySegment(property.name);
|
|
152
138
|
getOptionValuesFromEnvVars(
|
|
153
|
-
(envVarValues[option.name] as Array<PopulatedArgumentValues>)[
|
|
154
|
-
index
|
|
155
|
-
]!,
|
|
139
|
+
(envVarValues[option.name] as Array<PopulatedArgumentValues>)[index]!,
|
|
156
140
|
matches,
|
|
157
141
|
env,
|
|
158
142
|
property,
|
|
@@ -161,41 +145,30 @@ function getOptionValuesFromEnvVars(
|
|
|
161
145
|
});
|
|
162
146
|
if (
|
|
163
147
|
Object.keys(
|
|
164
|
-
(envVarValues[option.name] as Array<PopulatedArgumentValues>)[
|
|
165
|
-
|
|
166
|
-
|
|
148
|
+
(envVarValues[option.name] as Array<PopulatedArgumentValues>)[index] as Record<
|
|
149
|
+
string,
|
|
150
|
+
string
|
|
151
|
+
>,
|
|
167
152
|
).length === 0
|
|
168
153
|
) {
|
|
169
|
-
delete (envVarValues[option.name] as Array<
|
|
170
|
-
PopulatedArgumentValues
|
|
171
|
-
>)[index];
|
|
154
|
+
delete (envVarValues[option.name] as Array<PopulatedArgumentValues>)[index];
|
|
172
155
|
}
|
|
173
156
|
} else {
|
|
174
|
-
throw new Error(
|
|
175
|
-
`Unidentified suffix ${suffix} in env var: ${match}`,
|
|
176
|
-
);
|
|
157
|
+
throw new Error(`Unidentified suffix ${suffix} in env var: ${match}`);
|
|
177
158
|
}
|
|
178
159
|
} else if (option.type === ComplexValueTypeName.COMPLEX) {
|
|
179
160
|
throw new Error(`Incomplete argument path in env var: ${match}`);
|
|
180
161
|
} else {
|
|
181
162
|
// set primitive value
|
|
182
163
|
let envVarValue = env[match];
|
|
183
|
-
if (
|
|
184
|
-
(envVarValue != undefined) &&
|
|
185
|
-
(option.type === ArgumentValueTypeName.BOOLEAN)
|
|
186
|
-
) {
|
|
164
|
+
if (envVarValue != undefined && option.type === ArgumentValueTypeName.BOOLEAN) {
|
|
187
165
|
envVarValue = envVarValue.length > 1 ? "true" : "false";
|
|
188
166
|
}
|
|
189
|
-
(envVarValues[option.name] as Array<
|
|
190
|
-
|
|
191
|
-
>)[
|
|
192
|
-
index
|
|
193
|
-
] = envVarValue;
|
|
167
|
+
(envVarValues[option.name] as Array<PopulatedArgumentSingleValueType>)[index] =
|
|
168
|
+
envVarValue;
|
|
194
169
|
}
|
|
195
170
|
|
|
196
|
-
const elements = envVarValues[option.name] as Array<
|
|
197
|
-
PopulatedArgumentSingleValueType
|
|
198
|
-
>;
|
|
171
|
+
const elements = envVarValues[option.name] as Array<PopulatedArgumentSingleValueType>;
|
|
199
172
|
for (let i = elements.length - 1; i > -1; i--) {
|
|
200
173
|
if (elements[i] === undefined) {
|
|
201
174
|
elements.length = i;
|
|
@@ -209,10 +182,9 @@ function getOptionValuesFromEnvVars(
|
|
|
209
182
|
} else if (option.type === ComplexValueTypeName.COMPLEX) {
|
|
210
183
|
(option as ComplexOption).properties.forEach((property) => {
|
|
211
184
|
if (envVarValues[option.name] === undefined) {
|
|
212
|
-
envVarValues[option.name] =
|
|
185
|
+
envVarValues[option.name] = Object.create(null) as PopulatedArgumentValues;
|
|
213
186
|
}
|
|
214
|
-
const propertySegment = property.configurationKey ||
|
|
215
|
-
getKeySegment(property.name);
|
|
187
|
+
const propertySegment = property.configurationKey || getKeySegment(property.name);
|
|
216
188
|
getOptionValuesFromEnvVars(
|
|
217
189
|
envVarValues[option.name] as PopulatedArgumentValues,
|
|
218
190
|
potentialEnvVarNames,
|
|
@@ -220,10 +192,7 @@ function getOptionValuesFromEnvVars(
|
|
|
220
192
|
property,
|
|
221
193
|
`${envVarNamePrefix}_${propertySegment}`,
|
|
222
194
|
);
|
|
223
|
-
if (
|
|
224
|
-
Object.keys(envVarValues[option.name] as Record<string, string>)
|
|
225
|
-
.length === 0
|
|
226
|
-
) {
|
|
195
|
+
if (Object.keys(envVarValues[option.name] as Record<string, string>).length === 0) {
|
|
227
196
|
delete envVarValues[option.name];
|
|
228
197
|
}
|
|
229
198
|
});
|
|
@@ -252,15 +221,11 @@ export function getSubCommandValuesFromEnvVars(
|
|
|
252
221
|
cliConfig: CLIConfig,
|
|
253
222
|
command: SubCommand,
|
|
254
223
|
): PopulatedArgumentValues | undefined {
|
|
255
|
-
const envVarValues
|
|
224
|
+
const envVarValues = Object.create(null) as PopulatedArgumentValues;
|
|
256
225
|
if (command.options) {
|
|
257
226
|
for (const option of command.options) {
|
|
258
227
|
const potentialEnvVarNames = Object.keys(process.env);
|
|
259
|
-
const optionPrefix = getSubCommandArgumentKeyPrefix(
|
|
260
|
-
cliConfig,
|
|
261
|
-
command,
|
|
262
|
-
option as Option,
|
|
263
|
-
);
|
|
228
|
+
const optionPrefix = getSubCommandArgumentKeyPrefix(cliConfig, command, option as Option);
|
|
264
229
|
getOptionValuesFromEnvVars(
|
|
265
230
|
envVarValues,
|
|
266
231
|
potentialEnvVarNames,
|
|
@@ -272,47 +237,44 @@ export function getSubCommandValuesFromEnvVars(
|
|
|
272
237
|
}
|
|
273
238
|
if (command.positionals) {
|
|
274
239
|
for (const positional of command.positionals) {
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
positional
|
|
279
|
-
)
|
|
240
|
+
if (
|
|
241
|
+
positional.name === "__proto__" ||
|
|
242
|
+
positional.name === "constructor" ||
|
|
243
|
+
positional.name === "prototype"
|
|
244
|
+
) {
|
|
245
|
+
throw new Error(
|
|
246
|
+
`Unsafe key name in use: ${positional.name}, CodeQL Rule ID: js/prototype-polluting-assignment`,
|
|
247
|
+
);
|
|
248
|
+
}
|
|
249
|
+
let envVarNamePrefix = getSubCommandArgumentKeyPrefix(cliConfig, command, positional);
|
|
280
250
|
|
|
281
251
|
if (positional.isVarargMultiple) {
|
|
282
252
|
envVarNamePrefix = `${envVarNamePrefix}_`;
|
|
283
253
|
|
|
284
254
|
const matches = Object.keys(process.env).filter((envVarName) =>
|
|
285
|
-
envVarName.startsWith(envVarNamePrefix)
|
|
255
|
+
envVarName.startsWith(envVarNamePrefix),
|
|
286
256
|
);
|
|
287
257
|
matches.forEach((match) => {
|
|
288
258
|
let index;
|
|
289
259
|
try {
|
|
290
260
|
index = parseInt(match.substring(envVarNamePrefix.length));
|
|
291
|
-
} catch
|
|
292
|
-
throw new Error(
|
|
293
|
-
`Unable to parse array index from env var: ${match}`,
|
|
294
|
-
);
|
|
261
|
+
} catch {
|
|
262
|
+
throw new Error(`Unable to parse array index from env var: ${match}`);
|
|
295
263
|
}
|
|
296
264
|
if (index !== undefined) {
|
|
297
265
|
if (index > MAXIMUM_ARGUMENT_ARRAY_SIZE) {
|
|
298
|
-
throw new Error(
|
|
299
|
-
`Maximum array size exceeded: ${index} in env var: ${match}`,
|
|
300
|
-
);
|
|
266
|
+
throw new Error(`Maximum array size exceeded: ${index} in env var: ${match}`);
|
|
301
267
|
}
|
|
302
268
|
if (envVarValues[positional.name] === undefined) {
|
|
303
269
|
envVarValues[positional.name] = [];
|
|
304
270
|
}
|
|
305
271
|
// set primitive value
|
|
306
272
|
let envVarValue = process.env[match];
|
|
307
|
-
if (
|
|
308
|
-
(envVarValue != undefined) &&
|
|
309
|
-
(positional.type === ArgumentValueTypeName.BOOLEAN)
|
|
310
|
-
) {
|
|
273
|
+
if (envVarValue != undefined && positional.type === ArgumentValueTypeName.BOOLEAN) {
|
|
311
274
|
envVarValue = envVarValue.length > 1 ? "true" : "false";
|
|
312
275
|
}
|
|
313
|
-
(envVarValues[positional.name] as Array<
|
|
314
|
-
|
|
315
|
-
>)[index] = envVarValue;
|
|
276
|
+
(envVarValues[positional.name] as Array<PopulatedArgumentSingleValueType>)[index] =
|
|
277
|
+
envVarValue;
|
|
316
278
|
}
|
|
317
279
|
});
|
|
318
280
|
} else {
|