messageformat
Advanced tools
Comparing version 4.0.0-0 to 4.0.0-1
@@ -79,2 +79,8 @@ import type { ParseError } from './parser/data-model'; | ||
/** | ||
* A type guard for {@link CatchallKey} values | ||
* | ||
* @beta | ||
*/ | ||
export declare const isCatchallKey: (key: any) => key is CatchallKey; | ||
/** | ||
* The result of parsing input that cannot be represented by | ||
@@ -99,2 +105,8 @@ * a {@link PatternMessage} or a {@link SelectMessage}. | ||
/** | ||
* A type guard for {@link PatternMessage} values | ||
* | ||
* @beta | ||
*/ | ||
export declare const isPatternMessage: (msg: Message) => msg is PatternMessage; | ||
/** | ||
* A type guard for {@link SelectMessage} values | ||
@@ -101,0 +113,0 @@ * |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.isSelectMessage = exports.isMessage = void 0; | ||
exports.isSelectMessage = exports.isPatternMessage = exports.isMessage = exports.isCatchallKey = void 0; | ||
/** | ||
* A type guard for {@link CatchallKey} values | ||
* | ||
* @beta | ||
*/ | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
const isCatchallKey = (key) => !!key && typeof key === 'object' && key.type === '*'; | ||
exports.isCatchallKey = isCatchallKey; | ||
/** | ||
* A type guard for {@link Message} values | ||
@@ -17,2 +25,9 @@ * | ||
/** | ||
* A type guard for {@link PatternMessage} values | ||
* | ||
* @beta | ||
*/ | ||
const isPatternMessage = (msg) => msg.type === 'message'; | ||
exports.isPatternMessage = isPatternMessage; | ||
/** | ||
* A type guard for {@link SelectMessage} values | ||
@@ -19,0 +34,0 @@ * |
@@ -6,2 +6,3 @@ import type { Message } from '../data-model'; | ||
* | ||
* @remarks | ||
* Throws if `msg` is a {@link JunkMessage}, | ||
@@ -8,0 +9,0 @@ * if it contains parse `errors`, |
@@ -19,2 +19,3 @@ "use strict"; | ||
* | ||
* @remarks | ||
* Throws if `msg` is a {@link JunkMessage}, | ||
@@ -31,4 +32,3 @@ * if it contains parse `errors`, | ||
function validate(msg, runtime) { | ||
var _a; | ||
if ((_a = msg.errors) === null || _a === void 0 ? void 0 : _a.length) | ||
if (msg.errors?.length) | ||
throw new Error('Message parse failed'); | ||
@@ -35,0 +35,0 @@ switch (msg.type) { |
@@ -6,4 +6,5 @@ export * from './data-model'; | ||
export { parseMessage } from './parser/message.js'; | ||
export { stringifyMessage } from './stringifier/message.js'; | ||
export * from './pattern'; | ||
export * from './runtime'; | ||
export { validate } from './extra/validate'; |
@@ -17,3 +17,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.validate = exports.parseMessage = exports.MessageFormat = void 0; | ||
exports.validate = exports.stringifyMessage = exports.parseMessage = exports.MessageFormat = void 0; | ||
__exportStar(require("./data-model"), exports); | ||
@@ -25,2 +25,4 @@ __exportStar(require("./message-value"), exports); | ||
Object.defineProperty(exports, "parseMessage", { enumerable: true, get: function () { return message_js_1.parseMessage; } }); | ||
var message_js_2 = require("./stringifier/message.js"); | ||
Object.defineProperty(exports, "stringifyMessage", { enumerable: true, get: function () { return message_js_2.stringifyMessage; } }); | ||
__exportStar(require("./pattern"), exports); | ||
@@ -27,0 +29,0 @@ __exportStar(require("./runtime"), exports); |
@@ -9,5 +9,5 @@ "use strict"; | ||
if (value instanceof message_value_1.MessageValue) { | ||
if (format === null || format === void 0 ? void 0 : format.meta) | ||
value.meta = Object.assign(Object.assign({}, value.meta), format.meta); | ||
if (format === null || format === void 0 ? void 0 : format.source) | ||
if (format?.meta) | ||
value.meta = { ...value.meta, ...format.meta }; | ||
if (format?.source) | ||
value.source = format.source; | ||
@@ -20,4 +20,4 @@ return value; | ||
return new message_datetime_1.MessageDateTime(ctx, value, format); | ||
return new message_value_1.MessageValue(message_value_1.MessageValue.type, ctx, value, format); | ||
return new message_value_1.MessageValue(null, ctx, value, format); | ||
} | ||
exports.asMessageValue = asMessageValue; |
@@ -6,5 +6,5 @@ export { asMessageValue } from './as-message-value'; | ||
export { MessageLiteral } from './message-literal'; | ||
export { MessageMarkup } from './message-markup'; | ||
export { MessageMarkupStart, MessageMarkupEnd } from './message-markup'; | ||
export { MessageNumber } from './message-number'; | ||
export { MessageValue, Meta } from './message-value'; | ||
export { ResolvedMessage } from './resolved-message'; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.ResolvedMessage = exports.MessageValue = exports.MessageNumber = exports.MessageMarkup = exports.MessageLiteral = exports.MessageFallback = exports.MessageDateTime = exports.extendLocaleContext = exports.asMessageValue = void 0; | ||
exports.ResolvedMessage = exports.MessageValue = exports.MessageNumber = exports.MessageMarkupEnd = exports.MessageMarkupStart = exports.MessageLiteral = exports.MessageFallback = exports.MessageDateTime = exports.extendLocaleContext = exports.asMessageValue = void 0; | ||
var as_message_value_1 = require("./as-message-value"); | ||
@@ -15,3 +15,4 @@ Object.defineProperty(exports, "asMessageValue", { enumerable: true, get: function () { return as_message_value_1.asMessageValue; } }); | ||
var message_markup_1 = require("./message-markup"); | ||
Object.defineProperty(exports, "MessageMarkup", { enumerable: true, get: function () { return message_markup_1.MessageMarkup; } }); | ||
Object.defineProperty(exports, "MessageMarkupStart", { enumerable: true, get: function () { return message_markup_1.MessageMarkupStart; } }); | ||
Object.defineProperty(exports, "MessageMarkupEnd", { enumerable: true, get: function () { return message_markup_1.MessageMarkupEnd; } }); | ||
var message_number_1 = require("./message-number"); | ||
@@ -18,0 +19,0 @@ Object.defineProperty(exports, "MessageNumber", { enumerable: true, get: function () { return message_number_1.MessageNumber; } }); |
@@ -21,12 +21,12 @@ "use strict"; | ||
function extendLocaleContext(orig, lc) { | ||
let { locales, localeMatcher } = orig !== null && orig !== void 0 ? orig : {}; | ||
let { locales, localeMatcher } = orig ?? {}; | ||
if (lc && typeof lc === 'string') { | ||
locales !== null && locales !== void 0 ? locales : (locales = [lc]); | ||
locales ?? (locales = [lc]); | ||
} | ||
else if (Array.isArray(lc)) { | ||
locales !== null && locales !== void 0 ? locales : (locales = lc.slice()); | ||
locales ?? (locales = lc.slice()); | ||
} | ||
else if ((0, exports.isLocaleContext)(lc)) { | ||
locales !== null && locales !== void 0 ? locales : (locales = lc.locales.slice()); | ||
localeMatcher !== null && localeMatcher !== void 0 ? localeMatcher : (localeMatcher = lc.localeMatcher); | ||
locales ?? (locales = lc.locales.slice()); | ||
localeMatcher ?? (localeMatcher = lc.localeMatcher); | ||
} | ||
@@ -33,0 +33,0 @@ return locales ? { locales, localeMatcher } : null; |
@@ -10,3 +10,2 @@ import { Context } from '../format-context'; | ||
export declare class MessageDateTime extends MessageValue<Date> { | ||
static readonly type = "datetime"; | ||
options?: Intl.DateTimeFormatOptions; | ||
@@ -13,0 +12,0 @@ constructor(locale: LocaleContextArg, date: number | Date | Readonly<MessageDateTime>, { meta, options, source }?: { |
@@ -6,2 +6,3 @@ "use strict"; | ||
const message_value_1 = require("./message-value"); | ||
const DATETIME = 'datetime'; | ||
/** | ||
@@ -17,6 +18,7 @@ * A child class of {@link MessageValue} for Date values. | ||
const lc = (0, locale_context_1.extendLocaleContext)(date.localeContext, locale); | ||
super(MessageDateTime.type, lc, date.value, fmt); | ||
super(DATETIME, lc, date.value, fmt); | ||
if (options || date.options) | ||
this.options = date.options | ||
? Object.assign(Object.assign({}, date.options), options) : Object.assign({}, options); | ||
? { ...date.options, ...options } | ||
: { ...options }; | ||
} | ||
@@ -27,5 +29,5 @@ else { | ||
if (date instanceof Date) { | ||
super(MessageDateTime.type, locale, date, fmt); | ||
super(DATETIME, locale, date, fmt); | ||
if (options) | ||
this.options = Object.assign({}, options); | ||
this.options = { ...options }; | ||
} | ||
@@ -39,4 +41,5 @@ else | ||
const opt = lc | ||
? Object.assign({ localeMatcher: lc.localeMatcher }, this.options) : this.options; | ||
return new Intl.DateTimeFormat(lc === null || lc === void 0 ? void 0 : lc.locales, opt); | ||
? { localeMatcher: lc.localeMatcher, ...this.options } | ||
: this.options; | ||
return new Intl.DateTimeFormat(lc?.locales, opt); | ||
} | ||
@@ -73,2 +76,1 @@ toParts() { | ||
exports.MessageDateTime = MessageDateTime; | ||
MessageDateTime.type = 'datetime'; |
@@ -6,2 +6,3 @@ import type { LocaleContextArg } from './locale-context'; | ||
* | ||
* @remarks | ||
* Used to represent parse errors as well as runtime/formatting errors. | ||
@@ -12,3 +13,2 @@ * | ||
export declare class MessageFallback extends MessageValue<undefined> { | ||
static readonly type = "fallback"; | ||
constructor(locale: LocaleContextArg, fmt: { | ||
@@ -15,0 +15,0 @@ meta?: Readonly<Meta>; |
@@ -5,5 +5,7 @@ "use strict"; | ||
const message_value_1 = require("./message-value"); | ||
const FALLBACK = 'fallback'; | ||
/** | ||
* A child class of {@link MessageValue} for fallback values. | ||
* | ||
* @remarks | ||
* Used to represent parse errors as well as runtime/formatting errors. | ||
@@ -15,3 +17,3 @@ * | ||
constructor(locale, fmt) { | ||
super(MessageFallback.type, locale, undefined, fmt); | ||
super(FALLBACK, locale, undefined, fmt); | ||
} | ||
@@ -27,2 +29,1 @@ matchSelectKey() { | ||
exports.MessageFallback = MessageFallback; | ||
MessageFallback.type = 'fallback'; |
@@ -8,3 +8,2 @@ import { MessageValue, Meta } from './message-value'; | ||
export declare class MessageLiteral extends MessageValue<string> { | ||
static readonly type = "literal"; | ||
constructor(literal: string, fmt?: { | ||
@@ -11,0 +10,0 @@ meta?: Readonly<Meta>; |
@@ -5,2 +5,3 @@ "use strict"; | ||
const message_value_1 = require("./message-value"); | ||
const LITERAL = 'literal'; | ||
/** | ||
@@ -13,3 +14,3 @@ * A child class of {@link MessageValue} for values defined directly in the message data. | ||
constructor(literal, fmt) { | ||
super(MessageLiteral.type, null, literal, fmt); | ||
super(LITERAL, null, literal, fmt); | ||
} | ||
@@ -21,2 +22,1 @@ toString() { | ||
exports.MessageLiteral = MessageLiteral; | ||
MessageLiteral.type = 'literal'; |
@@ -5,12 +5,9 @@ import { Context } from '../format-context'; | ||
/** | ||
* A child class of {@link MessageValue} for numerical values. | ||
* A child class of {@link MessageValue} for starting markup elements. | ||
* | ||
* @beta | ||
*/ | ||
export declare class MessageMarkup extends MessageValue<MessageValue[]> { | ||
static readonly type = "markup"; | ||
name: string; | ||
options?: Record<string, unknown>; | ||
constructor(locale: LocaleContextArg, name: string, { tag, meta, options, source }: { | ||
tag?: 'empty' | 'start' | 'end'; | ||
export declare class MessageMarkupStart extends MessageValue<string> { | ||
options: Record<string, unknown>; | ||
constructor(locale: LocaleContextArg, name: string, { meta, options, source }: { | ||
meta?: Readonly<Meta>; | ||
@@ -20,3 +17,2 @@ options?: Readonly<Record<string, unknown>>; | ||
}); | ||
get isEndTag(): boolean; | ||
matchSelectKey(): boolean; | ||
@@ -26,6 +22,13 @@ toString(onError?: Context['onError']): string; | ||
/** | ||
* Fill out MessageMarkup `value`s with their appropriate contents | ||
* A child class of {@link MessageValue} for ending markup elements. | ||
* | ||
* @param body Modified, assigning element contents & dropping end tags | ||
* @beta | ||
*/ | ||
export declare function fillMessageMarkups(body: MessageValue[]): void; | ||
export declare class MessageMarkupEnd extends MessageValue<string> { | ||
constructor(locale: LocaleContextArg, name: string, options: { | ||
meta?: Readonly<Meta>; | ||
source?: string; | ||
}); | ||
matchSelectKey(): boolean; | ||
toString(): string; | ||
} |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.fillMessageMarkups = exports.MessageMarkup = void 0; | ||
exports.MessageMarkupEnd = exports.MessageMarkupStart = void 0; | ||
const message_value_1 = require("./message-value"); | ||
const elementTags = new WeakMap(); | ||
const MARKUP_START = 'markup-start'; | ||
const MARKUP_END = 'markup-end'; | ||
/** | ||
* A child class of {@link MessageValue} for numerical values. | ||
* A child class of {@link MessageValue} for starting markup elements. | ||
* | ||
* @beta | ||
*/ | ||
class MessageMarkup extends message_value_1.MessageValue { | ||
constructor(locale, name, { tag, meta, options, source }) { | ||
super(MessageMarkup.type, locale, [], { meta, source }); | ||
this.name = name; | ||
if (options) | ||
this.options = Object.assign({}, options); | ||
if (tag === 'start' || tag === 'end') | ||
elementTags.set(this, tag); | ||
class MessageMarkupStart extends message_value_1.MessageValue { | ||
constructor(locale, name, { meta, options, source }) { | ||
super(MARKUP_START, locale, name, { meta, source }); | ||
this.options = { ...options }; | ||
} | ||
get isEndTag() { | ||
return elementTags.get(this) === 'end'; | ||
} | ||
matchSelectKey() { | ||
@@ -27,81 +21,38 @@ return false; | ||
toString(onError) { | ||
const { name, options, value } = this; | ||
if (this.isEndTag) | ||
return `</${name}>`; | ||
let start = name; | ||
if (options) { | ||
for (const [key, opt] of Object.entries(options)) { | ||
try { | ||
if (/^\w[\w-]*$/.test(key)) | ||
start += ` ${key}=${JSON.stringify(String(opt))}`; | ||
let tag = this.value; | ||
for (const [key, opt] of Object.entries(this.options)) { | ||
try { | ||
if (/^\w[\w-]*$/.test(key)) { | ||
let strOpt = String(opt); | ||
if (/[^\w-]/.test(strOpt)) { | ||
strOpt = '(' + strOpt.replace(/[()\\]/g, '\\$&') + ')'; | ||
} | ||
tag += ` ${key}=${strOpt}`; | ||
} | ||
catch (error) { | ||
if (onError) | ||
onError(error, this); | ||
} | ||
} | ||
catch (error) { | ||
if (onError) | ||
onError(error, this); | ||
} | ||
} | ||
return value.length > 0 | ||
? `<${start}>${value.join('')}</${name}>` | ||
: `<${start}/>`; | ||
return `{+${tag}}`; | ||
} | ||
} | ||
exports.MessageMarkup = MessageMarkup; | ||
MessageMarkup.type = 'markup'; | ||
exports.MessageMarkupStart = MessageMarkupStart; | ||
/** | ||
* Fill out MessageMarkup `value`s with their appropriate contents | ||
* A child class of {@link MessageValue} for ending markup elements. | ||
* | ||
* @param body Modified, assigning element contents & dropping end tags | ||
* @beta | ||
*/ | ||
function fillMessageMarkups(body) { | ||
const stack = []; | ||
for (let i = 0; i < body.length; ++i) { | ||
const mv = body[i]; | ||
if (mv instanceof MessageMarkup) { | ||
switch (elementTags.get(mv)) { | ||
case 'start': | ||
stack.push(mv); | ||
break; | ||
case 'end': { | ||
const el = stack.pop(); | ||
if (!el) | ||
break; | ||
const start = body.indexOf(el) + 1; | ||
el.value = body.splice(start, i - start); | ||
i = start - 1; | ||
elementTags.delete(el); | ||
if (mv.name === el.name) { | ||
// Remove matching end element | ||
body.splice(start, 1); | ||
} | ||
else { | ||
// Improper nesting of tags needs special handling | ||
// | ||
// Example: <b>bold <i>both</b> italic</i> | ||
// ^ here, with stack = [<b>, <i>] | ||
// 1. End current <i> element | ||
// 2. Insert copy of <i> after </b> | ||
// 3. Re-handle this </b>, now with stack = [<b>] | ||
// | ||
// Result: <b>bold <i>both</i></b><i> italic</i> | ||
body.splice(start + 1, 0, copyStartMarkup(el)); | ||
} | ||
break; | ||
} | ||
} | ||
} | ||
class MessageMarkupEnd extends message_value_1.MessageValue { | ||
constructor(locale, name, options) { | ||
super(MARKUP_END, locale, name, options); | ||
} | ||
let el = stack.pop(); | ||
while (el) { | ||
// End of body before matching end element | ||
el.value = body.splice(body.indexOf(el) + 1); | ||
elementTags.delete(el); | ||
el = stack.pop(); | ||
matchSelectKey() { | ||
return false; | ||
} | ||
toString() { | ||
return `{-${this.value}}`; | ||
} | ||
} | ||
exports.fillMessageMarkups = fillMessageMarkups; | ||
function copyStartMarkup(el) { | ||
const { localeContext, name, meta, options, source } = el; | ||
const fmt = { tag: 'start', meta, options, source }; | ||
return new MessageMarkup(localeContext, name, fmt); | ||
} | ||
exports.MessageMarkupEnd = MessageMarkupEnd; |
@@ -10,3 +10,2 @@ import { Context } from '../format-context'; | ||
export declare class MessageNumber extends MessageValue<number | bigint> { | ||
static readonly type = "number"; | ||
options?: Intl.NumberFormatOptions & Intl.PluralRulesOptions; | ||
@@ -25,2 +24,3 @@ constructor(locale: LocaleContextArg, number: number | bigint | Readonly<MessageNumber>, { meta, options, source }?: { | ||
* | ||
* @remarks | ||
* Different languages use different subset of plural rule categories. | ||
@@ -27,0 +27,0 @@ * For example, cardinal English plurals only use `one` and `other`, |
@@ -6,2 +6,3 @@ "use strict"; | ||
const message_value_1 = require("./message-value"); | ||
const NUMBER = 'number'; | ||
/** | ||
@@ -17,11 +18,12 @@ * A child class of {@link MessageValue} for numerical values. | ||
const lc = (0, locale_context_1.extendLocaleContext)(number.localeContext, locale); | ||
super(MessageNumber.type, lc, number.value, fmt); | ||
super(NUMBER, lc, number.value, fmt); | ||
if (options || number.options) | ||
this.options = number.options | ||
? Object.assign(Object.assign({}, number.options), options) : Object.assign({}, options); | ||
? { ...number.options, ...options } | ||
: { ...options }; | ||
} | ||
else if (typeof number === 'number' || typeof number === 'bigint') { | ||
super(MessageNumber.type, locale, number, fmt); | ||
super(NUMBER, locale, number, fmt); | ||
if (options) | ||
this.options = Object.assign({}, options); | ||
this.options = { ...options }; | ||
} | ||
@@ -33,5 +35,5 @@ else | ||
const lc = this.localeContext; | ||
const lm = lc === null || lc === void 0 ? void 0 : lc.localeMatcher; | ||
const opt = lm ? Object.assign({ localeMatcher: lm }, this.options) : this.options; | ||
return new Class(lc === null || lc === void 0 ? void 0 : lc.locales, opt); | ||
const lm = lc?.localeMatcher; | ||
const opt = lm ? { localeMatcher: lm, ...this.options } : this.options; | ||
return new Class(lc?.locales, opt); | ||
} | ||
@@ -51,2 +53,3 @@ getPluralCategory() { | ||
* | ||
* @remarks | ||
* Different languages use different subset of plural rule categories. | ||
@@ -81,2 +84,1 @@ * For example, cardinal English plurals only use `one` and `other`, | ||
exports.MessageNumber = MessageNumber; | ||
MessageNumber.type = 'number'; |
@@ -26,3 +26,2 @@ import { Context } from '../format-context'; | ||
#private; | ||
static readonly type: string; | ||
readonly type: string; | ||
@@ -32,3 +31,3 @@ value: T; | ||
meta?: Meta; | ||
constructor(type: string, locale: LocaleContextArg, value: T, format?: { | ||
constructor(type: string | null, locale: LocaleContextArg, value: T, format?: { | ||
meta?: Readonly<Meta>; | ||
@@ -35,0 +34,0 @@ source?: string; |
@@ -35,3 +35,3 @@ "use strict"; | ||
_MessageValue_localeContext.set(this, void 0); | ||
this.type = type; | ||
this.type = type ?? 'value'; | ||
this.value = value; | ||
@@ -44,3 +44,3 @@ __classPrivateFieldSet(this, _MessageValue_localeContext, locale, "f"); | ||
if (meta) | ||
this.meta = Object.assign({}, meta); | ||
this.meta = { ...meta }; | ||
if (toString && Object.prototype.hasOwnProperty.call(format, 'toString')) | ||
@@ -93,2 +93,1 @@ this.toString = toString; | ||
_MessageValue_localeContext = new WeakMap(); | ||
MessageValue.type = 'value'; |
@@ -11,3 +11,2 @@ import type { Message } from '../data-model'; | ||
#private; | ||
static readonly type = "message"; | ||
constructor(context: Context, message: Message, source?: string); | ||
@@ -14,0 +13,0 @@ matchSelectKey(key: string): boolean; |
@@ -17,4 +17,4 @@ "use strict"; | ||
const detect_grammar_1 = require("../extra/detect-grammar"); | ||
const message_markup_1 = require("./message-markup"); | ||
const message_value_1 = require("./message-value"); | ||
const MESSAGE = 'message'; | ||
function getPattern(context, message) { | ||
@@ -52,4 +52,3 @@ switch (message.type) { | ||
const resMsg = pattern.map(elem => context.resolve(elem)); | ||
(0, message_markup_1.fillMessageMarkups)(resMsg); | ||
super(ResolvedMessage.type, context, resMsg, { meta, source }); | ||
super(MESSAGE, context, resMsg, { meta, source }); | ||
// Cache for string value | ||
@@ -72,2 +71,1 @@ _ResolvedMessage_str.set(this, void 0); | ||
_ResolvedMessage_str = new WeakMap(); | ||
ResolvedMessage.type = 'message'; |
@@ -11,2 +11,3 @@ import { Message } from './data-model'; | ||
* | ||
* @remarks | ||
* See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl#locale_negotiation | ||
@@ -17,4 +18,3 @@ */ | ||
* The set of functions available during message resolution. | ||
* | ||
* Default: {@link defaultRuntime} | ||
* If not set, defaults to {@link defaultRuntime}. | ||
*/ | ||
@@ -26,6 +26,2 @@ runtime?: Runtime; | ||
* | ||
* If `runtime` is unset, a default minimal set is used, consisting of `plural` | ||
* for selection and `datetime` & `number` formatters based on the `Intl` | ||
* equivalents. | ||
* | ||
* @beta | ||
@@ -32,0 +28,0 @@ */ |
@@ -23,6 +23,2 @@ "use strict"; | ||
* | ||
* If `runtime` is unset, a default minimal set is used, consisting of `plural` | ||
* for selection and `datetime` & `number` formatters based on the `Intl` | ||
* equivalents. | ||
* | ||
* @beta | ||
@@ -32,3 +28,2 @@ */ | ||
constructor(source, locales, options) { | ||
var _a, _b; | ||
_MessageFormat_localeMatcher.set(this, void 0); | ||
@@ -38,3 +33,3 @@ _MessageFormat_locales.set(this, void 0); | ||
_MessageFormat_runtime.set(this, void 0); | ||
__classPrivateFieldSet(this, _MessageFormat_localeMatcher, (_a = options === null || options === void 0 ? void 0 : options.localeMatcher) !== null && _a !== void 0 ? _a : 'best fit', "f"); | ||
__classPrivateFieldSet(this, _MessageFormat_localeMatcher, options?.localeMatcher ?? 'best fit', "f"); | ||
__classPrivateFieldSet(this, _MessageFormat_locales, Array.isArray(locales) | ||
@@ -46,4 +41,4 @@ ? locales.slice() | ||
__classPrivateFieldSet(this, _MessageFormat_message, typeof source === 'string' ? (0, message_1.parseMessage)(source) : source, "f"); | ||
const rt = (_b = options === null || options === void 0 ? void 0 : options.runtime) !== null && _b !== void 0 ? _b : runtime_1.defaultRuntime; | ||
__classPrivateFieldSet(this, _MessageFormat_runtime, Object.freeze(Object.assign({}, rt)), "f"); | ||
const rt = options?.runtime ?? runtime_1.defaultRuntime; | ||
__classPrivateFieldSet(this, _MessageFormat_runtime, Object.freeze({ ...rt }), "f"); | ||
} | ||
@@ -79,3 +74,3 @@ resolveMessage(msgParams, onError) { | ||
// If declarations exist, scope may be modified during formatting | ||
scope: declarations.length > 0 ? Object.assign({}, scope) : scope | ||
scope: declarations.length > 0 ? { ...scope } : scope | ||
}; | ||
@@ -82,0 +77,0 @@ return ctx; |
@@ -9,3 +9,3 @@ import type { CatchallKey, Declaration, JunkMessage, Pattern, PatternMessage, SelectMessage, Variant } from '../data-model'; | ||
} | { | ||
type: 'bad-escape' | 'bad-selector' | 'extra-content' | 'key-mismatch' | 'parse-error'; | ||
type: 'bad-escape' | 'bad-local-var' | 'bad-selector' | 'extra-content' | 'key-mismatch' | 'parse-error'; | ||
start: number; | ||
@@ -12,0 +12,0 @@ end: number; |
@@ -17,2 +17,3 @@ "use strict"; | ||
} | ||
checkLocalVarReferences(declarations, errors); | ||
return { declarations, end: pos }; | ||
@@ -71,1 +72,32 @@ } | ||
} | ||
/** Local variable declarations can't refer to later ones */ | ||
function checkLocalVarReferences(declarations, errors) { | ||
const check = (name, ref) => { | ||
if (ref.name === name) | ||
errors.push({ type: 'bad-local-var', start: ref.start, end: ref.end }); | ||
}; | ||
for (let i = 1; i < declarations.length; ++i) { | ||
const { name } = declarations[i].target; | ||
if (!name) | ||
continue; | ||
for (let j = 0; j < i; ++j) { | ||
const ph = declarations[j].value; | ||
if (ph.type === 'placeholder') { | ||
const exp = ph.body; | ||
switch (exp.type) { | ||
case 'expression': | ||
if (exp.operand?.type === 'variable') | ||
check(name, exp.operand); | ||
for (const opt of exp.options) { | ||
if (opt.value.type === 'variable') | ||
check(name, opt.value); | ||
} | ||
break; | ||
case 'variable': | ||
check(name, exp); | ||
break; | ||
} | ||
} | ||
} | ||
} | ||
} |
import type { NmtokenParsed, ParseError } from './data-model.js'; | ||
export declare function isValidNmtoken(str: string): boolean; | ||
export declare function parseNameValue(src: string, start: number): string; | ||
export declare function parseNmtoken(src: string, start: number, errors: ParseError[]): NmtokenParsed; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.parseNmtoken = exports.parseNameValue = void 0; | ||
exports.parseNmtoken = exports.parseNameValue = exports.isValidNmtoken = void 0; | ||
// NameStart ::= [a-zA-Z] | "_" | ||
@@ -38,2 +38,11 @@ // | [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x2FF] | ||
cc === 0x2040; // ⁀ | ||
function isValidNmtoken(str) { | ||
for (let i = 0; i < str.length; ++i) { | ||
const cc = str.charCodeAt(i); | ||
if (!isNameCharCode(cc)) | ||
return false; | ||
} | ||
return str.length > 0; | ||
} | ||
exports.isValidNmtoken = isValidNmtoken; | ||
// Name ::= NameStart NameChar* /* ws: explicit */ | ||
@@ -40,0 +49,0 @@ function parseNameValue(src, start) { |
@@ -7,2 +7,3 @@ import type { Context } from '../format-context'; | ||
* | ||
* @remarks | ||
* The `name` identifies a function that takes in the arguments `args`, the | ||
@@ -9,0 +10,0 @@ * current locale, as well as any `options`, and returns some corresponding |
@@ -83,3 +83,3 @@ "use strict"; | ||
catch (error) { | ||
source !== null && source !== void 0 ? source : (source = `${name}(${operand ? message_value_2.FALLBACK_SOURCE : ''})`); | ||
source ?? (source = `${name}(${operand ? message_value_2.FALLBACK_SOURCE : ''})`); | ||
const fb = new message_value_1.MessageFallback(ctx, { source }); | ||
@@ -86,0 +86,0 @@ ctx.onError(error, fb); |
@@ -10,3 +10,3 @@ import type { Context } from '../format-context'; | ||
export { isJunk, Junk } from './junk'; | ||
export { isLiteral, Literal, Text } from './literal'; | ||
export { isLiteral, isText, Literal, Text } from './literal'; | ||
export { isMarkupEnd, isMarkupStart, MarkupEnd, MarkupStart } from './markup'; | ||
@@ -24,2 +24,8 @@ export { isVariableRef, VariableRef } from './variable-ref'; | ||
/** | ||
* Type guard for {@link Placeholder} pattern elements | ||
* | ||
* @beta | ||
*/ | ||
export declare const isPlaceholder: (part: any) => part is Placeholder; | ||
/** | ||
* The contents of a message are a sequence of pattern elements, which may be | ||
@@ -30,2 +36,3 @@ * immediately defined literal values, a reference to a value that depends on | ||
* | ||
* @remarks | ||
* Depending on the syntax, pattern elements may be wrapped within a Placeholder. | ||
@@ -32,0 +39,0 @@ * |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.resolvePatternElement = exports.isVariableRef = exports.isMarkupStart = exports.isMarkupEnd = exports.isLiteral = exports.isJunk = exports.isExpression = void 0; | ||
exports.resolvePatternElement = exports.isPlaceholder = exports.isVariableRef = exports.isMarkupStart = exports.isMarkupEnd = exports.isText = exports.isLiteral = exports.isJunk = exports.isExpression = void 0; | ||
const expression_1 = require("./expression"); | ||
@@ -15,2 +15,3 @@ const junk_1 = require("./junk"); | ||
Object.defineProperty(exports, "isLiteral", { enumerable: true, get: function () { return literal_2.isLiteral; } }); | ||
Object.defineProperty(exports, "isText", { enumerable: true, get: function () { return literal_2.isText; } }); | ||
var markup_2 = require("./markup"); | ||
@@ -21,2 +22,10 @@ Object.defineProperty(exports, "isMarkupEnd", { enumerable: true, get: function () { return markup_2.isMarkupEnd; } }); | ||
Object.defineProperty(exports, "isVariableRef", { enumerable: true, get: function () { return variable_ref_2.isVariableRef; } }); | ||
/** | ||
* Type guard for {@link Placeholder} pattern elements | ||
* | ||
* @beta | ||
*/ | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
const isPlaceholder = (part) => !!part && typeof part === 'object' && part.type === 'placeholder'; | ||
exports.isPlaceholder = isPlaceholder; | ||
/** @internal */ | ||
@@ -23,0 +32,0 @@ function resolvePatternElement(ctx, elem) { |
@@ -7,2 +7,3 @@ import type { Context } from '../format-context'; | ||
* | ||
* @remarks | ||
* Garbage in, garbage out: Resolving a message that includes junk will always | ||
@@ -9,0 +10,0 @@ * resolve it using a fallback representation. |
@@ -5,2 +5,3 @@ import { MessageLiteral } from '../message-value'; | ||
* | ||
* @remarks | ||
* Always contains a string value. In Function arguments and options, | ||
@@ -21,6 +22,6 @@ * the expeted type of the value may result in the value being | ||
*/ | ||
export declare type Text = { | ||
export interface Text { | ||
type: 'text'; | ||
value: string; | ||
}; | ||
} | ||
/** | ||
@@ -32,2 +33,8 @@ * Type guard for {@link Literal} pattern elements | ||
export declare const isLiteral: (part: any) => part is Literal; | ||
/** | ||
* Type guard for {@link Text} pattern elements | ||
* | ||
* @beta | ||
*/ | ||
export declare const isText: (part: any) => part is Text; | ||
export declare function resolveLiteral(lit: Literal | Text): MessageLiteral; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.resolveLiteral = exports.isLiteral = void 0; | ||
exports.resolveLiteral = exports.isText = exports.isLiteral = void 0; | ||
const message_value_1 = require("../message-value"); | ||
@@ -15,2 +15,10 @@ /** | ||
exports.isLiteral = isLiteral; | ||
/** | ||
* Type guard for {@link Text} pattern elements | ||
* | ||
* @beta | ||
*/ | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
const isText = (part) => !!part && typeof part === 'object' && part.type === 'text'; | ||
exports.isText = isText; | ||
function resolveLiteral(lit) { | ||
@@ -17,0 +25,0 @@ return new message_value_1.MessageLiteral(lit.value); |
import type { Context } from '../format-context'; | ||
import { MessageMarkup, MessageFallback } from '../message-value'; | ||
import { MessageFallback, MessageMarkupEnd, MessageMarkupStart } from '../message-value'; | ||
import type { Option } from './index'; | ||
@@ -37,3 +37,3 @@ /** | ||
export declare const isMarkupEnd: (part: any) => part is MarkupEnd; | ||
export declare function resolveMarkupStart(ctx: Context, { name, options }: MarkupStart): MessageFallback | MessageMarkup; | ||
export declare function resolveMarkupEnd(ctx: Context, { name }: MarkupEnd): MessageMarkup; | ||
export declare function resolveMarkupStart(ctx: Context, { name, options }: MarkupStart): MessageFallback | MessageMarkupStart; | ||
export declare function resolveMarkupEnd(ctx: Context, { name }: MarkupEnd): MessageMarkupEnd; |
@@ -31,8 +31,7 @@ "use strict"; | ||
function resolveMarkupStart(ctx, { name, options }) { | ||
const source = `<${name}>`; | ||
const source = `+${name}`; | ||
try { | ||
return new message_value_1.MessageMarkup(ctx, name, { | ||
return new message_value_1.MessageMarkupStart(ctx, name, { | ||
options: resolveOptions(ctx, options), | ||
source, | ||
tag: 'start' | ||
source | ||
}); | ||
@@ -48,4 +47,4 @@ } | ||
function resolveMarkupEnd(ctx, { name }) { | ||
return new message_value_1.MessageMarkup(ctx, name, { source: `</${name}>`, tag: 'end' }); | ||
return new message_value_1.MessageMarkupEnd(ctx, name, { source: `-${name}` }); | ||
} | ||
exports.resolveMarkupEnd = resolveMarkupEnd; |
@@ -6,2 +6,3 @@ import { Context } from '../format-context'; | ||
* | ||
* @remarks | ||
* To refer to an inner property of an object value, use `.` as a separator; | ||
@@ -8,0 +9,0 @@ * in case of conflict, the longest starting substring wins. |
@@ -34,10 +34,11 @@ "use strict"; | ||
const source = '$' + name; | ||
let value = getValue(ctx.scope, name); | ||
if (value === undefined) { | ||
const decl = ctx.declarations.find(decl => decl.target.name === name); | ||
if (decl) { | ||
value = ctx.resolve(decl.value); | ||
ctx.scope[name] = value; | ||
} | ||
let value; | ||
const decl = ctx.declarations.find(decl => decl.target.name === name); | ||
if (decl) { | ||
value = ctx.resolve(decl.value); | ||
ctx.scope[name] = value; | ||
} | ||
else { | ||
value = getValue(ctx.scope, name); | ||
} | ||
if (value !== undefined) | ||
@@ -44,0 +45,0 @@ return (0, message_value_1.asMessageValue)(ctx, value, { source }); |
@@ -44,3 +44,3 @@ "use strict"; | ||
call: function number(locales, options, arg) { | ||
const num = arg instanceof message_value_1.MessageNumber ? arg : Number(arg === null || arg === void 0 ? void 0 : arg.value); | ||
const num = arg instanceof message_value_1.MessageNumber ? arg : Number(arg?.value); | ||
return new message_value_1.MessageNumber(locales, num, { options }); | ||
@@ -47,0 +47,0 @@ }, |
import { MessageValue } from '../message-value'; | ||
/** | ||
* The default Runtime includes two functions: | ||
* The default Runtime includes two functions, `datetime` and `number`. | ||
* | ||
* @remarks | ||
* - `datetime` accepts an optional Date, number or string as its argument | ||
@@ -11,2 +13,4 @@ * and formats it with the same options as | ||
* {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat | Intl.NumberFormat}. | ||
* It also supports plural category selection via | ||
* {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/PluralRules | Intl.PluralRules} | ||
* | ||
@@ -34,2 +38,4 @@ * @beta | ||
* Basic type checking is performed on option values. | ||
* | ||
* @remarks | ||
* - `'any'` - Value type is not checked | ||
@@ -36,0 +42,0 @@ * - `'never'` - No value is valid |
@@ -7,3 +7,5 @@ "use strict"; | ||
/** | ||
* The default Runtime includes two functions: | ||
* The default Runtime includes two functions, `datetime` and `number`. | ||
* | ||
* @remarks | ||
* - `datetime` accepts an optional Date, number or string as its argument | ||
@@ -16,2 +18,4 @@ * and formats it with the same options as | ||
* {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat | Intl.NumberFormat}. | ||
* It also supports plural category selection via | ||
* {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/PluralRules | Intl.PluralRules} | ||
* | ||
@@ -18,0 +22,0 @@ * @beta |
{ | ||
"name": "messageformat", | ||
"version": "4.0.0-0", | ||
"version": "4.0.0-1", | ||
"description": "Intl.MessageFormat / Unicode MessageFormat 2 parser, runtime and polyfill", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
112626
68
2737
0