Skip to content

Commit

Permalink
Merge pull request #369 from sparksuite/dont-convert-to-camel-case
Browse files Browse the repository at this point in the history
Stop folding options and flags to camel case
  • Loading branch information
WesCossick authored Jun 25, 2021
2 parents 536d764 + 3387521 commit 7647554
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 15 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "waterfall-cli",
"version": "1.0.0-alpha.5",
"version": "1.0.0-alpha.6",
"description": "Effortlessly create CLIs powered by Node.js",
"types": "dist/cjs/index.d.ts",
"files": [
Expand Down
30 changes: 28 additions & 2 deletions src/utils/construct-input-object.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ describe('#constructInputObject()', () => {
command: 'list',
data: 'toppings',
options: {
deliveryZipCode: '55555',
'delivery-zip-code': '55555',
limit: undefined,
maxPrice: undefined,
'max-price': undefined,
sort: 'popularity',
},
flags: {
Expand All @@ -37,6 +37,32 @@ describe('#constructInputObject()', () => {
});
});

it('Handles passthrough inputs too', async () => {
process.argv = [
'/path/to/node',
path.join(testProjectsPath, 'pizza-ordering', 'cli', 'entry.js'),
'order',
'to-go',
'--',
'--pass-through-flag',
'pass-through-option=value',
'pass-through-data',
];

expect(await constructInputObject()).toStrictEqual({
command: 'order to-go',
data: undefined,
options: {
'delivery-zip-code': undefined,
test: undefined,
},
flags: {
quiet: false,
},
passThroughArgs: ['--pass-through-flag', 'pass-through-option=value', 'pass-through-data'],
});
});

it('Complains about missing required option', async () => {
process.argv = [
'/path/to/node',
Expand Down
16 changes: 4 additions & 12 deletions src/utils/construct-input-object.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ export type InputObject<Input extends CommandInput> = OmitExcludeMeProperties<{
/** The final command being run. */
command: string;

/** For each available flag (converted to camel case), a boolean value indicating whether it was provided. */
/** For each available flag, a boolean value indicating whether it was provided. */
flags: undefined extends Input['flags']
? ExcludeMe
: {
[Flag in keyof Input['flags']]: boolean;
};

/** For each available option (converted to camel case), the value that was provided (or `undefined` if not provided). */
/** For each available option, the value that was provided (or `undefined` if not provided). */
options: undefined extends Input['options']
? ExcludeMe
: {
Expand Down Expand Up @@ -65,35 +65,27 @@ export default async function constructInputObject(): Promise<ConstructedInputOb
inputObject.options = {};
}

// Convert a string from aaa-aaa-aaa to aaaAaaAaa
const convertDashesToCamelCase = (string: string): string => {
return string.replace(/-(.)/g, (g) => g[1].toUpperCase());
};

// Loop over each component and store
Object.entries(mergedSpec.flags ?? {}).forEach(([flag]) => {
if (['help', 'version'].includes(flag)) {
return;
}

const camelCaseKey = convertDashesToCamelCase(flag);

if (!inputObject.flags) {
inputObject.flags = {};
}

inputObject.flags[camelCaseKey] = organizedArguments.flags.includes(flag);
inputObject.flags[flag] = organizedArguments.flags.includes(flag);
});

Object.entries(mergedSpec.options ?? {}).forEach(([option, details]) => {
const camelCaseKey = convertDashesToCamelCase(option);
const optionIndex = organizedArguments.options.indexOf(option);

if (!inputObject.options) {
inputObject.options = {};
}

inputObject.options[camelCaseKey] = organizedArguments.values[optionIndex];
inputObject.options[option] = organizedArguments.values[optionIndex];

if (details.required && !organizedArguments.options.includes(option)) {
throw new PrintableError(`The --${option} option is required`);
Expand Down

0 comments on commit 7647554

Please sign in to comment.