@tabnas/json 0.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/README.md ADDED
@@ -0,0 +1,179 @@
1
+ # @tabnas/json
2
+
3
+ A standard JSON parser (RFC 8259 / ECMA-404) for TypeScript and
4
+ JavaScript — the standard-JSON **grammar plugin** for the
5
+ [`tabnas`](https://github.com/tabnas/parser) parsing engine.
6
+
7
+ Available for [TypeScript/JavaScript](#install) and [Go](../go/).
8
+
9
+ ## Install
10
+
11
+ ```bash
12
+ npm install @tabnas/json
13
+ ```
14
+
15
+ `tabnas` (the engine) is a peer/dependency; see [Develop](#develop) for
16
+ the sibling-checkout setup used until it is published.
17
+
18
+ ## Quick example
19
+
20
+ ```ts
21
+ import { parse } from '@tabnas/json'
22
+
23
+ parse('{"a":1, "b":2}') // { a: 1, b: 2 }
24
+ parse('[1, 2, 3]') // [1, 2, 3]
25
+ parse('{"a": {"b": [true, null]}}') // { a: { b: [true, null] } }
26
+ ```
27
+
28
+ ```js
29
+ const { parse } = require('@tabnas/json')
30
+ parse('"hello"') // => "hello"
31
+ ```
32
+
33
+ `parse` is also the default export.
34
+
35
+ ## Documentation
36
+
37
+ Full [Diátaxis](https://diataxis.fr) docs:
38
+
39
+ - [`doc/tutorial.md`](doc/tutorial.md) — learn it step by step.
40
+ - [`doc/guide.md`](doc/guide.md) — task-focused recipes.
41
+ - [`doc/reference.md`](doc/reference.md) — the exact API and CLI surface.
42
+ - [`doc/concepts.md`](doc/concepts.md) — how it works and why.
43
+
44
+ The Go port has the [equivalent docs](../go/doc/).
45
+
46
+ ## Use it as a plugin
47
+
48
+ The package is a `tabnas` grammar plugin. Install it on your own engine
49
+ instance and layer further grammar on the shared rules:
50
+
51
+ ```ts
52
+ import { Tabnas } from '@tabnas/parser'
53
+ import { json } from '@tabnas/json'
54
+
55
+ const tn = new Tabnas({ plugins: [json] })
56
+ tn.parse('{"a":[1,2,3]}')
57
+ ```
58
+
59
+ `registerJsonGrammar(tn)` installs just the `val` / `map` / `list` /
60
+ `pair` / `elem` rules (jsonic's "Plain JSON" core) without the strict
61
+ options, for plugins that want to build on the JSON rule set.
62
+
63
+ ## Reuse and options
64
+
65
+ `parse` reuses a single lazily-created instance, so you don't pay to
66
+ rebuild the grammar on every call. To customize, build your own instance
67
+ with `make(opts?)` — extra options (e.g. the `info` metadata options) are
68
+ applied on top of the strict JSON config:
69
+
70
+ ```ts
71
+ import { make } from '@tabnas/json'
72
+
73
+ const p = make({ info: { map: true, list: true } })
74
+ p.parse('{"a":[1,2]}')
75
+ ```
76
+
77
+ `Version` is exported as the package version string.
78
+
79
+ ## What it accepts
80
+
81
+ Exactly standard JSON:
82
+
83
+ - objects `{ "key": value, ... }` with double-quoted string keys
84
+ - arrays `[ value, ... ]`
85
+ - double-quoted strings with the JSON escapes
86
+ (`\" \\ \/ \b \f \n \r \t \uXXXX`, including surrogate pairs)
87
+ - numbers: optional `-`, integer (no leading zeros), optional fraction,
88
+ optional `e`/`E` exponent
89
+ - `true`, `false`, `null`
90
+ - insignificant whitespace: space, tab, line feed, carriage return
91
+
92
+ It **rejects** everything outside that grammar — comments, trailing
93
+ commas, unquoted keys, single-quoted or backtick strings, multiline
94
+ strings, implicit objects/arrays, hex/octal/binary numbers, leading
95
+ zeros, a leading `+`, a bare `.5` or trailing `1.`, and empty input.
96
+ This matches the platform `JSON.parse`.
97
+
98
+ Parsed objects use a **null prototype** (`Object.create(null)`): this is
99
+ deliberate and prototype-pollution-safe — a `"__proto__"` key becomes a
100
+ normal own property rather than mutating the prototype. The only visible
101
+ difference from `JSON.parse` is the missing `Object.prototype` (so e.g.
102
+ `obj.hasOwnProperty` is `undefined`; use `Object.hasOwn(obj, k)`).
103
+
104
+ ## Extending the grammar
105
+
106
+ Because this is a plain grammar plugin on the shared engine, it is a
107
+ foundation to build other parsers on. Layer options or rules on top of
108
+ the `json` plugin. For example, a JSON-with-comments (JSONC) parser is
109
+ just the JSON grammar with comment lexing re-enabled:
110
+
111
+ ```ts
112
+ import { Tabnas } from '@tabnas/parser'
113
+ import { json } from '@tabnas/json'
114
+
115
+ const jsonc = new Tabnas({ plugins: [json] })
116
+ jsonc.options({ comment: { lex: true } })
117
+ jsonc.parse('{"a":1} // ok') // { a: 1 }
118
+ jsonc.parse('{"a":/* ok */1}') // { a: 1 }
119
+ ```
120
+
121
+ For deeper changes, call `registerJsonGrammar(tn)` to install just the
122
+ rules, then use the engine's rule API (`tn.rule(...)`, and the
123
+ `clearOpen` / `clearClose` / `@<rule>-<phase>/replace` hooks) to replace
124
+ or extend the shared `val` / `map` / `list` / `pair` / `elem` rules
125
+ without re-declaring the JSON core.
126
+
127
+ ## Errors
128
+
129
+ On invalid input, `parse` throws a `TabnasError` (also exported as
130
+ `JsonError`) carrying `code`, `lineNumber`, and `columnNumber`:
131
+
132
+ ```ts
133
+ import { parse, TabnasError } from '@tabnas/json'
134
+
135
+ try {
136
+ parse('{a:1}')
137
+ } catch (err) {
138
+ if (err instanceof TabnasError) {
139
+ err.code // 'unexpected'
140
+ }
141
+ }
142
+ ```
143
+
144
+ ## CLI
145
+
146
+ ```bash
147
+ echo '{"a":1}' | npx tabnas-json
148
+ tabnas-json '{"a":1}'
149
+ ```
150
+
151
+ Prints the re-serialized (pretty) JSON, or the error on stderr with exit
152
+ code 1.
153
+
154
+ ## Develop
155
+
156
+ This package depends on the engine as a sibling checkout:
157
+
158
+ ```bash
159
+ git clone https://github.com/tabnas/parser # sibling of this repo
160
+ ( cd parser/ts && npm install && npm run build )
161
+ npm install # resolves "@tabnas/parser": "file:../../parser/ts"
162
+ npm test # tsc build + node --test
163
+ ```
164
+
165
+ See [`AGENTS.md`](AGENTS.md) for layout and conventions.
166
+
167
+
168
+ ## Grammar diagram
169
+
170
+ The installed grammar as a railroad/syntax diagram, generated from the live
171
+ grammar with [`@tabnas/railroad`](https://github.com/tabnas/railroad):
172
+
173
+ ![json grammar railroad diagram](doc/grammar.svg)
174
+
175
+ A vertical ASCII version is in [`doc/grammar.txt`](doc/grammar.txt).
176
+
177
+ ## License
178
+
179
+ MIT.
package/bin/json ADDED
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env node
2
+ const { main } = require('../dist/json-cli.js')
3
+ main(
4
+ process.argv.slice(2),
5
+ process.stdin,
6
+ (s) => process.stdout.write(s),
7
+ (s) => process.stderr.write(s),
8
+ (code) => process.exit(code),
9
+ )
@@ -0,0 +1,2 @@
1
+ export declare function run(src: string, out: (s: string) => void, errOut: (s: string) => void): number;
2
+ export declare function main(argv: string[], stdin: NodeJS.ReadableStream, out: (s: string) => void, errOut: (s: string) => void, exit: (code: number) => void): void;
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ /* Copyright (c) 2026 tabnas, MIT License */
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.run = run;
5
+ exports.main = main;
6
+ /* json-cli.ts
7
+ *
8
+ * A tiny command-line front end: read JSON from the arguments or from
9
+ * stdin, parse it, and print the canonical re-serialized form. Exit code
10
+ * 1 (with the error on stderr) when the input is not valid JSON.
11
+ *
12
+ * The logic is split into `run` (pure: source in, exit code out, writes
13
+ * via injected sinks) and `main` (process wiring), so `run` and `main`
14
+ * are both testable in-process. `bin/json` calls `main`.
15
+ */
16
+ const json_1 = require("./json");
17
+ // Parse `src`, writing the pretty-printed value to `out` on success or
18
+ // the error message to `errOut` on failure. Returns the process exit code.
19
+ function run(src, out, errOut) {
20
+ try {
21
+ out(JSON.stringify((0, json_1.parse)(src), null, 2) + '\n');
22
+ return 0;
23
+ }
24
+ catch (err) {
25
+ if (err instanceof json_1.TabnasError) {
26
+ errOut(err.message + '\n');
27
+ return 1;
28
+ }
29
+ throw err;
30
+ }
31
+ }
32
+ // Wire `run` to a process-like environment. With arguments, parse them;
33
+ // otherwise read all of stdin. Calls `exit` with the resulting code.
34
+ function main(argv, stdin, out, errOut, exit) {
35
+ if (argv.length > 0) {
36
+ exit(run(argv.join(' '), out, errOut));
37
+ return;
38
+ }
39
+ const chunks = [];
40
+ stdin.on('data', (c) => chunks.push(Buffer.from(c)));
41
+ stdin.on('end', () => exit(run(Buffer.concat(chunks).toString('utf8'), out, errOut)));
42
+ }
43
+ //# sourceMappingURL=json-cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json-cli.js","sourceRoot":"","sources":["../src/json-cli.ts"],"names":[],"mappings":";AAAA,4CAA4C;;AAiB5C,kBAeC;AAID,oBAcC;AAhDD;;;;;;;;;GASG;AAEH,iCAA2C;AAE3C,uEAAuE;AACvE,2EAA2E;AAC3E,SAAgB,GAAG,CACjB,GAAW,EACX,GAAwB,EACxB,MAA2B;IAE3B,IAAI,CAAC;QACH,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAA,YAAK,EAAC,GAAG,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAA;QAC/C,OAAO,CAAC,CAAA;IACV,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,kBAAW,EAAE,CAAC;YAC/B,MAAM,CAAC,GAAG,CAAC,OAAO,GAAG,IAAI,CAAC,CAAA;YAC1B,OAAO,CAAC,CAAA;QACV,CAAC;QACD,MAAM,GAAG,CAAA;IACX,CAAC;AACH,CAAC;AAED,wEAAwE;AACxE,qEAAqE;AACrE,SAAgB,IAAI,CAClB,IAAc,EACd,KAA4B,EAC5B,GAAwB,EACxB,MAA2B,EAC3B,IAA4B;IAE5B,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC,CAAA;QACtC,OAAM;IACR,CAAC;IACD,MAAM,MAAM,GAAa,EAAE,CAAA;IAC3B,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IAC5D,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,CAAA;AACvF,CAAC"}
package/dist/json.d.ts ADDED
@@ -0,0 +1,9 @@
1
+ import { Tabnas, TabnasError, type Plugin } from '@tabnas/parser';
2
+ export declare const Version = "1.0.0";
3
+ export declare function registerJsonGrammar(tn: Tabnas): void;
4
+ export declare const json: Plugin;
5
+ export declare function make(opts?: Record<string, any>): Tabnas;
6
+ export declare function parse(src: string): any;
7
+ export { Tabnas, TabnasError };
8
+ export { TabnasError as JsonError };
9
+ export default parse;
package/dist/json.js ADDED
@@ -0,0 +1,210 @@
1
+ "use strict";
2
+ /* Copyright (c) 2026 tabnas, MIT License */
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.JsonError = exports.TabnasError = exports.Tabnas = exports.json = exports.Version = void 0;
5
+ exports.registerJsonGrammar = registerJsonGrammar;
6
+ exports.make = make;
7
+ exports.parse = parse;
8
+ /* json.ts
9
+ *
10
+ * A standard JSON grammar plugin for the `tabnas` parsing engine.
11
+ *
12
+ * The engine ships no grammar of its own; this package supplies the
13
+ * strict, standard-JSON one. The rule set (val / map / list / pair /
14
+ * elem) is the "Plain JSON" grammar from jsonic's `grammar.ts` — the
15
+ * pure-JSON core jsonic defines before extending it for the relaxed
16
+ * jsonic format. Here that core is installed on its own, with the lexer
17
+ * restricted to strict JSON, and none of jsonic's extended grammar
18
+ * (comments, unquoted keys, implicit objects/arrays, trailing commas,
19
+ * single/backtick strings, path diving).
20
+ *
21
+ * This plugin is intended to be the foundation other tabnas grammar
22
+ * plugins build on: `use` it first, then layer additional rules on the
23
+ * shared val / map / list / pair / elem rules.
24
+ */
25
+ const parser_1 = require("@tabnas/parser");
26
+ Object.defineProperty(exports, "Tabnas", { enumerable: true, get: function () { return parser_1.Tabnas; } });
27
+ Object.defineProperty(exports, "TabnasError", { enumerable: true, get: function () { return parser_1.TabnasError; } });
28
+ Object.defineProperty(exports, "JsonError", { enumerable: true, get: function () { return parser_1.TabnasError; } });
29
+ // Current package version.
30
+ exports.Version = '1.0.0';
31
+ // JSON-only lexer/parser options. Restrictive enough to mirror
32
+ // JSON.parse: double-quoted strings only, plain decimal numbers, quoted
33
+ // keys only, no comments, no trailing-comma map extension, no empty
34
+ // input, and the rule set restricted to the `json`-tagged alternates.
35
+ const JSON_OPTIONS = {
36
+ text: { lex: false },
37
+ number: {
38
+ hex: false,
39
+ oct: false,
40
+ bin: false,
41
+ sep: null,
42
+ // Reject any token the (lenient) number matcher accepts that is not a
43
+ // strict JSON number: leading `+`, a bare leading `.` (`.5`), a
44
+ // trailing `.` (`1.`), and leading zeros (`01`, `00`). The negative
45
+ // lookahead matches — and so excludes — anything not of the form
46
+ // -?(0|[1-9][0-9]*)(.[0-9]+)?([eE][+-]?[0-9]+)?.
47
+ exclude: /^(?!-?(?:0|[1-9][0-9]*)(?:\.[0-9]+)?(?:[eE][+-]?[0-9]+)?$)/,
48
+ },
49
+ string: {
50
+ chars: '"',
51
+ multiChars: '',
52
+ // Standard JSON escape handling: allowUnknown:false rejects any
53
+ // unrecognized escape (\q, \z); escapeStrict disables the engine's
54
+ // non-standard \xHH and \u{...} structural escapes (plain \uXXXX
55
+ // stays); and dropping v / ' / ` from the escape map removes the
56
+ // remaining non-standard built-ins. Result: exactly the JSON.parse
57
+ // escape set, identical to the Go engine.
58
+ allowUnknown: false,
59
+ escapeStrict: true,
60
+ escape: { v: '', "'": '', '`': '' },
61
+ },
62
+ comment: { lex: false },
63
+ map: { extend: false },
64
+ lex: { empty: false },
65
+ rule: { finish: false, include: 'json' },
66
+ result: { fail: [undefined, NaN] },
67
+ tokenSet: { KEY: ['#ST', null, null, null] },
68
+ };
69
+ // Install the pure JSON rule set (val / map / list / pair / elem) on the
70
+ // given engine instance. Exposed separately from the options so other
71
+ // grammar plugins can layer their extensions on top without re-declaring
72
+ // the JSON core. This is jsonic's "Plain JSON" grammar.
73
+ function registerJsonGrammar(tn) {
74
+ tn.grammar({
75
+ // The schema version of the native-value builtins this grammar binds
76
+ // to (object/array/reset/key/setval/push/value).
77
+ v: 2,
78
+ // The value tree is built ENTIRELY by the engine's native-value
79
+ // `$`-builtins — referenced by name on the alts below; the engine
80
+ // merges them in at load. There are NO grammar-local closures: the
81
+ // builders are info-aware, so when info.map/list/text is enabled they
82
+ // attach the introspection marker themselves (the json plugin used to
83
+ // hand-write that as @jsonMapMark/@jsonListMark/@jsonText/@jsonSetval).
84
+ // Strict JSON containers are always explicit, so @object$/@array$ take
85
+ // the default implicit:false (no `k` config needed).
86
+ //
87
+ // The builtin actions used below, one line each:
88
+ // @reset$ — clear the parent-seeded node (so a value doesn't inherit
89
+ // the parent container).
90
+ // @object$ — allocate an empty object into the node (a MapRef under
91
+ // info.map).
92
+ // @array$ — allocate an empty array into the node (a ListRef under
93
+ // info.list).
94
+ // @key$ — capture the matched key token into a scratch slot for the
95
+ // pending @setval$.
96
+ // @setval$ — assign the just-built child value into the object under
97
+ // the captured key.
98
+ // @push$ — append the just-built child value to the array.
99
+ // @value$ — resolve the rule's value: a built child wins, else the
100
+ // scalar token (boxed with quote info under info.text).
101
+ rule: {
102
+ val: {
103
+ // Opening token alternates. @reset$ clears the parent-seeded node
104
+ // so a scalar doesn't inherit the parent container.
105
+ open: [
106
+ // A map: `{ ...`
107
+ { s: '#OB', p: 'map', b: 1, a: '@reset$', g: 'map,json' },
108
+ // A list: `[ ...`
109
+ { s: '#OS', p: 'list', b: 1, a: '@reset$', g: 'list,json' },
110
+ // A plain value: `"x"` `1` `true` ....
111
+ { s: '#VAL', a: '@reset$', g: 'val,json' },
112
+ ],
113
+ // Closing alternates. @value$ coalesces (child wins, else the
114
+ // scalar token) and, under info.text, boxes a string with its quote.
115
+ close: [
116
+ // End of input.
117
+ { s: '#ZZ', a: '@value$', g: 'end,json' },
118
+ // There's more JSON.
119
+ { b: 1, a: '@value$', g: 'more,json' },
120
+ ],
121
+ },
122
+ map: {
123
+ open: [
124
+ // An empty map: {}.
125
+ { s: '#OB #CB', b: 1, n: { pk: 0 }, a: '@object$', g: 'map,json' },
126
+ // Start matching map key-value pairs.
127
+ // Reset counter n.pk as new map (for extensions).
128
+ { s: '#OB', p: 'pair', n: { pk: 0 }, a: '@object$', g: 'map,json,pair' },
129
+ ],
130
+ close: [
131
+ // End of map.
132
+ { s: '#CB', g: 'end,json' },
133
+ ],
134
+ },
135
+ list: {
136
+ open: [
137
+ // An empty list: [].
138
+ { s: '#OS #CS', b: 1, a: '@array$', g: 'list,json' },
139
+ // Start matching list elements.
140
+ { s: '#OS', p: 'elem', a: '@array$', g: 'list,elem,json' },
141
+ ],
142
+ close: [
143
+ // End of list.
144
+ { s: '#CS', g: 'end,json' },
145
+ ],
146
+ },
147
+ // sets key:val on node
148
+ pair: {
149
+ open: [
150
+ // Match key-colon start of pair. @key$ captures the key.
151
+ {
152
+ s: '#KEY #CL',
153
+ p: 'val',
154
+ u: { pair: true },
155
+ a: '@key$',
156
+ g: 'map,pair,key,json',
157
+ },
158
+ ],
159
+ close: [
160
+ // Comma means a new pair at same pair-key level. @setval$
161
+ // assigns the pair; on every close alt (fan-out).
162
+ { s: '#CA', r: 'pair', a: '@setval$', g: 'map,pair,json' },
163
+ // End of map.
164
+ { s: '#CB', b: 1, a: '@setval$', g: 'map,pair,json' },
165
+ ],
166
+ },
167
+ // push onto node
168
+ elem: {
169
+ open: [
170
+ // List elements are values.
171
+ { p: 'val', g: 'list,elem,val,json' },
172
+ ],
173
+ close: [
174
+ // Next element. @push$ appends the element.
175
+ { s: '#CA', r: 'elem', a: '@push$', g: 'list,elem,json' },
176
+ // End of list.
177
+ { s: '#CS', b: 1, a: '@push$', g: 'list,elem,json' },
178
+ ],
179
+ },
180
+ },
181
+ });
182
+ }
183
+ // The standard plugin form: apply the strict JSON options, then register
184
+ // the JSON grammar. `use` this on a bare engine, or pass it to `make`.
185
+ const json = function json(tn, _options) {
186
+ tn.options(JSON_OPTIONS);
187
+ registerJsonGrammar(tn);
188
+ };
189
+ exports.json = json;
190
+ // Create a standard-JSON parser instance: a tabnas engine with the json
191
+ // plugin installed. Extra options (e.g. info.map/list/text) are applied
192
+ // after the grammar exists, mirroring the Go `Make`.
193
+ function make(opts) {
194
+ const tn = new parser_1.Tabnas({ plugins: [exports.json] });
195
+ if (opts) {
196
+ tn.options(opts);
197
+ }
198
+ return tn;
199
+ }
200
+ // A lazily-created default instance reused by `parse`, so repeated calls
201
+ // don't rebuild the engine and grammar each time. Parsing creates a fresh
202
+ // context per call, so reuse is safe.
203
+ let defaultParser;
204
+ // Parse a JSON source string with a default standard-JSON parser and
205
+ // return the resulting value. Throws a TabnasError on invalid input.
206
+ function parse(src) {
207
+ return (defaultParser ??= make()).parse(src);
208
+ }
209
+ exports.default = parse;
210
+ //# sourceMappingURL=json.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json.js","sourceRoot":"","sources":["../src/json.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ {"root":["../src/json-cli.ts","../src/json.ts"],"version":"5.9.3"}
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "@tabnas/json",
3
+ "version": "0.2.0",
4
+ "main": "dist/json.js",
5
+ "type": "commonjs",
6
+ "types": "dist/json.d.ts",
7
+ "description": "A standard JSON parser (RFC 8259).",
8
+ "keywords": [
9
+ "json",
10
+ "parser",
11
+ "rfc8259",
12
+ "ecma-404"
13
+ ],
14
+ "author": "tabnas",
15
+ "license": "MIT",
16
+ "engines": {
17
+ "node": ">=24"
18
+ },
19
+ "scripts": {
20
+ "build": "tsc --build src",
21
+ "watch": "tsc --build src -w",
22
+ "clean": "rm -rf node_modules dist package-lock.json",
23
+ "test": "npm run build && node --enable-source-maps --test test/**/*.test.js",
24
+ "coverage": "npm run build && node --test --experimental-test-coverage --test-coverage-include=dist/json.js --test-coverage-include=dist/json-cli.js --test-coverage-lines=0.95 test/**/*.test.js"
25
+ },
26
+ "files": [
27
+ "dist",
28
+ "bin",
29
+ "LICENSE"
30
+ ],
31
+ "bin": {
32
+ "tabnas-json": "bin/json"
33
+ },
34
+ "exports": {
35
+ ".": "./dist/json.js"
36
+ },
37
+ "devDependencies": {
38
+ "@tabnas/debug": "file:../../debug/ts",
39
+ "@tabnas/parser": "file:../../parser/ts",
40
+ "@tabnas/railroad": "file:../../railroad/ts",
41
+ "@types/node": "20.x",
42
+ "typescript": "5.x"
43
+ },
44
+ "peerDependencies": {
45
+ "@tabnas/parser": "^0.2.0"
46
+ }
47
+ }