jsonata-w 1.0.0 → 1.1.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/README.md CHANGED
@@ -1,36 +1,41 @@
1
1
  # JSONata Workflow (jsonata-w)
2
2
 
3
- The **w** stands for **Workflow**. A command-line utility optimized to assist AI agents in transforming and inspecting JSON files, but equally powerful for manual workflows.
3
+ The **w** stands for **Workflow**. A command-line utility optimized to assist AI agents in transforming and inspecting JSON/YAML files, but equally powerful for manual workflows.
4
4
 
5
5
  ## Commands
6
6
 
7
7
  ### Inspect
8
- Inspects the structure of a JSON file.
8
+ Inspects the structure of a JSON or YAML file.
9
9
 
10
10
  ```bash
11
11
  jsonata-w inspect <file> [options]
12
12
  ```
13
13
 
14
14
  #### Options
15
- - `-s, --summary`: Show a high-level summary of the JSON structure (paths and keys).
15
+ - `-s, --summary`: Show a high-level summary of the structure (paths and keys).
16
16
  - `--schema`: Generate and print the JSON schema for the scanned file.
17
17
  - `-d, --depth <number>`: Limit the depth of inspection (default: 1).
18
- - `--jsonpath <query>`: Filter the input JSON using a JSONPath expression before inspecting.
19
- - `--jsonata <expression>`: Filter the input JSON using a JSONata expression before inspecting.
18
+ - `--jsonpath <query>`: Filter the input using a JSONPath expression before inspecting.
19
+ - `--jsonata <expression>`: Filter the input using a JSONata expression before inspecting.
20
20
 
21
21
  #### Examples
22
- **Summary view:**
22
+ **Summary view (JSON):**
23
23
  ```bash
24
24
  jsonata-w inspect data.json --summary
25
25
  ```
26
26
 
27
+ **Summary view (YAML):**
28
+ ```bash
29
+ jsonata-w inspect tokens.yml --summary
30
+ ```
31
+
27
32
  **Filter with JSONPath:**
28
33
  ```bash
29
34
  jsonata-w inspect data.json --jsonpath "$.users[*].name"
30
35
  ```
31
36
 
32
37
  ### Transform
33
- Transforms a JSON file using a JSONata expression file. The input and output paths are defined directly within the JSONata file using a standard configuration block.
38
+ Transforms a JSON or YAML file using a JSONata expression file. The input and output paths are defined directly within the JSONata file using a standard configuration block.
34
39
 
35
40
  ```bash
36
41
  jsonata-w transform <file>
@@ -40,11 +45,14 @@ jsonata-w transform <file>
40
45
  The JSONata file MUST start with a configuration comment block:
41
46
 
42
47
  ```javascript
43
- /* @config {
44
- "input": "./path/to/input.json",
45
- "output": "./path/to/output.json",
46
- "schema": "./optional/schema.json"
47
- } */
48
+ /**
49
+ * @config {
50
+ * "input": "./path/to/input.yml",
51
+ * "output": "./path/to/output.json",
52
+ * "schema": "./optional/schema.yml",
53
+ * "examples": "./path/to/example.yml"
54
+ * }
55
+ */
48
56
 
49
57
  (
50
58
  /* Your JSONata expression here */
@@ -52,10 +60,15 @@ The JSONata file MUST start with a configuration comment block:
52
60
  )
