|
| 1 | +/** |
| 2 | + * @typedef {import('estree-jsx').Program} Program |
| 3 | + * @typedef {typeof import('source-map').SourceMapGenerator} SourceMapGenerator |
| 4 | + * @typedef {import('./types.js').Handlers} Handlers |
| 5 | + * |
| 6 | + * @typedef BaseFields |
| 7 | + * @property {Handlers} [handlers] |
| 8 | + * Object mapping node types to functions handling the corresponding nodes. |
| 9 | + * |
| 10 | + * @typedef SourceMapFieldsWithoutSourceMapGenerator |
| 11 | + * @property {undefined} [SourceMapGenerator] |
| 12 | + * Generate a source map by passing a `SourceMapGenerator` from `source-map` |
| 13 | + * in. |
| 14 | + * @property {undefined} [filePath] |
| 15 | + * Path to input file. |
| 16 | + * |
| 17 | + * @typedef SourceMapFieldsWithSourceMapGenerator |
| 18 | + * @property {SourceMapGenerator} SourceMapGenerator |
| 19 | + * Generate a source map by passing a `SourceMapGenerator` from `source-map` |
| 20 | + * in. |
| 21 | + * @property {string} [filePath] |
| 22 | + * Path to input file. |
| 23 | + * |
| 24 | + * @typedef {BaseFields & SourceMapFieldsWithoutSourceMapGenerator} OptionsWithoutSourceMapGenerator |
| 25 | + * @typedef {BaseFields & SourceMapFieldsWithSourceMapGenerator} OptionsWithSourceMapGenerator |
| 26 | + * |
| 27 | + * @typedef {OptionsWithoutSourceMapGenerator|OptionsWithSourceMapGenerator} Options |
| 28 | + * Configuration (optional). |
| 29 | + * |
| 30 | + * @typedef Map |
| 31 | + * Raw source map, see: |
| 32 | + * <https://github.com/mozilla/source-map/blob/58819f0/source-map.d.ts#L15-L23>. |
| 33 | + * @property {number} version |
| 34 | + * @property {Array<string>} sources |
| 35 | + * @property {Array<string>} names |
| 36 | + * @property {string|undefined} [sourceRoot] |
| 37 | + * @property {Array<string>|undefined} [sourcesContent] |
| 38 | + * @property {string} mappings |
| 39 | + * @property {string} file |
| 40 | + * |
| 41 | + * @typedef BaseResultFields |
| 42 | + * @property {string} value |
| 43 | + * Serialized JavaScript. |
| 44 | + * |
| 45 | + * @typedef ResultFieldsWithoutSourceMapGenerator |
| 46 | + * @property {undefined} map |
| 47 | + * Source map as (parsed) JSON, if `SourceMapGenerator` is passed. |
| 48 | + * |
| 49 | + * @typedef ResultFieldsWithSourceMapGenerator |
| 50 | + * @property {Map} map |
| 51 | + * Source map as (parsed) JSON, if `SourceMapGenerator` is passed. |
| 52 | + * |
| 53 | + * @typedef ResultFieldsRegardlessOfSourceMapGenerator |
| 54 | + * @property {Map|undefined} map |
| 55 | + * Source map as (parsed) JSON, if `SourceMapGenerator` is passed. |
| 56 | + * |
| 57 | + * @typedef {BaseResultFields & ResultFieldsWithoutSourceMapGenerator} ResultWithoutSourceMapGenerator |
| 58 | + * @typedef {BaseResultFields & ResultFieldsWithSourceMapGenerator} ResultWithSourceMapGenerator |
| 59 | + * @typedef {BaseResultFields & ResultFieldsRegardlessOfSourceMapGenerator} ResultRegardlessOfSourceMapGenerator |
| 60 | + * |
| 61 | + * @typedef {ResultRegardlessOfSourceMapGenerator} Result |
| 62 | + */ |
| 63 | + |
| 64 | +import {GENERATOR, generate} from 'astring' |
| 65 | + |
| 66 | +/** |
| 67 | + * Estree (and esast) utility to serialize estrees as JavaScript. |
| 68 | + * |
| 69 | + * @param value |
| 70 | + * Estree (esast). |
| 71 | + * @param options |
| 72 | + * Configuration (optional). |
| 73 | + * @returns |
| 74 | + * An object with two fields: |
| 75 | + * * `value` (`string`) — serialized JavaScript |
| 76 | + * * `map` (`Object?`) — source map as (parsed) JSON, if |
| 77 | + * `SourceMapGenerator` is passed |
| 78 | + */ |
| 79 | +export const toJs = |
| 80 | + /** |
| 81 | + * @type {( |
| 82 | + * ((value: Program, options: OptionsWithSourceMapGenerator) => ResultWithSourceMapGenerator) & |
| 83 | + * ((value: Program, options?: OptionsWithoutSourceMapGenerator) => ResultWithoutSourceMapGenerator) |
| 84 | + * )} |
| 85 | + */ |
| 86 | + ( |
| 87 | + /** |
| 88 | + * @param {Program} tree |
| 89 | + * @param {Options} [options={}] |
| 90 | + * @returns {Result} |
| 91 | + */ |
| 92 | + function (tree, options = {}) { |
| 93 | + const {SourceMapGenerator, filePath, handlers} = options |
| 94 | + const sourceMap = SourceMapGenerator |
| 95 | + ? new SourceMapGenerator({file: filePath || '<unknown>.js'}) |
| 96 | + : undefined |
| 97 | + |
| 98 | + const value = generate(tree, { |
| 99 | + comments: true, |
| 100 | + // @ts-expect-error: `generator` is fine! |
| 101 | + generator: {...GENERATOR, ...handlers}, |
| 102 | + sourceMap |
| 103 | + }) |
| 104 | + const map = sourceMap ? sourceMap.toJSON() : undefined |
| 105 | + |
| 106 | + return {value, map} |
| 107 | + } |
| 108 | + ) |
0 commit comments