@wrongstack/tools 0.313.0 → 0.313.1

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 (134) hide show
  1. package/dist/audit.js +10 -4055
  2. package/dist/bash.js +9 -2308
  3. package/dist/batch-tool-use.js +2 -187
  4. package/dist/browser/index.js +25 -1339
  5. package/dist/builtin.js +69 -33949
  6. package/dist/chunk-2CTB3UK5.js +197 -0
  7. package/dist/chunk-2ME7ZWDD.js +1272 -0
  8. package/dist/chunk-2TFQDEPU.js +113 -0
  9. package/dist/chunk-2ZCJNKFE.js +315 -0
  10. package/dist/chunk-3PVYQFRQ.js +472 -0
  11. package/dist/chunk-3QMQBO5Z.js +89 -0
  12. package/dist/chunk-42AKKX7O.js +385 -0
  13. package/dist/chunk-42SKEETB.js +113 -0
  14. package/dist/chunk-4BHUSMNL.js +104 -0
  15. package/dist/chunk-4I4LWFOO.js +431 -0
  16. package/dist/chunk-553IQUMO.js +478 -0
  17. package/dist/chunk-55KF77OK.js +1944 -0
  18. package/dist/chunk-6HLZK37X.js +359 -0
  19. package/dist/chunk-6RNIFLG4.js +305 -0
  20. package/dist/chunk-A6BRWIXN.js +317 -0
  21. package/dist/chunk-AHHDWNXC.js +200 -0
  22. package/dist/chunk-B2CIOKWP.js +899 -0
  23. package/dist/chunk-BTSFTGIL.js +7 -0
  24. package/dist/chunk-D33S4RQG.js +222 -0
  25. package/dist/chunk-DIJKHSUO.js +134 -0
  26. package/dist/chunk-DPL47QGS.js +3515 -0
  27. package/dist/chunk-EMRGN4KM.js +170 -0
  28. package/dist/chunk-FGOABE4Z.js +955 -0
  29. package/dist/chunk-FW65TP4G.js +520 -0
  30. package/dist/chunk-GOIZNNOA.js +221 -0
  31. package/dist/chunk-H5MJUAA6.js +295 -0
  32. package/dist/chunk-H5OHH6F4.js +223 -0
  33. package/dist/chunk-HC5RM4WY.js +199 -0
  34. package/dist/chunk-HEQFMLZ7.js +190 -0
  35. package/dist/chunk-HFXSNKCV.js +196 -0
  36. package/dist/chunk-HXSBQ2SE.js +1723 -0
  37. package/dist/chunk-ILESNGNM.js +163 -0
  38. package/dist/chunk-INF5CGAO.js +137 -0
  39. package/dist/chunk-IWDFZ6XR.js +337 -0
  40. package/dist/chunk-IXMNTNW5.js +238 -0
  41. package/dist/chunk-J4SRJKBW.js +428 -0
  42. package/dist/chunk-J5SKD6LN.js +235 -0
  43. package/dist/chunk-JRJJX3L5.js +424 -0
  44. package/dist/chunk-KXNDHMUB.js +366 -0
  45. package/dist/chunk-LIJQMYYX.js +59 -0
  46. package/dist/chunk-MAN26PZ5.js +260 -0
  47. package/dist/chunk-MKRQMLZA.js +474 -0
  48. package/dist/chunk-NBDZMMG2.js +169 -0
  49. package/dist/chunk-NHA6BEIH.js +101 -0
  50. package/dist/chunk-OA6YJIWL.js +4412 -0
  51. package/dist/chunk-OZC255IC.js +2830 -0
  52. package/dist/chunk-PUR6WU2B.js +154 -0
  53. package/dist/chunk-Q5JPPCZC.js +12 -0
  54. package/dist/chunk-QBV725YG.js +128 -0
  55. package/dist/chunk-QHVW4AAM.js +892 -0
  56. package/dist/chunk-QNJ7AQ4B.js +1000 -0
  57. package/dist/chunk-RGISBZBD.js +231 -0
  58. package/dist/chunk-RJZQWEMS.js +84 -0
  59. package/dist/chunk-RP2ZA47V.js +15 -0
  60. package/dist/chunk-RXISBFR5.js +315 -0
  61. package/dist/chunk-S5CCLZL3.js +99 -0
  62. package/dist/chunk-TVTCSBJF.js +122 -0
  63. package/dist/chunk-U4D5S3VQ.js +21 -0
  64. package/dist/chunk-U4VAATKP.js +193 -0
  65. package/dist/chunk-UKU2ZX4C.js +203 -0
  66. package/dist/chunk-UNSKG6DC.js +159 -0
  67. package/dist/chunk-URFKEIHM.js +1091 -0
  68. package/dist/chunk-UTV7YAW7.js +178 -0
  69. package/dist/chunk-V43EQ6VR.js +68 -0
  70. package/dist/chunk-VB3MJGCV.js +610 -0
  71. package/dist/chunk-WHIIIREL.js +223 -0
  72. package/dist/chunk-XMIFYKUT.js +1371 -0
  73. package/dist/chunk-YF2RSV34.js +54 -0
  74. package/dist/chunk-Z6DAKQ3U.js +1 -0
  75. package/dist/chunk-ZIGAZFWE.js +522 -0
  76. package/dist/circuit-breaker.js +3 -191
  77. package/dist/codebase-index/index.js +84 -13688
  78. package/dist/codebase-index/parser-worker-script.js +8 -3995
  79. package/dist/codebase-index/project-server.js +60 -8548
  80. package/dist/codebase-index/worker.js +20 -8416
  81. package/dist/design.js +2 -299
  82. package/dist/diff.js +4 -256
  83. package/dist/document.js +4 -222
  84. package/dist/e2e.js +5 -476
  85. package/dist/edit.js +14 -10200
  86. package/dist/exec.js +16 -3131
  87. package/dist/fetch.js +8 -398
  88. package/dist/format.js +10 -3750
  89. package/dist/generic-parser-VUXDIAOZ.js +13 -0
  90. package/dist/git.js +4 -380
  91. package/dist/glob.js +6 -280
  92. package/dist/go-parser-6CA77WZ4.js +469 -0
  93. package/dist/grep.js +7 -604
  94. package/dist/index.js +318 -35387
  95. package/dist/install.js +10 -4091
  96. package/dist/json-parser-7YMDJSBJ.js +213 -0
  97. package/dist/json.js +4 -665
  98. package/dist/kanban.js +3 -2096
  99. package/dist/languages/index.js +23 -4664
  100. package/dist/legacy-bridge-7UKZT46G.js +18 -0
  101. package/dist/lint.js +10 -3706
  102. package/dist/logs.js +4 -287
  103. package/dist/memory.js +6 -215
  104. package/dist/mode.js +3 -99
  105. package/dist/outdated.js +4 -5170
  106. package/dist/pack.js +65 -33897
  107. package/dist/parser-dispatch-VPOFDO2U.js +14 -0
  108. package/dist/patch.js +13 -9935
  109. package/dist/plan.js +5 -3286
  110. package/dist/process-registry.js +8 -651
  111. package/dist/ps-slash.js +12 -1439
  112. package/dist/py-parser-GPM5VYRG.js +16 -0
  113. package/dist/read.js +13 -9816
  114. package/dist/replace.js +15 -10014
  115. package/dist/rs-parser-WVQ4KYCX.js +81 -0
  116. package/dist/scaffold.js +4 -253
  117. package/dist/search.js +5 -585
  118. package/dist/session-kanban.js +30 -972
  119. package/dist/skill.js +2 -215
  120. package/dist/task.js +5 -3410
  121. package/dist/test.js +10 -3773
  122. package/dist/todo.js +4 -2891
  123. package/dist/tool-help.js +3 -123
  124. package/dist/tool-search.js +3 -79
  125. package/dist/tool-tier.js +68 -33984
  126. package/dist/tool-use.js +2 -93
  127. package/dist/tree-sitter-parser-YCILHGZD.js +17 -0
  128. package/dist/tree.js +4 -288
  129. package/dist/ts-parser-YH4ZMWMH.js +232 -0
  130. package/dist/typecheck.js +10 -3753
  131. package/dist/win32.js +6 -60
  132. package/dist/write.js +14 -9882
  133. package/dist/yaml-parser-GFAOKV53.js +157 -0
  134. package/package.json +5 -5
