Skip to content

Commit a030058

Browse files
authored
feat(tools): add json-sort CLI tool for sorting JSON arrays (#286)
### TL;DR Added a new `json-sort` CLI tool to sort JSON arrays by specified properties. ### What changed? - Created a new `json-sort` CLI tool that sorts JSON arrays based on a specified property - Added the tool to the main CLI interface in `index.ts` - Updated the README to include the new tool - Added snapshot tests to verify the functionality: - Sorting an array of objects by the `name` property - Sorting an array of objects by the `age` property ### How to test? Run the tool with a JSON file containing an array and specify the property to sort by: ```bash tool json-sort array.json '_.name' ``` Or check the snapshot tests: ```bash tool snap-test json-sort ``` ### Why make this change? This tool provides a convenient way to sort JSON arrays by specific properties, which is useful for organizing data in configuration files, test fixtures, or any JSON array that needs to be sorted in a specific order. It complements the existing `json-edit` tool by providing another way to manipulate JSON files.
1 parent 4bb4def commit a030058

6 files changed

Lines changed: 131 additions & 1 deletion

File tree

packages/tools/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# tools for internal development use
22

33
- json-edit: A CLI tool to edit JSON files such as package.json in e2e tests
4+
- json-sort: A CLI tool to sort JSON keys in a file
45
- snap-test: run snapshot tests for CLI
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
[
2+
{
3+
"name": "test",
4+
"age": 18
5+
},
6+
{
7+
"name": "abc",
8+
"age": 20
9+
},
10+
{
11+
"name": "def",
12+
"age": 15
13+
},
14+
{
15+
"name": "ghi",
16+
"age": 18
17+
}
18+
]
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
> cat array.json # should show original array.json file
2+
[
3+
{
4+
"name": "test",
5+
"age": 18
6+
},
7+
{
8+
"name": "abc",
9+
"age": 20
10+
},
11+
{
12+
"name": "def",
13+
"age": 15
14+
},
15+
{
16+
"name": "ghi",
17+
"age": 18
18+
}
19+
]
20+
21+
> tool json-sort array.json '_.name' && cat array.json # should sort array.json file by name
22+
[
23+
{
24+
"name": "abc",
25+
"age": 20
26+
},
27+
{
28+
"name": "def",
29+
"age": 15
30+
},
31+
{
32+
"name": "ghi",
33+
"age": 18
34+
},
35+
{
36+
"name": "test",
37+
"age": 18
38+
}
39+
]
40+
41+
> tool json-sort array.json '_.age' && cat array.json # should sort array.json file by age
42+
[
43+
{
44+
"name": "def",
45+
"age": 15
46+
},
47+
{
48+
"name": "ghi",
49+
"age": 18
50+
},
51+
{
52+
"name": "test",
53+
"age": 18
54+
},
55+
{
56+
"name": "abc",
57+
"age": 20
58+
}
59+
]
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"env": {
3+
},
4+
"commands": [
5+
"cat array.json # should show original array.json file",
6+
"tool json-sort array.json '_.name' && cat array.json # should sort array.json file by name",
7+
"tool json-sort array.json '_.age' && cat array.json # should sort array.json file by age"
8+
]
9+
}

packages/tools/src/index.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,12 @@ switch (subcommand) {
1313
const { syncRemote } = await import('./sync-remote-deps');
1414
syncRemote();
1515
break;
16+
case 'json-sort':
17+
const { jsonSort } = await import('./json-sort');
18+
jsonSort();
19+
break;
1620
default:
1721
console.error(`Unknown subcommand: ${subcommand}`);
18-
console.error('Available subcommands: snap-test, replace-file-content, sync-remote');
22+
console.error('Available subcommands: snap-test, replace-file-content, sync-remote, json-sort');
1923
process.exit(1);
2024
}

packages/tools/src/json-sort.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#!/usr/bin/env node
2+
3+
import assert from 'node:assert';
4+
import { readFileSync, writeFileSync } from 'node:fs';
5+
import { parseArgs } from 'node:util';
6+
7+
export function jsonSort() {
8+
const { positionals } = parseArgs({
9+
allowPositionals: true,
10+
args: process.argv.slice(3),
11+
});
12+
13+
const filename = positionals[0];
14+
const script = positionals[1];
15+
16+
if (!filename || !script) {
17+
console.error('Usage: tool json-sort <filename> <script>');
18+
console.error("Example: tool json-sort array.json '_.name'");
19+
process.exit(1);
20+
}
21+
22+
const data = JSON.parse(readFileSync(filename, 'utf-8'));
23+
assert(Array.isArray(data), 'json data must be an array');
24+
// sort json by script
25+
const func = new Function('_', `return ${script};`);
26+
const sortedJson = data.sort((a: any, b: any) => {
27+
const aValue = func(a);
28+
const bValue = func(b);
29+
if (aValue < bValue) {
30+
return -1;
31+
}
32+
if (aValue > bValue) {
33+
return 1;
34+
}
35+
return 0;
36+
});
37+
38+
writeFileSync(filename, JSON.stringify(sortedJson, null, 2) + '\n', 'utf-8');
39+
}

0 commit comments

Comments
 (0)