import type { Annotate } from "./annotate.d.ts"; import type { SyntaxErrorCause } from "./error.d.ts"; import type { ContextualKeyword, Keyword, StrictKeyword, StrictReadonlyKeyword, } from "./keyword.d.ts"; import type { KindRecord } from "./kind.d.ts"; import type { Node } from "./node.d.ts"; import type { ModuleProgram, Program, ScriptProgram, } from "./node/program.d.ts"; import type { AssignmentOperator, BinaryOperator, LogicalOperator, UnaryOperator, UpdateOperator, } from "./operator.d.ts"; import type { Path, Segment } from "./path.d.ts"; export type * from "./node/call.d.ts"; export type * from "./node/chain.d.ts"; export type * from "./node/class.d.ts"; export type * from "./node/declaration.d.ts"; export type * from "./node/expression.d.ts"; export type * from "./node/function.d.ts"; export type * from "./node/identifier.d.ts"; export type * from "./node/key.d.ts"; export type * from "./node/literal.d.ts"; export type * from "./node/member.d.ts"; export type * from "./node/module.d.ts"; export type * from "./node/object.d.ts"; export type * from "./node/pattern.d.ts"; export type * from "./node/program.d.ts"; export type * from "./node/statement.d.ts"; export type * from "./node/template.d.ts"; export type * from "./util/brand.d.ts"; export type * from "./util/primitive.d.ts"; export type * from "./annotate.d.ts"; export type { SyntaxErrorCause } from "./error.d.ts"; export type * from "./keyword.d.ts"; export type * from "./kind.d.ts"; export type * from "./node.d.ts"; export type * from "./operator.d.ts"; export type * from "./path.d.ts"; /////////// // index // /////////// /** * * Returns a deep annotated copy of the input node with annotations if it is a * valid estree-sentry program. Throws a `EstreeSentrySyntaxError` if the input * node is not a valid estree-sentry program. See `guard` for a failing example. * * @example * ```js * import { ROOT_PATH, annotateProgram } from "estree-sentry"; * // returns: { * // type: "Program", * // sourceType: "script", * // body: [{ * // type: "EmptyStatement", * // path: "$.body.0", * // kind: "Statement", * // }], * // path: "$", * // kind: "Program" * // } * annotateProgram( * { * type: "Program", * sourceType: "script", * body: [ * { * type: "EmptyStatement", * }, * ], * }, * ROOT_PATH, * (_node, path, kind) => ({ path, kind }), * ); * ``` * * @template A * The type of the annotation. * @param root * The input root node. * @param path * The root path to which segments will be appended. * @param annotate * Annotation function that will be called on each visited node. * @returns * A deep copy of the input root node that is a valid estree-sentry program. * @throws * An `EstreeSentrySyntaxError` if the input root node is not a valid * estree-sentry program. * */ export const annotateProgram: ( root: object, path: Path, annotate: Annotate, ) => Program; /** * Same as `annotateProgram` but for module programs. */ export const annotateModuleProgram: ( root: object, path: Path, annotate: Annotate, ) => ModuleProgram; /** * Same as `annotateProgram` but for script programs. */ export const annotateScriptProgram: ( root: object, path: Path, annotate: Annotate, ) => ScriptProgram; /** * * Returns a deep copy of the input node if it is a valid estree-sentry program. * Throws a `EstreeSentrySyntaxError` if the input node is not a valid * estree-sentry program. * * @example * ```js * import { guardProgram } from "estree-sentry"; * // throws: EstreeSentrySyntaxError * // KeyIdentifier.type should be "Identifier" or "PrivateIdentifier" * // got "Literal" * // at $.body.0.expression.property * guardProgram( * { * type: "Program", * sourceType: "script", * body: [ * { * type: "ExpressionStatement", * expression: { * type: "MemberExpression", * computed: false, * object: { * type: "Identifier", * name: "obj", * }, * property: { * type: "Literal", * value: "key", * }, * }, * }, * ], * }, * ); * ``` * * @param root * The input root node. * @returns * A deep copy of the input root node that is a valid estree-sentry program. * @throws * An `EstreeSentrySyntaxError` if the input root node is not a valid * estree-sentry program. */ export const guardProgram: (root: object) => Program<{}>; /** * Same as `guardProgram` but for module programs. */ export const guardModuleProgram: (root: object) => ModuleProgram<{}>; /** * Same as `guardProgram` but for script programs. */ export const guardScriptProgram: (root: object) => ScriptProgram<{}>; ////////////// // children // ////////////// /** * * Lists the children of the given node into a new array. * * @example * ```ts * import {listChildren, VariableName} from "estree-sentry"; * // returns: [ * // { type: "Identifier", name: "x" }, * // { type: "Identifier", name: "y" }, * // ] * listChildren({ * type: "BinaryExpression", * operator: "+", * left: { * type: "Identifier", * name: "x" as VariableName, * }, * right: { * type: "Identifier", * name:"y" as VariableName, * }, * }); * ``` * * @template A * The annotation type. * @param {import("./node").Node} node * The parent node. * @returns {import("./node").Node[]} * The children of the parent node. * */ export const listChildren: (node: Node) => Node[]; /////////// // error // /////////// export class EstreeSentryTypeError extends TypeError { constructor(cause: never); message: string; cause: unknown; } export class EstreeSentrySyntaxError extends SyntaxError { constructor(cause: SyntaxErrorCause); message: string; cause: SyntaxErrorCause; } ///////////// // keyword // ///////////// export const KEYWORD_RECORD: { [key in Keyword]: null; }; export const STRICT_KEYWORD_RECORD: { [key in StrictKeyword]: null; }; export const STRICT_READONLY_KEYWORD_RECORD: { [key in StrictReadonlyKeyword]: null; }; export const CONTEXTUAL_KEYWORD_RECORD: { [key in ContextualKeyword]: null; }; ////////// // kind // ////////// export const KIND_RECORD: { [kind in keyof KindRecord<{}>]: { [type in KindRecord<{}>[kind]["type"]]: null; }; }; ////////////// // operator // ////////////// export const ASSIGNEMENT_OPERATOR_RECORD: { [key in AssignmentOperator]: null; }; export const UNARY_OPERATOR_RECORD: { [key in UnaryOperator]: null; }; export const UPDATE_OPERATOR_RECORD: { [key in UpdateOperator]: null; }; export const BINARY_OPERATOR_RECORD: { [key in BinaryOperator]: null; }; export const LOGICAL_OPERATOR_RECORD: { [key in LogicalOperator]: null; }; ////////// // path // ////////// /** * The default root path. */ export const ROOT_PATH: Path & "$"; /** * The path separator. */ export const PATH_SEPARATOR: "."; /** * * Appends a segment to an existing path. * * @example * ```js * import { ROOT_PATH, joinPath } from "estree-sentry"; * // returns: "$.body" * joinDeepPath(ROOT_PATH, "body"); * ``` * */ export const joinPath: (path: Path, segment: Segment) => Path; /** * * Appends two segments to an existing path. * * @example * ```js * import { ROOT_PATH, joinDeepPath } from "estree-sentry"; * // returns: "$.body.0" * joinDeepPath(ROOT_PATH, "body", 0); * ``` * */ export const joinDeepPath: ( path: Path, segment1: Segment, segment2: Segment, ) => Path; /** * * Splits a path relative to a base path. Returns null if the path is not * relative to the base path. * * @example * ```ts * import { splitPath, Path } from "estree-sentry"; * // returns: ["left", "argument"] * splitPath( * "$.body.0.expression.left.argument" as Path, * "$.body.0.expression" as Path, * ); * ``` * */ export const splitPath: (path: Path, base: Path) => Segment[] | null; /** * * Fetches a node or an array of nodes from a root node or an array of root * nodes by following the segments of a path. Returns null if the target could * not be found. * * @example * ```ts * import { walkPath, VariableName } from "estree-sentry"; * // returns: { type: 'Identifier', name: 'x' } * walkPath(["left", "argument"], { * type: "LogicalExpression", * operator: "&&", * left: { * type: "UnaryExpression", * prefix: true, * operator: "!", * argument: { * type: "Identifier", * name: "x" as VariableName, * }, * }, * right: { * type: "Identifier", * name:"y" as VariableName, * }, * }); * ``` * * @template A * Annotation type * @param segments * An array of segments which can be produced by `splitPath`. * @param root * The root node or an array of root nodes from which to start walking the path. * @returns * The target node or an array of target nodes if found, otherwise `null`. * */ export const walkPath: ( segments: Segment[], root: Node | Node[], ) => null | Node | Node[];