kjelsrud.dev/node_modules/estree-util-to-js/lib/index.js
2023-07-19 21:31:30 +02:00

118 lines
4.1 KiB
JavaScript

/**
* @typedef {import('estree-jsx').Program} Program
* @typedef {typeof import('source-map').SourceMapGenerator} SourceMapGenerator
* @typedef {import('source-map').RawSourceMap} Map
* @typedef {import('./types.js').Handlers} Handlers
*/
/**
* @typedef BaseFields
* @property {Handlers | null | undefined} [handlers]
* Object mapping node types to functions handling the corresponding nodes.
*
* @typedef SourceMapFieldsWithoutSourceMapGenerator
* @property {null | undefined} [SourceMapGenerator]
* Generate a source map by passing a `SourceMapGenerator` from `source-map`
* in.
* This works if there is positional info on nodes.
* @property {null | undefined} [filePath]
* Path to input file.
* Only used in source map.
*
* @typedef SourceMapFieldsWithSourceMapGenerator
* @property {SourceMapGenerator} SourceMapGenerator
* Generate a source map by passing a `SourceMapGenerator` from `source-map`
* in.
* This works if there is positional info on nodes.
* @property {string | null | undefined} [filePath]
* Path to input file.
* Only used in source map.
*
* @typedef SourceMapFieldsMaybeSourceMapGenerator
* @property {SourceMapGenerator | null | undefined} SourceMapGenerator
* Generate a source map by passing a `SourceMapGenerator` from `source-map`
* in.
* This works if there is positional info on nodes.
* @property {string | null | undefined} [filePath]
* Path to input file.
* Only used in source map.
*
* @typedef {BaseFields & SourceMapFieldsWithoutSourceMapGenerator} OptionsWithoutSourceMapGenerator
* @typedef {BaseFields & SourceMapFieldsWithSourceMapGenerator} OptionsWithSourceMapGenerator
* @typedef {BaseFields & SourceMapFieldsMaybeSourceMapGenerator} OptionsWithMaybeMapGenerator
*
* @typedef {OptionsWithMaybeMapGenerator} Options
* Configuration (optional).
*
* @typedef BaseResultFields
* @property {string} value
* Serialized JavaScript.
*
* @typedef ResultFieldsWithoutSourceMapGenerator
* @property {undefined} map
* Source map as (parsed) JSON, if `SourceMapGenerator` is passed.
*
* @typedef ResultFieldsWithSourceMapGenerator
* @property {Map} map
* Source map as (parsed) JSON, if `SourceMapGenerator` is not passed.
*
* @typedef ResultFieldsMaybeSourceMapGenerator
* @property {Map | undefined} map
* Source map as (parsed) JSON, if `SourceMapGenerator` might be passed.
*
* @typedef {BaseResultFields & ResultFieldsWithoutSourceMapGenerator} ResultWithoutSourceMapGenerator
* @typedef {BaseResultFields & ResultFieldsWithSourceMapGenerator} ResultWithSourceMapGenerator
* @typedef {BaseResultFields & ResultFieldsMaybeSourceMapGenerator} ResultMaybeSourceMapGenerator
*
* @typedef {ResultMaybeSourceMapGenerator} Result
*/
// @ts-expect-error: `astring` has broken types.
import * as astring from 'astring'
/** @type {Handlers} */
const GENERATOR = astring.GENERATOR
/** @type {(node: Program, options: unknown) => string} */
const generate = astring.generate
/**
* Serialize an estree as JavaScript.
*
* @param tree
* Estree (esast).
* @param options
* Configuration (optional).
* @returns
* Result, optionally with source map.
*/
export const toJs =
/**
* @type {(
* ((value: Program, options: OptionsWithSourceMapGenerator) => ResultWithSourceMapGenerator) &
* ((value: Program, options: OptionsWithMaybeMapGenerator) => ResultMaybeSourceMapGenerator) &
* ((value: Program, options?: OptionsWithoutSourceMapGenerator | null | undefined) => ResultWithoutSourceMapGenerator)
* )}
*/
(
/**
* @param {Program} tree
* @param {Options | null | undefined} [options]
* @returns {Result}
*/
function (tree, options) {
const {SourceMapGenerator, filePath, handlers} = options || {}
const sourceMap = SourceMapGenerator
? new SourceMapGenerator({file: filePath || '<unknown>.js'})
: undefined
const value = generate(tree, {
comments: true,
generator: {...GENERATOR, ...handlers},
sourceMap
})
const map = sourceMap ? sourceMap.toJSON() : undefined
return {value, map}
}
)