From 1f45f88da80245b89ad1e34d0fd347b1f57a7b8a Mon Sep 17 00:00:00 2001 From: kazuya kawaguchi Date: Sat, 19 Dec 2020 02:35:30 +0900 Subject: [PATCH 1/3] breacking: custom block fully pre-compilation --- README.md | 29 --- example/webpack.config.js | 11 +- package.json | 6 +- src/gen.ts | 116 ------------ src/generator/codegen.ts | 50 ++++-- src/generator/json.ts | 53 +++++- src/generator/yaml.ts | 47 ++++- src/index.ts | 104 ++++++----- src/options.ts | 1 - test/__snapshots__/custom-block.test.ts.snap | 169 ++++++++++++++++++ test/__snapshots__/fundamental.test.ts.snap | 137 -------------- test/custom-block.test.ts | 115 ++++++++++++ test/fundamental.test.ts | 77 -------- ...n.test.ts => resource-compilation.test.ts} | 0 test/utils.ts | 2 +- yarn.lock | 11 +- 16 files changed, 476 insertions(+), 452 deletions(-) delete mode 100644 src/gen.ts create mode 100644 test/__snapshots__/custom-block.test.ts.snap delete mode 100644 test/__snapshots__/fundamental.test.ts.snap create mode 100644 test/custom-block.test.ts delete mode 100644 test/fundamental.test.ts rename test/{pre-compilation.test.ts => resource-compilation.test.ts} (100%) diff --git a/README.md b/README.md index 372a1c7..ffc0c61 100644 --- a/README.md +++ b/README.md @@ -324,35 +324,6 @@ module.exports = { } ``` -## :rocket: i18n resource optimization - -You can optimize your localization performance with pre-compiling the i18n resources. - -You need to specify the `preCompile: true` option in your webpack config as below: - -```javascript -module.exports = { - module: { - rules: [ - // ... - { - resourceQuery: /blockType=i18n/, - type: 'javascript/auto', - use: [ - { - loader: '@intlify/vue-i18n-loader', - options: { - preCompile: true // you need to specify at here! - } - } - ] - }, - // ... - ] - } -} -``` - ## :scroll: Changelog Details changes for each release are documented in the [CHANGELOG.md](https://github.com/intlify/vue-i18n-loader/blob/master/CHANGELOG.md). diff --git a/example/webpack.config.js b/example/webpack.config.js index 2a10469..641e3bd 100644 --- a/example/webpack.config.js +++ b/example/webpack.config.js @@ -48,7 +48,7 @@ module.exports = { loader: path.resolve(__dirname, '../lib/index.js'), options: { // Whether pre-compile number and boolean literal as message functions that return the string value, default `false` - forceStringify: true + // forceStringify: true } } ] @@ -56,14 +56,7 @@ module.exports = { { resourceQuery: /blockType=i18n/, type: 'javascript/auto', - use: [ - { - loader: path.resolve(__dirname, '../lib/index.js'), - options: { - preCompile: true - } - } - ] + loader: path.resolve(__dirname, '../lib/index.js') } ] }, diff --git a/package.json b/package.json index 5eb1e3b..b36492c 100644 --- a/package.json +++ b/package.json @@ -27,12 +27,8 @@ "@intlify/core-base": "^9.0.0-beta.14", "@intlify/message-compiler": "^9.0.0-beta.14", "@intlify/shared": "^9.0.0-beta.14", - "flat": "^5.0.2", - "js-yaml": "^3.14.0", - "json5": "^2.1.3", "jsonc-eslint-parser": "^0.6.0", "loader-utils": "^2.0.0", - "prettier": "^2.2.1", "yaml-eslint-parser": "^0.1.0" }, "devDependencies": { @@ -122,6 +118,6 @@ "test:cover": "yarn test:unit --coverage", "test:e2e": "yarn build && jest --runInBand --config ./jest.e2e.config.js", "test:unit": "yarn clean:cache:jest && jest --env node", - "test:watch": "clean:cache:jest && jest --env node --watch" + "test:watch": "yarn clean:cache:jest && jest --env node --watch" } } diff --git a/src/gen.ts b/src/gen.ts deleted file mode 100644 index 69b6c34..0000000 --- a/src/gen.ts +++ /dev/null @@ -1,116 +0,0 @@ -import { ParsedUrlQuery } from 'querystring' -import JSON5 from 'json5' -import yaml from 'js-yaml' -import { flatten } from 'flat' -import prettier from 'prettier' -import { baseCompile, CompileOptions } from '@intlify/message-compiler' -import { friendlyJSONstringify, generateFormatCacheKey } from '@intlify/shared' -import { Locale, LocaleMessages } from '@intlify/core-base' - -import type { VueI18nLoaderOptions } from './options' - -export function generateCode( - source: string | Buffer, - query: ParsedUrlQuery, - options: VueI18nLoaderOptions -): string { - const value = merge(parse(source, query), query) - - let code = '' - const preCompile = !!options.preCompile - - if (preCompile) { - if (query.global) { - console.warn( - '[vue-i18n-loader] cannot support global scope for pre-compilation' - ) - } else { - code += generateCompiledCode(value as LocaleMessages) - code += `export default function (Component) { - Component.__i18n = Component.__i18n || _getResource -}\n` - } - } else { - const variableName = query.global ? '__i18nGlobal' : '__i18n' - code += `export default function (Component) { - Component.${variableName} = Component.${variableName} || [] - Component.${variableName}.push(${stringify(value)}) -}\n` - } - - return prettier.format(code, { parser: 'babel' }) -} - -// eslint-disable-next-line @typescript-eslint/no-explicit-any -function stringify(data: any): string { - return friendlyJSONstringify(data) -} - -// eslint-disable-next-line @typescript-eslint/no-explicit-any -function merge(data: any, query: ParsedUrlQuery): any { - if (query.locale && typeof query.locale === 'string') { - return Object.assign({}, { [query.locale]: data }) - } else { - return data - } -} - -// eslint-disable-next-line @typescript-eslint/no-explicit-any -function parse(source: string | Buffer, query: ParsedUrlQuery): any { - const value = Buffer.isBuffer(source) ? source.toString() : source - const { lang } = query - switch (lang) { - case 'yaml': - case 'yml': - return yaml.safeLoad(value) - case 'json5': - return JSON5.parse(value) - default: - return JSON.parse(value) - } -} - -function generateCompiledCode(messages: LocaleMessages): string { - let code = '' - code += `function _register(functions, pathkey, msg) { - const path = JSON.stringify(pathkey) - functions[path] = msg -} -` - code += `const _getResource = () => { - const functions = Object.create(null) -` - - const locales = Object.keys(messages) as Locale[] - locales.forEach(locale => { - const message = flatten(messages[locale]) as { [key: string]: string } - const keys = Object.keys(message) - keys.forEach(key => { - const format = message[key] - let occured = false - const options = { - mode: 'arrow', - // TODO: source mapping ! - onError(err) { - console.error(err) - occured = true - } - } as CompileOptions - const result = baseCompile(format, options) - if (!occured) { - code += ` _register(functions, ${generateFormatCacheKey( - locale, - key, - format - )}, ${result.code})\n` - } - }) - }) - - code += ` - return { functions } -} -` - - return code -} diff --git a/src/generator/codegen.ts b/src/generator/codegen.ts index 4a38eec..896d40d 100644 --- a/src/generator/codegen.ts +++ b/src/generator/codegen.ts @@ -5,7 +5,11 @@ import { ResourceNode, CompileOptions } from '@intlify/message-compiler' -import { SourceMapGenerator, SourceMapConsumer } from 'source-map' +import { + SourceMapGenerator, + SourceMapConsumer, + MappedPosition +} from 'source-map' import type { RawSourceMap } from 'source-map' @@ -25,9 +29,13 @@ export interface SourceLocationable { } export interface CodeGenOptions { + type?: 'plain' | 'sfc' source?: string sourceMap?: boolean filename?: string + inSourceMap?: RawSourceMap + isGlobal?: boolean + locale?: string env?: DevEnv forceStringify?: boolean onWarn?: (msg: string) => void @@ -214,13 +222,15 @@ export function generateMessageFunction( export function mapColumns( resMap: RawSourceMap, - codeMaps: Map + codeMaps: Map, + inSourceMap?: RawSourceMap ): RawSourceMap | null { if (!resMap) { return null } const resMapConsumer = new SourceMapConsumer(resMap) + const inMapConsumer = inSourceMap ? new SourceMapConsumer(inSourceMap) : null const mergedMapGenerator = new SourceMapGenerator() resMapConsumer.eachMapping(res => { @@ -233,18 +243,33 @@ export function mapColumns( return null } + let inMapOrigin: MappedPosition | null = null + if (inMapConsumer) { + inMapOrigin = inMapConsumer.originalPositionFor({ + line: res.originalLine, + column: res.originalColumn - 1 + }) + if (inMapOrigin.source == null) { + inMapOrigin = null + } + } + const mapConsumer = new SourceMapConsumer(map) mapConsumer.eachMapping(m => { + // console.log('message syntax map', m) mergedMapGenerator.addMapping({ original: { - line: res.originalLine, - column: res.originalColumn + line: inMapOrigin != null ? inMapOrigin.line : res.originalLine, + column: inMapOrigin != null ? inMapOrigin.column : res.originalColumn }, generated: { - line: res.originalLine, - column: res.originalColumn + m.generatedColumn // map column with message format compilation code map + line: inMapOrigin != null ? inMapOrigin.line : res.originalLine, + // map column with message format compilation code map + column: + (inMapOrigin != null ? inMapOrigin.column : res.originalColumn) + + m.generatedColumn }, - source: res.source, + source: inMapOrigin != null ? inMapOrigin.source : res.source, name: m.name // message format compilation code }) }) @@ -252,17 +277,20 @@ export function mapColumns( // eslint-disable-next-line @typescript-eslint/no-explicit-any const generator = mergedMapGenerator as any + const targetConsumer = inMapConsumer || resMapConsumer // eslint-disable-next-line @typescript-eslint/no-explicit-any - ;(resMapConsumer as any).sources.forEach((sourceFile: string) => { + ;(targetConsumer as any).sources.forEach((sourceFile: string) => { generator._sources.add(sourceFile) - const sourceContent = resMapConsumer.sourceContentFor(sourceFile) + const sourceContent = targetConsumer.sourceContentFor(sourceFile) if (sourceContent != null) { mergedMapGenerator.setSourceContent(sourceFile, sourceContent) } }) - generator._sourceRoot = resMap.sourceRoot - generator._file = resMap.file + generator._sourceRoot = inSourceMap + ? inSourceMap.sourceRoot + : resMap.sourceRoot + generator._file = inSourceMap ? inSourceMap.file : resMap.file return generator.toJSON() } diff --git a/src/generator/json.ts b/src/generator/json.ts index 95316af..4522224 100644 --- a/src/generator/json.ts +++ b/src/generator/json.ts @@ -17,7 +17,11 @@ import type { CodeGenOptions, CodeGenerator, CodeGenResult } from './codegen' export function generate( targetSource: string | Buffer, { + type = 'plain', filename = 'vue-i18n-loader.json', + inSourceMap = undefined, + locale = '', + isGlobal = false, sourceMap = false, env = 'development', forceStringify = false @@ -32,8 +36,12 @@ export function generate( const value = target const options = { + type, source: value, sourceMap, + locale, + isGlobal, + inSourceMap, env, filename, forceStringify @@ -44,8 +52,14 @@ export function generate( const codeMaps = generateNode(generator, ast, options) const { code, map } = generator.context() + // if (map) { + // const s = new SourceMapConsumer((map as any).toJSON()) + // s.eachMapping(m => { + // console.log('sourcemap json', m) + // }) + // } const newMap = map - ? mapColumns((map as any).toJSON(), codeMaps) || null // eslint-disable-line @typescript-eslint/no-explicit-any + ? mapColumns((map as any).toJSON(), codeMaps, inSourceMap) || null // eslint-disable-line @typescript-eslint/no-explicit-any : null return { ast, @@ -63,12 +77,29 @@ function generateNode( const itemsCountStack = [] as number[] const { forceStringify } = generator.context() const codeMaps = new Map() + const { type, sourceMap, isGlobal, locale } = options + const variableName = + type === 'sfc' ? (!isGlobal ? '__i18n' : '__i18nGlobal') : '' + const localeName = type === 'sfc' ? (locale != null ? locale : `""`) : '' traverseNodes(node, { enterNode(node: JSONNode, parent: JSONNode) { switch (node.type) { case 'Program': - generator.push(`export default `) + if (type === 'plain') { + generator.push(`export default `) + } else { + // for 'sfc' + generator.push(`export default function (Component) {`) + generator.indent() + generator.pushline( + `Component.${variableName} = Component.${variableName} || []` + ) + generator.push(`Component.${variableName}.push({`) + generator.indent() + generator.pushline(`locale: ${JSON.stringify(localeName)},`) + generator.push(`content: `) + } break case 'JSONObjectExpression': generator.push(`{`) @@ -91,14 +122,14 @@ function generateNode( if (isString(value)) { generator.push(`${JSON.stringify(name)}: `) const { code, map } = generateMessageFunction(value, options) - options.sourceMap && map != null && codeMaps.set(value, map) + 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)}: `) const { code, map } = generateMessageFunction(strValue, options) - options.sourceMap && map != null && codeMaps.set(strValue, map) + sourceMap && map != null && codeMaps.set(strValue, map) generator.push(`${code}`, node.value, strValue) } else { generator.push( @@ -130,7 +161,7 @@ function generateNode( const value = node.value if (isString(value)) { const { code, map } = generateMessageFunction(value, options) - options.sourceMap && map != null && codeMaps.set(value, map) + sourceMap && map != null && codeMaps.set(value, map) generator.push(`${code}`, node, value) } else { if (forceStringify) { @@ -139,9 +170,7 @@ function generateNode( strValue, options ) - options.sourceMap && - map != null && - codeMaps.set(strValue, map) + sourceMap && map != null && codeMaps.set(strValue, map) generator.push(`${code}`, node, strValue) } else { generator.push(`${JSON.stringify(value)}`) @@ -158,6 +187,14 @@ function generateNode( }, leaveNode(node: JSONNode, parent: JSONNode) { switch (node.type) { + case 'Program': + if (type === 'sfc') { + generator.deindent() + generator.push(`})`) + generator.deindent() + generator.push(`}`) + } + break case 'JSONObjectExpression': if (propsCountStack[propsCountStack.length - 1] === 0) { propsCountStack.pop() diff --git a/src/generator/yaml.ts b/src/generator/yaml.ts index 1ab0dd1..61315b2 100644 --- a/src/generator/yaml.ts +++ b/src/generator/yaml.ts @@ -17,7 +17,11 @@ import type { CodeGenOptions, CodeGenerator, CodeGenResult } from './codegen' export function generate( targetSource: string | Buffer, { + type = 'plain', filename = 'vue-i18n-loader.yaml', + inSourceMap = undefined, + locale = '', + isGlobal = false, sourceMap = false, env = 'development', forceStringify = false @@ -28,8 +32,12 @@ export function generate( : targetSource const options = { + type, source: value, sourceMap, + locale, + isGlobal, + inSourceMap, env, filename, forceStringify @@ -41,7 +49,7 @@ export function generate( const { code, map } = generator.context() const newMap = map - ? mapColumns((map as any).toJSON(), codeMaps) || null // eslint-disable-line @typescript-eslint/no-explicit-any + ? mapColumns((map as any).toJSON(), codeMaps, inSourceMap) || null // eslint-disable-line @typescript-eslint/no-explicit-any : null return { ast, @@ -59,12 +67,29 @@ function generateNode( const itemsCountStack = [] as number[] const { forceStringify } = generator.context() const codeMaps = new Map() + const { type, sourceMap, isGlobal, locale } = options + const variableName = + type === 'sfc' ? (!isGlobal ? '__i18n' : '__i18nGlobal') : '' + const localeName = type === 'sfc' ? (locale != null ? locale : `""`) : '' traverseNodes(node, { enterNode(node: YAMLNode, parent: YAMLNode) { switch (node.type) { case 'Program': - generator.push(`export default `) + if (type === 'plain') { + generator.push(`export default `) + } else { + // for 'sfc' + generator.push(`export default function (Component) {`) + generator.indent() + generator.pushline( + `Component.${variableName} = Component.${variableName} || []` + ) + generator.push(`Component.${variableName}.push({`) + generator.indent() + generator.pushline(`locale: ${JSON.stringify(localeName)},`) + generator.push(`content: `) + } break case 'YAMLMapping': generator.push(`{`) @@ -87,14 +112,14 @@ function generateNode( if (isString(value)) { generator.push(`${JSON.stringify(name)}: `) const { code, map } = generateMessageFunction(value, options) - options.sourceMap && map != null && codeMaps.set(value, map) + 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)}: `) const { code, map } = generateMessageFunction(strValue, options) - options.sourceMap && map != null && codeMaps.set(strValue, map) + sourceMap && map != null && codeMaps.set(strValue, map) generator.push(`${code}`, node.value, strValue) } else { generator.push( @@ -126,7 +151,7 @@ function generateNode( const value = node.value if (isString(value)) { const { code, map } = generateMessageFunction(value, options) - options.sourceMap && map != null && codeMaps.set(value, map) + sourceMap && map != null && codeMaps.set(value, map) generator.push(`${code}`, node, value) } else { if (forceStringify) { @@ -135,9 +160,7 @@ function generateNode( strValue, options ) - options.sourceMap && - map != null && - codeMaps.set(strValue, map) + sourceMap && map != null && codeMaps.set(strValue, map) generator.push(`${code}`, node, strValue) } else { generator.push(`${JSON.stringify(value)}`) @@ -154,6 +177,14 @@ function generateNode( }, leaveNode(node: YAMLNode, parent: YAMLNode) { switch (node.type) { + case 'Program': + if (type === 'sfc') { + generator.deindent() + generator.push(`})`) + generator.deindent() + generator.push(`}`) + } + break case 'YAMLMapping': if (propsCountStack[propsCountStack.length - 1] === 0) { propsCountStack.pop() diff --git a/src/index.ts b/src/index.ts index adb87db..ce8e7c4 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,10 +1,9 @@ import path from 'path' import webpack from 'webpack' import loaderUtils from 'loader-utils' -import { parse } from 'querystring' +import { parse, ParsedUrlQuery } from 'querystring' import { RawSourceMap } from 'source-map' -import { isEmptyObject } from '@intlify/shared' -import { generateCode } from './gen' +import { isEmptyObject, isString } from '@intlify/shared' import { generateJSON, generateYAML } from './generator' import type { CodeGenOptions, DevEnv } from './generator/codegen' @@ -15,49 +14,70 @@ const loader: webpack.loader.Loader = function ( sourceMap: RawSourceMap | undefined ): void { const loaderContext = this // eslint-disable-line @typescript-eslint/no-this-alias + const query = parse(loaderContext.resourceQuery) + const options = getOptions(loaderContext, query, sourceMap) as CodeGenOptions + const langInfo = !isEmptyObject(query) + ? isString(query.lang) + ? query.lang + : 'json' + : path.parse(loaderContext.resourcePath).ext + + try { + this.cacheable && this.cacheable() + // if (sourceMap) { + // const s = new SourceMapConsumer(sourceMap) + // console.log('sourcemap raw', sourceMap) + // s.eachMapping(m => { + // console.log(m) + // }) + // } + const generate = /json5?/.test(langInfo) ? generateJSON : generateYAML + const { code, map } = generate(source, options) + // console.log(options.filename, code) + this.callback(null, code, map) + } catch (err) { + this.emitError(`[vue-i18n-loader]: ${err.message}`) + } +} + +function getOptions( + loaderContext: webpack.loader.LoaderContext, + query: ParsedUrlQuery, + inSourceMap?: RawSourceMap +): Record { const loaderOptions = loaderUtils.getOptions(loaderContext) || {} - const query = parse(this.resourceQuery) + const { resourcePath: filename, mode, sourceMap } = loaderContext + const { forceStringify } = loaderOptions as VueI18nLoaderOptions - if (!isEmptyObject(query)) { - try { - this.cacheable && this.cacheable() - const code = `${generateCode( - source, - query, - loaderOptions as VueI18nLoaderOptions - )}` - this.callback(null, code, sourceMap) - } catch (err) { - this.emitError(`[vue-i18n-loader]: ${err.message}`) + const baseOptions = { + filename, + sourceMap, + inSourceMap, + forceStringify, + env: mode as DevEnv, + onWarn: (msg: string): void => { + loaderContext.emitWarning( + `[vue-i18n-loader]: ${loaderContext.resourcePath} ${msg}` + ) + }, + onError: (msg: string): void => { + loaderContext.emitError( + `[vue-i18n-loader]: ${loaderContext.resourcePath} ${msg}` + ) } - } else { - const { ext } = path.parse(loaderContext.resourcePath) - const { resourcePath: filename, mode } = loaderContext - const { forceStringify } = loaderOptions as VueI18nLoaderOptions + } - if (/\.(json5?|ya?ml)/.test(ext)) { - const options: CodeGenOptions = { - filename, - forceStringify, - sourceMap: loaderContext.sourceMap, - env: mode as DevEnv, - onWarn: (msg: string): void => { - loaderContext.emitWarning( - `[vue-i18n-loader]: ${loaderContext.resourcePath} ${msg}` - ) - }, - onError: (msg: string): void => { - loaderContext.emitError( - `[vue-i18n-loader]: ${loaderContext.resourcePath} ${msg}` - ) - } - } - const generate = /\.json5?/.test(ext) ? generateJSON : generateYAML - const { code, map } = generate(source, options) - this.callback(null, code, map) - } else { - this.callback(null, source, sourceMap) - } + if (!isEmptyObject(query)) { + return Object.assign(baseOptions, { + type: 'sfc', + locale: isString(query.locale) ? query.locale : '', + isGlobal: query.global != null + }) + } else { + return Object.assign(baseOptions, { + type: 'plain', + isGlobal: false + }) } } diff --git a/src/options.ts b/src/options.ts index a0f73b9..0349376 100644 --- a/src/options.ts +++ b/src/options.ts @@ -1,4 +1,3 @@ export type VueI18nLoaderOptions = { - preCompile?: boolean forceStringify?: boolean } diff --git a/test/__snapshots__/custom-block.test.ts.snap b/test/__snapshots__/custom-block.test.ts.snap new file mode 100644 index 0000000..bc8d149 --- /dev/null +++ b/test/__snapshots__/custom-block.test.ts.snap @@ -0,0 +1,169 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`basic 1`] = ` +Array [ + Object { + "content": Object { + "en": Object { + "hello": [Function], + }, + }, + "locale": "", + }, +] +`; + +exports[`global 1`] = ` +Array [ + Object { + "content": Object { + "en": Object { + "hello": [Function], + }, + }, + "locale": "", + }, +] +`; + +exports[`global and local 1`] = ` +Array [ + Object { + "content": Object { + "hello": [Function], + }, + "locale": "ja", + }, +] +`; + +exports[`global and local 2`] = ` +Array [ + Object { + "content": Object { + "en": Object { + "hello": [Function], + }, + }, + "locale": "", + }, +] +`; + +exports[`import 1`] = ` +Array [ + Object { + "content": Object { + "en": Object { + "hello": [Function], + }, + }, + "locale": "", + }, +] +`; + +exports[`json5 1`] = ` +Array [ + Object { + "content": Object { + "en": Object { + "hello": [Function], + }, + }, + "locale": "", + }, +] +`; + +exports[`locale attr 1`] = ` +Array [ + Object { + "content": Object { + "hello": [Function], + }, + "locale": "ja", + }, +] +`; + +exports[`locale attr and basic 1`] = ` +Array [ + Object { + "content": Object { + "en": Object { + "hello": [Function], + }, + }, + "locale": "", + }, + Object { + "content": Object { + "hello": [Function], + }, + "locale": "ja", + }, +] +`; + +exports[`locale attr and import 1`] = ` +Array [ + Object { + "content": Object { + "hello": [Function], + }, + "locale": "en", + }, +] +`; + +exports[`multiple 1`] = ` +Array [ + Object { + "content": Object { + "en": Object { + "hello": [Function], + }, + }, + "locale": "", + }, + Object { + "content": Object { + "ja": Object { + "hello": [Function], + }, + }, + "locale": "", + }, +] +`; + +exports[`special characters 1`] = ` +Array [ + Object { + "content": Object { + "en": Object { + "hello": [Function], + }, + }, + "locale": "", + }, +] +`; + +exports[`yaml 1`] = ` +Array [ + Object { + "content": Object { + "hello": [Function], + }, + "locale": "en", + }, + Object { + "content": Object { + "hello": [Function], + }, + "locale": "ja", + }, +] +`; diff --git a/test/__snapshots__/fundamental.test.ts.snap b/test/__snapshots__/fundamental.test.ts.snap deleted file mode 100644 index a471da3..0000000 --- a/test/__snapshots__/fundamental.test.ts.snap +++ /dev/null @@ -1,137 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`basic 1`] = ` -Array [ - Object { - "en": Object { - "hello": "hello world!", - }, - }, -] -`; - -exports[`global 1`] = ` -Array [ - Object { - "en": Object { - "hello": "hello global!", - }, - }, -] -`; - -exports[`global and local 1`] = ` -Array [ - Object { - "ja": Object { - "hello": "hello local!", - }, - }, -] -`; - -exports[`global and local 2`] = ` -Array [ - Object { - "en": Object { - "hello": "hello global!", - }, - }, -] -`; - -exports[`import 1`] = ` -Array [ - Object { - "en": Object { - "hello": "hello world!", - }, - }, -] -`; - -exports[`json5 1`] = ` -Array [ - Object { - "en": Object { - "hello": "hello world!", - }, - }, -] -`; - -exports[`locale attr 1`] = ` -Array [ - Object { - "ja": Object { - "hello": "こんにちは、世界!", - }, - }, -] -`; - -exports[`locale attr and basic 1`] = ` -Array [ - Object { - "en": Object { - "hello": "hello world!", - }, - }, - Object { - "ja": Object { - "hello": "こんにちは、世界!", - }, - }, -] -`; - -exports[`locale attr and import 1`] = ` -Array [ - Object { - "en": Object { - "hello": "hello world!", - }, - }, -] -`; - -exports[`multiple 1`] = ` -Array [ - Object { - "en": Object { - "hello": "hello world!", - }, - }, - Object { - "ja": Object { - "hello": "こんにちは、世界!", - }, - }, -] -`; - -exports[`special characters 1`] = ` -Array [ - Object { - "en": Object { - "hello": "hello -great \\"world\\"", - }, - }, -] -`; - -exports[`yaml 1`] = ` -Array [ - Object { - "en": Object { - "hello": "hello world!", - }, - }, - Object { - "ja": Object { - "hello": "こんにちは、世界!", - }, - }, -] -`; diff --git a/test/custom-block.test.ts b/test/custom-block.test.ts new file mode 100644 index 0000000..317373c --- /dev/null +++ b/test/custom-block.test.ts @@ -0,0 +1,115 @@ +import { bundleAndRun } from './utils' +import { createMessageContext } from '@intlify/runtime' + +test('basic', async () => { + const { module } = await bundleAndRun('basic.vue') + expect(module.__i18n).toMatchSnapshot() + const i18n = module.__i18n.pop() + expect(i18n.locale).toEqual('') + expect(i18n.content.en.hello(createMessageContext())).toEqual('hello world!') +}) + +test('special characters', async () => { + const { module } = await bundleAndRun('special-char.vue') + expect(module.__i18n).toMatchSnapshot() + const i18n = module.__i18n.pop() + expect(i18n.locale).toEqual('') + expect(i18n.content.en.hello(createMessageContext())).toEqual( + 'hello\ngreat\t"world"' + ) +}) + +test('multiple', async () => { + const { module } = await bundleAndRun('multiple.vue') + expect(module.__i18n).toMatchSnapshot() + expect(module.__i18n.length).toEqual(2) + let i18n = module.__i18n.pop() + expect(i18n.locale).toEqual('') + expect(i18n.content.ja.hello(createMessageContext())).toEqual( + 'こんにちは、世界!' + ) + i18n = module.__i18n.pop() + expect(i18n.locale).toEqual('') + expect(i18n.content.en.hello(createMessageContext())).toEqual('hello world!') +}) + +test('import', async () => { + const { module } = await bundleAndRun('import.vue') + expect(module.__i18n).toMatchSnapshot() + const i18n = module.__i18n.pop() + expect(i18n.locale).toEqual('') + expect(i18n.content.en.hello(createMessageContext())).toEqual('hello world!') +}) + +test('locale attr', async () => { + const { module } = await bundleAndRun('locale.vue') + expect(module.__i18n).toMatchSnapshot() + const i18n = module.__i18n.pop() + expect(i18n.locale).toEqual('ja') + expect(i18n.content.hello(createMessageContext())).toEqual( + 'こんにちは、世界!' + ) +}) + +test('locale attr and basic', async () => { + const { module } = await bundleAndRun('locale-mix.vue') + expect(module.__i18n).toMatchSnapshot() + let i18n = module.__i18n.pop() + expect(i18n.locale).toEqual('ja') + expect(i18n.content.hello(createMessageContext())).toEqual( + 'こんにちは、世界!' + ) + i18n = module.__i18n.pop() + expect(i18n.locale).toEqual('') + expect(i18n.content.en.hello(createMessageContext())).toEqual('hello world!') +}) + +test('locale attr and import', async () => { + const { module } = await bundleAndRun('locale-import.vue') + expect(module.__i18n).toMatchSnapshot() + const i18n = module.__i18n.pop() + expect(i18n.locale).toEqual('en') + expect(i18n.content.hello(createMessageContext())).toEqual('hello world!') +}) + +test('yaml', async () => { + const { module } = await bundleAndRun('yaml.vue') + expect(module.__i18n).toMatchSnapshot() + let i18n = module.__i18n.pop() + expect(i18n.locale).toEqual('ja') + expect(i18n.content.hello(createMessageContext())).toEqual( + 'こんにちは、世界!' + ) + i18n = module.__i18n.pop() + expect(i18n.locale).toEqual('en') + expect(i18n.content.hello(createMessageContext())).toEqual('hello world!') +}) + +test('json5', async () => { + const { module } = await bundleAndRun('json5.vue') + expect(module.__i18n).toMatchSnapshot() + const i18n = module.__i18n.pop() + expect(i18n.locale).toEqual('') + expect(i18n.content.en.hello(createMessageContext())).toEqual('hello world!') +}) + +test('global', async () => { + const { module } = await bundleAndRun('global.vue') + expect(module.__i18n).toBeUndefined() + expect(module.__i18nGlobal).toMatchSnapshot() + const i18n = module.__i18nGlobal.pop() + expect(i18n.locale).toEqual('') + expect(i18n.content.en.hello(createMessageContext())).toEqual('hello global!') +}) + +test('global and local', async () => { + const { module } = await bundleAndRun('global-mix.vue') + expect(module.__i18n).toMatchSnapshot() + expect(module.__i18nGlobal).toMatchSnapshot() + const l = module.__i18n.pop() + expect(l.locale).toEqual('ja') + expect(l.content.hello(createMessageContext())).toEqual('hello local!') + const g = module.__i18nGlobal.pop() + expect(g.locale).toEqual('') + expect(g.content.en.hello(createMessageContext())).toEqual('hello global!') +}) diff --git a/test/fundamental.test.ts b/test/fundamental.test.ts deleted file mode 100644 index cc7ddd8..0000000 --- a/test/fundamental.test.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { bundleAndRun, bundle } from './utils' -import { baseCompile } from '@intlify/message-compiler' -import { MessageFunction } from '@intlify/runtime' -import prettier from 'prettier' - -test('basic', async () => { - const { module } = await bundleAndRun('basic.vue') - expect(module.__i18n).toMatchSnapshot() -}) - -test('special characters', async () => { - const { module } = await bundleAndRun('special-char.vue') - expect(module.__i18n).toMatchSnapshot() -}) - -test('multiple', async () => { - const { module } = await bundleAndRun('multiple.vue') - expect(module.__i18n).toMatchSnapshot() -}) - -test('import', async () => { - const { module } = await bundleAndRun('import.vue') - expect(module.__i18n).toMatchSnapshot() -}) - -test('locale attr', async () => { - const { module } = await bundleAndRun('locale.vue') - expect(module.__i18n).toMatchSnapshot() -}) - -test('locale attr and basic', async () => { - const { module } = await bundleAndRun('locale-mix.vue') - expect(module.__i18n).toMatchSnapshot() -}) - -test('locale attr and import', async () => { - const { module } = await bundleAndRun('locale-import.vue') - expect(module.__i18n).toMatchSnapshot() -}) - -test('yaml', async () => { - const { module } = await bundleAndRun('yaml.vue') - expect(module.__i18n).toMatchSnapshot() -}) - -test('json5', async () => { - const { module } = await bundleAndRun('json5.vue') - expect(module.__i18n).toMatchSnapshot() -}) - -test('pre compile', async () => { - const options: prettier.Options = { parser: 'babel' } - const { module } = await bundleAndRun('compile.vue', bundle, { - preCompile: true - }) - const { functions } = module.__i18n() - for (const [key, value] of Object.entries(functions)) { - const msg = value as MessageFunction - const data = JSON.parse(key) - const result = baseCompile(data.s, { mode: 'arrow' }) - expect(prettier.format(msg.toString(), options)).toMatch( - prettier.format(result.code, options) - ) - } -}) - -test('global', async () => { - const { module } = await bundleAndRun('global.vue') - expect(module.__i18n).toBeUndefined() - expect(module.__i18nGlobal).toMatchSnapshot() -}) - -test('global and local', async () => { - const { module } = await bundleAndRun('global-mix.vue') - expect(module.__i18n).toMatchSnapshot() - expect(module.__i18nGlobal).toMatchSnapshot() -}) diff --git a/test/pre-compilation.test.ts b/test/resource-compilation.test.ts similarity index 100% rename from test/pre-compilation.test.ts rename to test/resource-compilation.test.ts diff --git a/test/utils.ts b/test/utils.ts index 7802bc0..3416349 100644 --- a/test/utils.ts +++ b/test/utils.ts @@ -22,7 +22,7 @@ type BundleResolveResolve = BundleResolve & { export function bundle(fixture: string, options = {}): Promise { const baseConfig: webpack.Configuration = { mode: 'development', - devtool: false, + devtool: 'source-map', entry: path.resolve(__dirname, './fixtures/entry.js'), resolve: { alias: { diff --git a/yarn.lock b/yarn.lock index 74f92a8..03b5ab4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3772,11 +3772,6 @@ flat-cache@^3.0.4: flatted "^3.1.0" rimraf "^3.0.2" -flat@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" - integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== - flatted@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.1.0.tgz#a5d06b4a8b01e3a63771daa5cb7a1903e2e57067" @@ -5416,7 +5411,7 @@ js-tokens@^4.0.0: resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== -js-yaml@^3.13.1, js-yaml@^3.14.0: +js-yaml@^3.13.1: version "3.14.1" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== @@ -5501,7 +5496,7 @@ json3@^3.3.2: resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.3.tgz#7fc10e375fc5ae42c4705a5cc0aa6f62be305b81" integrity sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA== -json5@2.x, json5@^2.1.2, json5@^2.1.3: +json5@2.x, json5@^2.1.2: version "2.1.3" resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.3.tgz#c9b0f7fa9233bfe5807fe66fcf3a5617ed597d43" integrity sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA== @@ -7064,7 +7059,7 @@ prettier-linter-helpers@^1.0.0: dependencies: fast-diff "^1.1.2" -prettier@^2.0.0, prettier@^2.2.1: +prettier@^2.0.0: version "2.2.1" resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.2.1.tgz#795a1a78dd52f073da0cd42b21f9c91381923ff5" integrity sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q== From c9c70b6c4c96f2b7a849f97d2147d5e05b2eedbc Mon Sep 17 00:00:00 2001 From: kazuya kawaguchi Date: Mon, 21 Dec 2020 03:56:31 +0900 Subject: [PATCH 2/3] implement custom block source mapping --- example/composition/{ => locales}/en.yaml | 0 example/composition/{ => locales}/ja.json | 0 example/composition/main.js | 4 +- example/legacy/{ => locales}/en.yaml | 0 example/legacy/{ => locales}/ja.json | 0 example/legacy/main.js | 4 +- example/webpack.config.js | 7 ++- package.json | 8 +-- src/generator/codegen.ts | 42 ++++++++++---- src/generator/json.ts | 11 ++-- src/generator/yaml.ts | 5 +- src/index.ts | 6 +- test/utils.ts | 68 +++++++++++++++++++++++ yarn.lock | 27 ++------- 14 files changed, 130 insertions(+), 52 deletions(-) rename example/composition/{ => locales}/en.yaml (100%) rename example/composition/{ => locales}/ja.json (100%) rename example/legacy/{ => locales}/en.yaml (100%) rename example/legacy/{ => locales}/ja.json (100%) diff --git a/example/composition/en.yaml b/example/composition/locales/en.yaml similarity index 100% rename from example/composition/en.yaml rename to example/composition/locales/en.yaml diff --git a/example/composition/ja.json b/example/composition/locales/ja.json similarity index 100% rename from example/composition/ja.json rename to example/composition/locales/ja.json diff --git a/example/composition/main.js b/example/composition/main.js index 8941c1b..f7028a7 100644 --- a/example/composition/main.js +++ b/example/composition/main.js @@ -2,8 +2,8 @@ import { createApp } from 'vue' import { createI18n } from 'vue-i18n' import App from './App.vue' -import ja from './ja.json' -import en from './en.yaml' +import ja from './locales/ja.json' +import en from './locales/en.yaml' const i18n = createI18n({ legacy: false, diff --git a/example/legacy/en.yaml b/example/legacy/locales/en.yaml similarity index 100% rename from example/legacy/en.yaml rename to example/legacy/locales/en.yaml diff --git a/example/legacy/ja.json b/example/legacy/locales/ja.json similarity index 100% rename from example/legacy/ja.json rename to example/legacy/locales/ja.json diff --git a/example/legacy/main.js b/example/legacy/main.js index 9a56d6b..9a92e17 100644 --- a/example/legacy/main.js +++ b/example/legacy/main.js @@ -2,8 +2,8 @@ import { createApp } from 'vue' import { createI18n } from 'vue-i18n' import App from './App.vue' -import ja from './ja.json' -import en from './en.yaml' +import ja from './locales/ja.json' +import en from './locales/en.yaml' const i18n = createI18n({ legacy: true, diff --git a/example/webpack.config.js b/example/webpack.config.js index 641e3bd..86a8a8e 100644 --- a/example/webpack.config.js +++ b/example/webpack.config.js @@ -42,7 +42,10 @@ module.exports = { test: /\.(json5?|ya?ml)$/, // target json, json5, yaml and yml files type: 'javascript/auto', // Use `Rule.include` to specify the files of locale messages to be pre-compiled - include: [path.resolve(__dirname, './')], + include: [ + path.resolve(__dirname, './composition/locales'), + path.resolve(__dirname, './legacy/locales') + ], use: [ { loader: path.resolve(__dirname, '../lib/index.js'), @@ -54,8 +57,8 @@ module.exports = { ] }, { - resourceQuery: /blockType=i18n/, type: 'javascript/auto', + resourceQuery: /blockType=i18n/, loader: path.resolve(__dirname, '../lib/index.js') } ] diff --git a/package.json b/package.json index b36492c..16bbc84 100644 --- a/package.json +++ b/package.json @@ -29,21 +29,17 @@ "@intlify/shared": "^9.0.0-beta.14", "jsonc-eslint-parser": "^0.6.0", "loader-utils": "^2.0.0", - "yaml-eslint-parser": "^0.1.0" + "yaml-eslint-parser": "^0.2.0" }, "devDependencies": { "@intlify/runtime": "^9.0.0-beta.14", "@types/eslint": "^7.2.6", "@types/eslint-visitor-keys": "^1.0.0", - "@types/flat": "^5.0.1", "@types/jest": "^26.0.16", - "@types/js-yaml": "^3.12.5", "@types/jsdom": "^16.2.5", - "@types/json5": "^0.0.30", "@types/loader-utils": "^2.0.0", "@types/memory-fs": "^0.3.2", "@types/node": "^14.14.10", - "@types/prettier": "^2.1.5", "@types/webpack": "^4.41.1", "@types/webpack-merge": "^4.1.5", "@typescript-eslint/eslint-plugin": "^4.9.0", @@ -70,7 +66,7 @@ "typescript-eslint-language-service": "^4.1.2", "vue": "^3.0.4", "vue-i18n": "^9.0.0-beta.14", - "vue-loader": "^16.1.0", + "vue-loader": "^16.1.2", "webpack": "^4.44.2", "webpack-cli": "^3.3.12", "webpack-dev-server": "^3.11.0", diff --git a/src/generator/codegen.ts b/src/generator/codegen.ts index 896d40d..21c3602 100644 --- a/src/generator/codegen.ts +++ b/src/generator/codegen.ts @@ -8,7 +8,8 @@ import { import { SourceMapGenerator, SourceMapConsumer, - MappedPosition + MappedPosition, + MappingItem } from 'source-map' import type { RawSourceMap } from 'source-map' @@ -220,7 +221,7 @@ export function generateMessageFunction( return { code: genCode, ast, map } } -export function mapColumns( +export function mapLinesColumns( resMap: RawSourceMap, codeMaps: Map, inSourceMap?: RawSourceMap @@ -233,6 +234,16 @@ export function mapColumns( const inMapConsumer = inSourceMap ? new SourceMapConsumer(inSourceMap) : null const mergedMapGenerator = new SourceMapGenerator() + let inMapFirstItem: MappingItem | null = null + if (inMapConsumer) { + inMapConsumer.eachMapping(m => { + if (inMapFirstItem) { + return + } + inMapFirstItem = m + }) + } + resMapConsumer.eachMapping(res => { if (res.originalLine == null) { return @@ -240,7 +251,7 @@ export function mapColumns( const map = codeMaps.get(res.name) if (!map) { - return null + return } let inMapOrigin: MappedPosition | null = null @@ -251,25 +262,33 @@ export function mapColumns( }) if (inMapOrigin.source == null) { inMapOrigin = null + return } } const mapConsumer = new SourceMapConsumer(map) mapConsumer.eachMapping(m => { - // console.log('message syntax map', m) mergedMapGenerator.addMapping({ original: { - line: inMapOrigin != null ? inMapOrigin.line : res.originalLine, - column: inMapOrigin != null ? inMapOrigin.column : res.originalColumn + line: inMapFirstItem + ? inMapFirstItem.originalLine + res.originalLine - 2 + : res.originalLine, + column: inMapFirstItem + ? inMapFirstItem.originalColumn + res.originalColumn + : res.originalColumn }, generated: { - line: inMapOrigin != null ? inMapOrigin.line : res.originalLine, + line: inMapFirstItem + ? inMapFirstItem.generatedLine + res.originalLine - 2 + : res.originalLine, // map column with message format compilation code map - column: - (inMapOrigin != null ? inMapOrigin.column : res.originalColumn) + - m.generatedColumn + column: inMapFirstItem + ? inMapFirstItem.generatedColumn + + res.originalColumn + + m.generatedColumn + : res.originalColumn + m.generatedColumn }, - source: inMapOrigin != null ? inMapOrigin.source : res.source, + source: inMapOrigin ? inMapOrigin.source : res.source, name: m.name // message format compilation code }) }) @@ -277,6 +296,7 @@ export function mapColumns( // eslint-disable-next-line @typescript-eslint/no-explicit-any const generator = mergedMapGenerator as any + // const targetConsumer = inMapConsumer || resMapConsumer const targetConsumer = inMapConsumer || resMapConsumer // eslint-disable-next-line @typescript-eslint/no-explicit-any ;(targetConsumer as any).sources.forEach((sourceFile: string) => { diff --git a/src/generator/json.ts b/src/generator/json.ts index 4522224..9913ec0 100644 --- a/src/generator/json.ts +++ b/src/generator/json.ts @@ -7,7 +7,7 @@ import { isString } from '@intlify/shared' import { createCodeGenerator, generateMessageFunction, - mapColumns + mapLinesColumns } from './codegen' import { RawSourceMap } from 'source-map' @@ -58,8 +58,9 @@ export function generate( // console.log('sourcemap json', m) // }) // } + // prettier-ignore const newMap = map - ? mapColumns((map as any).toJSON(), codeMaps, inSourceMap) || null // eslint-disable-line @typescript-eslint/no-explicit-any + ? mapLinesColumns((map as any).toJSON(), codeMaps, inSourceMap) || null // eslint-disable-line @typescript-eslint/no-explicit-any : null return { ast, @@ -97,8 +98,8 @@ function generateNode( ) generator.push(`Component.${variableName}.push({`) generator.indent() - generator.pushline(`locale: ${JSON.stringify(localeName)},`) - generator.push(`content: `) + generator.pushline(`"locale": ${JSON.stringify(localeName)},`) + generator.push(`"content": `) } break case 'JSONObjectExpression': @@ -192,7 +193,7 @@ function generateNode( generator.deindent() generator.push(`})`) generator.deindent() - generator.push(`}`) + generator.pushline(`}`) } break case 'JSONObjectExpression': diff --git a/src/generator/yaml.ts b/src/generator/yaml.ts index 61315b2..46c1f8f 100644 --- a/src/generator/yaml.ts +++ b/src/generator/yaml.ts @@ -6,7 +6,7 @@ import { isString } from '@intlify/shared' import { createCodeGenerator, generateMessageFunction, - mapColumns + mapLinesColumns } from './codegen' import { parseYAML, traverseNodes } from 'yaml-eslint-parser' import { RawSourceMap } from 'source-map' @@ -48,8 +48,9 @@ export function generate( const codeMaps = generateNode(generator, ast, options) const { code, map } = generator.context() + // prettier-ignore const newMap = map - ? mapColumns((map as any).toJSON(), codeMaps, inSourceMap) || null // eslint-disable-line @typescript-eslint/no-explicit-any + ? mapLinesColumns((map as any).toJSON(), codeMaps, inSourceMap) || null // eslint-disable-line @typescript-eslint/no-explicit-any : null return { ast, diff --git a/src/index.ts b/src/index.ts index ce8e7c4..89a3e10 100644 --- a/src/index.ts +++ b/src/index.ts @@ -16,6 +16,7 @@ const loader: webpack.loader.Loader = function ( const loaderContext = this // eslint-disable-line @typescript-eslint/no-this-alias const query = parse(loaderContext.resourceQuery) const options = getOptions(loaderContext, query, sourceMap) as CodeGenOptions + // console.log('query', this.resourcePath, this.resourceQuery, query, source) const langInfo = !isEmptyObject(query) ? isString(query.lang) ? query.lang @@ -25,6 +26,9 @@ const loader: webpack.loader.Loader = function ( try { this.cacheable && this.cacheable() // if (sourceMap) { + // console.log('in map', sourceMap) + // } + // if (sourceMap) { // const s = new SourceMapConsumer(sourceMap) // console.log('sourcemap raw', sourceMap) // s.eachMapping(m => { @@ -33,7 +37,7 @@ const loader: webpack.loader.Loader = function ( // } const generate = /json5?/.test(langInfo) ? generateJSON : generateYAML const { code, map } = generate(source, options) - // console.log(options.filename, code) + // console.log('code', code) this.callback(null, code, map) } catch (err) { this.emitError(`[vue-i18n-loader]: ${err.message}`) diff --git a/test/utils.ts b/test/utils.ts index 3416349..f19bb28 100644 --- a/test/utils.ts +++ b/test/utils.ts @@ -73,6 +73,74 @@ export function bundle(fixture: string, options = {}): Promise { }) } +export function bundleEx( + fixture: string, + options = {} +): Promise { + const baseConfig: webpack.Configuration = { + mode: 'development', + devtool: 'source-map', + entry: path.resolve(__dirname, './fixtures/entry.js'), + resolve: { + alias: { + '~target': path.resolve(__dirname, './fixtures', fixture) + } + }, + output: { + path: '/', + filename: 'bundle.js' + }, + module: { + rules: [ + { + test: /\.vue$/, + loader: 'vue-loader' + }, + { + test: /\.(json5?|ya?ml)$/, + type: 'javascript/auto', + include: [path.resolve(__dirname, './fixtures/locales')], + use: [ + { + loader: path.resolve(__dirname, '../src/index.ts'), + options + } + ] + }, + { + resourceQuery: /blockType=i18n/, + type: 'javascript/auto', + use: [ + { + loader: path.resolve(__dirname, '../src/index.ts'), + options + } + ] + } + ] + }, + plugins: [new VueLoaderPlugin()] + } + + const config = merge({}, baseConfig) + const compiler = webpack(config) + + const mfs = new memoryfs() // eslint-disable-line + compiler.outputFileSystem = mfs + + return new Promise((resolve, reject) => { + compiler.run((err, stats) => { + if (err) { + return reject(err) + } + if (stats.hasErrors()) { + return reject(new Error(stats.toJson().errors.join(' | '))) + } + resolve({ code: mfs.readFileSync('/bundle.js').toString(), stats }) + }) + }) +} + export function bundleLocale( fixture: string, options = {} diff --git a/yarn.lock b/yarn.lock index 03b5ab4..9d1282d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -780,11 +780,6 @@ resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.45.tgz#e9387572998e5ecdac221950dab3e8c3b16af884" integrity sha512-jnqIUKDUqJbDIUxm0Uj7bnlMnRm1T/eZ9N+AVMqhPgzrba2GhGG5o/jCTwmdPK709nEZsGoMzXEDUjcXHa3W0g== -"@types/flat@^5.0.1": - version "5.0.1" - resolved "https://registry.yarnpkg.com/@types/flat/-/flat-5.0.1.tgz#9d703bbfb59ad9ec9ce376bdeb93a0f85da27059" - integrity sha512-ykRODHi9G9exJdTZvQggsqCUtB7jqiwLHcXCjNMb7zgWx6Lc2bydIUYBG1+It6VXZVFaeROv6HqPjDCAsoPG3w== - "@types/glob@^7.1.1": version "7.1.3" resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.3.tgz#e6ba80f36b7daad2c685acd9266382e68985c183" @@ -827,11 +822,6 @@ jest-diff "^26.0.0" pretty-format "^26.0.0" -"@types/js-yaml@^3.12.5": - version "3.12.5" - resolved "https://registry.yarnpkg.com/@types/js-yaml/-/js-yaml-3.12.5.tgz#136d5e6a57a931e1cce6f9d8126aa98a9c92a6bb" - integrity sha512-JCcp6J0GV66Y4ZMDAQCXot4xprYB+Zfd3meK9+INSJeVZwJmHAW30BBEEkPzXswMXuiyReUGOP3GxrADc9wPww== - "@types/jsdom@^16.2.5": version "16.2.5" resolved "https://registry.yarnpkg.com/@types/jsdom/-/jsdom-16.2.5.tgz#74ebad438741d249ecb416c5486dcde4217eb66c" @@ -846,11 +836,6 @@ resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.6.tgz#f4c7ec43e81b319a9815115031709f26987891f0" integrity sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw== -"@types/json5@^0.0.30": - version "0.0.30" - resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.30.tgz#44cb52f32a809734ca562e685c6473b5754a7818" - integrity sha512-sqm9g7mHlPY/43fcSNrCYfOeX9zkTTK+euO5E6+CVijSMm5tTjkVdwdqRkY3ljjIAf8679vps5jKUoJBCLsMDA== - "@types/loader-utils@^2.0.0": version "2.0.1" resolved "https://registry.yarnpkg.com/@types/loader-utils/-/loader-utils-2.0.1.tgz#4073425aca25762099823f7b922e86599c2b85ec" @@ -896,7 +881,7 @@ resolved "https://registry.yarnpkg.com/@types/parse5/-/parse5-5.0.3.tgz#e7b5aebbac150f8b5fdd4a46e7f0bd8e65e19109" integrity sha512-kUNnecmtkunAoQ3CnjmMkzNU/gtxG8guhi+Fk2U/kOpIKjIMKnXGp4IJCgQJrXSgMsWYimYG4TGjz/UzbGEBTw== -"@types/prettier@^2.0.0", "@types/prettier@^2.1.5": +"@types/prettier@^2.0.0": version "2.1.5" resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.1.5.tgz#b6ab3bba29e16b821d84e09ecfaded462b816b00" integrity sha512-UEyp8LwZ4Dg30kVU2Q3amHHyTn1jEdhCIE59ANed76GaT1Vp76DD3ZWSAxgCrw6wJ0TqeoBpqmfUHiUDPs//HQ== @@ -9030,7 +9015,7 @@ vue-i18n@^9.0.0-beta.14: "@intlify/shared" "9.0.0-beta.14" "@vue/devtools-api" "^6.0.0-beta.2" -vue-loader@^16.1.0: +vue-loader@^16.1.2: version "16.1.2" resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-16.1.2.tgz#5c03b6c50d2a5f983c7ceba15c50d78ca2b298f4" integrity sha512-8QTxh+Fd+HB6fiL52iEVLKqE9N1JSlMXLR92Ijm6g8PZrwIxckgpqjPDWRP5TWxdiPaHR+alUWsnu1ShQOwt+Q== @@ -9403,10 +9388,10 @@ yallist@^4.0.0: resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== -yaml-eslint-parser@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/yaml-eslint-parser/-/yaml-eslint-parser-0.1.0.tgz#37e7281b6bd20186c76c4d3b6f87f21ffe5db827" - integrity sha512-JhDwzS/zlgxdOuzFG50sMZ4bDo3xbU5TjLyfW+Br7laIh/zaa//lRhHPVOQm6FanMvveS9DG+z6OkCVefyw5QA== +yaml-eslint-parser@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/yaml-eslint-parser/-/yaml-eslint-parser-0.2.0.tgz#76bfe1645caf39adcd9b274c32752b3f6da90882" + integrity sha512-ZIqeTBi4K1eXzqYp9CqfN5Gr0RIA4q1T7+jiv0XoUV1ti05FL31iH7Yfw5aY0GpIJv/A003yEjvVTDb3XLH31A== dependencies: eslint-visitor-keys "^1.3.0" yaml "^1.10.0" From b5690120be92c81a610dbab384545501a4f98427 Mon Sep 17 00:00:00 2001 From: kazuya kawaguchi Date: Mon, 21 Dec 2020 16:43:36 +0900 Subject: [PATCH 3/3] updates --- example/webpack.config.js | 3 +- package.json | 10 +-- src/generator/codegen.ts | 2 +- src/generator/json.ts | 9 ++- src/generator/yaml.ts | 12 +-- test/__snapshots__/custom-block.test.ts.snap | 60 +++++++-------- test/custom-block.test.ts | 32 ++++---- .../__snapshots__/codegen.test.ts.snap | 2 +- .../generator/__snapshots__/json.test.ts.snap | 52 ++++++------- .../__snapshots__/json5.test.ts.snap | 30 ++++---- .../generator/__snapshots__/yaml.test.ts.snap | 60 +++++++-------- yarn.lock | 76 +++++++++---------- 12 files changed, 175 insertions(+), 173 deletions(-) diff --git a/example/webpack.config.js b/example/webpack.config.js index 86a8a8e..ee366b5 100644 --- a/example/webpack.config.js +++ b/example/webpack.config.js @@ -20,8 +20,7 @@ module.exports = { // is a simple `export * from '@vue/runtime-dom`. However having this // extra re-export somehow causes webpack to always invalidate the module // on the first HMR update and causes the page to reload. - vue: '@vue/runtime-dom', - 'vue-i18n': 'vue-i18n/dist/vue-i18n.runtime.esm-bundler.js' + vue: '@vue/runtime-dom' } }, devServer: { diff --git a/package.json b/package.json index 16bbc84..8ee4d4a 100644 --- a/package.json +++ b/package.json @@ -24,15 +24,15 @@ } }, "dependencies": { - "@intlify/core-base": "^9.0.0-beta.14", - "@intlify/message-compiler": "^9.0.0-beta.14", - "@intlify/shared": "^9.0.0-beta.14", + "@intlify/core-base": "^9.0.0-beta.15", + "@intlify/message-compiler": "^9.0.0-beta.15", + "@intlify/shared": "^9.0.0-beta.15", "jsonc-eslint-parser": "^0.6.0", "loader-utils": "^2.0.0", "yaml-eslint-parser": "^0.2.0" }, "devDependencies": { - "@intlify/runtime": "^9.0.0-beta.14", + "@intlify/runtime": "^9.0.0-beta.15", "@types/eslint": "^7.2.6", "@types/eslint-visitor-keys": "^1.0.0", "@types/jest": "^26.0.16", @@ -65,7 +65,7 @@ "typescript": "^4.1.2", "typescript-eslint-language-service": "^4.1.2", "vue": "^3.0.4", - "vue-i18n": "^9.0.0-beta.14", + "vue-i18n": "^9.0.0-beta.15", "vue-loader": "^16.1.2", "webpack": "^4.44.2", "webpack-cli": "^3.3.12", diff --git a/src/generator/codegen.ts b/src/generator/codegen.ts index 21c3602..73b85da 100644 --- a/src/generator/codegen.ts +++ b/src/generator/codegen.ts @@ -215,7 +215,7 @@ export function generateMessageFunction( const { code, ast, map } = baseCompile(msg, newOptions) const genCode = !occured ? env === 'development' - ? `(()=>{const fn=${code};fn.source=${JSON.stringify(msg)};return fn})()` + ? `(()=>{const fn=${code};fn.source=${JSON.stringify(msg)};return fn;})()` : `${code}` : msg return { code: genCode, ast, map } diff --git a/src/generator/json.ts b/src/generator/json.ts index 9913ec0..0caab18 100644 --- a/src/generator/json.ts +++ b/src/generator/json.ts @@ -79,9 +79,6 @@ function generateNode( const { forceStringify } = generator.context() const codeMaps = new Map() const { type, sourceMap, isGlobal, locale } = options - const variableName = - type === 'sfc' ? (!isGlobal ? '__i18n' : '__i18nGlobal') : '' - const localeName = type === 'sfc' ? (locale != null ? locale : `""`) : '' traverseNodes(node, { enterNode(node: JSONNode, parent: JSONNode) { @@ -91,6 +88,10 @@ function generateNode( generator.push(`export default `) } else { // for 'sfc' + const variableName = + type === 'sfc' ? (!isGlobal ? '__i18n' : '__i18nGlobal') : '' + const localeName = + type === 'sfc' ? (locale != null ? locale : `""`) : '' generator.push(`export default function (Component) {`) generator.indent() generator.pushline( @@ -99,7 +100,7 @@ function generateNode( generator.push(`Component.${variableName}.push({`) generator.indent() generator.pushline(`"locale": ${JSON.stringify(localeName)},`) - generator.push(`"content": `) + generator.push(`"resource": `) } break case 'JSONObjectExpression': diff --git a/src/generator/yaml.ts b/src/generator/yaml.ts index 46c1f8f..889ab08 100644 --- a/src/generator/yaml.ts +++ b/src/generator/yaml.ts @@ -69,9 +69,6 @@ function generateNode( const { forceStringify } = generator.context() const codeMaps = new Map() const { type, sourceMap, isGlobal, locale } = options - const variableName = - type === 'sfc' ? (!isGlobal ? '__i18n' : '__i18nGlobal') : '' - const localeName = type === 'sfc' ? (locale != null ? locale : `""`) : '' traverseNodes(node, { enterNode(node: YAMLNode, parent: YAMLNode) { @@ -80,7 +77,10 @@ function generateNode( if (type === 'plain') { generator.push(`export default `) } else { - // for 'sfc' + const variableName = + type === 'sfc' ? (!isGlobal ? '__i18n' : '__i18nGlobal') : '' + const localeName = + type === 'sfc' ? (locale != null ? locale : `""`) : '' generator.push(`export default function (Component) {`) generator.indent() generator.pushline( @@ -88,8 +88,8 @@ function generateNode( ) generator.push(`Component.${variableName}.push({`) generator.indent() - generator.pushline(`locale: ${JSON.stringify(localeName)},`) - generator.push(`content: `) + generator.pushline(`"locale": ${JSON.stringify(localeName)},`) + generator.push(`"resource": `) } break case 'YAMLMapping': diff --git a/test/__snapshots__/custom-block.test.ts.snap b/test/__snapshots__/custom-block.test.ts.snap index bc8d149..1bb159f 100644 --- a/test/__snapshots__/custom-block.test.ts.snap +++ b/test/__snapshots__/custom-block.test.ts.snap @@ -3,12 +3,12 @@ exports[`basic 1`] = ` Array [ Object { - "content": Object { + "locale": "", + "resource": Object { "en": Object { "hello": [Function], }, }, - "locale": "", }, ] `; @@ -16,12 +16,12 @@ Array [ exports[`global 1`] = ` Array [ Object { - "content": Object { + "locale": "", + "resource": Object { "en": Object { "hello": [Function], }, }, - "locale": "", }, ] `; @@ -29,10 +29,10 @@ Array [ exports[`global and local 1`] = ` Array [ Object { - "content": Object { + "locale": "ja", + "resource": Object { "hello": [Function], }, - "locale": "ja", }, ] `; @@ -40,12 +40,12 @@ Array [ exports[`global and local 2`] = ` Array [ Object { - "content": Object { + "locale": "", + "resource": Object { "en": Object { "hello": [Function], }, }, - "locale": "", }, ] `; @@ -53,12 +53,12 @@ Array [ exports[`import 1`] = ` Array [ Object { - "content": Object { + "locale": "", + "resource": Object { "en": Object { "hello": [Function], }, }, - "locale": "", }, ] `; @@ -66,12 +66,12 @@ Array [ exports[`json5 1`] = ` Array [ Object { - "content": Object { + "locale": "", + "resource": Object { "en": Object { "hello": [Function], }, }, - "locale": "", }, ] `; @@ -79,10 +79,10 @@ Array [ exports[`locale attr 1`] = ` Array [ Object { - "content": Object { + "locale": "ja", + "resource": Object { "hello": [Function], }, - "locale": "ja", }, ] `; @@ -90,18 +90,18 @@ Array [ exports[`locale attr and basic 1`] = ` Array [ Object { - "content": Object { + "locale": "", + "resource": Object { "en": Object { "hello": [Function], }, }, - "locale": "", }, Object { - "content": Object { + "locale": "ja", + "resource": Object { "hello": [Function], }, - "locale": "ja", }, ] `; @@ -109,10 +109,10 @@ Array [ exports[`locale attr and import 1`] = ` Array [ Object { - "content": Object { + "locale": "en", + "resource": Object { "hello": [Function], }, - "locale": "en", }, ] `; @@ -120,20 +120,20 @@ Array [ exports[`multiple 1`] = ` Array [ Object { - "content": Object { + "locale": "", + "resource": Object { "en": Object { "hello": [Function], }, }, - "locale": "", }, Object { - "content": Object { + "locale": "", + "resource": Object { "ja": Object { "hello": [Function], }, }, - "locale": "", }, ] `; @@ -141,12 +141,12 @@ Array [ exports[`special characters 1`] = ` Array [ Object { - "content": Object { + "locale": "", + "resource": Object { "en": Object { "hello": [Function], }, }, - "locale": "", }, ] `; @@ -154,16 +154,16 @@ Array [ exports[`yaml 1`] = ` Array [ Object { - "content": Object { + "locale": "en", + "resource": Object { "hello": [Function], }, - "locale": "en", }, Object { - "content": Object { + "locale": "ja", + "resource": Object { "hello": [Function], }, - "locale": "ja", }, ] `; diff --git a/test/custom-block.test.ts b/test/custom-block.test.ts index 317373c..2cf5a6e 100644 --- a/test/custom-block.test.ts +++ b/test/custom-block.test.ts @@ -6,7 +6,7 @@ test('basic', async () => { expect(module.__i18n).toMatchSnapshot() const i18n = module.__i18n.pop() expect(i18n.locale).toEqual('') - expect(i18n.content.en.hello(createMessageContext())).toEqual('hello world!') + expect(i18n.resource.en.hello(createMessageContext())).toEqual('hello world!') }) test('special characters', async () => { @@ -14,7 +14,7 @@ test('special characters', async () => { expect(module.__i18n).toMatchSnapshot() const i18n = module.__i18n.pop() expect(i18n.locale).toEqual('') - expect(i18n.content.en.hello(createMessageContext())).toEqual( + expect(i18n.resource.en.hello(createMessageContext())).toEqual( 'hello\ngreat\t"world"' ) }) @@ -25,12 +25,12 @@ test('multiple', async () => { expect(module.__i18n.length).toEqual(2) let i18n = module.__i18n.pop() expect(i18n.locale).toEqual('') - expect(i18n.content.ja.hello(createMessageContext())).toEqual( + expect(i18n.resource.ja.hello(createMessageContext())).toEqual( 'こんにちは、世界!' ) i18n = module.__i18n.pop() expect(i18n.locale).toEqual('') - expect(i18n.content.en.hello(createMessageContext())).toEqual('hello world!') + expect(i18n.resource.en.hello(createMessageContext())).toEqual('hello world!') }) test('import', async () => { @@ -38,7 +38,7 @@ test('import', async () => { expect(module.__i18n).toMatchSnapshot() const i18n = module.__i18n.pop() expect(i18n.locale).toEqual('') - expect(i18n.content.en.hello(createMessageContext())).toEqual('hello world!') + expect(i18n.resource.en.hello(createMessageContext())).toEqual('hello world!') }) test('locale attr', async () => { @@ -46,7 +46,7 @@ test('locale attr', async () => { expect(module.__i18n).toMatchSnapshot() const i18n = module.__i18n.pop() expect(i18n.locale).toEqual('ja') - expect(i18n.content.hello(createMessageContext())).toEqual( + expect(i18n.resource.hello(createMessageContext())).toEqual( 'こんにちは、世界!' ) }) @@ -56,12 +56,12 @@ test('locale attr and basic', async () => { expect(module.__i18n).toMatchSnapshot() let i18n = module.__i18n.pop() expect(i18n.locale).toEqual('ja') - expect(i18n.content.hello(createMessageContext())).toEqual( + expect(i18n.resource.hello(createMessageContext())).toEqual( 'こんにちは、世界!' ) i18n = module.__i18n.pop() expect(i18n.locale).toEqual('') - expect(i18n.content.en.hello(createMessageContext())).toEqual('hello world!') + expect(i18n.resource.en.hello(createMessageContext())).toEqual('hello world!') }) test('locale attr and import', async () => { @@ -69,7 +69,7 @@ test('locale attr and import', async () => { expect(module.__i18n).toMatchSnapshot() const i18n = module.__i18n.pop() expect(i18n.locale).toEqual('en') - expect(i18n.content.hello(createMessageContext())).toEqual('hello world!') + expect(i18n.resource.hello(createMessageContext())).toEqual('hello world!') }) test('yaml', async () => { @@ -77,12 +77,12 @@ test('yaml', async () => { expect(module.__i18n).toMatchSnapshot() let i18n = module.__i18n.pop() expect(i18n.locale).toEqual('ja') - expect(i18n.content.hello(createMessageContext())).toEqual( + expect(i18n.resource.hello(createMessageContext())).toEqual( 'こんにちは、世界!' ) i18n = module.__i18n.pop() expect(i18n.locale).toEqual('en') - expect(i18n.content.hello(createMessageContext())).toEqual('hello world!') + expect(i18n.resource.hello(createMessageContext())).toEqual('hello world!') }) test('json5', async () => { @@ -90,7 +90,7 @@ test('json5', async () => { expect(module.__i18n).toMatchSnapshot() const i18n = module.__i18n.pop() expect(i18n.locale).toEqual('') - expect(i18n.content.en.hello(createMessageContext())).toEqual('hello world!') + expect(i18n.resource.en.hello(createMessageContext())).toEqual('hello world!') }) test('global', async () => { @@ -99,7 +99,9 @@ test('global', async () => { expect(module.__i18nGlobal).toMatchSnapshot() const i18n = module.__i18nGlobal.pop() expect(i18n.locale).toEqual('') - expect(i18n.content.en.hello(createMessageContext())).toEqual('hello global!') + expect(i18n.resource.en.hello(createMessageContext())).toEqual( + 'hello global!' + ) }) test('global and local', async () => { @@ -108,8 +110,8 @@ test('global and local', async () => { expect(module.__i18nGlobal).toMatchSnapshot() const l = module.__i18n.pop() expect(l.locale).toEqual('ja') - expect(l.content.hello(createMessageContext())).toEqual('hello local!') + expect(l.resource.hello(createMessageContext())).toEqual('hello local!') const g = module.__i18nGlobal.pop() expect(g.locale).toEqual('') - expect(g.content.en.hello(createMessageContext())).toEqual('hello global!') + expect(g.resource.en.hello(createMessageContext())).toEqual('hello global!') }) diff --git a/test/generator/__snapshots__/codegen.test.ts.snap b/test/generator/__snapshots__/codegen.test.ts.snap index 6cdffcd..3a46f9f 100644 --- a/test/generator/__snapshots__/codegen.test.ts.snap +++ b/test/generator/__snapshots__/codegen.test.ts.snap @@ -60,7 +60,7 @@ Object { "start": 0, "type": 0, }, - "code": "(()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"hello\\"])};fn.source=\\"hello\\";return fn})()", + "code": "(()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"hello\\"])};fn.source=\\"hello\\";return fn;})()", "map": Object { "mappings": "mEAAAA", "names": Array [ diff --git a/test/generator/__snapshots__/json.test.ts.snap b/test/generator/__snapshots__/json.test.ts.snap index ab6a51c..308c18d 100644 --- a/test/generator/__snapshots__/json.test.ts.snap +++ b/test/generator/__snapshots__/json.test.ts.snap @@ -2,30 +2,30 @@ exports[`complex: code 1`] = ` "export default { - \\"hi\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"hi there!\\"])};fn.source=\\"hi there!\\";return fn})(), + \\"hi\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"hi there!\\"])};fn.source=\\"hi there!\\";return fn;})(), \\"nested\\": { - \\"hello\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"hello world!\\"])};fn.source=\\"hello world!\\";return fn})(), + \\"hello\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"hello world!\\"])};fn.source=\\"hello world!\\";return fn;})(), \\"more\\": { - \\"plural\\": (()=>{const fn=(ctx) => {const { normalize: _normalize, linked: _linked, interpolate: _interpolate, list: _list, named: _named, plural: _plural } = ctx;return _plural([_normalize([_linked(\\"no apples\\", \\"caml\\")]), _normalize([_interpolate(_list(0)), \\" apple\\"]), _normalize([_interpolate(_named(\\"n\\")), \\" apples\\"])])};fn.source=\\"@.caml:{'no apples'} | {0} apple | {n} apples\\";return fn})() + \\"plural\\": (()=>{const fn=(ctx) => {const { normalize: _normalize, linked: _linked, interpolate: _interpolate, list: _list, named: _named, plural: _plural } = ctx;return _plural([_normalize([_linked(\\"no apples\\", \\"caml\\")]), _normalize([_interpolate(_list(0)), \\" apple\\"]), _normalize([_interpolate(_named(\\"n\\")), \\" apples\\"])])};fn.source=\\"@.caml:{'no apples'} | {0} apple | {n} apples\\";return fn;})() }, - \\"list\\": (()=>{const fn=(ctx) => {const { normalize: _normalize, interpolate: _interpolate, list: _list } = ctx;return _normalize([\\"hi, \\", _interpolate(_list(0)), \\" !\\"])};fn.source=\\"hi, {0} !\\";return fn})() + \\"list\\": (()=>{const fn=(ctx) => {const { normalize: _normalize, interpolate: _interpolate, list: _list } = ctx;return _normalize([\\"hi, \\", _interpolate(_list(0)), \\" !\\"])};fn.source=\\"hi, {0} !\\";return fn;})() }, - \\"こんにちは\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"こんにちは!\\"])};fn.source=\\"こんにちは!\\";return fn})(), - \\"single-quote\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"I don't know!\\"])};fn.source=\\"I don't know!\\";return fn})(), - \\"emoji\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"😺\\"])};fn.source=\\"😺\\";return fn})(), - \\"unicode\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"A\\"])};fn.source=\\"A\\";return fn})(), - \\"unicode-escape\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"\\\\\\\\u0041\\"])};fn.source=\\"\\\\\\\\u0041\\";return fn})(), - \\"backslash-single-quote\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"\\\\\\\\'\\"])};fn.source=\\"\\\\\\\\'\\";return fn})(), - \\"backslash-backslash\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"\\\\\\\\\\\\\\\\\\"])};fn.source=\\"\\\\\\\\\\\\\\\\\\";return fn})(), + \\"こんにちは\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"こんにちは!\\"])};fn.source=\\"こんにちは!\\";return fn;})(), + \\"single-quote\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"I don't know!\\"])};fn.source=\\"I don't know!\\";return fn;})(), + \\"emoji\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"😺\\"])};fn.source=\\"😺\\";return fn;})(), + \\"unicode\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"A\\"])};fn.source=\\"A\\";return fn;})(), + \\"unicode-escape\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"\\\\\\\\u0041\\"])};fn.source=\\"\\\\\\\\u0041\\";return fn;})(), + \\"backslash-single-quote\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"\\\\\\\\'\\"])};fn.source=\\"\\\\\\\\'\\";return fn;})(), + \\"backslash-backslash\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"\\\\\\\\\\\\\\\\\\"])};fn.source=\\"\\\\\\\\\\\\\\\\\\";return fn;})(), \\"errors\\": [ - (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"ERROR1001\\"])};fn.source=\\"ERROR1001\\";return fn})(), - (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"ERROR1002\\"])};fn.source=\\"ERROR1002\\";return fn})() + (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"ERROR1001\\"])};fn.source=\\"ERROR1001\\";return fn;})(), + (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"ERROR1002\\"])};fn.source=\\"ERROR1002\\";return fn;})() ], \\"complex\\": { \\"warnings\\": [ - (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"NOTE: This is warning\\"])};fn.source=\\"NOTE: This is warning\\";return fn})(), + (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"NOTE: This is warning\\"])};fn.source=\\"NOTE: This is warning\\";return fn;})(), { - \\"named-waring\\": (()=>{const fn=(ctx) => {const { normalize: _normalize, interpolate: _interpolate, named: _named } = ctx;return _normalize([\\"this is \\", _interpolate(_named(\\"type\\")), \\" warining\\"])};fn.source=\\"this is {type} warining\\";return fn})() + \\"named-waring\\": (()=>{const fn=(ctx) => {const { normalize: _normalize, interpolate: _interpolate, named: _named } = ctx;return _normalize([\\"this is \\", _interpolate(_named(\\"type\\")), \\" warining\\"])};fn.source=\\"this is {type} warining\\";return fn;})() } ] } @@ -98,10 +98,10 @@ Object { exports[`force stringify: code 1`] = ` "export default { - \\"trueValue\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"true\\"])};fn.source=\\"true\\";return fn})(), - \\"falseValue\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"false\\"])};fn.source=\\"false\\";return fn})(), - \\"nullValue\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"null\\"])};fn.source=\\"null\\";return fn})(), - \\"numberValue\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"1\\"])};fn.source=\\"1\\";return fn})() + \\"trueValue\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"true\\"])};fn.source=\\"true\\";return fn;})(), + \\"falseValue\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"false\\"])};fn.source=\\"false\\";return fn;})(), + \\"nullValue\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"null\\"])};fn.source=\\"null\\";return fn;})(), + \\"numberValue\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"1\\"])};fn.source=\\"1\\";return fn;})() }" `; @@ -132,13 +132,13 @@ Object { exports[`simple: code 1`] = ` "export default { - \\"hi\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"hi there!\\"])};fn.source=\\"hi there!\\";return fn})(), - \\"hello\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"hello world!\\"])};fn.source=\\"hello world!\\";return fn})(), - \\"named\\": (()=>{const fn=(ctx) => {const { normalize: _normalize, interpolate: _interpolate, named: _named } = ctx;return _normalize([\\"hi, \\", _interpolate(_named(\\"name\\")), \\" !\\"])};fn.source=\\"hi, {name} !\\";return fn})(), - \\"list\\": (()=>{const fn=(ctx) => {const { normalize: _normalize, interpolate: _interpolate, list: _list } = ctx;return _normalize([\\"hi, \\", _interpolate(_list(0)), \\" !\\"])};fn.source=\\"hi, {0} !\\";return fn})(), - \\"literal\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"hi, \\", \\"kazupon\\", \\" !\\"])};fn.source=\\"hi, { 'kazupon' } !\\";return fn})(), - \\"linked\\": (()=>{const fn=(ctx) => {const { normalize: _normalize, linked: _linked } = ctx;return _normalize([\\"hi, \\", _linked(\\"name\\"), \\" !\\"])};fn.source=\\"hi, @:name !\\";return fn})(), - \\"plural\\": (()=>{const fn=(ctx) => {const { normalize: _normalize, linked: _linked, interpolate: _interpolate, list: _list, named: _named, plural: _plural } = ctx;return _plural([_normalize([_linked(\\"no apples\\", \\"caml\\")]), _normalize([_interpolate(_list(0)), \\" apple\\"]), _normalize([_interpolate(_named(\\"n\\")), \\" apples\\"])])};fn.source=\\"@.caml:{'no apples'} | {0} apple | {n} apples\\";return fn})() + \\"hi\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"hi there!\\"])};fn.source=\\"hi there!\\";return fn;})(), + \\"hello\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"hello world!\\"])};fn.source=\\"hello world!\\";return fn;})(), + \\"named\\": (()=>{const fn=(ctx) => {const { normalize: _normalize, interpolate: _interpolate, named: _named } = ctx;return _normalize([\\"hi, \\", _interpolate(_named(\\"name\\")), \\" !\\"])};fn.source=\\"hi, {name} !\\";return fn;})(), + \\"list\\": (()=>{const fn=(ctx) => {const { normalize: _normalize, interpolate: _interpolate, list: _list } = ctx;return _normalize([\\"hi, \\", _interpolate(_list(0)), \\" !\\"])};fn.source=\\"hi, {0} !\\";return fn;})(), + \\"literal\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"hi, \\", \\"kazupon\\", \\" !\\"])};fn.source=\\"hi, { 'kazupon' } !\\";return fn;})(), + \\"linked\\": (()=>{const fn=(ctx) => {const { normalize: _normalize, linked: _linked } = ctx;return _normalize([\\"hi, \\", _linked(\\"name\\"), \\" !\\"])};fn.source=\\"hi, @:name !\\";return fn;})(), + \\"plural\\": (()=>{const fn=(ctx) => {const { normalize: _normalize, linked: _linked, interpolate: _interpolate, list: _list, named: _named, plural: _plural } = ctx;return _plural([_normalize([_linked(\\"no apples\\", \\"caml\\")]), _normalize([_interpolate(_list(0)), \\" apple\\"]), _normalize([_interpolate(_named(\\"n\\")), \\" apples\\"])])};fn.source=\\"@.caml:{'no apples'} | {0} apple | {n} apples\\";return fn;})() }" `; diff --git a/test/generator/__snapshots__/json5.test.ts.snap b/test/generator/__snapshots__/json5.test.ts.snap index 89a8d6b..15f7630 100644 --- a/test/generator/__snapshots__/json5.test.ts.snap +++ b/test/generator/__snapshots__/json5.test.ts.snap @@ -2,30 +2,30 @@ exports[`json5: code 1`] = ` "export default { - \\"hi\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"hi there!\\"])};fn.source=\\"hi there!\\";return fn})(), + \\"hi\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"hi there!\\"])};fn.source=\\"hi there!\\";return fn;})(), \\"nested\\": { - \\"hello\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"hello world!\\"])};fn.source=\\"hello world!\\";return fn})(), + \\"hello\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"hello world!\\"])};fn.source=\\"hello world!\\";return fn;})(), \\"more\\": { - \\"plural\\": (()=>{const fn=(ctx) => {const { normalize: _normalize, linked: _linked, interpolate: _interpolate, list: _list, named: _named, plural: _plural } = ctx;return _plural([_normalize([_linked(\\"no apples\\", \\"caml\\")]), _normalize([_interpolate(_list(0)), \\" apple\\"]), _normalize([_interpolate(_named(\\"n\\")), \\" apples\\"])])};fn.source=\\"@.caml:{'no apples'} | {0} apple | {n} apples\\";return fn})() + \\"plural\\": (()=>{const fn=(ctx) => {const { normalize: _normalize, linked: _linked, interpolate: _interpolate, list: _list, named: _named, plural: _plural } = ctx;return _plural([_normalize([_linked(\\"no apples\\", \\"caml\\")]), _normalize([_interpolate(_list(0)), \\" apple\\"]), _normalize([_interpolate(_named(\\"n\\")), \\" apples\\"])])};fn.source=\\"@.caml:{'no apples'} | {0} apple | {n} apples\\";return fn;})() }, - \\"list\\": (()=>{const fn=(ctx) => {const { normalize: _normalize, interpolate: _interpolate, list: _list } = ctx;return _normalize([\\"hi, \\", _interpolate(_list(0)), \\" !\\"])};fn.source=\\"hi, {0} !\\";return fn})() + \\"list\\": (()=>{const fn=(ctx) => {const { normalize: _normalize, interpolate: _interpolate, list: _list } = ctx;return _normalize([\\"hi, \\", _interpolate(_list(0)), \\" !\\"])};fn.source=\\"hi, {0} !\\";return fn;})() }, - \\"こんにちは\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"こんにちは!\\"])};fn.source=\\"こんにちは!\\";return fn})(), - \\"single-quote\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"I don't know!\\"])};fn.source=\\"I don't know!\\";return fn})(), - \\"emoji\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"😺\\"])};fn.source=\\"😺\\";return fn})(), - \\"unicode\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"A\\"])};fn.source=\\"A\\";return fn})(), - \\"unicode-escape\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"\\\\\\\\u0041\\"])};fn.source=\\"\\\\\\\\u0041\\";return fn})(), - \\"backslash-single-quote\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"\\\\\\\\'\\"])};fn.source=\\"\\\\\\\\'\\";return fn})(), - \\"backslash-backslash\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"\\\\\\\\\\\\\\\\\\"])};fn.source=\\"\\\\\\\\\\\\\\\\\\";return fn})(), + \\"こんにちは\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"こんにちは!\\"])};fn.source=\\"こんにちは!\\";return fn;})(), + \\"single-quote\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"I don't know!\\"])};fn.source=\\"I don't know!\\";return fn;})(), + \\"emoji\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"😺\\"])};fn.source=\\"😺\\";return fn;})(), + \\"unicode\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"A\\"])};fn.source=\\"A\\";return fn;})(), + \\"unicode-escape\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"\\\\\\\\u0041\\"])};fn.source=\\"\\\\\\\\u0041\\";return fn;})(), + \\"backslash-single-quote\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"\\\\\\\\'\\"])};fn.source=\\"\\\\\\\\'\\";return fn;})(), + \\"backslash-backslash\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"\\\\\\\\\\\\\\\\\\"])};fn.source=\\"\\\\\\\\\\\\\\\\\\";return fn;})(), \\"errors\\": [ - (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"ERROR1001\\"])};fn.source=\\"ERROR1001\\";return fn})(), - (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"ERROR1002\\"])};fn.source=\\"ERROR1002\\";return fn})() + (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"ERROR1001\\"])};fn.source=\\"ERROR1001\\";return fn;})(), + (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"ERROR1002\\"])};fn.source=\\"ERROR1002\\";return fn;})() ], \\"complex\\": { \\"warnings\\": [ - (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"NOTE: This is warning\\"])};fn.source=\\"NOTE: This is warning\\";return fn})(), + (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"NOTE: This is warning\\"])};fn.source=\\"NOTE: This is warning\\";return fn;})(), { - \\"named-waring\\": (()=>{const fn=(ctx) => {const { normalize: _normalize, interpolate: _interpolate, named: _named } = ctx;return _normalize([\\"this is \\", _interpolate(_named(\\"type\\")), \\" warining\\"])};fn.source=\\"this is {type} warining\\";return fn})() + \\"named-waring\\": (()=>{const fn=(ctx) => {const { normalize: _normalize, interpolate: _interpolate, named: _named } = ctx;return _normalize([\\"this is \\", _interpolate(_named(\\"type\\")), \\" warining\\"])};fn.source=\\"this is {type} warining\\";return fn;})() } ] } diff --git a/test/generator/__snapshots__/yaml.test.ts.snap b/test/generator/__snapshots__/yaml.test.ts.snap index 96464ad..c6cc3fc 100644 --- a/test/generator/__snapshots__/yaml.test.ts.snap +++ b/test/generator/__snapshots__/yaml.test.ts.snap @@ -2,30 +2,30 @@ exports[`yaml: code 1`] = ` "export default { - \\"hi\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"hi there!\\"])};fn.source=\\"hi there!\\";return fn})(), + \\"hi\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"hi there!\\"])};fn.source=\\"hi there!\\";return fn;})(), \\"nested\\": { - \\"hello\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"hello world!\\"])};fn.source=\\"hello world!\\";return fn})(), + \\"hello\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"hello world!\\"])};fn.source=\\"hello world!\\";return fn;})(), \\"more\\": { - \\"plural\\": (()=>{const fn=(ctx) => {const { normalize: _normalize, linked: _linked, interpolate: _interpolate, list: _list, named: _named, plural: _plural } = ctx;return _plural([_normalize([_linked(\\"no apples\\", \\"caml\\")]), _normalize([_interpolate(_list(0)), \\" apple\\"]), _normalize([_interpolate(_named(\\"n\\")), \\" apples\\"])])};fn.source=\\"@.caml:{'no apples'} | {0} apple | {n} apples\\";return fn})() + \\"plural\\": (()=>{const fn=(ctx) => {const { normalize: _normalize, linked: _linked, interpolate: _interpolate, list: _list, named: _named, plural: _plural } = ctx;return _plural([_normalize([_linked(\\"no apples\\", \\"caml\\")]), _normalize([_interpolate(_list(0)), \\" apple\\"]), _normalize([_interpolate(_named(\\"n\\")), \\" apples\\"])])};fn.source=\\"@.caml:{'no apples'} | {0} apple | {n} apples\\";return fn;})() }, - \\"list\\": (()=>{const fn=(ctx) => {const { normalize: _normalize, interpolate: _interpolate, list: _list } = ctx;return _normalize([\\"hi, \\", _interpolate(_list(0)), \\" !\\"])};fn.source=\\"hi, {0} !\\";return fn})() + \\"list\\": (()=>{const fn=(ctx) => {const { normalize: _normalize, interpolate: _interpolate, list: _list } = ctx;return _normalize([\\"hi, \\", _interpolate(_list(0)), \\" !\\"])};fn.source=\\"hi, {0} !\\";return fn;})() }, - \\"こんにちは\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"こんにちは!\\"])};fn.source=\\"こんにちは!\\";return fn})(), - \\"single-quote\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"I don't know!\\"])};fn.source=\\"I don't know!\\";return fn})(), - \\"emoji\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"😺\\"])};fn.source=\\"😺\\";return fn})(), - \\"unicode\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"A\\"])};fn.source=\\"A\\";return fn})(), - \\"unicode-escape\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"\\\\\\\\u0041\\"])};fn.source=\\"\\\\\\\\u0041\\";return fn})(), - \\"backslash-single-quote\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"\\\\\\\\'\\"])};fn.source=\\"\\\\\\\\'\\";return fn})(), - \\"backslash-backslash\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"\\\\\\\\\\\\\\\\\\"])};fn.source=\\"\\\\\\\\\\\\\\\\\\";return fn})(), + \\"こんにちは\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"こんにちは!\\"])};fn.source=\\"こんにちは!\\";return fn;})(), + \\"single-quote\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"I don't know!\\"])};fn.source=\\"I don't know!\\";return fn;})(), + \\"emoji\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"😺\\"])};fn.source=\\"😺\\";return fn;})(), + \\"unicode\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"A\\"])};fn.source=\\"A\\";return fn;})(), + \\"unicode-escape\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"\\\\\\\\u0041\\"])};fn.source=\\"\\\\\\\\u0041\\";return fn;})(), + \\"backslash-single-quote\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"\\\\\\\\'\\"])};fn.source=\\"\\\\\\\\'\\";return fn;})(), + \\"backslash-backslash\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"\\\\\\\\\\\\\\\\\\"])};fn.source=\\"\\\\\\\\\\\\\\\\\\";return fn;})(), \\"errors\\": [ - (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"ERROR1001\\"])};fn.source=\\"ERROR1001\\";return fn})(), - (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"ERROR1002\\"])};fn.source=\\"ERROR1002\\";return fn})() + (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"ERROR1001\\"])};fn.source=\\"ERROR1001\\";return fn;})(), + (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"ERROR1002\\"])};fn.source=\\"ERROR1002\\";return fn;})() ], \\"complex\\": { \\"warnings\\": [ - (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"NOTE: This is warning\\"])};fn.source=\\"NOTE: This is warning\\";return fn})(), + (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"NOTE: This is warning\\"])};fn.source=\\"NOTE: This is warning\\";return fn;})(), { - \\"named-waring\\": (()=>{const fn=(ctx) => {const { normalize: _normalize, interpolate: _interpolate, named: _named } = ctx;return _normalize([\\"this is \\", _interpolate(_named(\\"type\\")), \\" warining\\"])};fn.source=\\"this is {type} warining\\";return fn})() + \\"named-waring\\": (()=>{const fn=(ctx) => {const { normalize: _normalize, interpolate: _interpolate, named: _named } = ctx;return _normalize([\\"this is \\", _interpolate(_named(\\"type\\")), \\" warining\\"])};fn.source=\\"this is {type} warining\\";return fn;})() } ] } @@ -92,30 +92,30 @@ complex: exports[`yml: code 1`] = ` "export default { - \\"hi\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"hi there!\\"])};fn.source=\\"hi there!\\";return fn})(), + \\"hi\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"hi there!\\"])};fn.source=\\"hi there!\\";return fn;})(), \\"nested\\": { - \\"hello\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"hello world!\\"])};fn.source=\\"hello world!\\";return fn})(), + \\"hello\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"hello world!\\"])};fn.source=\\"hello world!\\";return fn;})(), \\"more\\": { - \\"plural\\": (()=>{const fn=(ctx) => {const { normalize: _normalize, linked: _linked, interpolate: _interpolate, list: _list, named: _named, plural: _plural } = ctx;return _plural([_normalize([_linked(\\"no apples\\", \\"caml\\")]), _normalize([_interpolate(_list(0)), \\" apple\\"]), _normalize([_interpolate(_named(\\"n\\")), \\" apples\\"])])};fn.source=\\"@.caml:{'no apples'} | {0} apple | {n} apples\\";return fn})() + \\"plural\\": (()=>{const fn=(ctx) => {const { normalize: _normalize, linked: _linked, interpolate: _interpolate, list: _list, named: _named, plural: _plural } = ctx;return _plural([_normalize([_linked(\\"no apples\\", \\"caml\\")]), _normalize([_interpolate(_list(0)), \\" apple\\"]), _normalize([_interpolate(_named(\\"n\\")), \\" apples\\"])])};fn.source=\\"@.caml:{'no apples'} | {0} apple | {n} apples\\";return fn;})() }, - \\"list\\": (()=>{const fn=(ctx) => {const { normalize: _normalize, interpolate: _interpolate, list: _list } = ctx;return _normalize([\\"hi, \\", _interpolate(_list(0)), \\" !\\"])};fn.source=\\"hi, {0} !\\";return fn})() + \\"list\\": (()=>{const fn=(ctx) => {const { normalize: _normalize, interpolate: _interpolate, list: _list } = ctx;return _normalize([\\"hi, \\", _interpolate(_list(0)), \\" !\\"])};fn.source=\\"hi, {0} !\\";return fn;})() }, - \\"こんにちは\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"こんにちは!\\"])};fn.source=\\"こんにちは!\\";return fn})(), - \\"single-quote\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"I don't know!\\"])};fn.source=\\"I don't know!\\";return fn})(), - \\"emoji\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"😺\\"])};fn.source=\\"😺\\";return fn})(), - \\"unicode\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"A\\"])};fn.source=\\"A\\";return fn})(), - \\"unicode-escape\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"\\\\\\\\u0041\\"])};fn.source=\\"\\\\\\\\u0041\\";return fn})(), - \\"backslash-single-quote\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"\\\\\\\\'\\"])};fn.source=\\"\\\\\\\\'\\";return fn})(), - \\"backslash-backslash\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"\\\\\\\\\\\\\\\\\\"])};fn.source=\\"\\\\\\\\\\\\\\\\\\";return fn})(), + \\"こんにちは\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"こんにちは!\\"])};fn.source=\\"こんにちは!\\";return fn;})(), + \\"single-quote\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"I don't know!\\"])};fn.source=\\"I don't know!\\";return fn;})(), + \\"emoji\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"😺\\"])};fn.source=\\"😺\\";return fn;})(), + \\"unicode\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"A\\"])};fn.source=\\"A\\";return fn;})(), + \\"unicode-escape\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"\\\\\\\\u0041\\"])};fn.source=\\"\\\\\\\\u0041\\";return fn;})(), + \\"backslash-single-quote\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"\\\\\\\\'\\"])};fn.source=\\"\\\\\\\\'\\";return fn;})(), + \\"backslash-backslash\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"\\\\\\\\\\\\\\\\\\"])};fn.source=\\"\\\\\\\\\\\\\\\\\\";return fn;})(), \\"errors\\": [ - (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"ERROR1001\\"])};fn.source=\\"ERROR1001\\";return fn})(), - (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"ERROR1002\\"])};fn.source=\\"ERROR1002\\";return fn})() + (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"ERROR1001\\"])};fn.source=\\"ERROR1001\\";return fn;})(), + (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"ERROR1002\\"])};fn.source=\\"ERROR1002\\";return fn;})() ], \\"complex\\": { \\"warnings\\": [ - (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"NOTE: This is warning\\"])};fn.source=\\"NOTE: This is warning\\";return fn})(), + (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"NOTE: This is warning\\"])};fn.source=\\"NOTE: This is warning\\";return fn;})(), { - \\"named-waring\\": (()=>{const fn=(ctx) => {const { normalize: _normalize, interpolate: _interpolate, named: _named } = ctx;return _normalize([\\"this is \\", _interpolate(_named(\\"type\\")), \\" warining\\"])};fn.source=\\"this is {type} warining\\";return fn})() + \\"named-waring\\": (()=>{const fn=(ctx) => {const { normalize: _normalize, interpolate: _interpolate, named: _named } = ctx;return _normalize([\\"this is \\", _interpolate(_named(\\"type\\")), \\" warining\\"])};fn.source=\\"this is {type} warining\\";return fn;})() } ] } diff --git a/yarn.lock b/yarn.lock index 9d1282d..34d6b72 100644 --- a/yarn.lock +++ b/yarn.lock @@ -333,43 +333,43 @@ dependencies: "@hapi/hoek" "^8.3.0" -"@intlify/core-base@9.0.0-beta.14", "@intlify/core-base@^9.0.0-beta.14": - version "9.0.0-beta.14" - resolved "https://registry.yarnpkg.com/@intlify/core-base/-/core-base-9.0.0-beta.14.tgz#b190d1dd95d28977b26353c77121d2d84d15b7ee" - integrity sha512-ZX+JJvBtcdVZxrTg8oO6flXC965aURIvAeDOYT3DqlUWekHKQ2hUVc1J8SP7rzEgFUqDqCMrDMtv2gZNvxD2Aw== - dependencies: - "@intlify/message-compiler" "9.0.0-beta.14" - "@intlify/message-resolver" "9.0.0-beta.14" - "@intlify/runtime" "9.0.0-beta.14" - "@intlify/shared" "9.0.0-beta.14" - -"@intlify/message-compiler@9.0.0-beta.14", "@intlify/message-compiler@^9.0.0-beta.14": - version "9.0.0-beta.14" - resolved "https://registry.yarnpkg.com/@intlify/message-compiler/-/message-compiler-9.0.0-beta.14.tgz#4b5a4467459c402e71652075e9d95e5d85e85588" - integrity sha512-fXgiQuLKsYINnzhnCQD3OJnT2/59HrPw8WWiG8MpuMSDcUkUXV4ie0DW+9x48QQqpel7TU11Lage3zuFxw27iQ== - dependencies: - "@intlify/message-resolver" "9.0.0-beta.14" - "@intlify/shared" "9.0.0-beta.14" +"@intlify/core-base@9.0.0-beta.15", "@intlify/core-base@^9.0.0-beta.15": + version "9.0.0-beta.15" + resolved "https://registry.yarnpkg.com/@intlify/core-base/-/core-base-9.0.0-beta.15.tgz#038939c58daf1e71ff1653f9aa942013c60f80a7" + integrity sha512-afH2Cf+DvBs3FtJ5iHs7idP+1sHcZ4jsWhRzJu/BG6fLmthfMi13TUIItr1bdHBsB22M/syv3yq5gP305LCZ2A== + dependencies: + "@intlify/message-compiler" "9.0.0-beta.15" + "@intlify/message-resolver" "9.0.0-beta.15" + "@intlify/runtime" "9.0.0-beta.15" + "@intlify/shared" "9.0.0-beta.15" + +"@intlify/message-compiler@9.0.0-beta.15", "@intlify/message-compiler@^9.0.0-beta.15": + version "9.0.0-beta.15" + resolved "https://registry.yarnpkg.com/@intlify/message-compiler/-/message-compiler-9.0.0-beta.15.tgz#8529070003a19036c45c2dce239afbac2e61f07b" + integrity sha512-N1bh5dxLIrBNGM99O1/Uxvyb1IYmHl+sYcae88BKB2T5pvOSDC18Oa52pLjM0PMDFpKbQN+m/SGgiRPPRkp0nQ== + dependencies: + "@intlify/message-resolver" "9.0.0-beta.15" + "@intlify/shared" "9.0.0-beta.15" source-map "0.6.1" -"@intlify/message-resolver@9.0.0-beta.14": - version "9.0.0-beta.14" - resolved "https://registry.yarnpkg.com/@intlify/message-resolver/-/message-resolver-9.0.0-beta.14.tgz#f964706650d71ef06669c17c29cb60500ef2617a" - integrity sha512-/PPLMHX0w/ECkG+Fmne8L3WVVVwAp3tpdisf5G775b49Fspy4dKXqkLXM2NZKhdguJbXWHXXXiRkr+mlhq8G9Q== +"@intlify/message-resolver@9.0.0-beta.15": + version "9.0.0-beta.15" + resolved "https://registry.yarnpkg.com/@intlify/message-resolver/-/message-resolver-9.0.0-beta.15.tgz#ac1bf84923e76bd4356daf8c2e36530601fc49a5" + integrity sha512-i64xy281nzNJbFSruc0EgFKJKSvXI/1bhYliWq0qtYi6Mv2sIXb4+arOB69YYYBKuDDNLBjSCNCuCmab62sP0A== -"@intlify/runtime@9.0.0-beta.14", "@intlify/runtime@^9.0.0-beta.14": - version "9.0.0-beta.14" - resolved "https://registry.yarnpkg.com/@intlify/runtime/-/runtime-9.0.0-beta.14.tgz#367f6b09c991c71905b73224e238aa8382976b2d" - integrity sha512-WgFnXkniJIMrZfW1kcxejQ96te56r3us632/WME7SL1IYsGV+WErXiJMBrHf8ngwAy15WmfYoKWr32sRxWjCtw== +"@intlify/runtime@9.0.0-beta.15", "@intlify/runtime@^9.0.0-beta.15": + version "9.0.0-beta.15" + resolved "https://registry.yarnpkg.com/@intlify/runtime/-/runtime-9.0.0-beta.15.tgz#1dc1ac3a24007d8146a55c179d6c98938cea3329" + integrity sha512-nMN1MVxg8ljSnYak+3iZ7WZ0fH7/YfpMWGYxMDiZaYdwGABracWHdJy/5ilzCKbt6qQ2xzSv6fIN+jr7wIMx6Q== dependencies: - "@intlify/message-compiler" "9.0.0-beta.14" - "@intlify/message-resolver" "9.0.0-beta.14" - "@intlify/shared" "9.0.0-beta.14" + "@intlify/message-compiler" "9.0.0-beta.15" + "@intlify/message-resolver" "9.0.0-beta.15" + "@intlify/shared" "9.0.0-beta.15" -"@intlify/shared@9.0.0-beta.14", "@intlify/shared@^9.0.0-beta.14": - version "9.0.0-beta.14" - resolved "https://registry.yarnpkg.com/@intlify/shared/-/shared-9.0.0-beta.14.tgz#c221a45f666a40935f998d2e3c14451a516b9f56" - integrity sha512-f+Gev5GnrNLyieJCB6sB/qqe03XaMf6yJiAXG3IamZ4mp45oj2Lw9Oj3hAepDW36VUZK2wCIDmWy53pxJNIFpQ== +"@intlify/shared@9.0.0-beta.15", "@intlify/shared@^9.0.0-beta.15": + version "9.0.0-beta.15" + resolved "https://registry.yarnpkg.com/@intlify/shared/-/shared-9.0.0-beta.15.tgz#beab8c49e0efd5cd5c4b9add2b71b9395e7cc7a1" + integrity sha512-f7qkzA8tUdGD5T7xUoNSiYA/qvPJSwu5DKt6xCrpitF2Ol+0QTLuk6jyZq81WKwo38DrTD/wjaM6STX/pF5zJg== "@istanbuljs/load-nyc-config@^1.0.0": version "1.1.0" @@ -9006,13 +9006,13 @@ vue-eslint-parser@^5.0.0: esquery "^1.0.1" lodash "^4.17.11" -vue-i18n@^9.0.0-beta.14: - version "9.0.0-beta.14" - resolved "https://registry.yarnpkg.com/vue-i18n/-/vue-i18n-9.0.0-beta.14.tgz#2b2b89bc5371263d499bd17e3c0696bb9582c4f9" - integrity sha512-jPFtBXcRLuGc4YrI97JJuvj70BndqOhpQNJNthAIPC5x8eJIno44NkK/P769nqQWkbsnYO1sNwb+6oCO6QhaxA== +vue-i18n@^9.0.0-beta.15: + version "9.0.0-beta.15" + resolved "https://registry.yarnpkg.com/vue-i18n/-/vue-i18n-9.0.0-beta.15.tgz#b6fa6ddad32f43f3c3c0ad7ec18580368692b143" + integrity sha512-DbSF82NZrLKZZ+UQSFWuSL6JfKS/yIZKpJbqc12byfUrlOw3rypJzoccfOPoEBgtVZy8/NrItU2dO2T0sL/UvQ== dependencies: - "@intlify/core-base" "9.0.0-beta.14" - "@intlify/shared" "9.0.0-beta.14" + "@intlify/core-base" "9.0.0-beta.15" + "@intlify/shared" "9.0.0-beta.15" "@vue/devtools-api" "^6.0.0-beta.2" vue-loader@^16.1.2: