Skip to content

Commit ae788e7

Browse files
committed
Rename to argv and apply inflektTree
1 parent a92d452 commit ae788e7

4 files changed

Lines changed: 207 additions & 0 deletions

File tree

packages/inflekt/README.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import {
3939
toFieldName,
4040
toQueryName,
4141
inflektTree,
42+
camelizeArgv,
4243
} from 'inflekt';
4344

4445
// Basic singularization/pluralization
@@ -74,6 +75,11 @@ const apiResponse = {
7475
};
7576
inflektTree(apiResponse, (key) => camelize(key, true));
7677
// Result: { userName: 'John', orderItems: [{ itemId: 1, productName: 'Widget' }] }
78+
79+
// CLI argument transformation (kebab-case to camelCase)
80+
const argv = { 'schema-file': 'test.graphql', 'dry-run': true, _: [] };
81+
camelizeArgv(argv);
82+
// Result: { schemaFile: 'test.graphql', dryRun: true, _: [] }
7783
```
7884

7985
## API
@@ -104,6 +110,10 @@ inflektTree(apiResponse, (key) => camelize(key, true));
104110

105111
- `inflektTree(obj, transformer, options?)` - Recursively transform all property names in an object tree
106112

113+
### CLI Argument Utilities
114+
115+
- `camelizeArgv(argv)` - Transform CLI argument keys (kebab-case/snake_case) to camelCase, preserving minimist internals
116+
107117
## Deep Object Key Transformation
108118

109119
The `inflektTree` function recursively transforms all property names in an object tree using any transformer function. This is useful for converting API responses between naming conventions.
@@ -180,6 +190,40 @@ const result3 = inflektTree(deepObject, (key) => camelize(key, true), {
180190
- Returns primitives unchanged
181191
- Works with any transformer function
182192

193+
## CLI Argument Transformation
194+
195+
The `camelizeArgv` function is a specialized utility for transforming CLI argument objects (typically from minimist or similar parsers) from kebab-case or snake_case to camelCase.
196+
197+
### Usage
198+
199+
```typescript
200+
import { camelizeArgv } from 'inflekt';
201+
202+
// Transform CLI arguments
203+
const argv = {
204+
'schema-file': 'test.graphql',
205+
'dry-run': true,
206+
output_dir: 'dist',
207+
_: ['arg1', 'arg2']
208+
};
209+
210+
const parsedArgv = camelizeArgv(argv);
211+
// Result:
212+
// {
213+
// schemaFile: 'test.graphql',
214+
// dryRun: true,
215+
// outputDir: 'dist',
216+
// _: ['arg1', 'arg2']
217+
// }
218+
```
219+
220+
### Features
221+
222+
- Transforms kebab-case and snake_case keys to camelCase
223+
- Only transforms top-level keys (preserves nested object structure)
224+
- Preserves minimist internal keys (`_` and keys starting with `_`)
225+
- Built on top of `inflektTree` for consistency
226+
183227
## Latin Suffix Overrides
184228

185229
This library handles Latin plural suffixes differently than the standard `inflection` package to match PostGraphile's behavior:
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
import { camelizeArgv } from '../src/argv';
2+
3+
describe('camelizeArgv', () => {
4+
it('should convert kebab-case keys to camelCase', () => {
5+
const argv = {
6+
'schema-file': 'test.graphql',
7+
'dry-run': true,
8+
output: 'dist'
9+
};
10+
11+
const result = camelizeArgv(argv);
12+
13+
expect(result).toEqual({
14+
schemaFile: 'test.graphql',
15+
dryRun: true,
16+
output: 'dist'
17+
});
18+
});
19+
20+
it('should convert snake_case keys to camelCase', () => {
21+
const argv = {
22+
schema_file: 'test.graphql',
23+
dry_run: true,
24+
output_dir: 'dist'
25+
};
26+
27+
const result = camelizeArgv(argv);
28+
29+
expect(result).toEqual({
30+
schemaFile: 'test.graphql',
31+
dryRun: true,
32+
outputDir: 'dist'
33+
});
34+
});
35+
36+
it('should preserve minimist internal _ key', () => {
37+
const argv = {
38+
'schema-file': 'test.graphql',
39+
_: ['arg1', 'arg2']
40+
};
41+
42+
const result = camelizeArgv(argv);
43+
44+
expect(result).toEqual({
45+
schemaFile: 'test.graphql',
46+
_: ['arg1', 'arg2']
47+
});
48+
});
49+
50+
it('should skip keys starting with underscore', () => {
51+
const argv = {
52+
'schema-file': 'test.graphql',
53+
_private: 'secret',
54+
_internal_flag: true
55+
};
56+
57+
const result = camelizeArgv(argv);
58+
59+
expect(result).toEqual({
60+
schemaFile: 'test.graphql',
61+
_private: 'secret',
62+
_internal_flag: true
63+
});
64+
});
65+
66+
it('should only transform top-level keys', () => {
67+
const argv = {
68+
'schema-file': 'test.graphql',
69+
config: {
70+
'nested-key': 'value',
71+
another_nested: 'data'
72+
}
73+
};
74+
75+
const result = camelizeArgv(argv);
76+
77+
expect(result).toEqual({
78+
schemaFile: 'test.graphql',
79+
config: {
80+
'nested-key': 'value',
81+
another_nested: 'data'
82+
}
83+
});
84+
});
85+
86+
it('should handle arrays in values', () => {
87+
const argv = {
88+
'include-files': ['file1.ts', 'file2.ts'],
89+
_: [] as string[]
90+
};
91+
92+
const result = camelizeArgv(argv);
93+
94+
expect(result).toEqual({
95+
includeFiles: ['file1.ts', 'file2.ts'],
96+
_: []
97+
});
98+
});
99+
100+
it('should handle mixed kebab-case and snake_case', () => {
101+
const argv = {
102+
'schema-file': 'test.graphql',
103+
output_dir: 'dist',
104+
'dry-run': true,
105+
verbose_mode: false
106+
};
107+
108+
const result = camelizeArgv(argv);
109+
110+
expect(result).toEqual({
111+
schemaFile: 'test.graphql',
112+
outputDir: 'dist',
113+
dryRun: true,
114+
verboseMode: false
115+
});
116+
});
117+
118+
it('should preserve already camelCase keys', () => {
119+
const argv = {
120+
schemaFile: 'test.graphql',
121+
dryRun: true,
122+
_: [] as string[]
123+
};
124+
125+
const result = camelizeArgv(argv);
126+
127+
expect(result).toEqual({
128+
schemaFile: 'test.graphql',
129+
dryRun: true,
130+
_: []
131+
});
132+
});
133+
});

packages/inflekt/src/argv.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/**
2+
* Object key transformation utilities for CLI arguments and other use cases
3+
*/
4+
5+
import { camelize } from 'inflection';
6+
import { inflektTree } from './transform-keys';
7+
8+
const isTopLevel = (_key: string, path: string[]) => path.length === 0;
9+
10+
/**
11+
* Camelize argv keys (typically from minimist or similar CLI parsers)
12+
* Transforms kebab-case and snake_case keys to camelCase at the top level only.
13+
* Skips minimist internal keys like '_' and keys starting with '_'.
14+
*
15+
* @param argv - Parsed CLI arguments object
16+
* @returns New object with camelCase keys
17+
*
18+
* @example
19+
* const argv = { 'schema-file': 'test.graphql', 'dry-run': true, _: [] };
20+
* const parsedArgv = camelizeArgv(argv);
21+
* // Result: { schemaFile: 'test.graphql', dryRun: true, _: [] }
22+
*/
23+
export const camelizeArgv = (argv: Record<string, any>) =>
24+
inflektTree(argv, (key) => camelize(key, true), {
25+
skip: (key, path) =>
26+
!isTopLevel(key, path) ||
27+
key === '_' ||
28+
key.startsWith('_')
29+
});

packages/inflekt/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@ export * from './pluralize';
99
export * from './case';
1010
export * from './naming';
1111
export * from './transform-keys';
12+
export * from './argv';

0 commit comments

Comments
 (0)