53
61
  ```
54
62
 
55
- - `input`: Path to the source JSON file (relative to the .jsonata file).
56
- - `output`: Path where the transformed JSON will be saved (relative to the .jsonata file).
57
- - `schema`: (Optional) Path to a JSON schema for validation.
63
+ - `input`: Path to the source file — supports `.json`, `.yml`, `.yaml` (relative to the .jsonata file).
64
+ - `output`: Path where the result will be saved format is auto-detected from extension:
65
+ - `.json` JSON output
66
+ - `.yml` / `.yaml` → YAML output
67
+ - other → raw string output
68
+ - `schema`: (Optional) Path to a JSON or YAML schema for validation.
69
+ - `examples`: (Optional) Path to a JSON or YAML file containing the expected output subset for validation.
58
70
 
59
71
  #### Features
72
+ - **YAML Support**: Full YAML support for input, output, schema, and example files. File format is detected from the extension (`.yml`/`.yaml` = YAML, everything else = JSON).
60
73
  - **Embedded Config**: No need for CLI arguments for input/output.
61
74
  - **Auto-Unflattening**: Results containing dot-notation keys (e.g., `{"a.b": 1}`) are automatically expanded into nested objects (`{"a": {"b": 1}}`). This simplifies generating deep hierarchies.
package/dist/cli.js CHANGED
@@ -58,9 +58,9 @@ function pickSubset(data, template) {
58
58
  return result;
59
59
  }
60
60
  (0, yargs_1.default)((0, helpers_1.hideBin)(process.argv))
61
- .command('inspect <file>', 'Inspect JSON structure', (yargs) => {
61
+ .command('inspect <file>', 'Inspect JSON/YAML structure', (yargs) => {
62
62
  return yargs
63
- .positional('file', { describe: 'JSON file to inspect', type: 'string', demandOption: true })
63
+ .positional('file', { describe: 'JSON/YAML file to inspect', type: 'string', demandOption: true })
64
64
  .option('depth', { alias: 'd', type: 'number', default: 1, describe: 'Depth to inspect' })
65
65
  .option('summary', { alias: 's', type: 'boolean', default: false, describe: 'Show structure summary' })
66
66
  .option('schema', { type: 'boolean', default: false, describe: 'Generate JSON schema from file' })
@@ -102,7 +102,7 @@ function pickSubset(data, template) {
102
102
  process.exit(1);
103
103
  }
104
104
  })
105
- .command('transform <file>', 'Transform JSON using a single JSONata file with embedded @config', (yargs) => {
105
+ .command('transform <file>', 'Transform JSON/YAML using a single JSONata file with embedded @config', (yargs) => {
106
106
  return yargs
107
107
  .positional('file', { describe: 'JSONata file with embedded @config', type: 'string', demandOption: true });
108
108
  }, async (argv) => {
@@ -182,7 +182,13 @@ function pickSubset(data, template) {
182
182
  const dir = path_1.default.dirname(outputPath);
183
183
  if (!fs_1.default.existsSync(dir))
184
184
  fs_1.default.mkdirSync(dir, { recursive: true });
185
- fs_1.default.writeFileSync(outputPath, JSON.stringify(finalResult, null, 2));
185
+ const isYamlOutput = outputPath.endsWith('.yml') || outputPath.endsWith('.yaml');
186
+ const outputContent = (typeof finalResult === 'string')
187
+ ? finalResult
188
+ : isYamlOutput
189
+ ? js_yaml_1.default.dump(finalResult, { indent: 2, lineWidth: -1 })
190
+ : JSON.stringify(finalResult, null, 2);
191
+ fs_1.default.writeFileSync(outputPath, outputContent);
186
192
  console.log(`Transformed ${config.input} -> ${config.output}`);
187
193
  }
188
194
  catch (e) {
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.SchemaValidator = void 0;
7
7
  const ajv_1 = __importDefault(require("ajv"));
8
8
  const fs_1 = __importDefault(require("fs"));
9
+ const js_yaml_1 = __importDefault(require("js-yaml"));
9
10
  class SchemaValidator {
10
11
  constructor() {
11
12
  this.ajv = new ajv_1.default();
@@ -17,10 +18,12 @@ class SchemaValidator {
17
18
  const schemaContent = fs_1.default.readFileSync(schemaPath, 'utf-8');
18
19
  let schema;
19
20
  try {
20
- schema = JSON.parse(schemaContent);
21
+ const isYaml = schemaPath.endsWith('.yml') || schemaPath.endsWith('.yaml');
22
+ schema = isYaml ? js_yaml_1.default.load(schemaContent) : JSON.parse(schemaContent);
21
23
  }
22
24
  catch (_e) {
23
- throw new Error(`Invalid JSON schema in file: ${schemaPath}`);
25
+ const format = (schemaPath.endsWith('.yml') || schemaPath.endsWith('.yaml')) ? 'YAML' : 'JSON';
26
+ throw new Error(`Invalid ${format} schema in file: ${schemaPath}`);
24
27
  }
25
28
  const validate = this.ajv.compile(schema);
26
29
  const valid = validate(data);
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.SourceLoader = void 0;
7
7
  const fs_1 = __importDefault(require("fs"));
8
+ const js_yaml_1 = __importDefault(require("js-yaml"));
8
9
  class SourceLoader {
9
10
  constructor() {
10
11
  this.cache = new Map();
@@ -18,12 +19,14 @@ class SourceLoader {
18
19
  }
19
20
  const content = fs_1.default.readFileSync(path, 'utf-8');
20
21
  try {
21
- const json = JSON.parse(content);
22
- this.cache.set(path, json);
23
- return json;
22
+ const isYaml = path.endsWith('.yml') || path.endsWith('.yaml');
23
+ const data = isYaml ? js_yaml_1.default.load(content) : JSON.parse(content);
24
+ this.cache.set(path, data);
25
+ return data;
24
26
  }
25
27
  catch (_e) {
26
- throw new Error(`Invalid JSON in file: ${path}`);
28
+ const format = (path.endsWith('.yml') || path.endsWith('.yaml')) ? 'YAML' : 'JSON';
29
+ throw new Error(`Invalid ${format} in file: ${path}`);
27
30
  }
28
31
  }
29
32
  clearCache() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jsonata-w",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Tool to assist AI in transforming JSON files",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -44,4 +44,4 @@
44
44
  "typescript": "^5.7.2",
45
45
  "typescript-eslint": "^8.51.0"
46
46
  }
47
- }
47
+ }