json-sort-cli 1.19.0 → 2.0.3

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.
Files changed (4) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/README.md +2 -0
  3. package/cli.js +60 -182
  4. package/package.json +30 -23
package/CHANGELOG.md CHANGED
@@ -3,6 +3,42 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## 2.0.3 (2021-11-02)
7
+
8
+ ### Bug Fixes
9
+
10
+ - bump TS and separate ESLint plugins away from this monorepo ([b1ebce1](https://github.com/codsen/codsen/commit/b1ebce1637d8c41c2d848fc24b0ba4058865bd5d))
11
+
12
+ ### Features
13
+
14
+ - migrate to ES Modules ([c579dff](https://github.com/codsen/codsen/commit/c579dff3b23205e383035ca10ddcec671e35d0fe))
15
+
16
+ ### BREAKING CHANGES
17
+
18
+ - programs now are in ES Modules and won't work with Common JS require()
19
+
20
+ ## 2.0.1 (2021-09-13)
21
+
22
+ ### Bug Fixes
23
+
24
+ - bump TS and separate ESLint plugins away from this monorepo ([2e07d42](https://github.com/codsen/codsen/commit/2e07d424222b6ffedf5fb45c83ad453627ec2904))
25
+
26
+ ## 2.0.0 (2021-09-09)
27
+
28
+ ### Features
29
+
30
+ - correct the default "n" flag value, also reach 100% coverage ([6e323cb](https://github.com/codsen/codsen/commit/6e323cbcb67888dcc83bf1ace77c976c44173796))
31
+ - migrate to ES Modules ([8c9d95d](https://github.com/codsen/codsen/commit/8c9d95d5dea0b769c2f070397141918a4893d575))
32
+
33
+ ### BREAKING CHANGES
34
+
35
+ - programs now are in ES Modules and won't work with Common JS require()
36
+
37
+ ## 1.20.0
38
+
39
+ - added more unit tests
40
+ - "help" and "version" flags, if present, override anything else; "version" takes priority of "help" if both are present
41
+
6
42
  ## 1.19.0 (2021-05-24)
7
43
 
8
44
  ### Features
package/README.md CHANGED
@@ -26,6 +26,8 @@
26
26
 
27
27
  ## Install
28
28
 
29
+ This package is ESM only: Node 12+ is needed to use it and it must be imported instead of required:
30
+
29
31
  ```bash
30
32
  npm i -g json-sort-cli
31
33
  ```
package/cli.js CHANGED
@@ -3,24 +3,25 @@
3
3
  // VARS
4
4
  // -----------------------------------------------------------------------------
5
5
 
6
- const fs = require("fs-extra");
7
- const chalk = require("chalk");
8
- const globby = require("globby");
9
- const meow = require("meow");
10
- const path = require("path");
11
- const updateNotifier = require("update-notifier");
12
- const isDirectory = require("is-d");
13
- const pReduce = require("p-reduce");
14
- const pFilter = require("p-filter");
15
- const sortObject = require("sorted-object");
16
- const { traverse } = require("ast-monkey-traverse");
17
- const isObj = require("lodash.isplainobject");
18
- const sortPackageJson = require("sort-package-json");
6
+ import fs from "fs-extra";
7
+ import chalk from "chalk";
8
+ import { globby } from "globby";
9
+ import meow from "meow";
10
+ import path from "path";
11
+ // import updateNotifier from "update-notifier";
12
+ import isDirectory from "is-d";
13
+ import pReduce from "p-reduce";
14
+ import pFilter from "p-filter";
15
+ import sortObject from "sorted-object";
16
+ import { traverse } from "ast-monkey-traverse";
17
+ import isObj from "lodash.isplainobject";
18
+ import sortPackageJson from "sort-package-json";
19
19
 
20
20
  function isStr(something) {
21
21
  return typeof something === "string";
22
22
  }
23
23
  function format(obj) {
24
+ /* istanbul ignore next */
24
25
  if (typeof obj !== "object") {
25
26
  return obj;
26
27
  }
@@ -54,7 +55,7 @@ const cli = meow(
54
55
  or, just type "jsonsort" and it will let you pick a file.
55
56
 
56
57
  Options
57
- -n, --nodemodules Don't ignore any node_modules folders and package-lock.json's
58
+ -n, --nodemodules Don't ignore any node_modules folders
58
59
  -t, --tabs Use tabs for JSON file indentation
59
60
  -i, --indentationCount How many spaces or tabs to use (default = 2 spaces or 1 tab)
60
61
  -s, --silent Does not show the result per-file, only totals in the end
@@ -70,11 +71,12 @@ const cli = meow(
70
71
  will parse globs. If you put as system globs without quotes, your shell will expand them.
71
72
  `,
72
73
  {
74
+ importMeta: import.meta,
73
75
  flags: {
74
76
  nodemodules: {
75
77
  type: "boolean",
76
78
  alias: "n",
77
- default: true,
79
+ default: false,
78
80
  },
79
81
  tabs: {
80
82
  type: "boolean",
@@ -123,7 +125,7 @@ const cli = meow(
123
125
  },
124
126
  }
125
127
  );
126
- updateNotifier({ pkg: cli.pkg }).notify();
128
+ // updateNotifier({ pkg: cli.pkg }).notify();
127
129
 
128
130
  const nonJsonFormats = ["yml", "toml", "yaml"]; // to save time
129
131
  const badFiles = [
@@ -137,16 +139,6 @@ const badFiles = [
137
139
  "npm-shrinkwrap.json",
138
140
  ];
139
141
 
140
- // console.log(
141
- // `120 ${`\u001b[${33}m${`cli.flags`}\u001b[${39}m`} = ${JSON.stringify(
142
- // cli.flags,
143
- // null,
144
- // 4
145
- // )}`
146
- // );
147
-
148
- // settle indentations type and count
149
-
150
142
  // 1. set defaults:
151
143
  let indentationCount = 2;
152
144
  if (cli.flags.tabs) {
@@ -154,38 +146,17 @@ if (cli.flags.tabs) {
154
146
  }
155
147
  // 2. overwrite defaults with explicitly set value:
156
148
  if (cli.flags.indentationCount) {
157
- indentationCount = Number.parseInt(cli.flags.indentationCount, 10);
149
+ indentationCount = +cli.flags.indentationCount;
158
150
  }
159
151
 
160
152
  // FUNCTIONS
161
153
  // -----------------------------------------------------------------------------
162
154
 
163
- function stripWhitespace(str) {
164
- return str.split("").reduce((acc, curr) => {
165
- return `${acc}${curr.trim().length ? curr : ""}`;
166
- }, "");
167
- }
168
-
169
155
  function readSortAndWriteOverFile(oneOfPaths) {
170
- // console.log("\n\n\n\n==========\n\n\n\n");
171
- // console.log(
172
- // `139 PROCESSING: ${`\u001b[${33}m${`oneOfPaths`}\u001b[${39}m`} = ${JSON.stringify(
173
- // oneOfPaths,
174
- // null,
175
- // 4
176
- // )}`
177
- // );
178
156
  return fs
179
157
  .readFile(oneOfPaths, "utf8")
180
158
  .then((filesContent) => {
181
159
  let parsedJson;
182
- // console.log(
183
- // `150 ${`\u001b[${33}m${`filesContent`}\u001b[${39}m`} = ${JSON.stringify(
184
- // filesContent,
185
- // null,
186
- // 4
187
- // )}`
188
- // );
189
160
  try {
190
161
  // try to parse JSON
191
162
  parsedJson = JSON.parse(filesContent);
@@ -230,7 +201,6 @@ function readSortAndWriteOverFile(oneOfPaths) {
230
201
  // input after processing, then we return an array.
231
202
  // In this function, readSortAndWriteOverFile(), path came in,
232
203
  // we read it, now we return true if result differs after processing
233
- // console.log(`200 returning compared:`);
234
204
 
235
205
  const stringified = JSON.stringify(
236
206
  traverse(obj, (key, val) => {
@@ -252,19 +222,7 @@ function readSortAndWriteOverFile(oneOfPaths) {
252
222
  null,
253
223
  cli.flags.tabs ? "\t".repeat(indentationCount) : indentationCount
254
224
  );
255
- // console.log(
256
- // `222 ${`\u001b[${33}m${`stringified`}\u001b[${39}m`} = ${JSON.stringify(
257
- // stringified,
258
- // null,
259
- // 4
260
- // )};\n${`\u001b[${33}m${`filesContent`}\u001b[${39}m`} = ${JSON.stringify(
261
- // filesContent,
262
- // null,
263
- // 4
264
- // )}`
265
- // );
266
-
267
- return stripWhitespace(stringified) !== stripWhitespace(filesContent);
225
+ return stringified.trimEnd() !== filesContent.trimEnd();
268
226
  }
269
227
  // ELSE,
270
228
  return fs
@@ -305,6 +263,7 @@ function readSortAndWriteOverFile(oneOfPaths) {
305
263
  });
306
264
  })
307
265
  .catch((err) => {
266
+ /* istanbul ignore next */
308
267
  console.log(
309
268
  `${oneOfPaths} - ${`\u001b[${31}m${`BAD`}\u001b[${39}m`} - ${err}`
310
269
  );
@@ -314,10 +273,10 @@ function readSortAndWriteOverFile(oneOfPaths) {
314
273
  // Step #0. take care of -v and -h flags that are left out in meow.
315
274
  // -----------------------------------------------------------------------------
316
275
 
317
- if (cli.flags.version && !cli.flags.silent) {
276
+ if (cli.flags.version) {
318
277
  log(cli.pkg.version);
319
278
  process.exit(0);
320
- } else if (cli.flags.help && !cli.flags.silent) {
279
+ } else if (cli.flags.help) {
321
280
  log(cli.help);
322
281
  process.exit(0);
323
282
  }
@@ -325,26 +284,15 @@ if (cli.flags.version && !cli.flags.silent) {
325
284
  // Step #1. set up the cli
326
285
  // -----------------------------------------------------------------------------
327
286
 
328
- let { input } = cli;
329
- // if the folder/file name follows the flag (for example "-d "templates1"),
330
- // that name will be put under the flag's key value, not into cli.input.
331
- // That's handy for certain types of CLI apps, but not this one, as in our case
332
- // the flags position does not matter, they don't affect the keywords that follow.
333
- if (cli.flags) {
334
- Object.keys(cli.flags).forEach((flag) => {
335
- if (typeof cli.flags[flag] === "string") {
336
- input = input.concat(cli.flags[flag]);
337
- }
338
- });
339
- }
287
+ const { input } = cli;
340
288
 
341
289
  // Step #2. query the glob and follow the pipeline
342
290
  // -----------------------------------------------------------------------------
343
291
 
344
292
  globby(input, { dot: true })
345
- .then((resolvedPathsArray) => {
293
+ .then((paths) => {
346
294
  // flip out of the pipeline if there are no paths resolved
347
- if (resolvedPathsArray.length === 0 && !cli.flags.silent) {
295
+ if (paths.length === 0 && !cli.flags.silent) {
348
296
  log(
349
297
  `${chalk.grey(prefix)}${chalk.red(
350
298
  "The inputs don't lead to any json files! Exiting."
@@ -352,27 +300,21 @@ globby(input, { dot: true })
352
300
  );
353
301
  process.exit(0);
354
302
  }
355
- // console.log(
356
- // `331 ${`\u001b[${33}m${`resolvedPathsArray`}\u001b[${39}m`} = ${JSON.stringify(
357
- // resolvedPathsArray,
358
- // null,
359
- // 4
360
- // )}`
361
- // );
362
- return resolvedPathsArray;
303
+ return paths;
363
304
  })
364
305
  // glob each directory, reduce'ing all results (in promise shape) until all are resolved
365
- .then((resolvedPathsArray) =>
306
+ .then((paths) =>
366
307
  pReduce(
367
- resolvedPathsArray,
308
+ paths,
368
309
  (concattedTotal, singleDirOrFilePath) =>
369
310
  concattedTotal.concat(
370
311
  isDirectory(singleDirOrFilePath).then((bool) =>
312
+ /* istanbul ignore next */
371
313
  bool
372
314
  ? globby(
373
315
  cli.flags.nodemodules
374
- ? [singleDirOrFilePath, "!node_modules"]
375
- : singleDirOrFilePath,
316
+ ? singleDirOrFilePath
317
+ : [singleDirOrFilePath, "!**/node_modules/**"],
376
318
  {
377
319
  expandDirectories: {
378
320
  files: [".*", "*.json"],
@@ -384,55 +326,29 @@ globby(input, { dot: true })
384
326
  ),
385
327
  []
386
328
  // then reduce again, now actually concatenating them all together
387
- ).then((received) => {
388
- // console.log(
389
- // `364 ${`\u001b[${33}m${`received`}\u001b[${39}m`} = ${JSON.stringify(
390
- // received,
391
- // null,
392
- // 4
393
- // )}`
394
- // );
395
- return pReduce(received, (total, single) => total.concat(single), []);
396
- })
329
+ ).then((received) =>
330
+ pReduce(received, (total, single) => total.concat(single), [])
331
+ )
332
+ )
333
+ .then((paths) =>
334
+ paths.filter(
335
+ (oneOfPaths) =>
336
+ !oneOfPaths.includes("package-lock.json") &&
337
+ !oneOfPaths.includes("yarn.lock")
338
+ )
397
339
  )
398
- .then((res) =>
340
+ .then((paths) =>
399
341
  !cli.flags.nodemodules
400
- ? res.filter(
401
- (oneOfPaths) =>
402
- !oneOfPaths.includes("node_modules") &&
403
- !oneOfPaths.includes("package-lock.json")
404
- )
405
- : res
342
+ ? paths.filter((oneOfPaths) => !oneOfPaths.includes("node_modules"))
343
+ : paths
406
344
  )
407
- .then((res) =>
345
+ .then((paths) =>
408
346
  cli.flags.pack
409
- ? res.filter((oneOfPaths) => !oneOfPaths.includes("package.json"))
410
- : res
347
+ ? paths.filter((oneOfPaths) => !oneOfPaths.includes("package.json"))
348
+ : paths
411
349
  )
412
- .then((paths) => {
413
- // console.log(
414
- // `389 ${`\u001b[${33}m${`paths BEFORE`}\u001b[${39}m`} = ${JSON.stringify(
415
- // paths,
416
- // null,
417
- // 4
418
- // )}`
419
- // );
420
- const tempRez = paths.filter((singlePath) => {
421
- // console.log(`---------\n396 processing: ${singlePath}`);
422
- // console.log(
423
- // `${`\u001b[${33}m${`path.extname(singlePath)`}\u001b[${39}m`} = ${JSON.stringify(
424
- // path.extname(singlePath),
425
- // null,
426
- // 4
427
- // )}`
428
- // );
429
- // console.log(
430
- // `${`\u001b[${33}m${`path.basename(singlePath)`}\u001b[${39}m`} = ${JSON.stringify(
431
- // path.basename(singlePath),
432
- // null,
433
- // 4
434
- // )}`
435
- // );
350
+ .then((paths) =>
351
+ paths.filter((singlePath) => {
436
352
  return (
437
353
  path.extname(singlePath) === ".json" ||
438
354
  (typeof path.basename(singlePath) === "string" &&
@@ -444,45 +360,23 @@ globby(input, { dot: true })
444
360
  path.basename(singlePath).includes(badFile)
445
361
  ))
446
362
  );
447
- });
448
- // console.log(
449
- // `424 ${`\u001b[${33}m${`paths AFTER`}\u001b[${39}m`} = ${JSON.stringify(
450
- // tempRez,
451
- // null,
452
- // 4
453
- // )}`
454
- // );
455
- return tempRez;
456
- })
363
+ })
364
+ )
457
365
  // eslint-disable-next-line consistent-return
458
- .then((received) => {
366
+ .then((paths) => {
459
367
  if (cli.flags.dry && !cli.flags.silent) {
460
368
  log(
461
369
  `${chalk.grey(prefix)}${chalk.yellow(
462
370
  "We'd try to sort the following files:"
463
- )}\n${received.join("\n")}`
371
+ )}\n${paths.join("\n")}`
464
372
  );
465
373
  } else {
466
374
  if (cli.flags.ci) {
467
375
  // CI setting
468
- // console.log(
469
- // `443 ${`\u001b[${33}m${`received`}\u001b[${39}m`} = ${JSON.stringify(
470
- // received,
471
- // null,
472
- // 4
473
- // )}`
474
- // );
475
- return pFilter(received, (currentPath) =>
376
+ return pFilter(paths, (currentPath) =>
476
377
  readSortAndWriteOverFile(currentPath)
477
378
  ).then((received2) => {
478
- // console.log(
479
- // `453 ${`\u001b[${33}m${`received2`}\u001b[${39}m`} = ${JSON.stringify(
480
- // received2,
481
- // null,
482
- // 4
483
- // )}`
484
- // );
485
- // if any files differ, report and exit with non-zero code:
379
+ /* istanbul ignore else */
486
380
  if (received2.length && !cli.flags.silent) {
487
381
  log(
488
382
  `${chalk.grey(prefix)}${chalk.red(
@@ -494,7 +388,7 @@ globby(input, { dot: true })
494
388
  log(
495
389
  `${chalk.grey(prefix)}${chalk.white(
496
390
  "All files were already sorted:"
497
- )}\n${received.join("\n")}`
391
+ )}\n${paths.join("\n")}`
498
392
  );
499
393
  process.exit(0);
500
394
  }
@@ -502,19 +396,9 @@ globby(input, { dot: true })
502
396
  }
503
397
  // not a CI setting
504
398
  return pReduce(
505
- received,
399
+ paths,
506
400
  (counter, currentPath) =>
507
401
  readSortAndWriteOverFile(currentPath)
508
- // .then((received2) => {
509
- // // console.log(
510
- // // `484 ${`\u001b[${33}m${`received`}\u001b[${39}m`} = ${JSON.stringify(
511
- // // received,
512
- // // null,
513
- // // 4
514
- // // )}`
515
- // // );
516
- // return received2;
517
- // })
518
402
  .then((res) =>
519
403
  res
520
404
  ? {
@@ -527,6 +411,7 @@ globby(input, { dot: true })
527
411
  }
528
412
  )
529
413
  .catch((err) => {
414
+ /* istanbul ignore next */
530
415
  if (!cli.flags.silent) {
531
416
  log(
532
417
  `${chalk.grey(prefix)}${chalk.red(
@@ -534,17 +419,9 @@ globby(input, { dot: true })
534
419
  )} ${err}`
535
420
  );
536
421
  }
537
- return counter;
538
422
  }),
539
423
  { good: [], bad: [] }
540
424
  ).then((counter) => {
541
- // console.log(
542
- // `516 ${`\u001b[${33}m${`counter`}\u001b[${39}m`} = ${JSON.stringify(
543
- // counter,
544
- // null,
545
- // 4
546
- // )}`
547
- // );
548
425
  if (!cli.flags.silent) {
549
426
  log(
550
427
  `\n${chalk.grey(prefix)}${chalk.green(
@@ -568,6 +445,7 @@ globby(input, { dot: true })
568
445
  }
569
446
  })
570
447
  .catch((err) => {
448
+ /* istanbul ignore next */
571
449
  if (!cli.flags.silent) {
572
450
  log(`${chalk.grey(prefix)}${chalk.red("Oops!")} ${err}`);
573
451
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "json-sort-cli",
3
- "version": "1.19.0",
3
+ "version": "2.0.3",
4
4
  "description": "Command line app to deep sort JSON files, retains package.json special key order",
5
5
  "keywords": [
6
6
  "app",
@@ -16,16 +16,17 @@
16
16
  ],
17
17
  "homepage": "https://codsen.com/os/json-sort-cli/",
18
18
  "repository": {
19
- "directory": "packages/json-sort-cli",
20
19
  "type": "git",
21
- "url": "https://github.com/codsen/codsen.git"
20
+ "url": "https://github.com/codsen/codsen.git",
21
+ "directory": "packages/json-sort-cli"
22
22
  },
23
23
  "license": "MIT",
24
24
  "author": {
25
- "email": "roy@codsen.com",
26
25
  "name": "Roy Revelt",
26
+ "email": "roy@codsen.com",
27
27
  "url": "https://codsen.com"
28
28
  },
29
+ "type": "module",
29
30
  "bin": {
30
31
  "jsonsort": "cli.js",
31
32
  "sortjson": "cli.js"
@@ -42,16 +43,18 @@
42
43
  "republish": "npm publish || :",
43
44
  "tap": "tap",
44
45
  "test": "npm run lint && npm run unittest && npm run format",
45
- "unittest": "./node_modules/.bin/tap --no-only --output-file=testStats.md --reporter=terse && npm run clean_cov"
46
+ "unittest": "tap --no-only --output-file=testStats.md --reporter=terse && npm run clean_cov"
46
47
  },
47
48
  "tap": {
49
+ "check-coverage": false,
48
50
  "coverage-report": [
49
51
  "json-summary",
50
52
  "text"
51
53
  ],
52
- "nyc-arg": [
53
- "--exclude=**/*.cjs.js",
54
- "--exclude=**/*.umd.js"
54
+ "node-arg": [
55
+ "--no-warnings",
56
+ "--experimental-loader",
57
+ "@istanbuljs/esm-loader-hook"
55
58
  ],
56
59
  "timeout": 0
57
60
  },
@@ -69,29 +72,33 @@
69
72
  }
70
73
  },
71
74
  "dependencies": {
72
- "ast-monkey-traverse": "^2.1.0",
73
- "chalk": "^4.1.1",
75
+ "ast-monkey-traverse": "^3.0.3",
76
+ "chalk": "^4.1.2",
74
77
  "fs-extra": "^10.0.0",
75
- "globby": "^11.0.3",
78
+ "globby": "^12.0.2",
76
79
  "is-d": "^1.0.0",
77
80
  "lodash.isplainobject": "^4.0.6",
78
- "meow": "^9.0.0",
79
- "p-filter": "^2.1.0",
80
- "p-reduce": "^2.1.0",
81
- "sort-package-json": "^1.50.0",
81
+ "meow": "^10.1.1",
82
+ "p-filter": "^3.0.0",
83
+ "p-reduce": "^3.0.0",
84
+ "sort-package-json": "^1.52.0",
82
85
  "sorted-object": "^2.0.1",
83
86
  "update-notifier": "^5.1.0"
84
87
  },
85
88
  "devDependencies": {
89
+ "@istanbuljs/esm-loader-hook": "^0.1.2",
86
90
  "@types/lodash.isplainobject": "^4.0.6",
87
- "core-js": "^3.12.1",
91
+ "core-js": "^3.19.0",
88
92
  "cross-env": "^7.0.3",
89
- "eslint": "^7.27.0",
90
- "execa": "^5.0.0",
91
- "lect": "^0.17.0",
92
- "p-map": "^4.0.0",
93
- "tap": "^14.11.0",
94
- "tempy": "^1.0.1",
95
- "tslib": "^2.2.0"
93
+ "eslint": "^8.1.0",
94
+ "execa": "^5.1.1",
95
+ "lect": "^0.18.3",
96
+ "p-map": "^5.2.0",
97
+ "tap": "^15.0.10",
98
+ "tempy": "^2.0.0",
99
+ "tslib": "^2.3.1"
100
+ },
101
+ "engines": {
102
+ "node": ">=12"
96
103
  }
97
104
  }