File size: 7,930 Bytes
7d73cf2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
"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;