From 74e9b2d90a6aa02188786ac5e8039910179035cc Mon Sep 17 00:00:00 2001 From: kazuya kawaguchi Date: Fri, 12 Apr 2024 10:18:43 +0900 Subject: [PATCH] fix: deprecate named interpolation with modulo syntax (#1795) --- packages/core-base/src/compilation.ts | 25 +++++- packages/core-base/src/context.ts | 90 +++++++++---------- packages/core-base/src/errors.ts | 16 ++-- packages/core-base/src/warnings.ts | 22 +++-- packages/core-base/test/compilation.test.ts | 36 +++++++- packages/core-base/test/errors.test.ts | 5 ++ packages/core-base/test/warnings.test.ts | 5 ++ packages/message-compiler/src/index.ts | 1 + packages/message-compiler/src/nodes.ts | 1 + packages/message-compiler/src/options.ts | 5 ++ packages/message-compiler/src/parser.ts | 43 ++++++++- packages/message-compiler/src/warnings.ts | 35 ++++++++ .../test/__snapshots__/compiler.test.ts.snap | 77 ++++++++++++++++ .../message-compiler/test/compiler.test.ts | 7 ++ .../parser/__snapshots__/modulo.test.ts.snap | 4 + packages/vue-i18n-core/src/errors.ts | 30 +++---- packages/vue-i18n-core/test/errors.test.ts | 5 ++ packages/vue-i18n-core/test/warnings.test.ts | 5 ++ rollup.config.mjs | 2 + 19 files changed, 332 insertions(+), 82 deletions(-) create mode 100644 packages/core-base/test/errors.test.ts create mode 100644 packages/core-base/test/warnings.test.ts create mode 100644 packages/message-compiler/src/warnings.ts create mode 100644 packages/vue-i18n-core/test/errors.test.ts create mode 100644 packages/vue-i18n-core/test/warnings.test.ts diff --git a/packages/core-base/src/compilation.ts b/packages/core-base/src/compilation.ts index 79e4b1354..66ca10a45 100644 --- a/packages/core-base/src/compilation.ts +++ b/packages/core-base/src/compilation.ts @@ -1,6 +1,7 @@ import { warn, format, isObject, isBoolean, isString } from '@intlify/shared' import { baseCompile as baseCompileCore, + CompileWarnCodes, defaultOnError, detectHtmlTag } from '@intlify/message-compiler' @@ -11,7 +12,8 @@ import type { CompileOptions, CompileError, CompilerResult, - ResourceNode + ResourceNode, + CompileWarn } from '@intlify/message-compiler' import type { MessageFunction, MessageFunctions } from './runtime' import type { MessageCompilerContext } from './context' @@ -27,6 +29,17 @@ function checkHtmlMessage(source: string, warnHtmlMessage?: boolean): void { const defaultOnCacheKey = (message: string): string => message let compileCache: unknown = Object.create(null) +function onCompileWarn(_warn: CompileWarn): void { + if (_warn.code === CompileWarnCodes.USE_MODULO_SYNTAX) { + warn( + `The use of named interpolation with modulo syntax is deprecated. ` + + `It will be removed in v10.\n` + + `reference: https://vue-i18n.intlify.dev/guide/essentials/syntax#rails-i18n-format \n` + + `(message compiler warning message: ${_warn.message})` + ) + } +} + export function clearCompileCache(): void { compileCache = Object.create(null) } @@ -64,6 +77,11 @@ export const compileToFunction = < throw createCoreError(CoreErrorCodes.NOT_SUPPORT_NON_STRING_MESSAGE) } + // set onWarn + if (__DEV__) { + context.onWarn = onCompileWarn + } + if (__RUNTIME__) { __DEV__ && warn( @@ -107,6 +125,11 @@ export function compile< message: MessageSource, context: MessageCompilerContext ): MessageFunction { + // set onWarn + if (__DEV__) { + context.onWarn = onCompileWarn + } + if ( (__ESM_BROWSER__ || __NODE_JS__ || diff --git a/packages/core-base/src/context.ts b/packages/core-base/src/context.ts index 3c673f74c..bf0a64553 100644 --- a/packages/core-base/src/context.ts +++ b/packages/core-base/src/context.ts @@ -66,14 +66,14 @@ export type LocaleMessageValue = export type LocaleMessageType = T extends string ? string : T extends () => Promise - ? LocaleMessageDictionary - : T extends (...args: infer Arguments) => any - ? (...args: Arguments) => ReturnType - : T extends Record - ? LocaleMessageDictionary - : T extends Array - ? { [K in keyof T]: T[K] } - : T + ? LocaleMessageDictionary + : T extends (...args: infer Arguments) => any + ? (...args: Arguments) => ReturnType + : T extends Record + ? LocaleMessageDictionary + : T extends Array + ? { [K in keyof T]: T[K] } + : T /** @VueI18nGeneral */ export type LocaleMessageDictionary = { @@ -145,7 +145,7 @@ export type PostTranslationHandler = ( */ export type MessageCompilerContext = Pick< CompileOptions, - 'onError' | 'onCacheKey' + 'onError' | 'onCacheKey' | 'onWarn' > & { /** * Whether to allow the use locale messages of HTML formatting. @@ -183,37 +183,37 @@ export type MessageCompiler< export interface CoreOptions< Message = string, Schema extends - { - message?: unknown - datetime?: unknown - number?: unknown - } = { - message: DefaultCoreLocaleMessageSchema, - datetime: DateTimeFormat, - number: NumberFormat - }, + { + message?: unknown + datetime?: unknown + number?: unknown + } = { + message: DefaultCoreLocaleMessageSchema, + datetime: DateTimeFormat, + number: NumberFormat + }, Locales extends - | { - messages: unknown - datetimeFormats: unknown - numberFormats: unknown - } - | string = Locale, + | { + messages: unknown + datetimeFormats: unknown + numberFormats: unknown + } + | string = Locale, MessagesLocales = Locales extends { messages: infer M } - ? M - : Locales extends string - ? Locales - : Locale, + ? M + : Locales extends string + ? Locales + : Locale, DateTimeFormatsLocales = Locales extends { datetimeFormats: infer D } - ? D - : Locales extends string - ? Locales - : Locale, + ? D + : Locales extends string + ? Locales + : Locale, NumberFormatsLocales = Locales extends { numberFormats: infer N } - ? N - : Locales extends string - ? Locales - : Locale, + ? N + : Locales extends string + ? Locales + : Locale, MessageSchema = Schema extends { message: infer M } ? M : DefaultCoreLocaleMessageSchema, DateTimeSchema = Schema extends { datetime: infer D } ? D : DateTimeFormat, NumberSchema = Schema extends { number: infer N } ? N : NumberFormat, @@ -300,14 +300,14 @@ export type CoreContext< NumberFormats = {}, LocaleType = Locale, ResourceLocales = - | PickupLocales> - | PickupLocales> - | PickupLocales>, + | PickupLocales> + | PickupLocales> + | PickupLocales>, Locales = IsNever extends true - ? LocaleType extends LocaleDetector | Locale - ? LocaleType - : Locale - : ResourceLocales + ? LocaleType extends LocaleDetector | Locale + ? LocaleType + : Locale + : ResourceLocales > = CoreCommonContext & CoreTranslationContext, Message> & CoreDateTimeContext> & @@ -355,7 +355,7 @@ function getDefaultLinkedModifiers< return type === 'text' && isString(val) ? val.toUpperCase() : type === 'vnode' && isObject(val) && '__v_isVNode' in val - ? (val as any).children.toUpperCase() + ? (val as any).children.toUpperCase() : val }, lower: (val: Message, type: string): MessageType => { @@ -371,7 +371,7 @@ function getDefaultLinkedModifiers< return (type === 'text' && isString(val) ? capitalize(val) : type === 'vnode' && isObject(val) && '__v_isVNode' in val - ? capitalize( (val as any).children) + ? capitalize((val as any).children) : val) as MessageType } } diff --git a/packages/core-base/src/errors.ts b/packages/core-base/src/errors.ts index 353ebd2b9..0d86ccbb8 100644 --- a/packages/core-base/src/errors.ts +++ b/packages/core-base/src/errors.ts @@ -12,14 +12,14 @@ const code = CompileErrorCodes.__EXTEND_POINT__ const inc = incrementer(code) export const CoreErrorCodes = { - INVALID_ARGUMENT: code, // 18 - INVALID_DATE_ARGUMENT: inc(), // 19 - INVALID_ISO_DATE_ARGUMENT: inc(), // 20 - NOT_SUPPORT_NON_STRING_MESSAGE: inc(), // 21 - NOT_SUPPORT_LOCALE_PROMISE_VALUE: inc(), // 22 - NOT_SUPPORT_LOCALE_ASYNC_FUNCTION: inc(), // 23 - NOT_SUPPORT_LOCALE_TYPE: inc(), // 24 - __EXTEND_POINT__: inc() // 25 + INVALID_ARGUMENT: code, // 17 + INVALID_DATE_ARGUMENT: inc(), // 18 + INVALID_ISO_DATE_ARGUMENT: inc(), // 19 + NOT_SUPPORT_NON_STRING_MESSAGE: inc(), // 20 + NOT_SUPPORT_LOCALE_PROMISE_VALUE: inc(), // 21 + NOT_SUPPORT_LOCALE_ASYNC_FUNCTION: inc(), // 22 + NOT_SUPPORT_LOCALE_TYPE: inc(), // 23 + __EXTEND_POINT__: inc() // 24 } as const export type CoreErrorCodes = diff --git a/packages/core-base/src/warnings.ts b/packages/core-base/src/warnings.ts index 61c1e5645..db6e0b29f 100644 --- a/packages/core-base/src/warnings.ts +++ b/packages/core-base/src/warnings.ts @@ -1,14 +1,18 @@ -import { format } from '@intlify/shared' +import { format, incrementer } from '@intlify/shared' +import { CompileWarnCodes } from '@intlify/message-compiler' + +const code = CompileWarnCodes.__EXTEND_POINT__ +const inc = incrementer(code) export const CoreWarnCodes = { - NOT_FOUND_KEY: 1, - FALLBACK_TO_TRANSLATE: 2, - CANNOT_FORMAT_NUMBER: 3, - FALLBACK_TO_NUMBER_FORMAT: 4, - CANNOT_FORMAT_DATE: 5, - FALLBACK_TO_DATE_FORMAT: 6, - EXPERIMENTAL_CUSTOM_MESSAGE_COMPILER: 7, - __EXTEND_POINT__: 8 + NOT_FOUND_KEY: code, // 2 + FALLBACK_TO_TRANSLATE: inc(), // 3 + CANNOT_FORMAT_NUMBER: inc(), // 4 + FALLBACK_TO_NUMBER_FORMAT: inc(), // 5 + CANNOT_FORMAT_DATE: inc(), // 6 + FALLBACK_TO_DATE_FORMAT: inc(), // 7 + EXPERIMENTAL_CUSTOM_MESSAGE_COMPILER: inc(), // 8 + __EXTEND_POINT__: inc() // 9 } as const export type CoreWarnCodes = (typeof CoreWarnCodes)[keyof typeof CoreWarnCodes] diff --git a/packages/core-base/test/compilation.test.ts b/packages/core-base/test/compilation.test.ts index 97747fec7..235f6ea68 100644 --- a/packages/core-base/test/compilation.test.ts +++ b/packages/core-base/test/compilation.test.ts @@ -1,3 +1,13 @@ +// utils +import * as shared from '@intlify/shared' +vi.mock('@intlify/shared', async () => { + const actual = await vi.importActual('@intlify/shared') + return { + ...actual, + warn: vi.fn() + } +}) + import { baseCompile } from '@intlify/message-compiler' import { compileToFunction, @@ -9,7 +19,7 @@ import { createMessageContext as context } from '../src/runtime' const DEFAULT_CONTEXT = { locale: 'en', key: 'key' } -beforeAll(() => { +beforeEach(() => { clearCompileCache() }) @@ -50,6 +60,19 @@ describe('compileToFunction', () => { }) expect(occured).toBe(true) }) + + test('modulo syntax warning', () => { + const mockWarn = vi.spyOn(shared, 'warn') + mockWarn.mockImplementation(() => {}) + + compileToFunction('hello %{name}!', { + ...DEFAULT_CONTEXT + }) + expect(mockWarn).toHaveBeenCalledTimes(1) + expect(mockWarn.mock.calls[0][0]).includes( + `The use of named interpolation with modulo syntax is deprecated. It will be removed in v10.` + ) + }) }) describe('compile', () => { @@ -109,4 +132,15 @@ describe('compile', () => { }) expect(occured).toBe(true) }) + + test('modulo syntax warning', () => { + const mockWarn = vi.spyOn(shared, 'warn') + mockWarn.mockImplementation(() => {}) + + compile('%{msg} world!', DEFAULT_CONTEXT) + expect(mockWarn).toHaveBeenCalledTimes(1) + expect(mockWarn.mock.calls[0][0]).includes( + `The use of named interpolation with modulo syntax is deprecated. It will be removed in v10.` + ) + }) }) diff --git a/packages/core-base/test/errors.test.ts b/packages/core-base/test/errors.test.ts new file mode 100644 index 000000000..abaae8baf --- /dev/null +++ b/packages/core-base/test/errors.test.ts @@ -0,0 +1,5 @@ +import { CoreErrorCodes } from '../src/errors' + +test('CoreErrorCodes', () => { + expect(CoreErrorCodes.INVALID_ARGUMENT).toBe(17) +}) diff --git a/packages/core-base/test/warnings.test.ts b/packages/core-base/test/warnings.test.ts new file mode 100644 index 000000000..211460d46 --- /dev/null +++ b/packages/core-base/test/warnings.test.ts @@ -0,0 +1,5 @@ +import { CoreWarnCodes } from '../src/warnings' + +test('CoreWarnCodes', () => { + expect(CoreWarnCodes.NOT_FOUND_KEY).toBe(2) +}) diff --git a/packages/message-compiler/src/index.ts b/packages/message-compiler/src/index.ts index f4fa8bf8f..9f129cf64 100644 --- a/packages/message-compiler/src/index.ts +++ b/packages/message-compiler/src/index.ts @@ -1,6 +1,7 @@ export * from './location' export * from './nodes' export * from './options' +export * from './warnings' export * from './errors' export * from './helpers' export * from './parser' diff --git a/packages/message-compiler/src/nodes.ts b/packages/message-compiler/src/nodes.ts index 658fa73ae..ee8ba188a 100644 --- a/packages/message-compiler/src/nodes.ts +++ b/packages/message-compiler/src/nodes.ts @@ -80,6 +80,7 @@ export interface TextNode extends Node { export interface NamedNode extends Node { type: NodeTypes.Named key: Identifier + modulo?: boolean /** * @internal `key` alias */ diff --git a/packages/message-compiler/src/options.ts b/packages/message-compiler/src/options.ts index 464010561..f9597065c 100644 --- a/packages/message-compiler/src/options.ts +++ b/packages/message-compiler/src/options.ts @@ -1,5 +1,7 @@ import type { CompileError } from './errors' +import type { CompileWarn } from './warnings' +export type CompileWarnHandler = (warn: CompileWarn) => void export type CompileErrorHandler = (error: CompileError) => void export type CacheKeyHandler = (source: string) => string @@ -11,10 +13,12 @@ export interface TokenizeOptions { export interface ParserOptions { location?: boolean // default true onCacheKey?: (source: string) => string + onWarn?: CompileWarnHandler onError?: CompileErrorHandler } export interface TransformOptions { + onWarn?: CompileWarnHandler onError?: CompileErrorHandler } @@ -23,6 +27,7 @@ export interface CodeGenOptions { mode?: 'normal' | 'arrow' // default normal breakLineCode?: '\n' | ';' // default newline needIndent?: boolean // default true + onWarn?: CompileWarnHandler onError?: CompileErrorHandler // Generate source map? // - Default: false diff --git a/packages/message-compiler/src/parser.ts b/packages/message-compiler/src/parser.ts index 5b9608029..a4619f725 100644 --- a/packages/message-compiler/src/parser.ts +++ b/packages/message-compiler/src/parser.ts @@ -1,5 +1,6 @@ import { createLocation } from './location' import { createCompileError, CompileErrorCodes } from './errors' +import { createCompileWarn, CompileWarnCodes } from './warnings' import { createTokenizer, TokenTypes } from './tokenizer' import { NodeTypes } from './nodes' import { assign } from '@intlify/shared' @@ -57,7 +58,7 @@ function fromEscapeSequence( export function createParser(options: ParserOptions = {}): Parser { const location = options.location !== false - const { onError } = options + const { onError, onWarn } = options function emitError( tokenzer: Tokenizer, code: CompileErrorCodes, @@ -77,6 +78,21 @@ export function createParser(options: ParserOptions = {}): Parser { onError(err) } } + function emitWarn( + tokenzer: Tokenizer, + code: CompileWarnCodes, + start: Position, + offset: number, + ...args: unknown[] + ): void { + const end = tokenzer.currentPosition() + end.offset += offset + end.column += offset + if (onWarn) { + const loc = location ? createLocation(start, end) : null + onWarn(createCompileWarn(code, loc, args)) + } + } function startNode(type: NodeTypes, offset: number, loc: Position): Node { const node = { type } as Node @@ -130,11 +146,18 @@ export function createParser(options: ParserOptions = {}): Parser { return node } - function parseNamed(tokenizer: Tokenizer, key: string): NamedNode { + function parseNamed( + tokenizer: Tokenizer, + key: string, + modulo?: boolean + ): NamedNode { const context = tokenizer.context() const { lastOffset: offset, lastStartLoc: loc } = context // get brace left loc const node = startNode(NodeTypes.Named, offset, loc) as NamedNode node.key = key + if (modulo === true) { + node.modulo = true + } tokenizer.nextToken() // skip brach right endNode(node, tokenizer.currentOffset(), tokenizer.currentPosition()) return node @@ -339,6 +362,7 @@ export function createParser(options: ParserOptions = {}): Parser { node.items = [] let nextToken: Token | null = null + let modulo: boolean | null = null do { const token = nextToken || tokenizer.nextToken() nextToken = null @@ -367,6 +391,9 @@ export function createParser(options: ParserOptions = {}): Parser { } node.items.push(parseList(tokenizer, token.value || '')) break + case TokenTypes.Modulo: + modulo = true + break case TokenTypes.Named: if (token.value == null) { emitError( @@ -377,7 +404,17 @@ export function createParser(options: ParserOptions = {}): Parser { getTokenCaption(token) ) } - node.items.push(parseNamed(tokenizer, token.value || '')) + node.items.push(parseNamed(tokenizer, token.value || '', !!modulo)) + if (modulo) { + emitWarn( + tokenizer, + CompileWarnCodes.USE_MODULO_SYNTAX, + context.lastStartLoc, + 0, + getTokenCaption(token) + ) + modulo = null + } break case TokenTypes.Literal: if (token.value == null) { diff --git a/packages/message-compiler/src/warnings.ts b/packages/message-compiler/src/warnings.ts new file mode 100644 index 000000000..0bf66ec6a --- /dev/null +++ b/packages/message-compiler/src/warnings.ts @@ -0,0 +1,35 @@ +import { format } from '@intlify/shared' + +import type { SourceLocation } from './location' + +export const CompileWarnCodes = { + USE_MODULO_SYNTAX: 1, + __EXTEND_POINT__: 2 +} as const + +export interface CompileWarn { + message: string + code: number + location?: SourceLocation +} + +export type CompileWarnCodes = + (typeof CompileWarnCodes)[keyof typeof CompileWarnCodes] + +/** @internal */ +export const warnMessages: { [code: number]: string } = { + [CompileWarnCodes.USE_MODULO_SYNTAX]: `Use modulo before '{{0}}'.` +} + +export function createCompileWarn( + code: T, + loc: SourceLocation | null, + ...args: unknown[] +): CompileWarn { + const msg = __DEV__ ? format(warnMessages[code] || '', ...(args || [])) : code + const message: CompileWarn = { message: String(msg), code } + if (loc) { + message.location = loc + } + return message +} diff --git a/packages/message-compiler/test/__snapshots__/compiler.test.ts.snap b/packages/message-compiler/test/__snapshots__/compiler.test.ts.snap index 522700eef..d458a7b73 100644 --- a/packages/message-compiler/test/__snapshots__/compiler.test.ts.snap +++ b/packages/message-compiler/test/__snapshots__/compiler.test.ts.snap @@ -317,6 +317,83 @@ exports[`compiler options > optimize: false > ast 1`] = ` } `; +exports[`compiler options > warning > ast 1`] = ` +{ + "body": { + "end": 12, + "items": [ + { + "end": 6, + "key": "msg", + "loc": { + "end": { + "column": 7, + "line": 1, + "offset": 6, + }, + "start": { + "column": 2, + "line": 1, + "offset": 1, + }, + }, + "modulo": true, + "start": 1, + "type": 4, + }, + { + "end": 12, + "loc": { + "end": { + "column": 13, + "line": 1, + "offset": 12, + }, + "start": { + "column": 7, + "line": 1, + "offset": 6, + }, + }, + "start": 6, + "type": 3, + "value": " world", + }, + ], + "loc": { + "end": { + "column": 13, + "line": 1, + "offset": 12, + }, + "start": { + "column": 1, + "line": 1, + "offset": 0, + }, + }, + "start": 0, + "type": 2, + }, + "end": 12, + "loc": { + "end": { + "column": 13, + "line": 1, + "offset": 12, + }, + "source": "%{msg} world", + "start": { + "column": 1, + "line": 1, + "offset": 0, + }, + }, + "start": 0, + "type": 0, +} +`; + exports[`edge cases > | | | > code 1`] = ` "function __msg__ (ctx) { const { normalize: _normalize, plural: _plural } = ctx diff --git a/packages/message-compiler/test/compiler.test.ts b/packages/message-compiler/test/compiler.test.ts index aaa26ff62..44abc140a 100644 --- a/packages/message-compiler/test/compiler.test.ts +++ b/packages/message-compiler/test/compiler.test.ts @@ -110,6 +110,13 @@ describe('compiler options', () => { }) expect(ast).toMatchSnapshot('ast') }) + + test('warning', () => { + const onWarn = vi.fn() + const { ast } = compile(`%{msg} world`, { onWarn }) + expect(ast).toMatchSnapshot('ast') + expect(onWarn.mock.calls[0][0].message).toBe(`Use modulo before '{msg}'.`) + }) }) describe('edge cases', () => { diff --git a/packages/message-compiler/test/parser/__snapshots__/modulo.test.ts.snap b/packages/message-compiler/test/parser/__snapshots__/modulo.test.ts.snap index d11b6d9d4..866afb0de 100644 --- a/packages/message-compiler/test/parser/__snapshots__/modulo.test.ts.snap +++ b/packages/message-compiler/test/parser/__snapshots__/modulo.test.ts.snap @@ -20,6 +20,7 @@ exports[`%{nickname} %{action} issue %{code} 1`] = ` "offset": 1, }, }, + "modulo": true, "start": 1, "type": 4, }, @@ -56,6 +57,7 @@ exports[`%{nickname} %{action} issue %{code} 1`] = ` "offset": 13, }, }, + "modulo": true, "start": 13, "type": 4, }, @@ -92,6 +94,7 @@ exports[`%{nickname} %{action} issue %{code} 1`] = ` "offset": 29, }, }, + "modulo": true, "start": 29, "type": 4, }, @@ -431,6 +434,7 @@ exports[`hi %{name}! 1`] = ` "offset": 4, }, }, + "modulo": true, "start": 4, "type": 4, }, diff --git a/packages/vue-i18n-core/src/errors.ts b/packages/vue-i18n-core/src/errors.ts index 763275068..8a796d5a8 100644 --- a/packages/vue-i18n-core/src/errors.ts +++ b/packages/vue-i18n-core/src/errors.ts @@ -10,31 +10,31 @@ const inc = incrementer(code) export const I18nErrorCodes = { // composer module errors - UNEXPECTED_RETURN_TYPE: code, // 26 + UNEXPECTED_RETURN_TYPE: code, // 24 // legacy module errors - INVALID_ARGUMENT: inc(), // 27 + INVALID_ARGUMENT: inc(), // 25 // i18n module errors - MUST_BE_CALL_SETUP_TOP: inc(), // 28 - NOT_INSTALLED: inc(), // 29 - NOT_AVAILABLE_IN_LEGACY_MODE: inc(), // 30 + MUST_BE_CALL_SETUP_TOP: inc(), // 26 + NOT_INSTALLED: inc(), // 27 + NOT_AVAILABLE_IN_LEGACY_MODE: inc(), // 28 // directive module errors - REQUIRED_VALUE: inc(), // 31 - INVALID_VALUE: inc(), // 32 + REQUIRED_VALUE: inc(), // 29 + INVALID_VALUE: inc(), // 30 // vue-devtools errors - CANNOT_SETUP_VUE_DEVTOOLS_PLUGIN: inc(), // 33 - NOT_INSTALLED_WITH_PROVIDE: inc(), // 34 + CANNOT_SETUP_VUE_DEVTOOLS_PLUGIN: inc(), // 31 + NOT_INSTALLED_WITH_PROVIDE: inc(), // 32 // unexpected error - UNEXPECTED_ERROR: inc(), // 35 + UNEXPECTED_ERROR: inc(), // 33 // not compatible legacy vue-i18n constructor - NOT_COMPATIBLE_LEGACY_VUE_I18N: inc(), // 36 + NOT_COMPATIBLE_LEGACY_VUE_I18N: inc(), // 34 // bridge support vue 2.x only - BRIDGE_SUPPORT_VUE_2_ONLY: inc(), // 37 + BRIDGE_SUPPORT_VUE_2_ONLY: inc(), // 35 // need to define `i18n` option in `allowComposition: true` and `useScope: 'local' at `useI18n`` - MUST_DEFINE_I18N_OPTION_IN_ALLOW_COMPOSITION: inc(), // 38 + MUST_DEFINE_I18N_OPTION_IN_ALLOW_COMPOSITION: inc(), // 36 // Not available Compostion API in Legacy API mode. Please make sure that the legacy API mode is working properly - NOT_AVAILABLE_COMPOSITION_IN_LEGACY: inc(), // 39 + NOT_AVAILABLE_COMPOSITION_IN_LEGACY: inc(), // 37 // for enhancement - __EXTEND_POINT__: inc() // 40 + __EXTEND_POINT__: inc() // 38 } as const type I18nErrorCodes = (typeof I18nErrorCodes)[keyof typeof I18nErrorCodes] diff --git a/packages/vue-i18n-core/test/errors.test.ts b/packages/vue-i18n-core/test/errors.test.ts new file mode 100644 index 000000000..46678b062 --- /dev/null +++ b/packages/vue-i18n-core/test/errors.test.ts @@ -0,0 +1,5 @@ +import { I18nErrorCodes } from '../src/errors' + +test('I18nErrorCodes', () => { + expect(I18nErrorCodes.UNEXPECTED_RETURN_TYPE).toBe(24) +}) diff --git a/packages/vue-i18n-core/test/warnings.test.ts b/packages/vue-i18n-core/test/warnings.test.ts new file mode 100644 index 000000000..b418dfac9 --- /dev/null +++ b/packages/vue-i18n-core/test/warnings.test.ts @@ -0,0 +1,5 @@ +import { I18nWarnCodes } from '../src/warnings' + +test('I18nWarnCodes', () => { + expect(I18nWarnCodes.FALLBACK_TO_ROOT).toBe(9) +}) diff --git a/rollup.config.mjs b/rollup.config.mjs index fee0f19b8..3f46124ed 100644 --- a/rollup.config.mjs +++ b/rollup.config.mjs @@ -380,6 +380,8 @@ function createReplacePlugin( ? { 'emitError(': `/*#__PURE__*/ emitError(`, 'createCompileError(': `/*#__PURE__*/ createCompileError(`, + 'emitWarn(': `/*#__PURE__*/ emitWarn(`, + 'createCompileWarn(': `/*#__PURE__*/ createCompileWarn(`, 'function createCoreError(': `/*#__PURE__*/ function createCoreError(`, 'throw createCoreError(': `throw Error(`, 'function createI18nError(': `/*#__PURE__*/ function createI18nError(`,