"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.mapLinesColumns = exports.generateMessageFunction = exports.createCodeGenerator = void 0; const message_compiler_1 = require("@intlify/message-compiler"); const source_map_1 = require("source-map"); const shared_1 = require("@intlify/shared"); function createCodeGenerator(options = { filename: 'bundle.json', sourceMap: false, env: 'development', forceStringify: false }) { const { sourceMap, source, filename } = options; const _context = Object.assign({ code: '', column: 1, line: 1, offset: 0, map: undefined, indentLevel: 0 }, options); const context = () => _context; function push(code, node, name) { _context.code += code; if (_context.map && node) { if (node.loc && node.loc !== message_compiler_1.LocationStub) { addMapping(node.loc.start, name); } advancePositionWithSource(_context, code); } } function _newline(n) { push('\n' + ` `.repeat(n)); } function indent(withNewLine = true) { const level = ++_context.indentLevel; withNewLine && _newline(level); } function deindent(withNewLine = true) { const level = --_context.indentLevel; withNewLine && _newline(level); } function newline() { _newline(_context.indentLevel); } function pushline(code, node, name) { push(code, node, name); newline(); } function addMapping(loc, name) { _context.map.addMapping({ name, source: _context.filename, original: { line: loc.line, column: loc.column - 1 }, generated: { line: _context.line, column: _context.column - 1 } }); } if (sourceMap && source) { _context.map = new source_map_1.SourceMapGenerator(); _context.map.setSourceContent(filename, source); } return { context, push, indent, deindent, newline, pushline }; } exports.createCodeGenerator = createCodeGenerator; function advancePositionWithSource(pos, source, numberOfCharacters = source.length) { if (pos.offset == null) { return pos; } let linesCount = 0; let lastNewLinePos = -1; for (let i = 0; i < numberOfCharacters; i++) { if (source.charCodeAt(i) === 10 /* newline char code */) { linesCount++; lastNewLinePos = i; } } pos.offset += numberOfCharacters; pos.line += linesCount; pos.column = lastNewLinePos === -1 ? pos.column + numberOfCharacters : numberOfCharacters - lastNewLinePos; return pos; } const DETECT_MESSAGE = `Detected HTML in '{msg}' message.`; const ON_ERROR_NOOP = () => { }; // eslint-disable-line @typescript-eslint/no-empty-function function parsePath(path) { return path ? path.join('.') : ''; } function generateMessageFunction(msg, options, path) { const env = options.env != null ? options.env : 'development'; const strictMessage = (0, shared_1.isBoolean)(options.strictMessage) ? options.strictMessage : true; const escapeHtml = !!options.escapeHtml; const onError = options.onError || ON_ERROR_NOOP; const errors = []; let detecteHtmlInMsg = false; if ((0, message_compiler_1.detectHtmlTag)(msg)) { detecteHtmlInMsg = true; if (strictMessage) { const errMsg = (0, shared_1.format)(DETECT_MESSAGE, { msg }); onError((0, shared_1.format)(errMsg), { source: msg, path: parsePath(path) }); } } const _msg = detecteHtmlInMsg && escapeHtml ? (0, shared_1.escapeHtml)(msg) : msg; const newOptions = Object.assign({ mode: 'arrow' }, options); newOptions.onError = (err) => { if (onError) { const extra = { source: msg, path: parsePath(path), code: err.code, domain: err.domain, location: err.location }; onError(err.message, extra); errors.push(err); } }; const { code, ast, map } = (0, message_compiler_1.baseCompile)(_msg, newOptions); const occured = errors.length > 0; const genCode = !occured ? env === 'development' ? `(()=>{const fn=${code};fn.source=${JSON.stringify(msg)};return fn;})()` : `${code}` : _msg; return { code: genCode, ast, map, errors }; } exports.generateMessageFunction = generateMessageFunction; function mapLinesColumns(resMap, codeMaps, inSourceMap) { if (!resMap) { return null; } const resMapConsumer = new source_map_1.SourceMapConsumer(resMap); const inMapConsumer = inSourceMap ? new source_map_1.SourceMapConsumer(inSourceMap) : null; const mergedMapGenerator = new source_map_1.SourceMapGenerator(); let inMapFirstItem = null; if (inMapConsumer) { inMapConsumer.eachMapping(m => { if (inMapFirstItem) { return; } inMapFirstItem = m; }); } resMapConsumer.eachMapping(res => { if (res.originalLine == null) { return; } const map = codeMaps.get(res.name); if (!map) { return; } let inMapOrigin = null; if (inMapConsumer) { inMapOrigin = inMapConsumer.originalPositionFor({ line: res.originalLine, column: res.originalColumn - 1 }); if (inMapOrigin.source == null) { inMapOrigin = null; return; } } const mapConsumer = new source_map_1.SourceMapConsumer(map); mapConsumer.eachMapping(m => { mergedMapGenerator.addMapping({ original: { line: inMapFirstItem ? inMapFirstItem.originalLine + res.originalLine - 2 : res.originalLine, column: inMapFirstItem ? inMapFirstItem.originalColumn + res.originalColumn : res.originalColumn }, generated: { line: inMapFirstItem ? inMapFirstItem.generatedLine + res.originalLine - 2 : res.originalLine, // map column with message format compilation code map column: inMapFirstItem ? inMapFirstItem.generatedColumn + res.originalColumn + m.generatedColumn : res.originalColumn + m.generatedColumn }, source: inMapOrigin ? inMapOrigin.source : res.source, name: m.name // message format compilation code }); }); }); // eslint-disable-next-line @typescript-eslint/no-explicit-any const generator = mergedMapGenerator; // const targetConsumer = inMapConsumer || resMapConsumer const targetConsumer = inMapConsumer || resMapConsumer; targetConsumer.sources.forEach((sourceFile) => { generator._sources.add(sourceFile); const sourceContent = targetConsumer.sourceContentFor(sourceFile); if (sourceContent != null) { mergedMapGenerator.setSourceContent(sourceFile, sourceContent); } }); generator._sourceRoot = inSourceMap ? inSourceMap.sourceRoot : resMap.sourceRoot; generator._file = inSourceMap ? inSourceMap.file : resMap.file; return generator.toJSON(); } exports.mapLinesColumns = mapLinesColumns;