"use strict"; /** * Code generator for i18n json/json5 resource */ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.generate = void 0; const jsonc_eslint_parser_1 = require("jsonc-eslint-parser"); const shared_1 = require("@intlify/shared"); const codegen_1 = require("./codegen"); const legacy_1 = require("./legacy"); const magic_string_1 = __importDefault(require("magic-string")); /** * @internal */ function generate(targetSource, { type = 'plain', legacy = false, bridge = false, exportESM = false, filename = 'vue-i18n-loader.json', inSourceMap = undefined, locale = '', isGlobal = false, sourceMap = false, env = 'development', forceStringify = false, onError = undefined, strictMessage = true, escapeHtml = false, useClassComponent = false }, injector) { const target = Buffer.isBuffer(targetSource) ? targetSource.toString() : targetSource; // const value = JSON.stringify(JSON.parse(target)) // .replace(/\u2028/g, '\\u2028') // line separator // .replace(/\u2029/g, '\\u2029') // paragraph separator const value = target; const options = { type, bridge, exportESM, source: value, sourceMap, locale, isGlobal, inSourceMap, env, filename, forceStringify, onError, strictMessage, escapeHtml, useClassComponent }; const generator = (0, codegen_1.createCodeGenerator)(options); const ast = (0, jsonc_eslint_parser_1.parseJSON)(value, { filePath: filename }); // for vue 2.x if (legacy && type === 'sfc') { const gen = () => (0, shared_1.friendlyJSONstringify)((0, jsonc_eslint_parser_1.getStaticJSONValue)(ast)); const code = (0, legacy_1.generateLegacyCode)(options, gen); const s = new magic_string_1.default(code); return { ast, code: s.toString(), map: s.generateMap({ file: filename, source: value, includeContent: true }) }; } const codeMaps = generateNode(generator, ast, options, injector); const { code, map } = generator.context(); // if (map) { // const s = new SourceMapConsumer((map as any).toJSON()) // s.eachMapping(m => { // console.log('sourcemap json', m) // }) // } // prettier-ignore const newMap = map ? (0, codegen_1.mapLinesColumns)(map.toJSON(), codeMaps, inSourceMap) || null // eslint-disable-line @typescript-eslint/no-explicit-any : null; return { ast, code, map: newMap != null ? newMap : undefined }; } exports.generate = generate; function generateNode(generator, node, options, injector) { const propsCountStack = []; const pathStack = []; const itemsCountStack = []; const { forceStringify } = generator.context(); const codeMaps = new Map(); const { type, bridge, exportESM, sourceMap, isGlobal, locale, useClassComponent } = options; const componentNamespace = '_Component'; (0, jsonc_eslint_parser_1.traverseNodes)(node, { enterNode(node, parent) { switch (node.type) { case 'Program': if (type === 'plain') { generator.push(`const resource = `); } else if (type === 'sfc') { // for 'sfc' const variableName = type === 'sfc' ? (!isGlobal ? '__i18n' : '__i18nGlobal') : ''; const localeName = type === 'sfc' ? (locale != null ? locale : `""`) : ''; const exportSyntax = bridge ? exportESM ? `export default` : `module.exports =` : `export default`; generator.push(`${exportSyntax} function (Component) {`); generator.indent(); // prettier-ignore const componentVariable = bridge ? `Component.options || Component` : useClassComponent ? `Component.__o || Component` : `Component`; // prettier-ignore generator.pushline(`const ${componentNamespace} = ${componentVariable}`); generator.pushline(`${componentNamespace}.${variableName} = ${componentNamespace}.${variableName} || []`); generator.push(`${componentNamespace}.${variableName}.push({`); generator.indent(); generator.pushline(`"locale": ${JSON.stringify(localeName)},`); generator.push(`"resource": `); } break; case 'JSONObjectExpression': generator.push(`{`); generator.indent(); propsCountStack.push(node.properties.length); if (parent.type === 'JSONArrayExpression') { const lastIndex = itemsCountStack.length - 1; const currentCount = parent.elements.length - itemsCountStack[lastIndex]; pathStack.push(currentCount.toString()); itemsCountStack[lastIndex] = --itemsCountStack[lastIndex]; } break; case 'JSONProperty': if (node.value.type === 'JSONLiteral' && (node.key.type === 'JSONLiteral' || node.key.type === 'JSONIdentifier')) { const name = node.key.type === 'JSONLiteral' ? node.key.value : node.key.name; const value = node.value.value; if ((0, shared_1.isString)(value)) { generator.push(`${JSON.stringify(name)}: `); pathStack.push(name.toString()); const { code, map } = (0, codegen_1.generateMessageFunction)(value, options, pathStack); sourceMap && map != null && codeMaps.set(value, map); generator.push(`${code}`, node.value, value); } else { if (forceStringify) { const strValue = JSON.stringify(value); generator.push(`${JSON.stringify(name)}: `); pathStack.push(name.toString()); const { code, map } = (0, codegen_1.generateMessageFunction)(strValue, options, pathStack); sourceMap && map != null && codeMaps.set(strValue, map); generator.push(`${code}`, node.value, strValue); } else { generator.push(`${JSON.stringify(name)}: ${JSON.stringify(value)}`); pathStack.push(name.toString()); } } } else if ((node.value.type === 'JSONObjectExpression' || node.value.type === 'JSONArrayExpression') && (node.key.type === 'JSONLiteral' || node.key.type === 'JSONIdentifier')) { const name = node.key.type === 'JSONLiteral' ? node.key.value : node.key.name; generator.push(`${JSON.stringify(name)}: `); pathStack.push(name.toString()); } const lastIndex = propsCountStack.length - 1; propsCountStack[lastIndex] = --propsCountStack[lastIndex]; break; case 'JSONArrayExpression': generator.push(`[`); generator.indent(); if (parent.type === 'JSONArrayExpression') { const lastIndex = itemsCountStack.length - 1; const currentCount = parent.elements.length - itemsCountStack[lastIndex]; pathStack.push(currentCount.toString()); itemsCountStack[lastIndex] = --itemsCountStack[lastIndex]; } itemsCountStack.push(node.elements.length); break; case 'JSONLiteral': if (parent.type === 'JSONArrayExpression') { const lastIndex = itemsCountStack.length - 1; const currentCount = parent.elements.length - itemsCountStack[lastIndex]; pathStack.push(currentCount.toString()); if (node.type === 'JSONLiteral') { const value = node.value; if ((0, shared_1.isString)(value)) { const { code, map } = (0, codegen_1.generateMessageFunction)(value, options, pathStack); sourceMap && map != null && codeMaps.set(value, map); generator.push(`${code}`, node, value); } else { if (forceStringify) { const strValue = JSON.stringify(value); const { code, map } = (0, codegen_1.generateMessageFunction)(strValue, options, pathStack); sourceMap && map != null && codeMaps.set(strValue, map); generator.push(`${code}`, node, strValue); } else { generator.push(`${JSON.stringify(value)}`); } } } itemsCountStack[lastIndex] = --itemsCountStack[lastIndex]; } break; default: break; } }, leaveNode(node, parent) { switch (node.type) { case 'Program': if (type === 'sfc') { generator.deindent(); generator.push(`})`); if (bridge && injector) { generator.newline(); generator.pushline(`${componentNamespace}.__i18nBridge = ${componentNamespace}.__i18nBridge || []`); generator.pushline(`${componentNamespace}.__i18nBridge.push('${injector()}')`); generator.pushline(`delete ${componentNamespace}._Ctor`); } generator.deindent(); generator.pushline(`}`); } else if (type === 'plain') { generator.push(`\n`); generator.push('export default resource'); } break; case 'JSONObjectExpression': if (propsCountStack[propsCountStack.length - 1] === 0) { pathStack.pop(); propsCountStack.pop(); } generator.deindent(); generator.push(`}`); if (parent.type === 'JSONArrayExpression') { if (itemsCountStack[itemsCountStack.length - 1] !== 0) { pathStack.pop(); generator.pushline(`,`); } } break; case 'JSONProperty': if (propsCountStack[propsCountStack.length - 1] !== 0) { pathStack.pop(); generator.pushline(`,`); } break; case 'JSONArrayExpression': if (itemsCountStack[itemsCountStack.length - 1] === 0) { pathStack.pop(); itemsCountStack.pop(); } generator.deindent(); generator.push(`]`); if (parent.type === 'JSONArrayExpression') { if (itemsCountStack[itemsCountStack.length - 1] !== 0) { pathStack.pop(); generator.pushline(`,`); } } break; case 'JSONLiteral': if (parent.type === 'JSONArrayExpression') { if (itemsCountStack[itemsCountStack.length - 1] !== 0) { pathStack.pop(); generator.pushline(`,`); } else { generator.pushline(`,`); } } break; default: break; } } }); return codeMaps; }