package/dist/json.js CHANGED
@@ -1,669 +1,8 @@
1
- // src/json.ts
2
- import * as fs from "node:fs/promises";
3
- import { deepMerge as deepMergeCore } from "@wrongstack/core/utils";
4
-
5
- // src/_regex.ts
6
1
  import {
7
- capSubject,
8
- compileUserRegex,
9
- MAX_SUBJECT_LEN
10
- } from "@wrongstack/primitives";
11
-
12
- // src/_util.ts
13
- import * as fsp from "node:fs/promises";
14
- import * as path from "node:path";
15
- import * as Core from "@wrongstack/core/utils";
16
- function resolvePath(input, ctx) {
17
- return path.isAbsolute(input) ? path.normalize(input) : path.resolve(ctx.workingDir ?? ctx.cwd, input);
18
- }
19
- function allowedRoots(ctx) {
20
- return [path.resolve(ctx.projectRoot), path.resolve(Core.wstackGlobalRoot())];
21
- }
22
- function isInsideAny(target, roots) {
23
- return roots.some((root) => {
24
- const rel = path.relative(root, target);
25
- return rel === "" || !rel.startsWith("..") && !path.isAbsolute(rel);
26
- });
27
- }
28
- function ensureInsideRoot(absPath, ctx) {
29
- const target = path.resolve(absPath);
30
- if (ctx.allowOutsideProjectRoot) return target;
31
- if (isInsideAny(target, allowedRoots(ctx))) return target;
32
- throw new Error(`Path "${absPath}" is outside project root "${path.resolve(ctx.projectRoot)}"`);
33
- }
34
- function safeResolve(input, ctx) {
35
- return ensureInsideRoot(resolvePath(input, ctx), ctx);
36
- }
37
- async function resolveRealInsideRoot(absPath, ctx) {
38
- if (ctx.allowOutsideProjectRoot) return absPath;
39
- const realRoots = await Promise.all(
40
- allowedRoots(ctx).map((r) => fsp.realpath(r).catch(() => path.resolve(r)))
41
- );
42
- let probe = absPath;
43
- const pendingTail = [];
44
- for (; ; ) {
45
- let real;
46
- try {
47
- real = await fsp.realpath(probe);
48
- } catch (err) {
49
- if (err.code === "ENOENT") {
50
- const parent = path.dirname(probe);
51
- if (parent === probe) return absPath;
52
- pendingTail.unshift(path.basename(probe));
53
- probe = parent;
54
- continue;
55
- }
56
- throw err;
57
- }
58
- const candidate = pendingTail.length > 0 ? path.join(real, ...pendingTail) : real;
59
- if (isInsideAny(candidate, realRoots)) {
60
- return candidate;
61
- }
62
- throw new Error(
63
- `Path "${absPath}" resolves through a symlink outside project root "${realRoots[0]}"`
64
- );
65
- }
66
- }
67
- async function safeResolveReal(input, ctx) {
68
- const abs = safeResolve(input, ctx);
69
- return await resolveRealInsideRoot(abs, ctx);
70
- }
71
-
72
- // src/json.ts
73
- var MAX_JSON_FILE_BYTES = 16 * 1024 * 1024;
74
- var MAX_JSON_FILE_BYTES_HUMAN = "16 MiB";
75
- var JsonFileTooLargeError = class extends Error {
76
- constructor(filePath, size) {
77
- super(
78
- `json: "${filePath}" is ${size} bytes \u2014 exceeds the ${MAX_JSON_FILE_BYTES_HUMAN} file-size limit. Extract the relevant portion into a smaller file first, or use a shell tool to query it directly.`
79
- );
80
- this.name = "JsonFileTooLargeError";
81
- }
82
- };
83
- async function readJsonFileBounded(filePath, ctx) {
84
- const resolved = await safeResolveReal(filePath, ctx);
85
- const stat2 = await fs.stat(resolved);
86
- if (stat2.size > MAX_JSON_FILE_BYTES) {
87
- throw new JsonFileTooLargeError(filePath, stat2.size);
88
- }
89
- return fs.readFile(resolved, "utf8");
90
- }
91
- var jsonTool = {
92
- name: "json",
93
- category: "Data",
94
- description: "Parse, pretty-print, query, validate, transform, and merge JSON/JSON5/YAML. Use `action` to select the operation: parse (default), query, validate, transform, or merge.",
95
- usageHint: 'VERY USEFUL FOR DATA INSPECTION:\n\n- `action: "parse"` (default): read/pretty-print/convert JSON, JSON5, or YAML from `file` or `data`.\n- `action: "query"`: JMESPath-like query (`a.b[0].c`, `items[*].name`, filters, functions).\n- `action: "validate"`: validate data against a JSON Schema (`schema` param).\n- `action: "transform"`: chain multiple JMESPath transforms (`transforms` param).\n- `action: "merge"`: deep merge `base` and `patch` objects (`conflictResolution` param).\nPrefer this over raw `read` + manual parsing when dealing with configuration or data files.',
96
- permission: "auto",
97
- mutating: false,
98
- maxOutputBytes: 262144,
99
- timeoutMs: 5e3,
100
- capabilities: ["fs.read"],
101
- icon: "json",
102
- inputSchema: {
103
- type: "object",
104
- properties: {
105
- action: {
106
- type: "string",
107
- enum: ["parse", "query", "validate", "transform", "merge"],
108
- description: "Operation (default: parse). parse=read/pretty-print, query=JMESPath, validate=schema, transform=chained queries, merge=deep merge."
109
- },
110
- file: { type: "string", description: "Path to JSON/JSON5/YAML file (parse/query/validate)" },
111
- data: {
112
- type: "string",
113
- description: "JSON/JSON5/YAML string (parse/query/validate, alternative to file)"
114
- },
115
- format: {
116
- type: "string",
117
- enum: ["json", "json5", "yaml"],
118
- description: "Output format for parse/query/transform (default: json)"
119
- },
120
- query: {
121
- type: "string",
122
- description: "JMESPath-like query expression (query action)"
123
- },
124
- transforms: {
125
- type: "array",
126
- items: { type: "string" },
127
- description: "Ordered JMESPath query strings (transform action)"
128
- },
129
- schema: {
130
- type: "object",
131
- description: "JSON Schema to validate against (validate action)"
132
- },
133
- base: { description: "Base JSON object (merge action)" },
134
- patch: { description: "Patch JSON object to merge in (merge action)" },
135
- conflictResolution: {
136
- type: "string",
137
- enum: ["prefer-base", "prefer-patch"],
138
- description: "Merge conflict resolution (default: prefer-patch)"
139
- },
140
- validate: {
141
- type: "boolean",
142
- description: "Validate syntax only, no output (parse action, default: false)"
143
- }
144
- }
145
- },
146
- async execute(input, ctx) {
147
- const action = input.action ?? "parse";
148
- switch (action) {
149
- case "query":
150
- return executeQuery(input, ctx);
151
- case "validate":
152
- return executeValidate(input, ctx);
153
- case "transform":
154
- return executeTransform(input, ctx);
155
- case "merge":
156
- return executeMerge(input);
157
- default:
158
- return executeParse(input, ctx);
159
- }
160
- }
161
- };
162
- async function executeParse(input, ctx) {
163
- const format = input.format ?? "json";
164
- let parsed;
165
- let raw;
166
- if (input.file) {
167
- try {
168
- raw = await readJsonFileBounded(input.file, ctx);
169
- } catch (error) {
170
- return {
171
- data: null,
172
- formatted: "",
173
- type: "unknown",
174
- action: "parse",
175
- error: error instanceof JsonFileTooLargeError ? error.message : "Could not read file"
176
- };
177
- }
178
- } else if (input.data) {
179
- raw = input.data;
180
- } else {
181
- return {
182
- data: null,
183
- formatted: "",
184
- type: "unknown",
185
- action: "parse",
186
- error: "Provide file or data"
187
- };
188
- }
189
- try {
190
- parsed = JSON.parse(raw);
191
- } catch (e) {
192
- return {
193
- data: null,
194
- formatted: "",
195
- type: "unknown",
196
- action: "parse",
197
- /* v8 ignore next -- JSON.parse only throws SyntaxError (an Error); the String(e) side is defensive. */
198
- error: `Parse failed: ${e instanceof Error ? e.message : String(e)}`
199
- };
200
- }
201
- if (input.validate) {
202
- return {
203
- data: parsed,
204
- formatted: "valid",
205
- type: Array.isArray(parsed) ? "array" : typeof parsed,
206
- action: "parse",
207
- keys: typeof parsed === "object" && parsed !== null ? Object.keys(parsed) : void 0
208
- };
209
- }
210
- if (input.query) {
211
- const queryResult = simpleQuery(parsed, input.query);
212
- const formatted2 = formatOutput(queryResult, format);
213
- return {
214
- data: parsed,
215
- formatted: formatted2,
216
- type: Array.isArray(parsed) ? "array" : typeof parsed,
217
- action: "parse",
218
- keys: typeof parsed === "object" && parsed !== null ? Object.keys(parsed) : void 0,
219
- query_result: queryResult
220
- };
221
- }
222
- const formatted = formatOutput(parsed, format);
223
- return {
224
- data: parsed,
225
- formatted,
226
- type: Array.isArray(parsed) ? "array" : typeof parsed,
227
- action: "parse",
228
- keys: typeof parsed === "object" && parsed !== null ? Object.keys(parsed) : void 0
229
- };
230
- }
231
- async function executeQuery(input, ctx) {
232
- if (!input.query) {
233
- return {
234
- data: null,
235
- formatted: "",
236
- type: "unknown",
237
- action: "query",
238
- error: "query is required for action: query"
239
- };
240
- }
241
- let parsed;
242
- if (input.file) {
243
- try {
244
- const raw = await readJsonFileBounded(input.file, ctx);
245
- parsed = JSON.parse(raw);
246
- } catch (error) {
247
- return {
248
- data: null,
249
- formatted: "",
250
- type: "unknown",
251
- action: "query",
252
- error: error instanceof JsonFileTooLargeError ? error.message : "Could not read/parse file"
253
- };
254
- }
255
- } else if (input.data) {
256
- try {
257
- parsed = JSON.parse(input.data);
258
- } catch {
259
- return {
260
- data: null,
261
- formatted: "",
262
- type: "unknown",
263
- action: "query",
264
- error: "Could not parse data string"
265
- };
266
- }
267
- } else {
268
- return {
269
- data: null,
270
- formatted: "",
271
- type: "unknown",
272
- action: "query",
273
- error: "Provide file or data"
274
- };
275
- }
276
- try {
277
- const result = jmespathSearch(parsed, input.query);
278
- const format = input.format ?? "json";
279
- return {
280
- data: parsed,
281
- formatted: formatOutput(result, format),
282
- type: result === null ? "null" : Array.isArray(result) ? "array" : typeof result,
283
- action: "query",
284
- query_result: result
285
- };
286
- } catch (e) {
287
- return {
288
- data: null,
289
- formatted: "",
290
- type: "unknown",
291
- action: "query",
292
- /* v8 ignore next -- defensive String(e) */
293
- error: `Query failed: ${e instanceof Error ? e.message : String(e)}`
294
- };
295
- }
296
- }
297
- async function executeValidate(input, ctx) {
298
- if (!input.schema) {
299
- return {
300
- data: null,
301
- formatted: "",
302
- type: "unknown",
303
- action: "validate",
304
- error: "schema is required for action: validate"
305
- };
306
- }
307
- let parsed;
308
- if (input.file) {
309
- try {
310
- const raw = await readJsonFileBounded(input.file, ctx);
311
- parsed = JSON.parse(raw);
312
- } catch (error) {
313
- return {
314
- data: null,
315
- formatted: "",
316
- type: "unknown",
317
- action: "validate",
318
- error: error instanceof JsonFileTooLargeError ? error.message : "Could not read/parse file"
319
- };
320
- }
321
- } else if (input.data) {
322
- try {
323
- parsed = JSON.parse(input.data);
324
- } catch {
325
- return {
326
- data: null,
327
- formatted: "",
328
- type: "unknown",
329
- action: "validate",
330
- error: "Could not parse data string"
331
- };
332
- }
333
- } else {
334
- return {
335
- data: null,
336
- formatted: "",
337
- type: "unknown",
338
- action: "validate",
339
- error: "Provide file or data"
340
- };
341
- }
342
- try {
343
- const { valid, errors } = validateJsonSchema(parsed, input.schema);
344
- return {
345
- data: parsed,
346
- formatted: valid ? "valid" : "invalid",
347
- type: Array.isArray(parsed) ? "array" : typeof parsed,
348
- action: "validate",
349
- valid,
350
- errors
351
- };
352
- } catch (e) {
353
- return {
354
- data: null,
355
- formatted: "",
356
- type: "unknown",
357
- action: "validate",
358
- /* v8 ignore next -- defensive String(e) */
359
- error: `Validation failed: ${e instanceof Error ? e.message : String(e)}`
360
- };
361
- }
362
- }
363
- async function executeTransform(input, ctx) {
364
- if (!input.transforms || input.transforms.length === 0) {
365
- return {
366
- data: null,
367
- formatted: "",
368
- type: "unknown",
369
- action: "transform",
370
- error: "transforms array is required for action: transform"
371
- };
372
- }
373
- let parsed;
374
- if (input.file) {
375
- try {
376
- const raw = await readJsonFileBounded(input.file, ctx);
377
- parsed = JSON.parse(raw);
378
- } catch (error) {
379
- return {
380
- data: null,
381
- formatted: "",
382
- type: "unknown",
383
- action: "transform",
384
- error: error instanceof JsonFileTooLargeError ? error.message : "Could not read/parse file"
385
- };
386
- }
387
- } else if (input.data) {
388
- try {
389
- parsed = JSON.parse(input.data);
390
- } catch {
391
- return {
392
- data: null,
393
- formatted: "",
394
- type: "unknown",
395
- action: "transform",
396
- error: "Could not parse data string"
397
- };
398
- }
399
- } else {
400
- return {
401
- data: null,
402
- formatted: "",
403
- type: "unknown",
404
- action: "transform",
405
- error: "Provide file or data"
406
- };
407
- }
408
- try {
409
- let current = parsed;
410
- const steps = [];
411
- for (const t of input.transforms) {
412
- current = jmespathSearch(current, t);
413
- steps.push({ transform: t, result: current });
414
- }
415
- const format = input.format ?? "json";
416
- return {
417
- data: parsed,
418
- formatted: formatOutput(current, format),
419
- type: current === null ? "null" : Array.isArray(current) ? "array" : typeof current,
420
- action: "transform",
421
- result: current,
422
- steps
423
- };
424
- } catch (e) {
425
- return {
426
- data: null,
427
- formatted: "",
428
- type: "unknown",
429
- action: "transform",
430
- /* v8 ignore next -- defensive String(e) */
431
- error: `Transform failed: ${e instanceof Error ? e.message : String(e)}`
432
- };
433
- }
434
- }
435
- async function executeMerge(input) {
436
- if (input.base === void 0 || input.patch === void 0) {
437
- return {
438
- data: null,
439
- formatted: "",
440
- type: "unknown",
441
- action: "merge",
442
- error: "base and patch are required for action: merge"
443
- };
444
- }
445
- const conflictResolution = input.conflictResolution ?? "prefer-patch";
446
- try {
447
- const result = deepMergeCore(input.base, input.patch, { conflictResolution });
448
- const format = input.format ?? "json";
449
- return {
450
- data: result,
451
- formatted: formatOutput(result, format),
452
- type: result === null ? "null" : Array.isArray(result) ? "array" : typeof result,
453
- action: "merge",
454
- result
455
- };
456
- } catch (e) {
457
- return {
458
- data: null,
459
- formatted: "",
460
- type: "unknown",
461
- action: "merge",
462
- /* v8 ignore next -- defensive String(e) */
463
- error: `Merge failed: ${e instanceof Error ? e.message : String(e)}`
464
- };
465
- }
466
- }
467
- function jmespathSearch(data, query) {
468
- if (!query || query === "@") return data;
469
- if (query === "$") return data;
470
- const dotMatch = query.match(/^([a-zA-Z_][a-zA-Z0-9_]*)(?:\.(.+))?$/);
471
- if (dotMatch) {
472
- const key = dotMatch[1];
473
- const rest = dotMatch[2];
474
- const val = data?.[key];
475
- if (rest === void 0) return val;
476
- return jmespathSearch(val, rest);
477
- }
478
- const arrMatch = query.match(/^\[(\d+)\](?:\.(.+))?$/);
479
- if (arrMatch) {
480
- const idx = Number.parseInt(arrMatch[1], 10);
481
- const rest = arrMatch[2];
482
- const arr = data;
483
- const val = arr?.[idx];
484
- if (rest === void 0) return val;
485
- return jmespathSearch(val, rest);
486
- }
487
- if (query === "[*]") {
488
- if (Array.isArray(data)) {
489
- return data;
490
- }
491
- return data;
492
- }
493
- const multiMatch = query.match(/^([a-zA-Z_][a-zA-Z0-9_]*)\[\*\](?:\.(.+))?$/);
494
- if (multiMatch) {
495
- const key = multiMatch[1];
496
- const rest = multiMatch[2];
497
- const arr = data?.[key];
498
- if (!Array.isArray(arr)) return [];
499
- if (rest === void 0) return arr;
500
- return arr.map((item) => jmespathSearch(item, rest));
501
- }
502
- const filterMatch = query.match(
503
- /^\[\\?([a-zA-Z_][a-zA-Z0-9_]*)(==|!=|<|>|<=|>=)(`[^`]+`|'[^']*')\](?:\.(.+))?$/
504
- );
505
- if (filterMatch) {
506
- const field = filterMatch[1];
507
- const op = filterMatch[2];
508
- const rawVal = filterMatch[3];
509
- const rest = filterMatch[4];
510
- const cmpVal = JSON.parse(rawVal.slice(1, -1));
511
- const arr = data;
512
- if (!Array.isArray(arr)) return [];
513
- const filtered = arr.filter((item) => {
514
- const itemVal = item[field];
515
- switch (op) {
516
- case "==":
517
- return itemVal === cmpVal;
518
- case "!=":
519
- return itemVal !== cmpVal;
520
- case ">":
521
- return Number(itemVal) > Number(cmpVal);
522
- case "<":
523
- return Number(itemVal) < Number(cmpVal);
524
- case ">=":
525
- return Number(itemVal) >= Number(cmpVal);
526
- case "<=":
527
- return Number(itemVal) <= Number(cmpVal);
528
- /* v8 ignore next -- op is constrained to the six operators by the filter regex; default is unreachable. */
529
- default:
530
- return true;
531
- }
532
- });
533
- if (rest === void 0) return filtered;
534
- return filtered.map((item) => jmespathSearch(item, rest));
535
- }
536
- const fnMatch = query.match(/^(length|keys|values|type)\(@\)$/);
537
- if (fnMatch) {
538
- const fn = fnMatch[1];
539
- switch (fn) {
540
- case "length":
541
- if (Array.isArray(data)) return data.length;
542
- if (typeof data === "string") return data.length;
543
- if (typeof data === "object" && data !== null) return Object.keys(data).length;
544
- return 0;
545
- case "keys":
546
- if (typeof data === "object" && data !== null && !Array.isArray(data))
547
- return Object.keys(data);
548
- return [];
549
- case "values":
550
- if (typeof data === "object" && data !== null && !Array.isArray(data))
551
- return Object.values(data);
552
- return [];
553
- case "type":
554
- if (data === null) return "null";
555
- if (Array.isArray(data)) return "array";
556
- return typeof data;
557
- /* v8 ignore next 2 -- fn is constrained to the four names by the function regex; default is unreachable. */
558
- default:
559
- return null;
560
- }
561
- }
562
- return null;
563
- }
564
- function validateJsonSchema(data, schema) {
565
- const errors = [];
566
- function check(value, s, path2) {
567
- if (s["type"]) {
568
- const expectedType = s["type"];
569
- const actualType = Array.isArray(value) ? "array" : value === null ? "null" : typeof value;
570
- if (expectedType === "integer") {
571
- if (!Number.isInteger(value)) errors.push(`${path2}: expected integer, got ${actualType}`);
572
- } else if (expectedType !== actualType) {
573
- errors.push(`${path2}: expected ${expectedType}, got ${actualType}`);
574
- }
575
- }
576
- if (typeof value === "string" && s["format"] === "uri" && value) {
577
- try {
578
- new URL(value);
579
- } catch {
580
- errors.push(`${path2}: not a valid URI`);
581
- }
582
- }
583
- if (typeof value === "string" && s["pattern"]) {
584
- const compiled = compileUserRegex(s["pattern"], "");
585
- if (!compiled.ok) {
586
- errors.push(`${path2}: invalid schema pattern \u2014 ${compiled.reason}`);
587
- } else if (!compiled.regex.test(capSubject(value))) {
588
- errors.push(`${path2}: does not match pattern ${s["pattern"]}`);
589
- }
590
- }
591
- if (typeof value === "string" && s["minLength"] !== void 0 && value.length < s["minLength"]) {
592
- errors.push(`${path2}: string too short (min ${s["minLength"]})`);
593
- }
594
- if (typeof value === "string" && s["maxLength"] !== void 0 && value.length > s["maxLength"]) {
595
- errors.push(`${path2}: string too long (max ${s["maxLength"]})`);
596
- }
597
- if (typeof value === "number" && s["minimum"] !== void 0 && value < s["minimum"]) {
598
- errors.push(`${path2}: below minimum ${s["minimum"]}`);
599
- }
600
- if (typeof value === "number" && s["maximum"] !== void 0 && value > s["maximum"]) {
601
- errors.push(`${path2}: above maximum ${s["maximum"]}`);
602
- }
603
- if (Array.isArray(value) && s["items"] && Array.isArray(s["items"])) {
604
- for (let i = 0; i < value.length; i++) {
605
- check(value[i], s["items"], `${path2}[${i}]`);
606
- }
607
- }
608
- if (typeof value === "object" && value !== null && !Array.isArray(value) && s["properties"]) {
609
- const props = s["properties"];
610
- for (const [k, propSchema] of Object.entries(props)) {
611
- check(value[k], propSchema, `${path2}.${k}`);
612
- }
613
- }
614
- }
615
- check(data, schema, "$");
616
- return { valid: errors.length === 0, errors };
617
- }
618
- function simpleQuery(data, path2) {
619
- const parts = path2.replace(/\[(\d+)\]/g, ".$1").split(".").filter(Boolean);
620
- let current = data;
621
- for (const part of parts) {
622
- if (current === null || current === void 0) return void 0;
623
- const idx = Number(part);
624
- if (!Number.isNaN(idx) && Array.isArray(current)) {
625
- current = current[idx];
626
- } else if (typeof current === "object" && current !== null) {
627
- current = current[part];
628
- } else {
629
- return void 0;
630
- }
631
- }
632
- return current;
633
- }
634
- function formatOutput(data, format) {
635
- if (format === "json5") {
636
- return JSON.stringify(data, null, 2).replace(/,\s*}/g, "}").replace(/,\s*\]/g, "]");
637
- }
638
- if (format === "yaml") {
639
- return toYaml(data);
640
- }
641
- return JSON.stringify(data, null, 2);
642
- }
643
- function toYaml(data, indent = 0) {
644
- if (data === null) return "null\n";
645
- if (data === void 0) return "";
646
- if (typeof data === "boolean") return String(data) + "\n";
647
- if (typeof data === "number") return String(data) + "\n";
648
- if (typeof data === "string") {
649
- if (data.includes("\n") || data.includes(":") || data.includes("#")) {
650
- return `"${data.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"
651
- `;
652
- }
653
- return data + "\n";
654
- }
655
- if (Array.isArray(data)) {
656
- if (data.length === 0) return "[]\n";
657
- const prefix = " ".repeat(indent);
658
- return data.map((item) => `${prefix}- ${toYaml(item, indent + 1).trimStart()}`).join("");
659
- }
660
- if (typeof data === "object") {
661
- const prefix = " ".repeat(indent);
662
- const entries = Object.entries(data);
663
- return entries.map(([k, v]) => `${prefix}${k}: ${toYaml(v, indent + 1)}`).join("");
664
- }
665
- return String(data) + "\n";
666
- }
2
+ jsonTool
3
+ } from "./chunk-VB3MJGCV.js";
4
+ import "./chunk-Q5JPPCZC.js";
5
+ import "./chunk-D33S4RQG.js";
667
6
  export {
668
7
  jsonTool
669
8
  };