first commit
This commit is contained in:
+294
@@ -0,0 +1,294 @@
|
||||
# Momoa JSON
|
||||
|
||||
by [Nicholas C. Zakas](https://humanwhocodes.com)
|
||||
|
||||
If you find this useful, please consider supporting my work with a [donation](https://humanwhocodes.com/donate).
|
||||
|
||||
## About
|
||||
|
||||
Momoa is a general purpose JSON utility toolkit, containing:
|
||||
|
||||
* A **tokenizer** that allows you to separate a JSON string into its component parts.
|
||||
* A ECMA-404 compliant **parser** that produces an abstract syntax tree (AST) representing everything inside of a JSON string.
|
||||
* A **traverser** that visits an AST produced by the parser in order.
|
||||
* A **printer** that can convert an AST produced by the parser back into a valid JSON string.
|
||||
|
||||
## Background
|
||||
|
||||
JavaScript defines the `JSON` object with methods for both parsing strings into objects and converting objects into JSON-formatted strings. In most cases, this is exactly what you need and should use without question. However, these methods aren't useful for more fine-grained analysis of JSON structures. For instance, you'll never know if a JSON object contains two properties with the same names because `JSON.parse()` will ignore the first one and return the value of the second. A tool like Momoa comes in handy when you want to know not just the result of JSON parsing, but exactly what is contained in the original JSON string.
|
||||
|
||||
## Usage
|
||||
|
||||
### Node.js
|
||||
|
||||
Install using [npm][npm] or [yarn][yarn]:
|
||||
|
||||
```
|
||||
npm install @humanwhocodes/momoa
|
||||
|
||||
# or
|
||||
|
||||
yarn add @humanwhocodes/momoa
|
||||
```
|
||||
|
||||
Import into your Node.js project:
|
||||
|
||||
```js
|
||||
// CommonJS
|
||||
const { parse } = require("@humanwhocodes/momoa");
|
||||
|
||||
// ESM
|
||||
import { parse } from "@humanwhocodes/momoa";
|
||||
```
|
||||
|
||||
### Deno
|
||||
|
||||
Import into your Deno project:
|
||||
|
||||
```js
|
||||
import { parse } from "https://cdn.skypack.dev/@humanwhocodes/momoa?dts";
|
||||
```
|
||||
|
||||
### Bun
|
||||
|
||||
Install using this command:
|
||||
|
||||
```
|
||||
bun add @humanwhocodes/momoa
|
||||
```
|
||||
|
||||
Import into your Bun project:
|
||||
|
||||
```js
|
||||
import { parse } from "@humanwhocodes/momoa";
|
||||
```
|
||||
|
||||
### Browser
|
||||
|
||||
It's recommended to import the minified version to save bandwidth:
|
||||
|
||||
```js
|
||||
import { parse } from "https://cdn.skypack.dev/@humanwhocodes/momoa?min";
|
||||
```
|
||||
|
||||
However, you can also import the unminified version for debugging purposes:
|
||||
|
||||
```js
|
||||
import { parse } from "https://cdn.skypack.dev/@humanwhocodes/momoa";
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
### Parsing
|
||||
|
||||
To parse a JSON string into an AST, use the `parse()` function:
|
||||
|
||||
```js
|
||||
const { parse } = require("@humanwhocodes/momoa");
|
||||
|
||||
const ast = parse(some_json_string);
|
||||
```
|
||||
|
||||
The `parse()` function accepts a second argument, which is an options object that may contain one or more of the following properties:
|
||||
|
||||
* `mode` (default: `"json"`) - specify the parsing mode. Possible options are `"json"`, `"jsonc"` (JSON with comments), and `"json5"`.
|
||||
* `ranges` (default: `false`) - set to `true` if you want each node to also have a `range` property, which is an array containing the start and stop index for the syntax within the source string.
|
||||
* `tokens` - set to `true` to return a `tokens` property on the root node containing all of the tokens used to parse the code. If `mode` is `"jsonc"` or `"json5"`, then the tokens include comment tokens.
|
||||
* `allowTrailingCommas` - set to `true` to allow trailing commas in arrays and objects in `"json"` and `"jsonc"` modes. This option is ignored in JSON5 mode.
|
||||
|
||||
Here's an example of passing options:
|
||||
|
||||
```js
|
||||
const { parse } = require("@humanwhocodes/momoa");
|
||||
|
||||
const ast = parse(some_json_string, {
|
||||
mode: "jsonc",
|
||||
ranges: true,
|
||||
tokens: true
|
||||
});
|
||||
|
||||
// root now has a range array
|
||||
console.dir(ast.range);
|
||||
|
||||
// root now has a tokens array
|
||||
console.dir(ast.tokens);
|
||||
```
|
||||
|
||||
### Tokenizing
|
||||
|
||||
To produce JSON tokens from a string, use the `tokenize()` function:
|
||||
|
||||
```js
|
||||
const { tokenize } = require("@humanwhocodes/momoa");
|
||||
const json = "{\"foo\":\"bar\"}";
|
||||
|
||||
for (const token of tokenize(json)) {
|
||||
console.log("Token type is", token.type);
|
||||
|
||||
const start = token.loc.start.offset;
|
||||
const end = token.loc.end.offset;
|
||||
console.log("Token value is", json.slice(start, end));
|
||||
}
|
||||
```
|
||||
|
||||
The `tokenize()` function accepts a second parameter, which is an options object that may contain one or more of the following properties:
|
||||
|
||||
* `mode` (default: `"json"`) - specify the parsing mode. Possible options are `"json"`, `"jsonc"` (JSON with comments), and `"json5"`.
|
||||
* `ranges` (default: `false`) - set to `true` if you want each token to also have a `range` property, which is an array containing the start and stop index for the syntax within the source string.
|
||||
|
||||
### Traversing
|
||||
|
||||
There are two ways to traverse an AST: iteration and traditional traversal.
|
||||
|
||||
#### Iterating
|
||||
|
||||
Iteration uses a generator function to create an iterator over the AST:
|
||||
|
||||
```js
|
||||
const { parse, iterator } = require("@humanwhocodes/momoa");
|
||||
|
||||
const ast = parse(some_json_string);
|
||||
|
||||
for (const { node, parent, phase } of iterator(ast)) {
|
||||
console.log(node.type);
|
||||
console.log(phase); // "enter" or "exit"
|
||||
}
|
||||
```
|
||||
|
||||
Each step of the iterator returns an object with three properties:
|
||||
|
||||
1. `node` - the node that the traversal is currently visiting
|
||||
1. `parent` - the parent node of `node`
|
||||
1. `phase` - a string indicating the phase of traversal (`"enter"` when first visiting the node, `"exit"` when leaving the node)
|
||||
|
||||
You can also filter the iterator by passing in a filter function. For instance, if you only want steps to be returned in the `"enter"` phase, you can do this:
|
||||
|
||||
```js
|
||||
const { parse, iterator } = require("@humanwhocodes/momoa");
|
||||
|
||||
const ast = parse(some_json_string);
|
||||
|
||||
for (const { node } of iterator(ast, ({ phase }) => phase === "enter")) {
|
||||
console.log(node.type);
|
||||
}
|
||||
```
|
||||
|
||||
#### Traversing
|
||||
|
||||
Traversing uses a function that accepts an object with `enter` and `exit` properties:
|
||||
|
||||
```js
|
||||
const { parse, traverse } = require("@humanwhocodes/momoa");
|
||||
|
||||
const ast = parse(some_json_string);
|
||||
|
||||
traverse(ast, {
|
||||
enter(node, parent) {
|
||||
console.log("Entering", node.type);
|
||||
},
|
||||
exit(node, parent) {
|
||||
console.log("Exiting", node.type);
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
## Evaluating
|
||||
|
||||
To convert an AST into the JavaScript value it represents, use the `evaluate()` function:
|
||||
|
||||
```js
|
||||
const { parse, evaluate } = require("@humanwhocodes/momoa");
|
||||
|
||||
// same as JSON.parse(some_json_string)
|
||||
const ast = parse(some_json_string);
|
||||
const value = evaluate(ast);
|
||||
```
|
||||
|
||||
In this example, `value` is the same result you would get from calling `JSON.parse(some_json_string)` (`ast` is the intermediate format representing the syntax).
|
||||
|
||||
### Printing
|
||||
|
||||
To convert an AST back into a JSON string, use the `print()` function:
|
||||
|
||||
```js
|
||||
const { parse, print } = require("@humanwhocodes/momoa");
|
||||
|
||||
const ast = parse(some_json_string);
|
||||
const text = print(ast);
|
||||
```
|
||||
|
||||
**Note:** The printed AST will not produce the same result as the original JSON text as the AST does not preserve whitespace.
|
||||
|
||||
You can modify the output of the `print()` function by passing in an object with an `indent` option specifying the number of spaces to use for indentation. When the `indent` option is passed, the text produced will automatically have newlines insert after each `{`, `}`, `[`, `]`, and `,` characters.
|
||||
|
||||
```js
|
||||
const { parse, print } = require("@humanwhocodes/momoa");
|
||||
|
||||
const ast = parse(some_json_string);
|
||||
const text = print(ast, { indent: 4 });
|
||||
```
|
||||
|
||||
### Visitor Keys
|
||||
|
||||
Momoa also exports a map of traversable properties in AST nodes that is helpful if you'd like to traverse an AST manually. This is a map where the keys are the `type` property of each AST node and the values are an array of property names to traverse.
|
||||
|
||||
```js
|
||||
const { visitorKeys } = require("@humanwhocodes/momoa");
|
||||
|
||||
console.log(visitorKeys.get("Document")); // "body"
|
||||
```
|
||||
|
||||
## Development
|
||||
|
||||
To work on Momoa, you'll need:
|
||||
|
||||
* [Git](https://git-scm.com/)
|
||||
* [Node.js](https://nodejs.org)
|
||||
|
||||
Make sure both are installed by visiting the links and following the instructions to install.
|
||||
|
||||
Now you're ready to clone the repository:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/humanwhocodes/momoa.git
|
||||
```
|
||||
|
||||
Then, enter the directory and install the dependencies:
|
||||
|
||||
```bash
|
||||
cd momoa/js
|
||||
npm install
|
||||
```
|
||||
|
||||
After that, you can run the tests via:
|
||||
|
||||
```bash
|
||||
npm test
|
||||
```
|
||||
|
||||
**Note:** Momoa builds itself into a single file for deployment. The `npm test` command automatically rebuilds Momoa into that single file whenever it is run. If you are testing in a different way, then you may need to manually rebuild using the `npm run build` command.
|
||||
|
||||
## Acknowledgements
|
||||
|
||||
This project takes inspiration (but not code) from a number of other projects:
|
||||
|
||||
* [`Esprima`](https://esprima.org) inspired the package interface and AST format.
|
||||
* [`json-to-ast`](https://github.com/vtrushin/json-to-ast) inspired the AST format.
|
||||
* [`parseJson.js`](https://gist.github.com/rgrove/5cc64db4b9ae8c946401b230ba9d2451) inspired me by showing writing a parser isn't all that hard.
|
||||
|
||||
## License
|
||||
|
||||
Apache 2.0
|
||||
|
||||
## Frequently Asked Questions
|
||||
|
||||
### What does "Momoa" even mean?
|
||||
|
||||
Momoa is the last name of American actor [Jason Momoa](https://en.wikipedia.org/wiki/Jason_Momoa). Because "JSON" is pronounced "Jason", I wanted a name that played off of this fact. The most obvious choice would have been something related to [Jason and the Argonauts](https://en.wikipedia.org/wiki/Jason_and_the_Argonauts_(1963_film)), as this movie is referenced in the [JSON specification](https://ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf) directly. However, both "Argo" and "Argonaut" were already used for open source projects. When I did a search for "Jason" online, Jason Momoa was the first result that came up. He always plays badass characters so it seemed to fit.
|
||||
|
||||
### Why support comments in JSON?
|
||||
|
||||
There are a number of programs that allow C-style comments in JSON files, most notably, configuration files for [Visual Studio Code](https://code.visualstudio.com). As there seems to be a need for this functionality, I decided to add it out-of-the-box.
|
||||
|
||||
[npm]: https://npmjs.com/
|
||||
[yarn]: https://yarnpkg.com/
|
||||
+2674
File diff suppressed because one or more lines are too long
+202
@@ -0,0 +1,202 @@
|
||||
export type FilterPredicate = (item: {
|
||||
node: Node;
|
||||
parent?: Node;
|
||||
phase: TraversalPhase;
|
||||
}, index: number, array: Array<{
|
||||
node: Node;
|
||||
parent?: Node;
|
||||
phase: TraversalPhase;
|
||||
}>) => boolean;
|
||||
export type AnyNode = import("./typedefs.cjs").AnyNode;
|
||||
export type JSONValue = import("./typedefs.cjs").JSONValue;
|
||||
export type TokenType = import("./typedefs.cjs").TokenType;
|
||||
export type Location = import("./typedefs.cjs").Location;
|
||||
export type Token = import("./typedefs.cjs").Token;
|
||||
export type Range = import("./typedefs.cjs").Range;
|
||||
export type TokenizeOptions = import("./typedefs.cjs").TokenizeOptions;
|
||||
export type LocationRange = import("./typedefs.cjs").LocationRange;
|
||||
export type NodeParts = import("./typedefs.cjs").NodeParts;
|
||||
export type DocumentNode = import("./typedefs.cjs").DocumentNode;
|
||||
export type StringNode = import("./typedefs.cjs").StringNode;
|
||||
export type NumberNode = import("./typedefs.cjs").NumberNode;
|
||||
export type BooleanNode = import("./typedefs.cjs").BooleanNode;
|
||||
export type MemberNode = import("./typedefs.cjs").MemberNode;
|
||||
export type ObjectNode = import("./typedefs.cjs").ObjectNode;
|
||||
export type ElementNode = import("./typedefs.cjs").ElementNode;
|
||||
export type ArrayNode = import("./typedefs.cjs").ArrayNode;
|
||||
export type NullNode = import("./typedefs.cjs").NullNode;
|
||||
export type ValueNode = import("./typedefs.cjs").ValueNode;
|
||||
export type IdentifierNode = import("./typedefs.cjs").IdentifierNode;
|
||||
export type NaNNode = import("./typedefs.cjs").NaNNode;
|
||||
export type InfinityNode = import("./typedefs.cjs").InfinityNode;
|
||||
export type Sign = import("./typedefs.cjs").Sign;
|
||||
export type Node = import("./typedefs.cjs").Node;
|
||||
export type Mode = import("./typedefs.cjs").Mode;
|
||||
export type ParseOptions = import("./typedefs.cjs").ParseOptions;
|
||||
export type TraversalPhase = import("./typedefs.cjs").TraversalPhase;
|
||||
export type TraversalVisitor = {
|
||||
enter?: (node: Node, parent?: Node) => void;
|
||||
exit?: (node: Node, parent?: Node) => void;
|
||||
};
|
||||
/**
|
||||
* @fileoverview Evaluator for Momoa AST.
|
||||
* @author Nicholas C. Zakas
|
||||
*/
|
||||
/** @typedef {import("./typedefs.cjs").AnyNode} AnyNode */
|
||||
/** @typedef {import("./typedefs.cjs").JSONValue} JSONValue */
|
||||
/**
|
||||
* Evaluates a Momoa AST node into a JavaScript value.
|
||||
* @param {AnyNode} node The node to interpet.
|
||||
* @returns {JSONValue} The JavaScript value for the node.
|
||||
*/
|
||||
export function evaluate(node: AnyNode): JSONValue;
|
||||
/**
|
||||
* @callback FilterPredicate
|
||||
* @param {{node: Node, parent?: Node, phase: TraversalPhase}} item
|
||||
* @param {number} index
|
||||
* @param {Array<{node: Node, parent?: Node, phase: TraversalPhase}>} array
|
||||
* @returns {boolean}
|
||||
*/
|
||||
/**
|
||||
* Creates an iterator over the given AST.
|
||||
* @param {Node} root The root AST node to traverse.
|
||||
* @param {FilterPredicate} [filter] A filter function to determine which steps to
|
||||
* return;
|
||||
* @returns {IterableIterator<{node: Node, parent?: Node, phase: TraversalPhase}>} An iterator over the AST.
|
||||
*/
|
||||
export function iterator(root: Node, filter?: FilterPredicate): IterableIterator<{
|
||||
node: Node;
|
||||
parent?: Node;
|
||||
phase: TraversalPhase;
|
||||
}>;
|
||||
/**
|
||||
*
|
||||
* @param {string} text The text to parse.
|
||||
* @param {ParseOptions} [options] The options object.
|
||||
* @returns {DocumentNode} The AST representing the parsed JSON.
|
||||
* @throws {Error} When there is a parsing error.
|
||||
*/
|
||||
export function parse(text: string, options?: ParseOptions): DocumentNode;
|
||||
/**
|
||||
* Converts a Momoa AST back into a JSON string.
|
||||
* @param {AnyNode} node The node to print.
|
||||
* @param {Object} options Options for the print.
|
||||
* @param {number} [options.indent=0] The number of spaces to indent each line. If
|
||||
* greater than 0, then newlines and indents will be added to output.
|
||||
* @returns {string} The JSON representation of the AST.
|
||||
*/
|
||||
export function print(node: AnyNode, { indent }?: {
|
||||
indent?: number;
|
||||
}): string;
|
||||
/**
|
||||
* Creates an iterator over the tokens representing the source text.
|
||||
* @param {string} text The source text to tokenize.
|
||||
* @param {TokenizeOptions} [options] Options for doing the tokenization.
|
||||
* @returns {Array<Token>} An iterator over the tokens.
|
||||
*/
|
||||
export function tokenize(text: string, options?: TokenizeOptions): Array<Token>;
|
||||
/**
|
||||
* Traverses an AST from the given node.
|
||||
* @param {Node} root The node to traverse from
|
||||
* @param {TraversalVisitor} visitor An object with an `enter` and `exit` method.
|
||||
*/
|
||||
export function traverse(root: Node, visitor: TraversalVisitor): void;
|
||||
export namespace types {
|
||||
/**
|
||||
* Creates a document node.
|
||||
* @param {ValueNode} body The body of the document.
|
||||
* @param {NodeParts} parts Additional properties for the node.
|
||||
* @returns {DocumentNode} The document node.
|
||||
*/
|
||||
export function document(body: ValueNode, parts?: NodeParts): DocumentNode;
|
||||
/**
|
||||
* Creates a string node.
|
||||
* @param {string} value The value for the string.
|
||||
* @param {NodeParts} parts Additional properties for the node.
|
||||
* @returns {StringNode} The string node.
|
||||
*/
|
||||
export function string(value: string, parts?: NodeParts): StringNode;
|
||||
/**
|
||||
* Creates a number node.
|
||||
* @param {number} value The value for the number.
|
||||
* @param {NodeParts} parts Additional properties for the node.
|
||||
* @returns {NumberNode} The number node.
|
||||
*/
|
||||
export function number(value: number, parts?: NodeParts): NumberNode;
|
||||
/**
|
||||
* Creates a boolean node.
|
||||
* @param {boolean} value The value for the boolean.
|
||||
* @param {NodeParts} parts Additional properties for the node.
|
||||
* @returns {BooleanNode} The boolean node.
|
||||
*/
|
||||
export function boolean(value: boolean, parts?: NodeParts): BooleanNode;
|
||||
/**
|
||||
* Creates a null node.
|
||||
* @param {NodeParts} parts Additional properties for the node.
|
||||
* @returns {NullNode} The null node.
|
||||
*/
|
||||
function _null(parts?: NodeParts): NullNode;
|
||||
export { _null as null };
|
||||
/**
|
||||
* Creates an array node.
|
||||
* @param {Array<ElementNode>} elements The elements to add.
|
||||
* @param {NodeParts} parts Additional properties for the node.
|
||||
* @returns {ArrayNode} The array node.
|
||||
*/
|
||||
export function array(elements: Array<ElementNode>, parts?: NodeParts): ArrayNode;
|
||||
/**
|
||||
* Creates an element node.
|
||||
* @param {ValueNode} value The value for the element.
|
||||
* @param {NodeParts} parts Additional properties for the node.
|
||||
* @returns {ElementNode} The element node.
|
||||
*/
|
||||
export function element(value: ValueNode, parts?: NodeParts): ElementNode;
|
||||
/**
|
||||
* Creates an object node.
|
||||
* @param {Array<MemberNode>} members The members to add.
|
||||
* @param {NodeParts} parts Additional properties for the node.
|
||||
* @returns {ObjectNode} The object node.
|
||||
*/
|
||||
export function object(members: Array<MemberNode>, parts?: NodeParts): ObjectNode;
|
||||
/**
|
||||
* Creates a member node.
|
||||
* @param {StringNode|IdentifierNode} name The name for the member.
|
||||
* @param {ValueNode} value The value for the member.
|
||||
* @param {NodeParts} parts Additional properties for the node.
|
||||
* @returns {MemberNode} The member node.
|
||||
*/
|
||||
export function member(name: StringNode | IdentifierNode, value: ValueNode, parts?: NodeParts): MemberNode;
|
||||
/**
|
||||
* Creates an identifier node.
|
||||
* @param {string} name The name for the identifier.
|
||||
* @param {NodeParts} parts Additional properties for the node.
|
||||
* @returns {IdentifierNode} The identifier node.
|
||||
*/
|
||||
export function identifier(name: string, parts?: NodeParts): IdentifierNode;
|
||||
/**
|
||||
* Creates a NaN node.
|
||||
* @param {Sign} sign The sign for the Infinity.
|
||||
* @param {NodeParts} parts Additional properties for the node.
|
||||
* @returns {NaNNode} The NaN node.
|
||||
*/
|
||||
export function nan(sign?: Sign, parts?: NodeParts): NaNNode;
|
||||
/**
|
||||
* Creates an Infinity node.
|
||||
* @param {Sign} sign The sign for the Infinity.
|
||||
* @param {NodeParts} parts Additional properties for the node.
|
||||
* @returns {InfinityNode} The Infinity node.
|
||||
*/
|
||||
export function infinity(sign?: Sign, parts?: NodeParts): InfinityNode;
|
||||
}
|
||||
/**
|
||||
* @fileoverview Traversal approaches for Momoa JSON AST.
|
||||
* @author Nicholas C. Zakas
|
||||
*/
|
||||
/** @typedef {import("./typedefs.cjs").TraversalPhase} TraversalPhase */
|
||||
/**
|
||||
* @typedef {Object} TraversalVisitor
|
||||
* @property {(node: Node, parent?: Node) => void} [enter]
|
||||
* @property {(node: Node, parent?: Node) => void} [exit]
|
||||
*/
|
||||
declare const childKeys: Map<string, string[]>;
|
||||
export { childKeys as visitorKeys };
|
||||
+202
@@ -0,0 +1,202 @@
|
||||
export type FilterPredicate = (item: {
|
||||
node: Node;
|
||||
parent?: Node;
|
||||
phase: TraversalPhase;
|
||||
}, index: number, array: Array<{
|
||||
node: Node;
|
||||
parent?: Node;
|
||||
phase: TraversalPhase;
|
||||
}>) => boolean;
|
||||
export type AnyNode = import("./typedefs.js").AnyNode;
|
||||
export type JSONValue = import("./typedefs.js").JSONValue;
|
||||
export type TokenType = import("./typedefs.js").TokenType;
|
||||
export type Location = import("./typedefs.js").Location;
|
||||
export type Token = import("./typedefs.js").Token;
|
||||
export type Range = import("./typedefs.js").Range;
|
||||
export type TokenizeOptions = import("./typedefs.js").TokenizeOptions;
|
||||
export type LocationRange = import("./typedefs.js").LocationRange;
|
||||
export type NodeParts = import("./typedefs.js").NodeParts;
|
||||
export type DocumentNode = import("./typedefs.js").DocumentNode;
|
||||
export type StringNode = import("./typedefs.js").StringNode;
|
||||
export type NumberNode = import("./typedefs.js").NumberNode;
|
||||
export type BooleanNode = import("./typedefs.js").BooleanNode;
|
||||
export type MemberNode = import("./typedefs.js").MemberNode;
|
||||
export type ObjectNode = import("./typedefs.js").ObjectNode;
|
||||
export type ElementNode = import("./typedefs.js").ElementNode;
|
||||
export type ArrayNode = import("./typedefs.js").ArrayNode;
|
||||
export type NullNode = import("./typedefs.js").NullNode;
|
||||
export type ValueNode = import("./typedefs.js").ValueNode;
|
||||
export type IdentifierNode = import("./typedefs.js").IdentifierNode;
|
||||
export type NaNNode = import("./typedefs.js").NaNNode;
|
||||
export type InfinityNode = import("./typedefs.js").InfinityNode;
|
||||
export type Sign = import("./typedefs.js").Sign;
|
||||
export type Node = import("./typedefs.js").Node;
|
||||
export type Mode = import("./typedefs.js").Mode;
|
||||
export type ParseOptions = import("./typedefs.js").ParseOptions;
|
||||
export type TraversalPhase = import("./typedefs.js").TraversalPhase;
|
||||
export type TraversalVisitor = {
|
||||
enter?: (node: Node, parent?: Node) => void;
|
||||
exit?: (node: Node, parent?: Node) => void;
|
||||
};
|
||||
/**
|
||||
* @fileoverview Evaluator for Momoa AST.
|
||||
* @author Nicholas C. Zakas
|
||||
*/
|
||||
/** @typedef {import("./typedefs.js").AnyNode} AnyNode */
|
||||
/** @typedef {import("./typedefs.js").JSONValue} JSONValue */
|
||||
/**
|
||||
* Evaluates a Momoa AST node into a JavaScript value.
|
||||
* @param {AnyNode} node The node to interpet.
|
||||
* @returns {JSONValue} The JavaScript value for the node.
|
||||
*/
|
||||
export function evaluate(node: AnyNode): JSONValue;
|
||||
/**
|
||||
* @callback FilterPredicate
|
||||
* @param {{node: Node, parent?: Node, phase: TraversalPhase}} item
|
||||
* @param {number} index
|
||||
* @param {Array<{node: Node, parent?: Node, phase: TraversalPhase}>} array
|
||||
* @returns {boolean}
|
||||
*/
|
||||
/**
|
||||
* Creates an iterator over the given AST.
|
||||
* @param {Node} root The root AST node to traverse.
|
||||
* @param {FilterPredicate} [filter] A filter function to determine which steps to
|
||||
* return;
|
||||
* @returns {IterableIterator<{node: Node, parent?: Node, phase: TraversalPhase}>} An iterator over the AST.
|
||||
*/
|
||||
export function iterator(root: Node, filter?: FilterPredicate): IterableIterator<{
|
||||
node: Node;
|
||||
parent?: Node;
|
||||
phase: TraversalPhase;
|
||||
}>;
|
||||
/**
|
||||
*
|
||||
* @param {string} text The text to parse.
|
||||
* @param {ParseOptions} [options] The options object.
|
||||
* @returns {DocumentNode} The AST representing the parsed JSON.
|
||||
* @throws {Error} When there is a parsing error.
|
||||
*/
|
||||
export function parse(text: string, options?: ParseOptions): DocumentNode;
|
||||
/**
|
||||
* Converts a Momoa AST back into a JSON string.
|
||||
* @param {AnyNode} node The node to print.
|
||||
* @param {Object} options Options for the print.
|
||||
* @param {number} [options.indent=0] The number of spaces to indent each line. If
|
||||
* greater than 0, then newlines and indents will be added to output.
|
||||
* @returns {string} The JSON representation of the AST.
|
||||
*/
|
||||
export function print(node: AnyNode, { indent }?: {
|
||||
indent?: number;
|
||||
}): string;
|
||||
/**
|
||||
* Creates an iterator over the tokens representing the source text.
|
||||
* @param {string} text The source text to tokenize.
|
||||
* @param {TokenizeOptions} [options] Options for doing the tokenization.
|
||||
* @returns {Array<Token>} An iterator over the tokens.
|
||||
*/
|
||||
export function tokenize(text: string, options?: TokenizeOptions): Array<Token>;
|
||||
/**
|
||||
* Traverses an AST from the given node.
|
||||
* @param {Node} root The node to traverse from
|
||||
* @param {TraversalVisitor} visitor An object with an `enter` and `exit` method.
|
||||
*/
|
||||
export function traverse(root: Node, visitor: TraversalVisitor): void;
|
||||
export namespace types {
|
||||
/**
|
||||
* Creates a document node.
|
||||
* @param {ValueNode} body The body of the document.
|
||||
* @param {NodeParts} parts Additional properties for the node.
|
||||
* @returns {DocumentNode} The document node.
|
||||
*/
|
||||
export function document(body: ValueNode, parts?: NodeParts): DocumentNode;
|
||||
/**
|
||||
* Creates a string node.
|
||||
* @param {string} value The value for the string.
|
||||
* @param {NodeParts} parts Additional properties for the node.
|
||||
* @returns {StringNode} The string node.
|
||||
*/
|
||||
export function string(value: string, parts?: NodeParts): StringNode;
|
||||
/**
|
||||
* Creates a number node.
|
||||
* @param {number} value The value for the number.
|
||||
* @param {NodeParts} parts Additional properties for the node.
|
||||
* @returns {NumberNode} The number node.
|
||||
*/
|
||||
export function number(value: number, parts?: NodeParts): NumberNode;
|
||||
/**
|
||||
* Creates a boolean node.
|
||||
* @param {boolean} value The value for the boolean.
|
||||
* @param {NodeParts} parts Additional properties for the node.
|
||||
* @returns {BooleanNode} The boolean node.
|
||||
*/
|
||||
export function boolean(value: boolean, parts?: NodeParts): BooleanNode;
|
||||
/**
|
||||
* Creates a null node.
|
||||
* @param {NodeParts} parts Additional properties for the node.
|
||||
* @returns {NullNode} The null node.
|
||||
*/
|
||||
function _null(parts?: NodeParts): NullNode;
|
||||
export { _null as null };
|
||||
/**
|
||||
* Creates an array node.
|
||||
* @param {Array<ElementNode>} elements The elements to add.
|
||||
* @param {NodeParts} parts Additional properties for the node.
|
||||
* @returns {ArrayNode} The array node.
|
||||
*/
|
||||
export function array(elements: Array<ElementNode>, parts?: NodeParts): ArrayNode;
|
||||
/**
|
||||
* Creates an element node.
|
||||
* @param {ValueNode} value The value for the element.
|
||||
* @param {NodeParts} parts Additional properties for the node.
|
||||
* @returns {ElementNode} The element node.
|
||||
*/
|
||||
export function element(value: ValueNode, parts?: NodeParts): ElementNode;
|
||||
/**
|
||||
* Creates an object node.
|
||||
* @param {Array<MemberNode>} members The members to add.
|
||||
* @param {NodeParts} parts Additional properties for the node.
|
||||
* @returns {ObjectNode} The object node.
|
||||
*/
|
||||
export function object(members: Array<MemberNode>, parts?: NodeParts): ObjectNode;
|
||||
/**
|
||||
* Creates a member node.
|
||||
* @param {StringNode|IdentifierNode} name The name for the member.
|
||||
* @param {ValueNode} value The value for the member.
|
||||
* @param {NodeParts} parts Additional properties for the node.
|
||||
* @returns {MemberNode} The member node.
|
||||
*/
|
||||
export function member(name: StringNode | IdentifierNode, value: ValueNode, parts?: NodeParts): MemberNode;
|
||||
/**
|
||||
* Creates an identifier node.
|
||||
* @param {string} name The name for the identifier.
|
||||
* @param {NodeParts} parts Additional properties for the node.
|
||||
* @returns {IdentifierNode} The identifier node.
|
||||
*/
|
||||
export function identifier(name: string, parts?: NodeParts): IdentifierNode;
|
||||
/**
|
||||
* Creates a NaN node.
|
||||
* @param {Sign} sign The sign for the Infinity.
|
||||
* @param {NodeParts} parts Additional properties for the node.
|
||||
* @returns {NaNNode} The NaN node.
|
||||
*/
|
||||
export function nan(sign?: Sign, parts?: NodeParts): NaNNode;
|
||||
/**
|
||||
* Creates an Infinity node.
|
||||
* @param {Sign} sign The sign for the Infinity.
|
||||
* @param {NodeParts} parts Additional properties for the node.
|
||||
* @returns {InfinityNode} The Infinity node.
|
||||
*/
|
||||
export function infinity(sign?: Sign, parts?: NodeParts): InfinityNode;
|
||||
}
|
||||
/**
|
||||
* @fileoverview Traversal approaches for Momoa JSON AST.
|
||||
* @author Nicholas C. Zakas
|
||||
*/
|
||||
/** @typedef {import("./typedefs.js").TraversalPhase} TraversalPhase */
|
||||
/**
|
||||
* @typedef {Object} TraversalVisitor
|
||||
* @property {(node: Node, parent?: Node) => void} [enter]
|
||||
* @property {(node: Node, parent?: Node) => void} [exit]
|
||||
*/
|
||||
declare const childKeys: Map<string, string[]>;
|
||||
export { childKeys as visitorKeys };
|
||||
+2619
File diff suppressed because one or more lines are too long
+205
@@ -0,0 +1,205 @@
|
||||
/**
|
||||
* @fileoverview Type definitions for the Momoa JSON parser.
|
||||
* @author Nicholas C. Zakas
|
||||
*/
|
||||
/**
|
||||
* The mode that Momoa runs in:
|
||||
* - "json" for regular JSON
|
||||
* - "jsonc" for JSON with C-style comments
|
||||
*/
|
||||
export type Mode = "json" | "jsonc" | "json5";
|
||||
/**
|
||||
* The phase of the traversal step.
|
||||
*/
|
||||
export type TraversalPhase = "enter" | "exit";
|
||||
/**
|
||||
* The type of a JSON5 Infinity or NaN value.
|
||||
* - "+" for positive Infinity or postive NaN
|
||||
* - "-" for negative Infinity or negative NaN
|
||||
* - "" for Infinity or NaN without a sign
|
||||
*/
|
||||
export type Sign = "+" | "-" | "";
|
||||
/**
|
||||
* Tokenization options.
|
||||
*/
|
||||
export interface TokenizeOptions {
|
||||
/**
|
||||
* The mode to tokenize in.
|
||||
*/
|
||||
readonly mode?: Mode;
|
||||
/**
|
||||
* When true, includes the `range` key on each token.
|
||||
*/
|
||||
readonly ranges?: boolean;
|
||||
}
|
||||
/**
|
||||
* Parse options.
|
||||
*/
|
||||
export interface ParseOptions {
|
||||
/**
|
||||
* The mode to parse in.
|
||||
*/
|
||||
readonly mode?: Mode;
|
||||
/**
|
||||
* When true, includes the `range` key on each node and token.
|
||||
*/
|
||||
readonly ranges?: boolean;
|
||||
/**
|
||||
* When true, includes the `tokens` key on the document node containing
|
||||
* all of the tokens used during parsing.
|
||||
*/
|
||||
readonly tokens?: boolean;
|
||||
/**
|
||||
* When true, allows trailing commas in arrays and objects. Defaults to
|
||||
* false for JSON and JSONC modes, and true for JSON5 mode.
|
||||
*/
|
||||
readonly allowTrailingCommas?: boolean;
|
||||
}
|
||||
export interface Node {
|
||||
type: string;
|
||||
loc: LocationRange;
|
||||
range?: Range;
|
||||
}
|
||||
/**
|
||||
* The root node of a JSON document.
|
||||
*/
|
||||
export interface DocumentNode extends Node {
|
||||
type: "Document";
|
||||
body: ValueNode;
|
||||
tokens?: Array<Token>;
|
||||
}
|
||||
export interface NullNode extends Node {
|
||||
type: "Null";
|
||||
}
|
||||
interface LiteralNode<T> extends Node {
|
||||
value: T;
|
||||
}
|
||||
/**
|
||||
* Represents a JSON5 NaN value.
|
||||
*/
|
||||
export interface NaNNode extends Node {
|
||||
type: "NaN";
|
||||
sign: Sign;
|
||||
}
|
||||
/**
|
||||
* Represents a JSON5 Infinity value.
|
||||
*/
|
||||
export interface InfinityNode extends Node {
|
||||
type: "Infinity";
|
||||
sign: Sign;
|
||||
}
|
||||
/**
|
||||
* Represents a JSON identifier.
|
||||
*/
|
||||
export interface IdentifierNode extends Node {
|
||||
type: "Identifier";
|
||||
name: string;
|
||||
}
|
||||
/**
|
||||
* Represents a JSON string.
|
||||
*/
|
||||
export interface StringNode extends LiteralNode<string> {
|
||||
type: "String";
|
||||
}
|
||||
/**
|
||||
* Represents a JSON number.
|
||||
*/
|
||||
export interface NumberNode extends LiteralNode<number> {
|
||||
type: "Number";
|
||||
}
|
||||
/**
|
||||
* Represents a JSON boolean.
|
||||
*/
|
||||
export interface BooleanNode extends LiteralNode<boolean> {
|
||||
type: "Boolean";
|
||||
}
|
||||
/**
|
||||
* Represents an element of a JSON array.
|
||||
*/
|
||||
export interface ElementNode extends Node {
|
||||
type: "Element";
|
||||
value: ValueNode;
|
||||
}
|
||||
/**
|
||||
* Represents a JSON array.
|
||||
*/
|
||||
export interface ArrayNode extends Node {
|
||||
type: "Array";
|
||||
elements: Array<ElementNode>;
|
||||
}
|
||||
/**
|
||||
* Represents a member of a JSON object.
|
||||
*/
|
||||
export interface MemberNode extends Node {
|
||||
type: "Member";
|
||||
name: StringNode | IdentifierNode;
|
||||
value: ValueNode;
|
||||
}
|
||||
/**
|
||||
* Represents a JSON object.
|
||||
*/
|
||||
export interface ObjectNode extends Node {
|
||||
type: "Object";
|
||||
members: Array<MemberNode>;
|
||||
}
|
||||
/**
|
||||
* Any node that represents a JSON value.
|
||||
*/
|
||||
export type ValueNode = ArrayNode | ObjectNode | BooleanNode | StringNode | NumberNode | NullNode | NaNNode | InfinityNode;
|
||||
/**
|
||||
* Any node that represents the container for a JSON value.
|
||||
*/
|
||||
export type ContainerNode = DocumentNode | MemberNode | ElementNode;
|
||||
/**
|
||||
* Any node that represents a JSON5 extension.
|
||||
*/
|
||||
export type JSON5ExtensionNode = NaNNode | InfinityNode | IdentifierNode;
|
||||
/**
|
||||
* Any valid AST node.
|
||||
*/
|
||||
export type AnyNode = ValueNode | ContainerNode | JSON5ExtensionNode;
|
||||
/**
|
||||
* Additional information about an AST node.
|
||||
*/
|
||||
export interface NodeParts {
|
||||
loc?: LocationRange;
|
||||
range?: Range;
|
||||
}
|
||||
/**
|
||||
* Values that can be represented in JSON.
|
||||
*/
|
||||
export type JSONValue = Array<JSONValue> | boolean | number | string | {
|
||||
[property: string]: JSONValue;
|
||||
} | null;
|
||||
/**
|
||||
* A token used to during JSON parsing.
|
||||
*/
|
||||
export interface Token {
|
||||
type: TokenType;
|
||||
loc: LocationRange;
|
||||
range?: Range;
|
||||
}
|
||||
/**
|
||||
* The type of token.
|
||||
*/
|
||||
export type TokenType = "Number" | "String" | "Boolean" | "Colon" | "LBrace" | "RBrace" | "RBracket" | "LBracket" | "Comma" | "Null" | "LineComment" | "BlockComment" | "NaN" | "Infinity" | "Identifier";
|
||||
/**
|
||||
* The start and stop location for a token or node inside the source text.
|
||||
*/
|
||||
export interface LocationRange {
|
||||
start: Location;
|
||||
end: Location;
|
||||
}
|
||||
/**
|
||||
* A cursor location inside the source text.
|
||||
*/
|
||||
export interface Location {
|
||||
line: number;
|
||||
column: number;
|
||||
offset: number;
|
||||
}
|
||||
/**
|
||||
* The start and stop offset for a given node or token inside the source text.
|
||||
*/
|
||||
export type Range = [number, number];
|
||||
export {};
|
||||
+205
@@ -0,0 +1,205 @@
|
||||
/**
|
||||
* @fileoverview Type definitions for the Momoa JSON parser.
|
||||
* @author Nicholas C. Zakas
|
||||
*/
|
||||
/**
|
||||
* The mode that Momoa runs in:
|
||||
* - "json" for regular JSON
|
||||
* - "jsonc" for JSON with C-style comments
|
||||
*/
|
||||
export type Mode = "json" | "jsonc" | "json5";
|
||||
/**
|
||||
* The phase of the traversal step.
|
||||
*/
|
||||
export type TraversalPhase = "enter" | "exit";
|
||||
/**
|
||||
* The type of a JSON5 Infinity or NaN value.
|
||||
* - "+" for positive Infinity or postive NaN
|
||||
* - "-" for negative Infinity or negative NaN
|
||||
* - "" for Infinity or NaN without a sign
|
||||
*/
|
||||
export type Sign = "+" | "-" | "";
|
||||
/**
|
||||
* Tokenization options.
|
||||
*/
|
||||
export interface TokenizeOptions {
|
||||
/**
|
||||
* The mode to tokenize in.
|
||||
*/
|
||||
readonly mode?: Mode;
|
||||
/**
|
||||
* When true, includes the `range` key on each token.
|
||||
*/
|
||||
readonly ranges?: boolean;
|
||||
}
|
||||
/**
|
||||
* Parse options.
|
||||
*/
|
||||
export interface ParseOptions {
|
||||
/**
|
||||
* The mode to parse in.
|
||||
*/
|
||||
readonly mode?: Mode;
|
||||
/**
|
||||
* When true, includes the `range` key on each node and token.
|
||||
*/
|
||||
readonly ranges?: boolean;
|
||||
/**
|
||||
* When true, includes the `tokens` key on the document node containing
|
||||
* all of the tokens used during parsing.
|
||||
*/
|
||||
readonly tokens?: boolean;
|
||||
/**
|
||||
* When true, allows trailing commas in arrays and objects. Defaults to
|
||||
* false for JSON and JSONC modes, and true for JSON5 mode.
|
||||
*/
|
||||
readonly allowTrailingCommas?: boolean;
|
||||
}
|
||||
export interface Node {
|
||||
type: string;
|
||||
loc: LocationRange;
|
||||
range?: Range;
|
||||
}
|
||||
/**
|
||||
* The root node of a JSON document.
|
||||
*/
|
||||
export interface DocumentNode extends Node {
|
||||
type: "Document";
|
||||
body: ValueNode;
|
||||
tokens?: Array<Token>;
|
||||
}
|
||||
export interface NullNode extends Node {
|
||||
type: "Null";
|
||||
}
|
||||
interface LiteralNode<T> extends Node {
|
||||
value: T;
|
||||
}
|
||||
/**
|
||||
* Represents a JSON5 NaN value.
|
||||
*/
|
||||
export interface NaNNode extends Node {
|
||||
type: "NaN";
|
||||
sign: Sign;
|
||||
}
|
||||
/**
|
||||
* Represents a JSON5 Infinity value.
|
||||
*/
|
||||
export interface InfinityNode extends Node {
|
||||
type: "Infinity";
|
||||
sign: Sign;
|
||||
}
|
||||
/**
|
||||
* Represents a JSON identifier.
|
||||
*/
|
||||
export interface IdentifierNode extends Node {
|
||||
type: "Identifier";
|
||||
name: string;
|
||||
}
|
||||
/**
|
||||
* Represents a JSON string.
|
||||
*/
|
||||
export interface StringNode extends LiteralNode<string> {
|
||||
type: "String";
|
||||
}
|
||||
/**
|
||||
* Represents a JSON number.
|
||||
*/
|
||||
export interface NumberNode extends LiteralNode<number> {
|
||||
type: "Number";
|
||||
}
|
||||
/**
|
||||
* Represents a JSON boolean.
|
||||
*/
|
||||
export interface BooleanNode extends LiteralNode<boolean> {
|
||||
type: "Boolean";
|
||||
}
|
||||
/**
|
||||
* Represents an element of a JSON array.
|
||||
*/
|
||||
export interface ElementNode extends Node {
|
||||
type: "Element";
|
||||
value: ValueNode;
|
||||
}
|
||||
/**
|
||||
* Represents a JSON array.
|
||||
*/
|
||||
export interface ArrayNode extends Node {
|
||||
type: "Array";
|
||||
elements: Array<ElementNode>;
|
||||
}
|
||||
/**
|
||||
* Represents a member of a JSON object.
|
||||
*/
|
||||
export interface MemberNode extends Node {
|
||||
type: "Member";
|
||||
name: StringNode | IdentifierNode;
|
||||
value: ValueNode;
|
||||
}
|
||||
/**
|
||||
* Represents a JSON object.
|
||||
*/
|
||||
export interface ObjectNode extends Node {
|
||||
type: "Object";
|
||||
members: Array<MemberNode>;
|
||||
}
|
||||
/**
|
||||
* Any node that represents a JSON value.
|
||||
*/
|
||||
export type ValueNode = ArrayNode | ObjectNode | BooleanNode | StringNode | NumberNode | NullNode | NaNNode | InfinityNode;
|
||||
/**
|
||||
* Any node that represents the container for a JSON value.
|
||||
*/
|
||||
export type ContainerNode = DocumentNode | MemberNode | ElementNode;
|
||||
/**
|
||||
* Any node that represents a JSON5 extension.
|
||||
*/
|
||||
export type JSON5ExtensionNode = NaNNode | InfinityNode | IdentifierNode;
|
||||
/**
|
||||
* Any valid AST node.
|
||||
*/
|
||||
export type AnyNode = ValueNode | ContainerNode | JSON5ExtensionNode;
|
||||
/**
|
||||
* Additional information about an AST node.
|
||||
*/
|
||||
export interface NodeParts {
|
||||
loc?: LocationRange;
|
||||
range?: Range;
|
||||
}
|
||||
/**
|
||||
* Values that can be represented in JSON.
|
||||
*/
|
||||
export type JSONValue = Array<JSONValue> | boolean | number | string | {
|
||||
[property: string]: JSONValue;
|
||||
} | null;
|
||||
/**
|
||||
* A token used to during JSON parsing.
|
||||
*/
|
||||
export interface Token {
|
||||
type: TokenType;
|
||||
loc: LocationRange;
|
||||
range?: Range;
|
||||
}
|
||||
/**
|
||||
* The type of token.
|
||||
*/
|
||||
export type TokenType = "Number" | "String" | "Boolean" | "Colon" | "LBrace" | "RBrace" | "RBracket" | "LBracket" | "Comma" | "Null" | "LineComment" | "BlockComment" | "NaN" | "Infinity" | "Identifier";
|
||||
/**
|
||||
* The start and stop location for a token or node inside the source text.
|
||||
*/
|
||||
export interface LocationRange {
|
||||
start: Location;
|
||||
end: Location;
|
||||
}
|
||||
/**
|
||||
* A cursor location inside the source text.
|
||||
*/
|
||||
export interface Location {
|
||||
line: number;
|
||||
column: number;
|
||||
offset: number;
|
||||
}
|
||||
/**
|
||||
* The start and stop offset for a given node or token inside the source text.
|
||||
*/
|
||||
export type Range = [number, number];
|
||||
export {};
|
||||
+268
@@ -0,0 +1,268 @@
|
||||
/**
|
||||
* @fileoverview Type definitions for the Momoa JSON parser.
|
||||
* @author Nicholas C. Zakas
|
||||
*/
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Options
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* The mode that Momoa runs in:
|
||||
* - "json" for regular JSON
|
||||
* - "jsonc" for JSON with C-style comments
|
||||
*/
|
||||
export type Mode = "json" | "jsonc" | "json5";
|
||||
|
||||
/**
|
||||
* The phase of the traversal step.
|
||||
*/
|
||||
export type TraversalPhase = "enter" | "exit";
|
||||
|
||||
/**
|
||||
* The type of a JSON5 Infinity or NaN value.
|
||||
* - "+" for positive Infinity or postive NaN
|
||||
* - "-" for negative Infinity or negative NaN
|
||||
* - "" for Infinity or NaN without a sign
|
||||
*/
|
||||
export type Sign = "+" | "-" | "";
|
||||
|
||||
/**
|
||||
* Tokenization options.
|
||||
*/
|
||||
export interface TokenizeOptions {
|
||||
|
||||
/**
|
||||
* The mode to tokenize in.
|
||||
*/
|
||||
readonly mode?: Mode;
|
||||
|
||||
/**
|
||||
* When true, includes the `range` key on each token.
|
||||
*/
|
||||
readonly ranges?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse options.
|
||||
*/
|
||||
export interface ParseOptions {
|
||||
|
||||
/**
|
||||
* The mode to parse in.
|
||||
*/
|
||||
readonly mode?: Mode;
|
||||
|
||||
/**
|
||||
* When true, includes the `range` key on each node and token.
|
||||
*/
|
||||
readonly ranges?: boolean;
|
||||
|
||||
/**
|
||||
* When true, includes the `tokens` key on the document node containing
|
||||
* all of the tokens used during parsing.
|
||||
*/
|
||||
readonly tokens?: boolean;
|
||||
|
||||
/**
|
||||
* When true, allows trailing commas in arrays and objects. Defaults to
|
||||
* false for JSON and JSONC modes, and true for JSON5 mode.
|
||||
*/
|
||||
readonly allowTrailingCommas?: boolean;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Nodes
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
export interface Node {
|
||||
type: string;
|
||||
loc: LocationRange;
|
||||
range?: Range;
|
||||
}
|
||||
|
||||
/**
|
||||
* The root node of a JSON document.
|
||||
*/
|
||||
export interface DocumentNode extends Node {
|
||||
type: "Document";
|
||||
body: ValueNode;
|
||||
tokens?: Array<Token>;
|
||||
}
|
||||
|
||||
export interface NullNode extends Node {
|
||||
type: "Null";
|
||||
}
|
||||
|
||||
interface LiteralNode<T> extends Node {
|
||||
value: T;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a JSON5 NaN value.
|
||||
*/
|
||||
export interface NaNNode extends Node {
|
||||
type: "NaN";
|
||||
sign: Sign;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a JSON5 Infinity value.
|
||||
*/
|
||||
export interface InfinityNode extends Node {
|
||||
type: "Infinity";
|
||||
sign: Sign;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a JSON identifier.
|
||||
*/
|
||||
export interface IdentifierNode extends Node {
|
||||
type: "Identifier";
|
||||
name: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a JSON string.
|
||||
*/
|
||||
export interface StringNode extends LiteralNode<string> {
|
||||
type: "String";
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a JSON number.
|
||||
*/
|
||||
export interface NumberNode extends LiteralNode<number> {
|
||||
type: "Number";
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a JSON boolean.
|
||||
*/
|
||||
export interface BooleanNode extends LiteralNode<boolean> {
|
||||
type: "Boolean";
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents an element of a JSON array.
|
||||
*/
|
||||
export interface ElementNode extends Node {
|
||||
type: "Element";
|
||||
value: ValueNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a JSON array.
|
||||
*/
|
||||
export interface ArrayNode extends Node {
|
||||
type: "Array";
|
||||
elements: Array<ElementNode>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a member of a JSON object.
|
||||
*/
|
||||
export interface MemberNode extends Node {
|
||||
type: "Member";
|
||||
name: StringNode | IdentifierNode;
|
||||
value: ValueNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a JSON object.
|
||||
*/
|
||||
export interface ObjectNode extends Node {
|
||||
type: "Object";
|
||||
members: Array<MemberNode>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Any node that represents a JSON value.
|
||||
*/
|
||||
export type ValueNode = ArrayNode | ObjectNode |
|
||||
BooleanNode | StringNode | NumberNode | NullNode |
|
||||
NaNNode | InfinityNode;
|
||||
|
||||
/**
|
||||
* Any node that represents the container for a JSON value.
|
||||
*/
|
||||
export type ContainerNode = DocumentNode | MemberNode | ElementNode;
|
||||
|
||||
/**
|
||||
* Any node that represents a JSON5 extension.
|
||||
*/
|
||||
export type JSON5ExtensionNode = NaNNode | InfinityNode | IdentifierNode;
|
||||
|
||||
/**
|
||||
* Any valid AST node.
|
||||
*/
|
||||
export type AnyNode = ValueNode | ContainerNode | JSON5ExtensionNode;
|
||||
|
||||
/**
|
||||
* Additional information about an AST node.
|
||||
*/
|
||||
export interface NodeParts {
|
||||
loc?: LocationRange;
|
||||
range?: Range;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Values
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Values that can be represented in JSON.
|
||||
*/
|
||||
export type JSONValue =
|
||||
| Array<JSONValue>
|
||||
| boolean
|
||||
| number
|
||||
| string
|
||||
| { [property: string]: JSONValue }
|
||||
| null;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Tokens
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* A token used to during JSON parsing.
|
||||
*/
|
||||
export interface Token {
|
||||
type: TokenType;
|
||||
loc: LocationRange;
|
||||
range?: Range;
|
||||
}
|
||||
|
||||
/**
|
||||
* The type of token.
|
||||
*/
|
||||
export type TokenType = "Number" | "String" | "Boolean" | "Colon" | "LBrace" |
|
||||
"RBrace" | "RBracket" | "LBracket" | "Comma" | "Null" | "LineComment" |
|
||||
"BlockComment" | "NaN" | "Infinity" | "Identifier";
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Location Related
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* The start and stop location for a token or node inside the source text.
|
||||
*/
|
||||
export interface LocationRange {
|
||||
start: Location;
|
||||
end: Location;
|
||||
}
|
||||
|
||||
/**
|
||||
* A cursor location inside the source text.
|
||||
*/
|
||||
export interface Location {
|
||||
line: number;
|
||||
column: number;
|
||||
offset: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* The start and stop offset for a given node or token inside the source text.
|
||||
*/
|
||||
export type Range = [number, number];
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
{
|
||||
"name": "@humanwhocodes/momoa",
|
||||
"version": "3.3.10",
|
||||
"description": "JSON AST parser, tokenizer, printer, traverser.",
|
||||
"author": "Nicholas C. Zakas",
|
||||
"type": "module",
|
||||
"main": "dist/momoa.cjs",
|
||||
"module": "dist/momoa.js",
|
||||
"types": "dist/momoa.d.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"require": {
|
||||
"types": "./dist/momoa.d.cts",
|
||||
"default": "./dist/momoa.cjs"
|
||||
},
|
||||
"import": {
|
||||
"types": "./dist/momoa.d.ts",
|
||||
"default": "./dist/momoa.js"
|
||||
}
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/humanwhocodes/momoa.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/humanwhocodes/momoa/issues"
|
||||
},
|
||||
"homepage": "https://github.com/humanwhocodes/momoa#readme",
|
||||
"scripts": {
|
||||
"build": "rollup -c && npm run fixup && tsc -p tsconfig.build.json && npm run copy-dts && npm run build-dcts",
|
||||
"copy-dts": "node -e \"fs.copyFileSync('dist/momoa.d.ts', 'dist/momoa.d.cts')\"",
|
||||
"build-dcts": "node tools/update-cts-references.js",
|
||||
"fixup": "node tools/strip-typedef-aliases.js",
|
||||
"lint": "eslint *.js src/*.js tests/*.js",
|
||||
"perf": "npm run build && node tools/perf.js",
|
||||
"regen": "npm run build && node tools/regenerate-test-data.js",
|
||||
"prepare": "npm run build",
|
||||
"pretest": "npm run build",
|
||||
"test": "mocha tests/*.test.js && npm run test:types",
|
||||
"test:types": "tsc --noEmit --project tests/types/tsconfig.json",
|
||||
"test:attw": "attw --pack"
|
||||
},
|
||||
"keywords": [
|
||||
"json",
|
||||
"ast",
|
||||
"json tree",
|
||||
"abstract syntax tree"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@arethetypeswrong/cli": "^0.17.4",
|
||||
"beautify-benchmark": "0.2.4",
|
||||
"benchmark": "2.1.4",
|
||||
"chai": "^4.3.7",
|
||||
"eslint": "8.57.1",
|
||||
"esm": "3.2.25",
|
||||
"json-to-ast": "2.1.0",
|
||||
"json5": "^2.2.3",
|
||||
"mocha": "^11.0.0",
|
||||
"npm-run-all2": "^7.0.0",
|
||||
"rollup": "^4.19.0",
|
||||
"rollup-plugin-copy": "^3.4.0",
|
||||
"rollup-plugin-dts": "^6.1.1",
|
||||
"sinon": "^19.0.0",
|
||||
"typescript": "^5.7.2"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user