json-sort-cli 4.1.0 → 4.2.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/CHANGELOG.md CHANGED
@@ -3,11 +3,21 @@
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
- ## 4.1.0 (2025-10-15)
6
+ ## 4.2.0 (2026-08-19)
7
+
8
+ ### Bug Fixes
9
+
10
+ - retire direct publish aliases ([f98e31e](https://github.com/codsen/codsen/commit/f98e31eb89bc185471225664e610b55f34fbf648))
7
11
 
8
12
  ### Features
9
13
 
10
- - if value to be added is a number, keep it as is, don't stringify ([ce3e1a5](https://github.com/codsen/codsen/commit/ce3e1a525998ca3c0abf0142affef95b14cd1990))
14
+ - add codsen-glob and migrate glob consumers ([5595a2b](https://github.com/codsen/codsen/commit/5595a2b267eaa6cb60072d037aef00b7a28edd42))
15
+ - refresh the tooling and generate with the latest dependencies ([781f802](https://github.com/codsen/codsen/commit/781f802911066a82a4533b0e5a3fcbd742d0dd83))
16
+
17
+ ### Reverts
18
+
19
+ - Revert "Merge pull request #128 from codsen/release/npm-32198404552-1" ([5baeeaa](https://github.com/codsen/codsen/commit/5baeeaaa677b86f1eaa6396cadf3aea32b06416e)), closes [#128](https://github.com/codsen/codsen/issues/128)
20
+ - Revert "Merge pull request #127 from codsen/release/npm-32194020886-1" ([5f1e94d](https://github.com/codsen/codsen/commit/5f1e94deef910ce735266b16aeee08a76de7a862)), closes [#127](https://github.com/codsen/codsen/issues/127)
11
21
 
12
22
  ## 4.0.0 (2024-01-05)
13
23
 
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright © 2010-2025 Roy Revelt and other contributors
3
+ Copyright © 2010-2026 Roy Revelt and other contributors
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining
6
6
  a copy of this software and associated documentation files (the
package/README.md CHANGED
@@ -46,6 +46,6 @@ To report bugs or request features or assistance, [raise an issue](https://githu
46
46
 
47
47
  MIT License
48
48
 
49
- Copyright © 2010-2025 Roy Revelt and other contributors
49
+ Copyright © 2010-2026 Roy Revelt and other contributors
50
50
 
51
51
  <p align="center"><img src="https://codsen.com/images/png-codsen-ok.png" width="98" alt="ok" align="center"> <img src="https://codsen.com/images/png-codsen-1.png" width="148" alt="codsen" align="center"> <img src="https://codsen.com/images/png-codsen-star-small.png" width="32" alt="star" align="center"></p>
package/cli.js CHANGED
@@ -3,59 +3,31 @@
3
3
  // VARS
4
4
  // -----------------------------------------------------------------------------
5
5
 
6
- import meow from "meow";
7
- import path from "path";
8
- import fs from "fs-extra";
9
- import chalk from "chalk";
10
- import isDirectory from "is-d";
11
- import pReduce from "p-reduce";
12
- import pFilter from "p-filter";
13
- import { globby } from "globby";
14
- import { createRequire } from "module";
15
- import { isPlainObject, resolveEolSetting } from "codsen-utils";
6
+ import { createRequire } from "node:module";
7
+ import path from "node:path";
8
+ import { glob } from "codsen-glob";
9
+ import { codsenCLI } from "codsen-utils";
16
10
  import updateNotifier from "update-notifier";
17
- import { traverse } from "ast-monkey-traverse";
18
- import sortPackageJson, { sortOrder } from "sort-package-json";
11
+ import { ProcessingError, processFiles } from "./process-files.js";
19
12
 
20
13
  const require1 = createRequire(import.meta.url);
21
14
  const pkg = require1("./package.json");
22
15
 
23
- function isStr(something) {
24
- return typeof something === "string";
25
- }
26
- function format(obj) {
27
- if (typeof obj !== "object") {
28
- return obj;
29
- }
30
- let newSortOrder = sortOrder
31
- // 1. delete tap and lect fields
32
- .filter((field) => !["lect", "tap"].includes(field));
33
-
34
- // 2. then, insert both after resolutions, first tap then lect
35
- let idxOfResolutions = newSortOrder.indexOf("resolutions");
36
- // console.log(idxOfResolutions);
37
- // => 63
38
-
39
- newSortOrder.splice(idxOfResolutions, 0, "tap", "lect");
16
+ const colours = {
17
+ green: 32,
18
+ grey: 90,
19
+ red: 31,
20
+ white: 37,
21
+ yellow: 33,
22
+ };
40
23
 
41
- // use custom array for sorting order:
42
- return sortPackageJson(obj, {
43
- sortOrder: newSortOrder,
44
- });
45
- }
46
- function sortObj(obj) {
47
- let res = {};
48
- Object.keys(obj)
49
- .sort()
50
- .forEach((key) => {
51
- res[key] = obj[key];
52
- });
53
- return res;
24
+ function colour(str, colourCode) {
25
+ return `\u001b[${colourCode}m${str}\u001b[39m`;
54
26
  }
55
27
 
56
28
  const prefix = "✨ json-sort-cli: ";
57
29
  const { log } = console;
58
- const cli = meow(
30
+ const cli = codsenCLI(
59
31
  `
60
32
  Usage
61
33
  $ jsonsort YOURFILE.json
@@ -82,7 +54,7 @@ const cli = meow(
82
54
  will parse globs. If you put as system globs without quotes, your shell will expand them.
83
55
  `,
84
56
  {
85
- importMeta: import.meta,
57
+ pkg,
86
58
  flags: {
87
59
  nodemodules: {
88
60
  type: "boolean",
@@ -164,152 +136,8 @@ if (cli.flags.indentationCount) {
164
136
  indentationCount = +cli.flags.indentationCount;
165
137
  }
166
138
 
167
- // FUNCTIONS
168
- // -----------------------------------------------------------------------------
169
-
170
- function readSortAndWriteOverFile(oneOfPaths) {
171
- return fs
172
- .readFile(oneOfPaths, "utf8")
173
- .then((filesContent) => {
174
- let eolChar = resolveEolSetting(filesContent, cli.flags.lineEnding);
175
-
176
- let parsedJson;
177
- try {
178
- // try to parse JSON
179
- parsedJson = JSON.parse(filesContent);
180
- } catch (err) {
181
- // if it is not parseable, stop
182
- if (!cli.flags.silent) {
183
- log(`${chalk.grey(prefix)}${oneOfPaths} - ${chalk.red(err)}`);
184
- }
185
- return Promise.resolve(null);
186
- }
187
- let result;
188
-
189
- if (isPlainObject(parsedJson)) {
190
- result = sortObj(parsedJson);
191
- } else if (
192
- cli.flags.arrays &&
193
- Array.isArray(parsedJson) &&
194
- parsedJson.length &&
195
- parsedJson.every(isStr)
196
- ) {
197
- // if it was an array full of strings, it's an early ending:
198
- return fs.writeJson(
199
- oneOfPaths,
200
- parsedJson.sort((a, b) => a.localeCompare(b)),
201
- {
202
- spaces: cli.flags.tabs
203
- ? "\t".repeat(indentationCount)
204
- : indentationCount,
205
- EOL: eolChar,
206
- },
207
- );
208
- } else {
209
- result = parsedJson;
210
- }
211
-
212
- return Promise.resolve(
213
- !cli.flags.pack && path.basename(oneOfPaths) === "package.json"
214
- ? format(result)
215
- : result,
216
- ).then((obj) => {
217
- if (cli.flags.ci) {
218
- // if it's CI mode, we only gather a list of files that differ from
219
- // input after processing, then we return an array.
220
- // In this function, readSortAndWriteOverFile(), path came in,
221
- // we read it, now we return true if result differs after processing
222
-
223
- let stringified = JSON.stringify(
224
- // The traversal below will mutate, not just traverse, -
225
- // whatever you return from the callback below, gets written
226
- traverse(obj, (key, val) => {
227
- let current = val !== undefined ? val : key;
228
- if (isPlainObject(current)) {
229
- return sortObj(current);
230
- }
231
- if (
232
- cli.flags.arrays &&
233
- Array.isArray(current) &&
234
- current.length > 1 &&
235
- current.every(isStr)
236
- ) {
237
- // alphabetical sort, this value gets written
238
- return current.sort((a, b) => a.localeCompare(b));
239
- }
240
- return current;
241
- }),
242
- null,
243
- cli.flags.tabs ? "\t".repeat(indentationCount) : indentationCount,
244
- );
245
-
246
- if (eolChar === "\r\n") {
247
- // CRLF
248
- stringified = stringified
249
- .replaceAll(/(?<!\r)\n/g, "\r\n")
250
- .replaceAll(/\r(?!\n)/g, "\n");
251
- } else {
252
- // LF or CR
253
- stringified = stringified.replaceAll(/(?:\r?\n)|\r/g, eolChar);
254
- }
255
-
256
- return (
257
- stringified
258
- .replaceAll(
259
- /\r\n/g,
260
- resolveEolSetting(filesContent, cli.flags.lineEnding),
261
- )
262
- .trimEnd() !== filesContent.trimEnd()
263
- );
264
- }
265
-
266
- // ELSE,
267
- return fs
268
- .writeJson(
269
- oneOfPaths,
270
- traverse(obj, (key, val) => {
271
- let current = val !== undefined ? val : key;
272
- if (isPlainObject(current)) {
273
- return sortObj(current);
274
- }
275
- if (
276
- cli.flags.arrays &&
277
- Array.isArray(current) &&
278
- current.length > 1 &&
279
- current.every(isStr)
280
- ) {
281
- // alphabetical sort
282
- return current.sort((a, b) => a.localeCompare(b));
283
- }
284
- return current;
285
- }),
286
- {
287
- spaces: cli.flags.tabs
288
- ? "\t".repeat(indentationCount)
289
- : indentationCount,
290
- EOL: resolveEolSetting(filesContent, cli.flags.lineEnding),
291
- },
292
- )
293
- .then(() => {
294
- if (!cli.flags.silent) {
295
- log(
296
- `${chalk.grey(
297
- prefix,
298
- )}${oneOfPaths} - ${`\u001b[${32}m${"OK"}\u001b[${39}m`}`,
299
- );
300
- }
301
- return true;
302
- });
303
- });
304
- })
305
- .catch((err) => {
306
- console.log(
307
- `${oneOfPaths} - ${`\u001b[${31}m${"BAD"}\u001b[${39}m`} - ${err}`,
308
- );
309
- });
310
- }
311
-
312
- // Step #0. take care of -v and -h flags that are left out in meow.
139
+ // Step #0. take care of the short -v and -h flags, which codsenCLI leaves
140
+ // to us (it answers the long --version and --help on its own).
313
141
  // -----------------------------------------------------------------------------
314
142
 
315
143
  if (cli.flags.version) {
@@ -331,46 +159,32 @@ if (Array.isArray(input) && !input.length) {
331
159
  // Step #2. query the glob and follow the pipeline
332
160
  // -----------------------------------------------------------------------------
333
161
 
334
- globby(input, { dot: true })
162
+ glob(
163
+ [
164
+ ...input,
165
+ "!**/package-lock.json",
166
+ "!**/yarn.lock",
167
+ ...(cli.flags.nodemodules ? [] : ["!**/node_modules/**"]),
168
+ ...(cli.flags.pack ? ["!**/package.json"] : []),
169
+ ],
170
+ {
171
+ dot: true,
172
+ expandDirectories: { files: [".*", "*.json"] },
173
+ },
174
+ )
335
175
  .then((paths) => {
336
176
  // flip out of the pipeline if there are no paths resolved
337
177
  if (paths.length === 0 && !cli.flags.silent) {
338
178
  log(
339
- `${chalk.grey(prefix)}${chalk.red(
179
+ `${colour(prefix, colours.grey)}${colour(
340
180
  "The inputs don't lead to any json files! Exiting.",
181
+ colours.red,
341
182
  )}`,
342
183
  );
343
184
  process.exit(0);
344
185
  }
345
186
  return paths;
346
187
  })
347
- // glob each directory, reduce'ing all results (in promise shape) until all are resolved
348
- .then((paths) =>
349
- pReduce(
350
- paths,
351
- (concatTotal, singleDirOrFilePath) =>
352
- concatTotal.concat(
353
- isDirectory(singleDirOrFilePath).then((bool) =>
354
- bool
355
- ? globby(
356
- cli.flags.nodemodules
357
- ? singleDirOrFilePath
358
- : [singleDirOrFilePath, "!**/node_modules/**"],
359
- {
360
- expandDirectories: {
361
- files: [".*", "*.json"],
362
- },
363
- },
364
- )
365
- : [singleDirOrFilePath],
366
- ),
367
- ),
368
- [],
369
- // then reduce again, now actually concatenating them all together
370
- ).then((received) =>
371
- pReduce(received, (total, single) => total.concat(single), []),
372
- ),
373
- )
374
188
  .then((paths) =>
375
189
  paths.filter(
376
190
  (oneOfPaths) =>
@@ -407,84 +221,139 @@ globby(input, { dot: true })
407
221
  .then((paths) => {
408
222
  if (cli.flags.dry && !cli.flags.silent) {
409
223
  log(
410
- `${chalk.grey(prefix)}${chalk.yellow(
224
+ `${colour(prefix, colours.grey)}${colour(
411
225
  "We'd try to sort the following files:",
226
+ colours.yellow,
412
227
  )}\n${paths.join("\n")}`,
413
228
  );
414
- } else {
415
- if (cli.flags.ci) {
416
- // CI setting
417
- return pFilter(paths, (currentPath) =>
418
- readSortAndWriteOverFile(currentPath),
419
- ).then((received2) => {
420
- if (received2.length && !cli.flags.silent) {
229
+ return;
230
+ }
231
+
232
+ const options = {
233
+ arrays: cli.flags.arrays,
234
+ ci: cli.flags.ci,
235
+ indentationCount,
236
+ lineEnding: cli.flags.lineEnding,
237
+ pack: cli.flags.pack,
238
+ tabs: cli.flags.tabs,
239
+ onOutcome(outcome) {
240
+ if (cli.flags.silent) {
241
+ return;
242
+ }
243
+ if (outcome.status === "failure") {
244
+ log(
245
+ `${colour(prefix, colours.grey)}${outcome.path} - ${colour(
246
+ "BAD",
247
+ colours.red,
248
+ )} (${outcome.stage}) - ${outcome.error}`,
249
+ );
250
+ } else if (!cli.flags.ci) {
251
+ log(
252
+ `${colour(prefix, colours.grey)}${outcome.path} - ${colour(
253
+ "OK",
254
+ colours.green,
255
+ )}`,
256
+ );
257
+ }
258
+ },
259
+ };
260
+
261
+ return processFiles(paths, options)
262
+ .then(({ successful, unsorted }) => {
263
+ if (cli.flags.silent) {
264
+ if (cli.flags.ci && unsorted.length) {
265
+ process.exitCode = 9;
266
+ }
267
+ return;
268
+ }
269
+ if (cli.flags.ci) {
270
+ if (unsorted.length) {
421
271
  log(
422
- `${chalk.grey(prefix)}${chalk.red(
272
+ `${colour(prefix, colours.grey)}${colour(
423
273
  "Unsorted files:",
424
- )}\n${received2.join("\n")}`,
274
+ colours.red,
275
+ )}\n${unsorted.join("\n")}`,
425
276
  );
426
- process.exit(9);
427
- } else if (!cli.flags.silent) {
277
+ process.exitCode = 9;
278
+ } else {
428
279
  log(
429
- `${chalk.grey(prefix)}${chalk.white(
280
+ `${colour(prefix, colours.grey)}${colour(
430
281
  "All files were already sorted:",
431
- )}\n${paths.join("\n")}`,
282
+ colours.white,
283
+ )}\n${successful.join("\n")}`,
432
284
  );
433
- process.exit(0);
434
285
  }
435
- });
436
- }
437
- // not a CI setting
438
- return pReduce(
439
- paths,
440
- (counter, currentPath) =>
441
- readSortAndWriteOverFile(currentPath)
442
- .then((res) =>
443
- res
444
- ? {
445
- good: counter.good.concat([currentPath]),
446
- bad: counter.bad,
447
- }
448
- : {
449
- good: counter.good,
450
- bad: counter.bad.concat([currentPath]),
451
- },
452
- )
453
- .catch((err) => {
454
- if (!cli.flags.silent) {
455
- log(
456
- `${chalk.grey(prefix)}${chalk.red(
457
- "Could not write out the sorted file:",
458
- )} ${err}`,
459
- );
460
- }
461
- }),
462
- { good: [], bad: [] },
463
- ).then((counter) => {
286
+ return;
287
+ }
288
+ log(
289
+ `\n${colour(prefix, colours.grey)}${colour(
290
+ `All ${successful.length} file${
291
+ successful.length === 1 ? "" : "s"
292
+ } sorted`,
293
+ colours.green,
294
+ )}`,
295
+ );
296
+ })
297
+ .catch((error) => {
298
+ if (!(error instanceof ProcessingError)) {
299
+ throw error;
300
+ }
464
301
  if (!cli.flags.silent) {
302
+ if (cli.flags.ci) {
303
+ const unsorted = new Set(error.unsorted);
304
+ const alreadySorted = error.successful.filter(
305
+ (filePath) => !unsorted.has(filePath),
306
+ );
307
+ if (alreadySorted.length) {
308
+ log(
309
+ `${colour(prefix, colours.grey)}${colour(
310
+ `${alreadySorted.length} file${
311
+ alreadySorted.length === 1 ? "" : "s"
312
+ } already sorted:`,
313
+ colours.green,
314
+ )}\n${alreadySorted.join("\n")}`,
315
+ );
316
+ }
317
+ if (error.unsorted.length) {
318
+ log(
319
+ `${colour(prefix, colours.grey)}${colour(
320
+ "Unsorted files:",
321
+ colours.red,
322
+ )}\n${error.unsorted.join("\n")}`,
323
+ );
324
+ }
325
+ } else if (error.successful.length) {
326
+ log(
327
+ `\n${colour(prefix, colours.grey)}${colour(
328
+ `${error.successful.length} file${
329
+ error.successful.length === 1 ? "" : "s"
330
+ } sorted`,
331
+ colours.green,
332
+ )}`,
333
+ );
334
+ }
465
335
  log(
466
- `\n${chalk.grey(prefix)}${chalk.green(
467
- `${counter?.bad.length === 0 ? "All " : ""}${
468
- counter.good.length
469
- } files sorted`,
470
- )}${
471
- counter?.bad.length
472
- ? `\n${chalk.grey(prefix)}${chalk.red(
473
- `${counter.bad.length} file${
474
- counter.bad.length === 1 ? "" : "s"
475
- } could not be sorted`,
476
- )} ${`\u001b[${90}m - ${counter.bad.join(
477
- " - ",
478
- )}\u001b[${39}m`}`
479
- : ""
480
- }`,
336
+ `${colour(prefix, colours.grey)}${colour(
337
+ `${error.failures.length} file${
338
+ error.failures.length === 1 ? "" : "s"
339
+ } could not be ${cli.flags.ci ? "checked" : "sorted"}`,
340
+ colours.red,
341
+ )} ${colour(
342
+ ` - ${error.failures
343
+ .map(({ path: failedPath }) => failedPath)
344
+ .join(" - ")}`,
345
+ colours.grey,
346
+ )}`,
481
347
  );
482
348
  }
349
+ process.exitCode = 1;
483
350
  });
484
- }
485
351
  })
486
352
  .catch((err) => {
487
353
  if (!cli.flags.silent) {
488
- log(`${chalk.grey(prefix)}${chalk.red("Oops!")} ${err}`);
354
+ log(
355
+ `${colour(prefix, colours.grey)}${colour("Oops!", colours.red)} ${err}`,
356
+ );
489
357
  }
358
+ process.exitCode = 1;
490
359
  });
package/json-file.js ADDED
@@ -0,0 +1,42 @@
1
+ import { readFile, writeFile } from "node:fs/promises";
2
+
3
+ export async function readJson(file, options = {}) {
4
+ if (typeof options === "string") {
5
+ options = { encoding: options };
6
+ }
7
+
8
+ const shouldThrow = "throws" in options ? options.throws : true;
9
+ let content = await readFile(file, options);
10
+
11
+ if (Buffer.isBuffer(content)) {
12
+ content = content.toString("utf8");
13
+ }
14
+
15
+ try {
16
+ return JSON.parse(content.replace(/^\uFEFF/, ""), options.reviver);
17
+ } catch (error) {
18
+ if (!shouldThrow) {
19
+ return null;
20
+ }
21
+
22
+ error.message = `${file}: ${error.message}`;
23
+ throw error;
24
+ }
25
+ }
26
+
27
+ export async function writeJson(file, value, options = {}) {
28
+ const { EOL = "\n", finalEOL = true, replacer = null, spaces } = options;
29
+ const stringified = JSON.stringify(value, replacer, spaces);
30
+
31
+ if (stringified === undefined) {
32
+ throw new TypeError(
33
+ `json-sort-cli/writeJson(): [THROW_ID_01] Converting ${typeof value} value to JSON is not supported`,
34
+ );
35
+ }
36
+
37
+ await writeFile(
38
+ file,
39
+ stringified.replaceAll("\n", EOL) + (finalEOL ? EOL : ""),
40
+ options,
41
+ );
42
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "json-sort-cli",
3
- "version": "4.1.0",
3
+ "version": "4.2.0",
4
4
  "description": "Command line app to deep sort JSON files, retains package.json special key order",
5
5
  "keywords": [
6
6
  "app",
@@ -33,54 +33,46 @@
33
33
  },
34
34
  "scripts": {
35
35
  "build": "exit 0",
36
- "cjs-off": "exit 0",
37
- "cjs-on": "exit 0",
36
+ "coverage": "c8 uvu test",
38
37
  "dev": "exit 0",
39
38
  "devtest": "npm run test",
40
39
  "dts": "exit 0",
41
40
  "examples": "exit 0",
42
41
  "lect": "node '../../ops/lect/lect.js'",
43
- "letspublish": "npm publish --provenance || :",
44
- "lint": "eslint . --fix --concurrency=auto --cache",
42
+ "lect:check": "node '../../ops/lect/lect.js' --check",
43
+ "lint": "biome lint --error-on-warnings .",
44
+ "lint:fix": "biome lint --write --error-on-warnings .",
45
45
  "perf": "exit 0",
46
46
  "prep": "echo 'ready'",
47
- "prettier": "prettier",
48
- "prettier:format": "npm run prettier -- --write '**/*.{js,md}' --no-error-on-unmatched-pattern --log-level 'silent'",
49
- "pretest": "exit 0",
47
+ "prettier": "biome format",
48
+ "prettier:format": "biome format --write .",
49
+ "pretest": "npm run lect:check",
50
50
  "test": "c8 npm run unit && npm run lint",
51
51
  "unit": "uvu test"
52
52
  },
53
- "engines": {
54
- "node": ">=18"
55
- },
56
53
  "c8": {
57
- "check-coverage": false,
58
- "exclude": [
59
- "**/test/**/*.*"
60
- ]
54
+ "all": true,
55
+ "check-coverage": true,
56
+ "exclude": ["**/test/**/*.*"],
57
+ "lines": 97
61
58
  },
62
59
  "lect": {
63
60
  "licence": {
64
- "extras": [
65
- ""
66
- ]
61
+ "extras": [""]
67
62
  }
68
63
  },
69
64
  "dependencies": {
70
- "ast-monkey-traverse": "^4.1.0",
71
- "chalk": "^5.6.2",
72
- "codsen-utils": "^1.7.0",
73
- "fs-extra": "^11.3.2",
74
- "globby": "^15.0.0",
75
- "is-d": "^1.0.0",
76
- "meow": "^14.0.0",
77
- "p-filter": "^4.1.0",
78
- "p-reduce": "^3.0.0",
79
- "sort-package-json": "^3.4.0",
65
+ "ast-monkey-traverse": "^4.2.0",
66
+ "codsen-glob": "^1.1.0",
67
+ "codsen-utils": "^1.8.0",
68
+ "sort-package-json": "^2.15.1",
80
69
  "update-notifier": "^7.3.1"
81
70
  },
82
71
  "devDependencies": {
83
- "p-map": "^7.0.3"
72
+ "p-map": "^7.0.4"
73
+ },
74
+ "engines": {
75
+ "node": ">=18.20.8"
84
76
  },
85
77
  "publishConfig": {
86
78
  "registry": "https://registry.npmjs.org/"
@@ -0,0 +1,247 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { traverse } from "ast-monkey-traverse";
4
+ import { isPlainObject, resolveEolSetting } from "codsen-utils";
5
+ import sortPackageJson, { sortOrder } from "sort-package-json";
6
+ import { writeJson } from "./json-file.js";
7
+
8
+ function asError(error) {
9
+ return error instanceof Error ? error : new Error(String(error));
10
+ }
11
+
12
+ function sortObject(object) {
13
+ const result = {};
14
+ for (const key of Object.keys(object).sort()) {
15
+ result[key] = object[key];
16
+ }
17
+ return result;
18
+ }
19
+
20
+ function formatPackageJson(object) {
21
+ if (typeof object !== "object") {
22
+ return object;
23
+ }
24
+ const customSortOrder = sortOrder.filter(
25
+ (field) => !["lect", "tap"].includes(field),
26
+ );
27
+ const resolutionsIndex = customSortOrder.indexOf("resolutions");
28
+ customSortOrder.splice(resolutionsIndex, 0, "tap", "lect");
29
+ return sortPackageJson(object, { sortOrder: customSortOrder });
30
+ }
31
+
32
+ function normalizeLineEndings(stringified, eolChar) {
33
+ if (eolChar === "\r\n") {
34
+ return stringified
35
+ .replaceAll(/(?<!\r)\n/g, "\r\n")
36
+ .replaceAll(/\r(?!\n)/g, "\n");
37
+ }
38
+ return stringified.replaceAll(/(?:\r?\n)|\r/g, eolChar);
39
+ }
40
+
41
+ function prepareJson(
42
+ parsedJson,
43
+ { arrays, contents, filePath, indentationCount, lineEnding, pack, tabs },
44
+ ) {
45
+ const eol = resolveEolSetting(contents, lineEnding);
46
+ let result = isPlainObject(parsedJson) ? sortObject(parsedJson) : parsedJson;
47
+ if (
48
+ arrays &&
49
+ Array.isArray(result) &&
50
+ result.length &&
51
+ result.every((item) => typeof item === "string")
52
+ ) {
53
+ result.sort((a, b) => a.localeCompare(b));
54
+ } else if (!pack && path.basename(filePath) === "package.json") {
55
+ result = formatPackageJson(result);
56
+ }
57
+
58
+ const value = traverse(result, (key, val) => {
59
+ const current = val !== undefined ? val : key;
60
+ if (isPlainObject(current)) {
61
+ return sortObject(current);
62
+ }
63
+ if (
64
+ arrays &&
65
+ Array.isArray(current) &&
66
+ current.length > 1 &&
67
+ current.every((item) => typeof item === "string")
68
+ ) {
69
+ return current.sort((a, b) => a.localeCompare(b));
70
+ }
71
+ return current;
72
+ });
73
+ const spaces = tabs ? "\t".repeat(indentationCount) : indentationCount;
74
+ const stringified = normalizeLineEndings(
75
+ JSON.stringify(value, null, spaces),
76
+ eol,
77
+ );
78
+
79
+ return {
80
+ changed: stringified.trimEnd() !== contents.trimEnd(),
81
+ eol,
82
+ spaces,
83
+ value,
84
+ };
85
+ }
86
+
87
+ export class FileProcessingError extends Error {
88
+ constructor(filePath, stage, error) {
89
+ const cause = asError(error);
90
+ super(`${filePath}: ${stage} failed: ${cause.message}`, { cause });
91
+ this.name = "FileProcessingError";
92
+ this.error = cause;
93
+ this.path = filePath;
94
+ this.stage = stage;
95
+ }
96
+ }
97
+
98
+ export class ProcessingError extends AggregateError {
99
+ constructor(failures, successful, unsorted) {
100
+ super(
101
+ failures.map(({ error }) => error),
102
+ `${failures.length} file${failures.length === 1 ? "" : "s"} could not be sorted`,
103
+ );
104
+ this.name = "ProcessingError";
105
+ this.failures = failures;
106
+ this.successful = successful;
107
+ this.unsorted = unsorted;
108
+ }
109
+ }
110
+
111
+ async function processFile(
112
+ filePath,
113
+ options,
114
+ { parse, read, transform, write },
115
+ ) {
116
+ let contents;
117
+ try {
118
+ contents = await read(filePath, "utf8");
119
+ } catch (error) {
120
+ throw new FileProcessingError(filePath, "read", error);
121
+ }
122
+
123
+ let parsedJson;
124
+ try {
125
+ parsedJson = parse(contents);
126
+ } catch (error) {
127
+ throw new FileProcessingError(filePath, "parse", error);
128
+ }
129
+
130
+ let prepared;
131
+ try {
132
+ prepared = transform(parsedJson, { contents, filePath, ...options });
133
+ } catch (error) {
134
+ throw new FileProcessingError(filePath, "transform", error);
135
+ }
136
+
137
+ if (!options.ci) {
138
+ try {
139
+ await write(filePath, prepared.value, {
140
+ EOL: prepared.eol,
141
+ spaces: prepared.spaces,
142
+ });
143
+ } catch (error) {
144
+ throw new FileProcessingError(filePath, "write", error);
145
+ }
146
+ }
147
+
148
+ return { changed: prepared.changed, path: filePath };
149
+ }
150
+
151
+ async function mapWithConcurrency(values, mapper, concurrency) {
152
+ const results = new Array(values.length);
153
+ let nextIndex = 0;
154
+
155
+ async function worker() {
156
+ while (nextIndex < values.length) {
157
+ const currentIndex = nextIndex;
158
+ nextIndex += 1;
159
+ results[currentIndex] = await mapper(values[currentIndex]);
160
+ }
161
+ }
162
+
163
+ await Promise.all(
164
+ Array.from({ length: Math.min(concurrency, values.length) }, () =>
165
+ worker(),
166
+ ),
167
+ );
168
+ return results;
169
+ }
170
+
171
+ export async function processFiles(
172
+ paths,
173
+ {
174
+ arrays = false,
175
+ ci = false,
176
+ indentationCount = 2,
177
+ lineEnding,
178
+ onOutcome = () => {},
179
+ pack = false,
180
+ parse = JSON.parse,
181
+ read = readFile,
182
+ tabs = false,
183
+ transform = prepareJson,
184
+ write = writeJson,
185
+ } = {},
186
+ ) {
187
+ const failures = [];
188
+ const successful = [];
189
+ const unsorted = [];
190
+ const options = {
191
+ arrays,
192
+ ci,
193
+ indentationCount,
194
+ lineEnding,
195
+ pack,
196
+ tabs,
197
+ };
198
+
199
+ async function captureOutcome(filePath) {
200
+ try {
201
+ const outcome = await processFile(filePath, options, {
202
+ parse,
203
+ read,
204
+ transform,
205
+ write,
206
+ });
207
+ return { ...outcome, status: "success" };
208
+ } catch (error) {
209
+ if (!(error instanceof FileProcessingError)) {
210
+ throw error;
211
+ }
212
+ return {
213
+ error: error.error,
214
+ failure: error,
215
+ path: error.path,
216
+ stage: error.stage,
217
+ status: "failure",
218
+ };
219
+ }
220
+ }
221
+
222
+ const outcomes = ci
223
+ ? await mapWithConcurrency(paths, captureOutcome, 16)
224
+ : [];
225
+ if (!ci) {
226
+ for (const filePath of paths) {
227
+ outcomes.push(await captureOutcome(filePath));
228
+ }
229
+ }
230
+
231
+ for (const outcome of outcomes) {
232
+ if (outcome.status === "failure") {
233
+ failures.push(outcome.failure);
234
+ } else {
235
+ successful.push(outcome.path);
236
+ if (ci && outcome.changed) {
237
+ unsorted.push(outcome.path);
238
+ }
239
+ }
240
+ onOutcome(outcome);
241
+ }
242
+
243
+ if (failures.length) {
244
+ throw new ProcessingError(failures, successful, unsorted);
245
+ }
246
+ return { failures, successful, unsorted };
247
+ }
package/.eslintcache DELETED
@@ -1 +0,0 @@
1
- [{"/home/runner/work/codsen/codsen/packages/json-sort-cli/cli.js":"1","/home/runner/work/codsen/codsen/packages/json-sort-cli/test/test-a.js":"2","/home/runner/work/codsen/codsen/packages/json-sort-cli/test/test-c.js":"3","/home/runner/work/codsen/codsen/packages/json-sort-cli/test/test-h.js":"4","/home/runner/work/codsen/codsen/packages/json-sort-cli/test/test-i.js":"5","/home/runner/work/codsen/codsen/packages/json-sort-cli/test/test-l.js":"6","/home/runner/work/codsen/codsen/packages/json-sort-cli/test/test-n.js":"7","/home/runner/work/codsen/codsen/packages/json-sort-cli/test/test-p.js":"8","/home/runner/work/codsen/codsen/packages/json-sort-cli/test/test-s.js":"9","/home/runner/work/codsen/codsen/packages/json-sort-cli/test/test-t.js":"10","/home/runner/work/codsen/codsen/packages/json-sort-cli/test/test-v.js":"11","/home/runner/work/codsen/codsen/packages/json-sort-cli/test/test.js":"12","/home/runner/work/codsen/codsen/packages/json-sort-cli/test/util/data.js":"13"},{"size":14281,"mtime":1760566739114,"results":"14","hashOfConfig":"15"},{"size":3523,"mtime":1760566739115,"results":"16","hashOfConfig":"17"},{"size":10425,"mtime":1760566739115,"results":"18","hashOfConfig":"17"},{"size":1798,"mtime":1760566739115,"results":"19","hashOfConfig":"17"},{"size":2722,"mtime":1760566739115,"results":"20","hashOfConfig":"17"},{"size":2792,"mtime":1760566739115,"results":"21","hashOfConfig":"17"},{"size":4392,"mtime":1760566739115,"results":"22","hashOfConfig":"17"},{"size":3500,"mtime":1760566739115,"results":"23","hashOfConfig":"17"},{"size":2667,"mtime":1760566739115,"results":"24","hashOfConfig":"17"},{"size":2079,"mtime":1760566739115,"results":"25","hashOfConfig":"17"},{"size":1434,"mtime":1760566739115,"results":"26","hashOfConfig":"17"},{"size":6679,"mtime":1760566739115,"results":"27","hashOfConfig":"17"},{"size":9635,"mtime":1760566739115,"results":"28","hashOfConfig":"17"},{"filePath":"29","messages":"30","suppressedMessages":"31","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"vtm9kz",{"filePath":"32","messages":"33","suppressedMessages":"34","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"nrihsz",{"filePath":"35","messages":"36","suppressedMessages":"37","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"38","messages":"39","suppressedMessages":"40","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"41","messages":"42","suppressedMessages":"43","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"44","messages":"45","suppressedMessages":"46","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"47","messages":"48","suppressedMessages":"49","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"50","messages":"51","suppressedMessages":"52","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"53","messages":"54","suppressedMessages":"55","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"56","messages":"57","suppressedMessages":"58","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"59","messages":"60","suppressedMessages":"61","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"62","messages":"63","suppressedMessages":"64","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"65","messages":"66","suppressedMessages":"67","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"/home/runner/work/codsen/codsen/packages/json-sort-cli/cli.js",[],[],"/home/runner/work/codsen/codsen/packages/json-sort-cli/test/test-a.js",[],["68","69","70","71","72","73"],"/home/runner/work/codsen/codsen/packages/json-sort-cli/test/test-c.js",[],["74","75","76"],"/home/runner/work/codsen/codsen/packages/json-sort-cli/test/test-h.js",[],["77","78","79","80","81"],"/home/runner/work/codsen/codsen/packages/json-sort-cli/test/test-i.js",[],["82","83","84","85","86","87"],"/home/runner/work/codsen/codsen/packages/json-sort-cli/test/test-l.js",[],["88","89","90","91","92","93"],"/home/runner/work/codsen/codsen/packages/json-sort-cli/test/test-n.js",[],["94","95","96","97","98","99"],"/home/runner/work/codsen/codsen/packages/json-sort-cli/test/test-p.js",[],["100","101","102","103","104","105"],"/home/runner/work/codsen/codsen/packages/json-sort-cli/test/test-s.js",[],["106","107","108","109","110","111"],"/home/runner/work/codsen/codsen/packages/json-sort-cli/test/test-t.js",[],["112","113","114","115","116","117"],"/home/runner/work/codsen/codsen/packages/json-sort-cli/test/test-v.js",[],["118","119","120","121","122"],"/home/runner/work/codsen/codsen/packages/json-sort-cli/test/test.js",[],["123","124","125","126","127"],"/home/runner/work/codsen/codsen/packages/json-sort-cli/test/util/data.js",[],[],{"ruleId":"128","severity":2,"message":"129","line":5,"column":17,"nodeType":null,"messageId":"130","endLine":5,"endColumn":19,"suppressions":"131"},{"ruleId":"128","severity":2,"message":"132","line":5,"column":21,"nodeType":null,"messageId":"130","endLine":5,"endColumn":23,"suppressions":"133"},{"ruleId":"128","severity":2,"message":"134","line":5,"column":25,"nodeType":null,"messageId":"130","endLine":5,"endColumn":31,"suppressions":"135"},{"ruleId":"128","severity":2,"message":"136","line":5,"column":33,"nodeType":null,"messageId":"130","endLine":5,"endColumn":37,"suppressions":"137"},{"ruleId":"128","severity":2,"message":"138","line":5,"column":39,"nodeType":null,"messageId":"130","endLine":5,"endColumn":42,"suppressions":"139"},{"ruleId":"128","severity":2,"message":"140","line":5,"column":44,"nodeType":null,"messageId":"130","endLine":5,"endColumn":49,"suppressions":"141"},{"ruleId":"128","severity":2,"message":"129","line":5,"column":17,"nodeType":null,"messageId":"130","endLine":5,"endColumn":19,"suppressions":"142"},{"ruleId":"128","severity":2,"message":"134","line":5,"column":25,"nodeType":null,"messageId":"130","endLine":5,"endColumn":31,"suppressions":"143"},{"ruleId":"128","severity":2,"message":"136","line":5,"column":33,"nodeType":null,"messageId":"130","endLine":5,"endColumn":37,"suppressions":"144"},{"ruleId":"128","severity":2,"message":"129","line":5,"column":17,"nodeType":null,"messageId":"130","endLine":5,"endColumn":19,"suppressions":"145"},{"ruleId":"128","severity":2,"message":"132","line":5,"column":21,"nodeType":null,"messageId":"130","endLine":5,"endColumn":23,"suppressions":"146"},{"ruleId":"128","severity":2,"message":"134","line":5,"column":25,"nodeType":null,"messageId":"130","endLine":5,"endColumn":31,"suppressions":"147"},{"ruleId":"128","severity":2,"message":"136","line":5,"column":33,"nodeType":null,"messageId":"130","endLine":5,"endColumn":37,"suppressions":"148"},{"ruleId":"128","severity":2,"message":"138","line":5,"column":39,"nodeType":null,"messageId":"130","endLine":5,"endColumn":42,"suppressions":"149"},{"ruleId":"128","severity":2,"message":"129","line":5,"column":17,"nodeType":null,"messageId":"130","endLine":5,"endColumn":19,"suppressions":"150"},{"ruleId":"128","severity":2,"message":"132","line":5,"column":21,"nodeType":null,"messageId":"130","endLine":5,"endColumn":23,"suppressions":"151"},{"ruleId":"128","severity":2,"message":"134","line":5,"column":25,"nodeType":null,"messageId":"130","endLine":5,"endColumn":31,"suppressions":"152"},{"ruleId":"128","severity":2,"message":"136","line":5,"column":33,"nodeType":null,"messageId":"130","endLine":5,"endColumn":37,"suppressions":"153"},{"ruleId":"128","severity":2,"message":"138","line":5,"column":39,"nodeType":null,"messageId":"130","endLine":5,"endColumn":42,"suppressions":"154"},{"ruleId":"128","severity":2,"message":"140","line":5,"column":44,"nodeType":null,"messageId":"130","endLine":5,"endColumn":49,"suppressions":"155"},{"ruleId":"128","severity":2,"message":"129","line":5,"column":17,"nodeType":null,"messageId":"130","endLine":5,"endColumn":19,"suppressions":"156"},{"ruleId":"128","severity":2,"message":"132","line":5,"column":21,"nodeType":null,"messageId":"130","endLine":5,"endColumn":23,"suppressions":"157"},{"ruleId":"128","severity":2,"message":"134","line":5,"column":25,"nodeType":null,"messageId":"130","endLine":5,"endColumn":31,"suppressions":"158"},{"ruleId":"128","severity":2,"message":"136","line":5,"column":33,"nodeType":null,"messageId":"130","endLine":5,"endColumn":37,"suppressions":"159"},{"ruleId":"128","severity":2,"message":"138","line":5,"column":39,"nodeType":null,"messageId":"130","endLine":5,"endColumn":42,"suppressions":"160"},{"ruleId":"128","severity":2,"message":"140","line":5,"column":44,"nodeType":null,"messageId":"130","endLine":5,"endColumn":49,"suppressions":"161"},{"ruleId":"128","severity":2,"message":"129","line":5,"column":17,"nodeType":null,"messageId":"130","endLine":5,"endColumn":19,"suppressions":"162"},{"ruleId":"128","severity":2,"message":"132","line":5,"column":21,"nodeType":null,"messageId":"130","endLine":5,"endColumn":23,"suppressions":"163"},{"ruleId":"128","severity":2,"message":"134","line":5,"column":25,"nodeType":null,"messageId":"130","endLine":5,"endColumn":31,"suppressions":"164"},{"ruleId":"128","severity":2,"message":"136","line":5,"column":33,"nodeType":null,"messageId":"130","endLine":5,"endColumn":37,"suppressions":"165"},{"ruleId":"128","severity":2,"message":"138","line":5,"column":39,"nodeType":null,"messageId":"130","endLine":5,"endColumn":42,"suppressions":"166"},{"ruleId":"128","severity":2,"message":"140","line":5,"column":44,"nodeType":null,"messageId":"130","endLine":5,"endColumn":49,"suppressions":"167"},{"ruleId":"128","severity":2,"message":"129","line":5,"column":17,"nodeType":null,"messageId":"130","endLine":5,"endColumn":19,"suppressions":"168"},{"ruleId":"128","severity":2,"message":"132","line":5,"column":21,"nodeType":null,"messageId":"130","endLine":5,"endColumn":23,"suppressions":"169"},{"ruleId":"128","severity":2,"message":"134","line":5,"column":25,"nodeType":null,"messageId":"130","endLine":5,"endColumn":31,"suppressions":"170"},{"ruleId":"128","severity":2,"message":"136","line":5,"column":33,"nodeType":null,"messageId":"130","endLine":5,"endColumn":37,"suppressions":"171"},{"ruleId":"128","severity":2,"message":"138","line":5,"column":39,"nodeType":null,"messageId":"130","endLine":5,"endColumn":42,"suppressions":"172"},{"ruleId":"128","severity":2,"message":"140","line":5,"column":44,"nodeType":null,"messageId":"130","endLine":5,"endColumn":49,"suppressions":"173"},{"ruleId":"128","severity":2,"message":"129","line":5,"column":17,"nodeType":null,"messageId":"130","endLine":5,"endColumn":19,"suppressions":"174"},{"ruleId":"128","severity":2,"message":"132","line":5,"column":21,"nodeType":null,"messageId":"130","endLine":5,"endColumn":23,"suppressions":"175"},{"ruleId":"128","severity":2,"message":"134","line":5,"column":25,"nodeType":null,"messageId":"130","endLine":5,"endColumn":31,"suppressions":"176"},{"ruleId":"128","severity":2,"message":"136","line":5,"column":33,"nodeType":null,"messageId":"130","endLine":5,"endColumn":37,"suppressions":"177"},{"ruleId":"128","severity":2,"message":"138","line":5,"column":39,"nodeType":null,"messageId":"130","endLine":5,"endColumn":42,"suppressions":"178"},{"ruleId":"128","severity":2,"message":"140","line":5,"column":44,"nodeType":null,"messageId":"130","endLine":5,"endColumn":49,"suppressions":"179"},{"ruleId":"128","severity":2,"message":"129","line":5,"column":17,"nodeType":null,"messageId":"130","endLine":5,"endColumn":19,"suppressions":"180"},{"ruleId":"128","severity":2,"message":"132","line":5,"column":21,"nodeType":null,"messageId":"130","endLine":5,"endColumn":23,"suppressions":"181"},{"ruleId":"128","severity":2,"message":"134","line":5,"column":25,"nodeType":null,"messageId":"130","endLine":5,"endColumn":31,"suppressions":"182"},{"ruleId":"128","severity":2,"message":"136","line":5,"column":33,"nodeType":null,"messageId":"130","endLine":5,"endColumn":37,"suppressions":"183"},{"ruleId":"128","severity":2,"message":"138","line":5,"column":39,"nodeType":null,"messageId":"130","endLine":5,"endColumn":42,"suppressions":"184"},{"ruleId":"128","severity":2,"message":"140","line":5,"column":44,"nodeType":null,"messageId":"130","endLine":5,"endColumn":49,"suppressions":"185"},{"ruleId":"128","severity":2,"message":"129","line":5,"column":17,"nodeType":null,"messageId":"130","endLine":5,"endColumn":19,"suppressions":"186"},{"ruleId":"128","severity":2,"message":"132","line":5,"column":21,"nodeType":null,"messageId":"130","endLine":5,"endColumn":23,"suppressions":"187"},{"ruleId":"128","severity":2,"message":"134","line":5,"column":25,"nodeType":null,"messageId":"130","endLine":5,"endColumn":31,"suppressions":"188"},{"ruleId":"128","severity":2,"message":"136","line":5,"column":33,"nodeType":null,"messageId":"130","endLine":5,"endColumn":37,"suppressions":"189"},{"ruleId":"128","severity":2,"message":"138","line":5,"column":39,"nodeType":null,"messageId":"130","endLine":5,"endColumn":42,"suppressions":"190"},{"ruleId":"128","severity":2,"message":"129","line":5,"column":17,"nodeType":null,"messageId":"130","endLine":5,"endColumn":19,"suppressions":"191"},{"ruleId":"128","severity":2,"message":"132","line":5,"column":21,"nodeType":null,"messageId":"130","endLine":5,"endColumn":23,"suppressions":"192"},{"ruleId":"128","severity":2,"message":"134","line":5,"column":25,"nodeType":null,"messageId":"130","endLine":5,"endColumn":31,"suppressions":"193"},{"ruleId":"128","severity":2,"message":"136","line":5,"column":33,"nodeType":null,"messageId":"130","endLine":5,"endColumn":37,"suppressions":"194"},{"ruleId":"128","severity":2,"message":"138","line":5,"column":39,"nodeType":null,"messageId":"130","endLine":5,"endColumn":42,"suppressions":"195"},"@typescript-eslint/no-unused-vars","'is' is defined but never used.","unusedVar",["196"],"'ok' is defined but never used.",["197"],"'throws' is defined but never used.",["198"],"'type' is defined but never used.",["199"],"'not' is defined but never used.",["200"],"'match' is defined but never used.",["201"],["202"],["203"],["204"],["205"],["206"],["207"],["208"],["209"],["210"],["211"],["212"],["213"],["214"],["215"],["216"],["217"],["218"],["219"],["220"],["221"],["222"],["223"],["224"],["225"],["226"],["227"],["228"],["229"],["230"],["231"],["232"],["233"],["234"],["235"],["236"],["237"],["238"],["239"],["240"],["241"],["242"],["243"],["244"],["245"],["246"],["247"],["248"],["249"],["250"],["251"],["252"],["253"],["254"],["255"],{"kind":"256","justification":"257"},{"kind":"256","justification":"257"},{"kind":"256","justification":"257"},{"kind":"256","justification":"257"},{"kind":"256","justification":"257"},{"kind":"256","justification":"257"},{"kind":"256","justification":"257"},{"kind":"256","justification":"257"},{"kind":"256","justification":"257"},{"kind":"256","justification":"257"},{"kind":"256","justification":"257"},{"kind":"256","justification":"257"},{"kind":"256","justification":"257"},{"kind":"256","justification":"257"},{"kind":"256","justification":"257"},{"kind":"256","justification":"257"},{"kind":"256","justification":"257"},{"kind":"256","justification":"257"},{"kind":"256","justification":"257"},{"kind":"256","justification":"257"},{"kind":"256","justification":"257"},{"kind":"256","justification":"257"},{"kind":"256","justification":"257"},{"kind":"256","justification":"257"},{"kind":"256","justification":"257"},{"kind":"256","justification":"257"},{"kind":"256","justification":"257"},{"kind":"256","justification":"257"},{"kind":"256","justification":"257"},{"kind":"256","justification":"257"},{"kind":"256","justification":"257"},{"kind":"256","justification":"257"},{"kind":"256","justification":"257"},{"kind":"256","justification":"257"},{"kind":"256","justification":"257"},{"kind":"256","justification":"257"},{"kind":"256","justification":"257"},{"kind":"256","justification":"257"},{"kind":"256","justification":"257"},{"kind":"256","justification":"257"},{"kind":"256","justification":"257"},{"kind":"256","justification":"257"},{"kind":"256","justification":"257"},{"kind":"256","justification":"257"},{"kind":"256","justification":"257"},{"kind":"256","justification":"257"},{"kind":"256","justification":"257"},{"kind":"256","justification":"257"},{"kind":"256","justification":"257"},{"kind":"256","justification":"257"},{"kind":"256","justification":"257"},{"kind":"256","justification":"257"},{"kind":"256","justification":"257"},{"kind":"256","justification":"257"},{"kind":"256","justification":"257"},{"kind":"256","justification":"257"},{"kind":"256","justification":"257"},{"kind":"256","justification":"257"},{"kind":"256","justification":"257"},{"kind":"256","justification":"257"},"directive",""]