Spaces:
Runtime error
Runtime error
| import * as perisopic from 'periscopic'; | |
| import { handle } from './handlers.js'; | |
| import { encode } from '@jridgewell/sourcemap-codec'; | |
| /** @type {(str?: string) => string} str */ | |
| let btoa = () => { | |
| throw new Error( | |
| 'Unsupported environment: `window.btoa` or `Buffer` should be supported.' | |
| ); | |
| }; | |
| if (typeof window !== 'undefined' && typeof window.btoa === 'function') { | |
| btoa = (str) => window.btoa(unescape(encodeURIComponent(str))); | |
| } else if (typeof Buffer === 'function') { | |
| btoa = (str) => Buffer.from(str, 'utf-8').toString('base64'); | |
| } | |
| /** @typedef {import('estree').Node} Node */ | |
| /** | |
| * @typedef {{ | |
| * file?: string; | |
| * sourceMapSource?: string; | |
| * sourceMapContent?: string; | |
| * sourceMapEncodeMappings?: boolean; // default true | |
| * getName?: (name: string) => string; | |
| * }} PrintOptions | |
| */ | |
| /** | |
| * @param {Node} node | |
| * @param {PrintOptions} opts | |
| * @returns {{ code: string, map: any }} // TODO | |
| */ | |
| export function print(node, opts = {}) { | |
| if (Array.isArray(node)) { | |
| return print( | |
| { | |
| type: 'Program', | |
| body: node, | |
| sourceType: 'module' | |
| }, | |
| opts | |
| ); | |
| } | |
| const { | |
| getName = /** @param {string} x */ (x) => { | |
| throw new Error(`Unhandled sigil @${x}`); | |
| } | |
| } = opts; | |
| let { map: scope_map, scope } = perisopic.analyze(node); | |
| const deconflicted = new WeakMap(); | |
| const chunks = handle(node, { | |
| indent: '', | |
| getName, | |
| scope, | |
| scope_map, | |
| deconflicted, | |
| comments: [] | |
| }); | |
| /** @typedef {[number, number, number, number]} Segment */ | |
| let code = ''; | |
| let current_column = 0; | |
| /** @type {Segment[][]} */ | |
| let mappings = []; | |
| /** @type {Segment[]} */ | |
| let current_line = []; | |
| for (let i = 0; i < chunks.length; i += 1) { | |
| const chunk = chunks[i]; | |
| code += chunk.content; | |
| if (chunk.loc) { | |
| current_line.push([ | |
| current_column, | |
| 0, // source index is always zero | |
| chunk.loc.start.line - 1, | |
| chunk.loc.start.column | |
| ]); | |
| } | |
| for (let i = 0; i < chunk.content.length; i += 1) { | |
| if (chunk.content[i] === '\n') { | |
| mappings.push(current_line); | |
| current_line = []; | |
| current_column = 0; | |
| } else { | |
| current_column += 1; | |
| } | |
| } | |
| if (chunk.loc) { | |
| current_line.push([ | |
| current_column, | |
| 0, // source index is always zero | |
| chunk.loc.end.line - 1, | |
| chunk.loc.end.column | |
| ]); | |
| } | |
| } | |
| mappings.push(current_line); | |
| const map = { | |
| version: 3, | |
| /** @type {string[]} */ | |
| names: [], | |
| sources: [opts.sourceMapSource || null], | |
| sourcesContent: [opts.sourceMapContent || null], | |
| mappings: | |
| opts.sourceMapEncodeMappings == undefined || opts.sourceMapEncodeMappings | |
| ? encode(mappings) | |
| : mappings | |
| }; | |
| Object.defineProperties(map, { | |
| toString: { | |
| enumerable: false, | |
| value: function toString() { | |
| return JSON.stringify(this); | |
| } | |
| }, | |
| toUrl: { | |
| enumerable: false, | |
| value: function toUrl() { | |
| return ( | |
| 'data:application/json;charset=utf-8;base64,' + btoa(this.toString()) | |
| ); | |
| } | |
| } | |
| }); | |
| return { | |
| code, | |
| map | |
| }; | |
| } | |