diff --git a/.gitignore b/.gitignore index 20c62c8ea..c28424f5b 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,8 @@ node_modules html .vscode +/fluent-*/dist/ + # Test coverage .nyc_output coverage diff --git a/.prettierignore b/.prettierignore index 195cca863..6b53b9882 100644 --- a/.prettierignore +++ b/.prettierignore @@ -4,8 +4,6 @@ html coverage/ dist/ -esm/ -/fluent-*/index.js /tools/**/*.ftl /tools/**/*.json diff --git a/eslint.config.mjs b/eslint.config.mjs index 409194ea8..252cdd97d 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -10,7 +10,6 @@ export default [ "**/node_modules/", "*/coverage/", "*/dist/", - "*/esm/", "*/vendor/", "fluent-*/index.js", "html/", diff --git a/fluent-bundle/.gitignore b/fluent-bundle/.gitignore deleted file mode 100644 index 0bd1f3fc5..000000000 --- a/fluent-bundle/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -esm/ -/index.js diff --git a/fluent-bundle/.npmignore b/fluent-bundle/.npmignore deleted file mode 100644 index abad613ff..000000000 --- a/fluent-bundle/.npmignore +++ /dev/null @@ -1,7 +0,0 @@ -.nyc_output -coverage -esm/.compiled -src -test -makefile -tsconfig.json diff --git a/fluent-bundle/esm/package.json b/fluent-bundle/esm/package.json deleted file mode 100644 index 3dbc1ca59..000000000 --- a/fluent-bundle/esm/package.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "type": "module" -} diff --git a/fluent-bundle/package.json b/fluent-bundle/package.json index 730a4f357..362e570c4 100644 --- a/fluent-bundle/package.json +++ b/fluent-bundle/package.json @@ -2,6 +2,16 @@ "name": "@fluent/bundle", "description": "Localization library for expressive translations.", "version": "0.19.1", + "type": "module", + "exports": { + ".": "./dist/index.js", + "./ast": "./dist/ast.js", + "./builtins": "./dist/builtins.js", + "./package.json": "./package.json" + }, + "files": [ + "./dist/" + ], "homepage": "https://projectfluent.org", "author": "Mozilla ", "license": "Apache-2.0", @@ -15,9 +25,6 @@ "email": "stas@mozilla.com" } ], - "main": "./index.js", - "module": "./esm/index.js", - "types": "./esm/index.d.ts", "repository": { "type": "git", "url": "https://github.com/projectfluent/fluent.js.git" @@ -39,14 +46,12 @@ "parser" ], "scripts": { - "build": "tsc", - "postbuild": "rollup -c ../rollup.config.mjs" + "build": "tsc" }, "engines": { "node": "^20.19 || ^22.12 || >=24" }, "devDependencies": { - "@fluent/dedent": "^0.5.0", "temporal-polyfill": "^0.2.5" } } diff --git a/fluent-bundle/src/index.ts b/fluent-bundle/src/index.ts index 0470f9e56..726ccef86 100644 --- a/fluent-bundle/src/index.ts +++ b/fluent-bundle/src/index.ts @@ -6,14 +6,14 @@ */ export type { Message } from "./ast.js"; -export { FluentBundle, TextTransform } from "./bundle.js"; +export { FluentBundle, type TextTransform } from "./bundle.js"; export { FluentResource } from "./resource.js"; export type { Scope } from "./scope.js"; export { - FluentValue, - FluentVariable, - FluentType, - FluentFunction, + type FluentValue, + type FluentVariable, + type FluentType, + type FluentFunction, FluentNone, FluentNumber, FluentDateTime, diff --git a/fluent-bundle/tsconfig.json b/fluent-bundle/tsconfig.json index 1a76d9a43..ae18d140e 100644 --- a/fluent-bundle/tsconfig.json +++ b/fluent-bundle/tsconfig.json @@ -1,7 +1,7 @@ { "extends": "../tsconfig.base.json", "compilerOptions": { - "outDir": "./esm", + "outDir": "./dist", "rootDir": "./src" }, "include": ["./src/**/*.ts"] diff --git a/fluent-dedent/.gitignore b/fluent-dedent/.gitignore deleted file mode 100644 index 0bd1f3fc5..000000000 --- a/fluent-dedent/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -esm/ -/index.js diff --git a/fluent-dedent/.npmignore b/fluent-dedent/.npmignore deleted file mode 100644 index abad613ff..000000000 --- a/fluent-dedent/.npmignore +++ /dev/null @@ -1,7 +0,0 @@ -.nyc_output -coverage -esm/.compiled -src -test -makefile -tsconfig.json diff --git a/fluent-dedent/esm/package.json b/fluent-dedent/esm/package.json deleted file mode 100644 index 3dbc1ca59..000000000 --- a/fluent-dedent/esm/package.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "type": "module" -} diff --git a/fluent-dedent/package.json b/fluent-dedent/package.json index 9f60cbd64..973e11994 100644 --- a/fluent-dedent/package.json +++ b/fluent-dedent/package.json @@ -2,6 +2,14 @@ "name": "@fluent/dedent", "description": "A template literal tag for dedenting Fluent code", "version": "0.5.0", + "type": "module", + "exports": { + ".": "./dist/index.js", + "./package.json": "./package.json" + }, + "files": [ + "./dist/" + ], "homepage": "https://projectfluent.org", "author": "Mozilla ", "license": "Apache-2.0", @@ -11,9 +19,6 @@ "email": "stas@mozilla.com" } ], - "main": "./index.js", - "module": "./esm/index.js", - "types": "./esm/index.d.ts", "repository": { "type": "git", "url": "https://github.com/projectfluent/fluent.js.git" @@ -24,8 +29,7 @@ "ftl" ], "scripts": { - "build": "tsc", - "postbuild": "rollup -c ../rollup.config.mjs" + "build": "tsc" }, "engines": { "node": "^20.19 || ^22.12 || >=24" diff --git a/fluent-dedent/tsconfig.json b/fluent-dedent/tsconfig.json index 1c5501631..d3d83334d 100644 --- a/fluent-dedent/tsconfig.json +++ b/fluent-dedent/tsconfig.json @@ -1,7 +1,7 @@ { "extends": "../tsconfig.base.json", "compilerOptions": { - "outDir": "./esm" + "outDir": "./dist" }, "include": ["./src/**/*.ts"] } diff --git a/fluent-dom/.gitignore b/fluent-dom/.gitignore deleted file mode 100644 index 0bd1f3fc5..000000000 --- a/fluent-dom/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -esm/ -/index.js diff --git a/fluent-dom/.npmignore b/fluent-dom/.npmignore deleted file mode 100644 index abad613ff..000000000 --- a/fluent-dom/.npmignore +++ /dev/null @@ -1,7 +0,0 @@ -.nyc_output -coverage -esm/.compiled -src -test -makefile -tsconfig.json diff --git a/fluent-dom/esm/package.json b/fluent-dom/esm/package.json deleted file mode 100644 index 3dbc1ca59..000000000 --- a/fluent-dom/esm/package.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "type": "module" -} diff --git a/fluent-dom/package.json b/fluent-dom/package.json index 315a853a1..b29bcebce 100644 --- a/fluent-dom/package.json +++ b/fluent-dom/package.json @@ -2,6 +2,15 @@ "name": "@fluent/dom", "version": "0.10.2", "description": "Fluent bindings for DOM", + "type": "module", + "exports": { + ".": "./dist/index.js", + "./overlay": "./dist/overlay.js", + "./package.json": "./package.json" + }, + "files": [ + "./dist/" + ], "repository": { "type": "git", "url": "https://github.com/projectfluent/fluent.js.git" @@ -18,9 +27,6 @@ "email": "stas@mozilla.com" } ], - "main": "./index.js", - "module": "./esm/index.js", - "types": "./esm/index.d.ts", "keywords": [ "localization", "l10n", @@ -34,15 +40,11 @@ "format" ], "scripts": { - "build": "tsc", - "postbuild": "rollup -c ../rollup.config.mjs --globals cached-iterable:CachedIterable" + "build": "tsc" }, "engines": { "node": "^20.19 || ^22.12 || >=24" }, - "devDependencies": { - "@fluent/bundle": "^0.19.0" - }, "dependencies": { "cached-iterable": "^0.3" } diff --git a/fluent-dom/src/dom_localization.js b/fluent-dom/src/dom_localization.ts similarity index 68% rename from fluent-dom/src/dom_localization.js rename to fluent-dom/src/dom_localization.ts index dc7e410e7..717962458 100644 --- a/fluent-dom/src/dom_localization.js +++ b/fluent-dom/src/dom_localization.ts @@ -1,5 +1,10 @@ +import type { FluentBundle } from "@fluent/bundle"; +import { + Localization, + type FormattedMessage, + type MessageKey, +} from "./localization.js"; import translateElement from "./overlay.js"; -import Localization from "./localization.js"; const L10NID_ATTR_NAME = "data-l10n-id"; const L10NARGS_ATTR_NAME = "data-l10n-args"; @@ -14,37 +19,36 @@ const L10N_ELEMENT_QUERY = `[${L10NID_ATTR_NAME}]`; * formatting of translations and methods for observing DOM * trees with a `MutationObserver`. */ -export default class DOMLocalization extends Localization { - /** - * @param {Array} resourceIds - List of resource IDs - * @param {Function} generateBundles - Function that returns a - * generator over FluentBundles - * @returns {DOMLocalization} - */ - constructor(resourceIds, generateBundles) { - super(resourceIds, generateBundles); +export class DOMLocalization extends Localization { + // A Set of DOM trees observed by the `MutationObserver`. + roots = new Set(); - // A Set of DOM trees observed by the `MutationObserver`. - this.roots = new Set(); - // requestAnimationFrame handler. - this.pendingrAF = null; - // list of elements pending for translation. - this.pendingElements = new Set(); - this.windowElement = null; - this.mutationObserver = null; - - this.observerConfig = { - attributes: true, - characterData: false, - childList: true, - subtree: true, - attributeFilter: [L10NID_ATTR_NAME, L10NARGS_ATTR_NAME], - }; + // requestAnimationFrame handler. + pendingrAF: number | null = null; + + pendingElements = new Set(); + windowElement: (Window & typeof globalThis) | null = null; + mutationObserver: MutationObserver | null = null; + + observerConfig = { + attributes: true, + characterData: false, + childList: true, + subtree: true, + attributeFilter: [L10NID_ATTR_NAME, L10NARGS_ATTR_NAME], + }; + + constructor( + resourceIds: string[], + generateBundles: (resourceIds: string[]) => Iterable + ) { + super(resourceIds, generateBundles); } - onChange(eager = false) { + onChange(eager = false): void { super.onChange(eager); if (this.roots) { + // eslint-disable-next-line @typescript-eslint/no-floating-promises this.translateRoots(); } } @@ -79,13 +83,23 @@ export default class DOMLocalization extends Localization { *

* ``` * - * @param {Element} element - Element to set attributes on - * @param {string} id - l10n-id string - * @param {Object} args - KVP list of l10n arguments - * @returns {Element} + * @param element - Element to set attributes on + * @param id - l10n-id string + * @param args - KVP list of l10n arguments */ - setAttributes(element, id, args) { + setAttributes( + element: Element, + id: string, + args?: Record + ): Element { element.setAttribute(L10NID_ATTR_NAME, id); + return this.setArgs(element, args); + } + + /** + * Set only the `data-l10n-args` attribute on a DOM element. + */ + setArgs(element: Element, args?: Record): Element { if (args) { element.setAttribute(L10NARGS_ATTR_NAME, JSON.stringify(args)); } else { @@ -103,14 +117,15 @@ export default class DOMLocalization extends Localization { * ); * // -> { id: 'hello', args: { who: 'world' } } * ``` - * - * @param {Element} element - HTML element - * @returns {{id: string, args: Object}} */ - getAttributes(element) { + getAttributes(element: Element): { + id: string | null; + args: Record | null; + } { + const args = element.getAttribute(L10NARGS_ATTR_NAME); return { id: element.getAttribute(L10NID_ATTR_NAME), - args: JSON.parse(element.getAttribute(L10NARGS_ATTR_NAME) || null), + args: args ? (JSON.parse(args) as Record) : null, }; } @@ -119,10 +134,8 @@ export default class DOMLocalization extends Localization { * * Additionally, if this `DOMLocalization` has an observer, start observing * `newRoot` in order to translate mutations in it. - * - * @param {Element | DocumentFragment} newRoot - Root to observe. */ - connectRoot(newRoot) { + connectRoot(newRoot: Element | DocumentFragment): void { for (const root of this.roots) { if ( root === newRoot || @@ -140,13 +153,13 @@ export default class DOMLocalization extends Localization { } } else { this.windowElement = newRoot.ownerDocument.defaultView; - this.mutationObserver = new this.windowElement.MutationObserver( + this.mutationObserver = new this.windowElement!.MutationObserver( mutations => this.translateMutations(mutations) ); } this.roots.add(newRoot); - this.mutationObserver.observe(newRoot, this.observerConfig); + this.mutationObserver!.observe(newRoot, this.observerConfig); } /** @@ -157,11 +170,8 @@ export default class DOMLocalization extends Localization { * * Returns `true` if the root was the last one managed by this * `DOMLocalization`. - * - * @param {Element | DocumentFragment} root - Root to disconnect. - * @returns {boolean} */ - disconnectRoot(root) { + disconnectRoot(root: Element | DocumentFragment): boolean { this.roots.delete(root); // Pause the mutation observer to stop observing `root`. this.pauseObserving(); @@ -187,7 +197,7 @@ export default class DOMLocalization extends Localization { * * @returns {Promise} */ - translateRoots() { + translateRoots(): Promise { const roots = Array.from(this.roots); return Promise.all(roots.map(root => this.translateFragment(root))); } @@ -195,7 +205,7 @@ export default class DOMLocalization extends Localization { /** * Pauses the `MutationObserver`. */ - pauseObserving() { + pauseObserving(): void { if (!this.mutationObserver) { return; } @@ -207,7 +217,7 @@ export default class DOMLocalization extends Localization { /** * Resumes the `MutationObserver`. */ - resumeObserving() { + resumeObserving(): void { if (!this.mutationObserver) { return; } @@ -219,19 +229,19 @@ export default class DOMLocalization extends Localization { /** * Translate mutations detected by the `MutationObserver`. - * - * @private */ - translateMutations(mutations) { + private translateMutations(mutations: MutationRecord[]): void { for (const mutation of mutations) { switch (mutation.type) { - case "attributes": - if (mutation.target.hasAttribute("data-l10n-id")) { - this.pendingElements.add(mutation.target); + case "attributes": { + const target = mutation.target as HTMLElement; + if (target.hasAttribute("data-l10n-id")) { + this.pendingElements.add(target); } break; + } case "childList": - for (const addedNode of mutation.addedNodes) { + for (const addedNode of mutation.addedNodes as NodeListOf) { if (addedNode.nodeType === addedNode.ELEMENT_NODE) { if (addedNode.childElementCount) { for (const element of this.getTranslatables(addedNode)) { @@ -250,7 +260,8 @@ export default class DOMLocalization extends Localization { // into a single requestAnimationFrame. if (this.pendingElements.size > 0) { if (this.pendingrAF === null) { - this.pendingrAF = this.windowElement.requestAnimationFrame(() => { + this.pendingrAF = this.windowElement!.requestAnimationFrame(() => { + // eslint-disable-next-line @typescript-eslint/no-floating-promises this.translateElements(Array.from(this.pendingElements)); this.pendingElements.clear(); this.pendingrAF = null; @@ -269,10 +280,10 @@ export default class DOMLocalization extends Localization { * * Returns a `Promise` that gets resolved once the translation is complete. * - * @param {Element | DocumentFragment} frag - Element or DocumentFragment to be translated + * @param {} frag - Element or DocumentFragment to be translated * @returns {Promise} */ - translateFragment(frag) { + translateFragment(frag: Element | DocumentFragment): Promise { return this.translateElements(this.getTranslatables(frag)); } @@ -285,28 +296,25 @@ export default class DOMLocalization extends Localization { * with information about which translations to use. * * Returns a `Promise` that gets resolved once the translation is complete. - * - * @param {Array} elements - List of elements to be translated - * @returns {Promise} */ - async translateElements(elements) { + async translateElements(elements: Element[]): Promise { if (!elements.length) { return undefined; } - const keys = elements.map(this.getKeysForElement); - const translations = await this.formatMessages(keys); + // eslint-disable-next-line @typescript-eslint/unbound-method + const keys = elements.map(this.getAttributes); + const translations = await this.formatMessages(keys as MessageKey[]); return this.applyTranslations(elements, translations); } /** * Applies translations onto elements. - * - * @param {Array} elements - * @param {Array} translations - * @private */ - applyTranslations(elements, translations) { + private applyTranslations( + elements: Element[], + translations: FormattedMessage[] + ): void { this.pauseObserving(); for (let i = 0; i < elements.length; i++) { @@ -320,36 +328,14 @@ export default class DOMLocalization extends Localization { /** * Collects all translatable child elements of the element. - * - * @param {Element | DocumentFragment} element - * @returns {Array} - * @private */ - getTranslatables(element) { + private getTranslatables(element: Element | DocumentFragment): Element[] { const nodes = Array.from(element.querySelectorAll(L10N_ELEMENT_QUERY)); - if ( - typeof element.hasAttribute === "function" && - element.hasAttribute(L10NID_ATTR_NAME) - ) { + if (element instanceof Element && element.hasAttribute(L10NID_ATTR_NAME)) { nodes.push(element); } return nodes; } - - /** - * Get the `data-l10n-*` attributes from DOM elements as a two-element - * array. - * - * @param {Element} element - * @returns {Object} - * @private - */ - getKeysForElement(element) { - return { - id: element.getAttribute(L10NID_ATTR_NAME), - args: JSON.parse(element.getAttribute(L10NARGS_ATTR_NAME) || null), - }; - } } diff --git a/fluent-dom/src/index.js b/fluent-dom/src/index.js deleted file mode 100644 index d5575ad4d..000000000 --- a/fluent-dom/src/index.js +++ /dev/null @@ -1,2 +0,0 @@ -export { default as DOMLocalization } from "./dom_localization.js"; -export { default as Localization } from "./localization.js"; diff --git a/fluent-dom/src/index.ts b/fluent-dom/src/index.ts new file mode 100644 index 000000000..9c06b790f --- /dev/null +++ b/fluent-dom/src/index.ts @@ -0,0 +1,7 @@ +export { DOMLocalization } from "./dom_localization.js"; +export { + Localization, + type FormatMethod, + type FormattedMessage, + type MessageKey, +} from "./localization.js"; diff --git a/fluent-dom/src/localization.js b/fluent-dom/src/localization.ts similarity index 74% rename from fluent-dom/src/localization.js rename to fluent-dom/src/localization.ts index 8977165f4..966e9ac5a 100644 --- a/fluent-dom/src/localization.js +++ b/fluent-dom/src/localization.ts @@ -1,35 +1,52 @@ /* eslint no-console: ["error", { allow: ["warn", "error"] }] */ /* global console */ +// @ts-expect-error Ignore types import { CachedAsyncIterable } from "cached-iterable"; +import type { FluentBundle, FluentVariable, Message } from "@fluent/bundle"; + +export type MessageKey = + | string + | { id: string; args?: Record }; +export type FormatMethod = ( + bundle: FluentBundle, + messageErrors: Error[], + message: Message, + args: Record | undefined +) => T; +export type FormattedMessage = { + value: string | null; + attributes: Array<{ name: string; value: string }> | null; +}; + /** * The `Localization` class is a central high-level API for vanilla * JavaScript use of Fluent. * It combines language negotiation, FluentBundle and I/O to * provide a scriptable API to format translations. */ -export default class Localization { - /** - * @param {Array} resourceIds - List of resource IDs - * @param {Function} generateBundles - Function that returns a - * generator over FluentBundles - * - * @returns {Localization} - */ - constructor(resourceIds = [], generateBundles) { +export class Localization { + declare bundles: AsyncIterable; + resourceIds: string[]; + generateBundles: (resourceIds: string[]) => Iterable; + + constructor( + resourceIds: string[] = [], + generateBundles: (resourceIds: string[]) => Iterable + ) { this.resourceIds = resourceIds; this.generateBundles = generateBundles; this.onChange(true); } - addResourceIds(resourceIds, eager = false) { + addResourceIds(resourceIds: string[], eager = false): number { this.resourceIds.push(...resourceIds); this.onChange(eager); return this.resourceIds.length; } - removeResourceIds(resourceIds) { + removeResourceIds(resourceIds: string[]): number { this.resourceIds = this.resourceIds.filter(r => !resourceIds.includes(r)); this.onChange(); return this.resourceIds.length; @@ -41,14 +58,12 @@ export default class Localization { * Format translations for `keys` from `FluentBundle` instances on this * DOMLocalization. In case of errors, fetch the next context in the * fallback chain. - * - * @param {Array} keys - Translation keys to format. - * @param {Function} method - Formatting function. - * @returns {Promise>} - * @private */ - async formatWithFallback(keys, method) { - const translations = []; + private async formatWithFallback( + keys: MessageKey[], + method: FormatMethod + ): Promise { + const translations: T[] = []; let hasAtLeastOneBundle = false; for await (const bundle of this.bundles) { @@ -99,12 +114,8 @@ export default class Localization { * // } * // ] * ``` - * - * @param {Array} keys - * @returns {Promise>} - * @private */ - formatMessages(keys) { + formatMessages(keys: MessageKey[]): Promise { return this.formatWithFallback(keys, messageFromBundle); } @@ -126,11 +137,8 @@ export default class Localization { * * // ['Hello, Mary!', 'Hello, John!', 'Welcome!'] * ``` - * - * @param {Array} keys - * @returns {Promise>} */ - formatValues(keys) { + formatValues(keys: MessageKey[]): Promise> { return this.formatWithFallback(keys, valueFromBundle); } @@ -154,17 +162,16 @@ export default class Localization { * * // 'Hello, world!' * ``` - * - * @param {string} id - Identifier of the translation to format - * @param {Object} [args] - Optional external arguments - * @returns {Promise} */ - async formatValue(id, args) { + async formatValue( + id: string, + args?: Record + ): Promise { const [val] = await this.formatValues([{ id, args }]); return val; } - handleEvent() { + handleEvent(): void { this.onChange(); } @@ -172,11 +179,14 @@ export default class Localization { * This method should be called when there's a reason to believe * that language negotiation or available resources changed. */ - onChange(eager = false) { + onChange(eager = false): void { + // eslint-disable-next-line this.bundles = CachedAsyncIterable.from( this.generateBundles(this.resourceIds) ); if (eager) { + // @ts-expect-error cached-iterable is not typed + // eslint-disable-next-line this.bundles.touchNext(2); } } @@ -190,14 +200,14 @@ export default class Localization { * * If the message doesn't have a value, return `null`. * - * @param {FluentBundle} bundle - * @param {Array} errors - * @param {Object} message - * @param {Object} args - * @returns {string|null} * @private */ -function valueFromBundle(bundle, errors, message, args) { +function valueFromBundle( + bundle: FluentBundle, + errors: Error[], + message: Message, + args: Record | undefined +): string | null { if (message.value) { return bundle.formatPattern(message.value, args, errors); } @@ -214,15 +224,15 @@ function valueFromBundle(bundle, errors, message, args) { * The function will return an object with a value and attributes of the * entity. * - * @param {FluentBundle} bundle - * @param {Array} errors - * @param {Object} message - * @param {Object} args - * @returns {Object} * @private */ -function messageFromBundle(bundle, errors, message, args) { - const formatted = { +function messageFromBundle( + bundle: FluentBundle, + errors: Error[], + message: Message, + args: Record | undefined +): FormattedMessage { + const formatted: FormattedMessage = { value: null, attributes: null, }; @@ -267,23 +277,32 @@ function messageFromBundle(bundle, errors, message, args) { * * See `Localization.formatWithFallback` for more info on how this is used. * - * @param {Function} method - * @param {FluentBundle} bundle - * @param {Array} keys - * @param {{Array<{value: string, attributes: Object}>}} translations - * - * @returns {Set} * @private */ -function keysFromBundle(method, bundle, keys, translations) { - const messageErrors = []; - const missingIds = new Set(); +function keysFromBundle( + method: FormatMethod, + bundle: FluentBundle, + keys: MessageKey[], + translations: T[] +): Set { + const messageErrors: Error[] = []; + const missingIds = new Set(); - keys.forEach(({ id, args }, i) => { + keys.forEach((key, i) => { if (translations[i] !== undefined) { return; } + let id: string; + let args: Record | undefined; + if (typeof key === "string") { + id = key; + args = undefined; + } else { + id = key.id; + args = key.args; + } + let message = bundle.getMessage(id); if (message) { messageErrors.length = 0; diff --git a/fluent-dom/src/overlay.js b/fluent-dom/src/overlay.ts similarity index 81% rename from fluent-dom/src/overlay.js rename to fluent-dom/src/overlay.ts index 1a6b52a6a..2edd281cc 100644 --- a/fluent-dom/src/overlay.js +++ b/fluent-dom/src/overlay.ts @@ -1,6 +1,8 @@ /* eslint no-console: ["error", {allow: ["warn"]}] */ /* global console */ +import type { FormattedMessage } from "./localization.js"; + // Match the opening angle bracket (<) in HTML tags, and HTML entities like // &, &, &. const reOverlay = /<|&#?\w+;/; @@ -13,8 +15,8 @@ const reOverlay = /<|&#?\w+;/; * - a - because we don't allow href on it anyways, * - ruby, rt, rp - because we don't allow nested elements to be inserted. */ -const TEXT_LEVEL_ELEMENTS = { - "http://www.w3.org/1999/xhtml": [ +const TEXT_LEVEL_ELEMENTS: Record> = { + "http://www.w3.org/1999/xhtml": new Set([ "em", "strong", "small", @@ -40,10 +42,10 @@ const TEXT_LEVEL_ELEMENTS = { "span", "br", "wbr", - ], + ]), }; -const LOCALIZABLE_ATTRIBUTES = { +const LOCALIZABLE_ATTRIBUTES: Record> = { "http://www.w3.org/1999/xhtml": { global: ["title", "aria-description", "aria-label", "aria-valuetext"], a: ["download"], @@ -88,7 +90,10 @@ const LOCALIZABLE_ATTRIBUTES = { * @param {Object} translation * @private */ -export default function translateElement(element, translation) { +export default function translateElement( + element: Element, + translation: FormattedMessage +): void { const { value } = translation; if (typeof value === "string") { @@ -107,7 +112,7 @@ export default function translateElement(element, translation) { const templateElement = element.ownerDocument.createElementNS( "http://www.w3.org/1999/xhtml", "template" - ); + ) as HTMLTemplateElement; templateElement.innerHTML = value; overlayChildNodes(templateElement.content, element); } @@ -125,12 +130,15 @@ export default function translateElement(element, translation) { * The contents of the target element will be cleared and fully replaced with * sanitized contents of the source element. * - * @param {DocumentFragment} fromFragment - The source of children to overlay. - * @param {Element} toElement - The target of the overlay. + * @param fromFragment - The source of children to overlay. + * @param toElement - The target of the overlay. * @private */ -function overlayChildNodes(fromFragment, toElement) { - for (const childNode of fromFragment.childNodes) { +function overlayChildNodes( + fromFragment: DocumentFragment, + toElement: Element +): void { + for (const childNode of fromFragment.childNodes as NodeListOf) { if (childNode.nodeType === childNode.TEXT_NODE) { // Keep the translated text node. continue; @@ -165,7 +173,10 @@ function overlayChildNodes(fromFragment, toElement) { toElement.appendChild(fromFragment); } -function hasAttribute(attributes, name) { +function hasAttribute( + attributes: Element["attributes"] | FormattedMessage["attributes"], + name: string +): boolean { if (!attributes) { return false; } @@ -183,17 +194,18 @@ function hasAttribute(attributes, name) { * Any localizable attributes already set on the target element will be * cleared. * - * @param {Element|Object} fromElement - The source of child nodes to overlay. - * @param {Element} toElement - The target of the overlay. + * @param fromElement - The source of child nodes to overlay. + * @param toElement - The target of the overlay. * @private */ -function overlayAttributes(fromElement, toElement) { - const explicitlyAllowed = toElement.hasAttribute("data-l10n-attrs") - ? toElement - .getAttribute("data-l10n-attrs") - .split(",") - .map(i => i.trim()) - : null; +function overlayAttributes( + fromElement: Element | FormattedMessage, + toElement: Element +): void { + const explicitlyAllowed = toElement + .getAttribute("data-l10n-attrs") + ?.split(",") + .map(i => i.trim()); // Remove existing localizable attributes if they // will not be used in the new translation. @@ -231,12 +243,14 @@ function overlayAttributes(fromElement, toElement) { * for the sanitization. This will preserve functional attribtues defined on * the child element in the source HTML. * - * @param {Element} sourceElement - The source for data-l10n-name lookups. - * @param {Element} translatedChild - The translated child to be sanitized. - * @returns {Element} + * @param sourceElement - The source for data-l10n-name lookups. + * @param translatedChild - The translated child to be sanitized. * @private */ -function getNodeForNamedElement(sourceElement, translatedChild) { +function getNodeForNamedElement( + sourceElement: Element, + translatedChild: Element +): Element | Text { const childName = translatedChild.getAttribute("data-l10n-name"); const sourceChild = sourceElement.querySelector( `[data-l10n-name="${childName}"]` @@ -266,7 +280,7 @@ function getNodeForNamedElement(sourceElement, translatedChild) { // sourceChild by cloning it. This will destroy all event handlers // attached to sourceChild via addEventListener and via on // properties. - const clone = sourceChild.cloneNode(false); + const clone = sourceChild.cloneNode(false) as Element; return shallowPopulateUsing(translatedChild, clone); } @@ -276,11 +290,9 @@ function getNodeForNamedElement(sourceElement, translatedChild) { * Text-level elements allowed in translations may only use safe attributes * and will have any nested markup stripped to text content. * - * @param {Element} element - The element to be sanitized. - * @returns {Element} * @private */ -function createSanitizedElement(element) { +function createSanitizedElement(element: Element): Element { // Start with an empty element of the same type to remove nested children // and non-localizable attributes defined by the translation. const clone = element.ownerDocument.createElement(element.localName); @@ -290,11 +302,9 @@ function createSanitizedElement(element) { /** * Convert an element to a text node. * - * @param {Element} element - The element to be sanitized. - * @returns {Node} * @private */ -function createTextNodeFromTextContent(element) { +function createTextNodeFromTextContent(element: Element): Text { return element.ownerDocument.createTextNode(element.textContent); } @@ -304,13 +314,12 @@ function createTextNodeFromTextContent(element) { * This method is used by the sanitizer when the translation markup contains * an element which is not present in the source code. * - * @param {Element} element - * @returns {boolean} * @private */ -function isElementAllowed(element) { - const allowed = TEXT_LEVEL_ELEMENTS[element.namespaceURI]; - return allowed && allowed.includes(element.localName); +function isElementAllowed(element: Element): boolean { + return ( + TEXT_LEVEL_ELEMENTS[element.namespaceURI!]?.has(element.localName) ?? false + ); } /** @@ -323,18 +332,18 @@ function isElementAllowed(element) { * `explicitlyAllowed` can be passed as a list of attributes explicitly * allowed on this element. * - * @param {string} name - * @param {Element} element - * @param {Array} explicitlyAllowed - * @returns {boolean} * @private */ -function isAttrNameLocalizable(name, element, explicitlyAllowed = null) { - if (explicitlyAllowed && explicitlyAllowed.includes(name)) { +function isAttrNameLocalizable( + name: string, + element: Element, + explicitlyAllowed?: string[] +): boolean { + if (explicitlyAllowed?.includes(name)) { return true; } - const allowed = LOCALIZABLE_ATTRIBUTES[element.namespaceURI]; + const allowed = LOCALIZABLE_ATTRIBUTES[element.namespaceURI!]; if (!allowed) { return false; } @@ -363,7 +372,7 @@ function isAttrNameLocalizable(name, element, explicitlyAllowed = null) { elemName === "input" && attrName === "value" ) { - const type = element.type.toLowerCase(); + const type = (element as HTMLInputElement).type.toLowerCase(); if (type === "submit" || type === "button" || type === "reset") { return true; } @@ -375,12 +384,12 @@ function isAttrNameLocalizable(name, element, explicitlyAllowed = null) { /** * Helper to set textContent and localizable attributes on an element. * - * @param {Element} fromElement - * @param {Element} toElement - * @returns {Element} * @private */ -function shallowPopulateUsing(fromElement, toElement) { +function shallowPopulateUsing( + fromElement: Element, + toElement: Element +): Element { toElement.textContent = fromElement.textContent; overlayAttributes(fromElement, toElement); return toElement; diff --git a/fluent-dom/test/dom_localization_test.js b/fluent-dom/test/dom_localization_test.js index 54effa56d..b27d62fcf 100644 --- a/fluent-dom/test/dom_localization_test.js +++ b/fluent-dom/test/dom_localization_test.js @@ -1,11 +1,11 @@ import assert from "assert"; import { FluentBundle, FluentResource } from "@fluent/bundle"; -import DOMLocalization from "../src/dom_localization.js"; +import { DOMLocalization } from "../src/dom_localization.ts"; import { vi } from "vitest"; async function* mockGenerateMessages() { const bundle = new FluentBundle(["en-US"]); - const resource = new FluentResource("key1 = Key 1"); + const resource = new FluentResource("key1 = Key 1\nkey2 = Key {$arg}\n"); bundle.addResource(resource); yield bundle; } @@ -24,6 +24,24 @@ suite("translateFragment", function () { assert.strictEqual(elem.textContent, "Key 1"); }); + test("translates a node with arguments", async function () { + const FSI = "\u2068"; + const PDI = "\u2069"; + const domLoc = new DOMLocalization(["test.ftl"], mockGenerateMessages); + + const frag = document.createDocumentFragment(); + const elem = document.createElement("p"); + domLoc.setAttributes(elem, "key2", { arg: 42 }); + frag.appendChild(elem); + + await domLoc.translateFragment(frag); + assert.strictEqual(elem.textContent, `Key ${FSI}42${PDI}`); + + domLoc.setArgs(elem, { arg: 99 }); + await domLoc.translateFragment(frag); + assert.strictEqual(elem.textContent, `Key ${FSI}99${PDI}`); + }); + test("does not inject content into a node with missing translation", async function () { const domLoc = new DOMLocalization(["test.ftl"], mockGenerateMessages); diff --git a/fluent-dom/test/extra_text_markup_test.js b/fluent-dom/test/extra_text_markup_test.js index e439f79c8..93829e0f0 100644 --- a/fluent-dom/test/extra_text_markup_test.js +++ b/fluent-dom/test/extra_text_markup_test.js @@ -1,5 +1,5 @@ import assert from "assert"; -import translateElement from "../src/overlay.js"; +import translateElement from "../src/overlay.ts"; import { elem } from "./util.js"; import { beforeAll, vi } from "vitest"; diff --git a/fluent-dom/test/localization_test.js b/fluent-dom/test/localization_test.js index cc8a3cbfa..214495b03 100644 --- a/fluent-dom/test/localization_test.js +++ b/fluent-dom/test/localization_test.js @@ -1,7 +1,6 @@ -import assert from "assert"; import { FluentBundle, FluentResource } from "@fluent/bundle"; -import Localization from "../src/localization.js"; -import { vi } from "vitest"; +import { afterEach, beforeAll, expect, vi } from "vitest"; +import { Localization } from "../src/localization.ts"; async function* mockGenerateMessages() { const bundle = new FluentBundle(["en-US"]); @@ -10,21 +9,35 @@ async function* mockGenerateMessages() { yield bundle; } -suite("formatMessages", function () { - test("returns a translation", async function () { - const loc = new Localization(["test.ftl"], mockGenerateMessages); - const translations = await loc.formatMessages([{ id: "key1" }]); +beforeAll(() => vi.spyOn(console, "warn").mockImplementation(() => {})); +afterEach(vi.clearAllMocks); - assert.strictEqual(translations[0].value, "Key 1"); - }); +for (const [name, keys] of [ + ["string keys", ["missing_key", "key1"]], + ["object keys", [{ id: "missing_key" }, { id: "key1" }]], +]) { + suite(name, () => { + test("formatMessages", async function () { + const loc = new Localization(["test.ftl"], mockGenerateMessages); + const translations = await loc.formatMessages(keys); + + expect(translations).toEqual([ + undefined, + { value: "Key 1", attributes: null }, + ]); + expect(console.warn.mock.calls).toEqual([ + ["[fluent] Missing translations in en-US: missing_key"], + ]); + }); - test("returns undefined for a missing translation", async function () { - vi.spyOn(console, "warn").mockImplementation(() => {}); - const loc = new Localization(["test.ftl"], mockGenerateMessages); - const translations = await loc.formatMessages([{ id: "missing_key" }]); + test("formatValues", async function () { + const loc = new Localization(["test.ftl"], mockGenerateMessages); + const translations = await loc.formatValues(keys); - // Make sure that the returned value here is `undefined`. - // This allows bindings to handle missing translations. - assert.strictEqual(translations[1], undefined); + expect(translations).toEqual([undefined, "Key 1"]); + expect(console.warn.mock.calls).toEqual([ + ["[fluent] Missing translations in en-US: missing_key"], + ]); + }); }); -}); +} diff --git a/fluent-dom/test/overlay_attributes_test.js b/fluent-dom/test/overlay_attributes_test.js index fa22b986f..9d66a8d1a 100644 --- a/fluent-dom/test/overlay_attributes_test.js +++ b/fluent-dom/test/overlay_attributes_test.js @@ -1,5 +1,5 @@ import assert from "assert"; -import translateElement from "../src/overlay.js"; +import translateElement from "../src/overlay.ts"; import { elem } from "./util.js"; suite("Top-level attributes", function () { diff --git a/fluent-dom/test/overlay_functional_children_test.js b/fluent-dom/test/overlay_functional_children_test.js index 082f625d4..783b61112 100644 --- a/fluent-dom/test/overlay_functional_children_test.js +++ b/fluent-dom/test/overlay_functional_children_test.js @@ -1,5 +1,5 @@ import assert from "assert"; -import translateElement from "../src/overlay.js"; +import translateElement from "../src/overlay.ts"; import { elem } from "./util.js"; import { beforeAll, vi } from "vitest"; diff --git a/fluent-dom/test/overlay_test.js b/fluent-dom/test/overlay_test.js index b763a5bce..fbec4efb5 100644 --- a/fluent-dom/test/overlay_test.js +++ b/fluent-dom/test/overlay_test.js @@ -1,5 +1,5 @@ import assert from "assert"; -import translateElement from "../src/overlay.js"; +import translateElement from "../src/overlay.ts"; import { elem } from "./util.js"; suite("Applying translations", function () { diff --git a/fluent-dom/test/overlay_text_children_test.js b/fluent-dom/test/overlay_text_children_test.js index 5680bebfe..b2f2e0ea1 100644 --- a/fluent-dom/test/overlay_text_children_test.js +++ b/fluent-dom/test/overlay_text_children_test.js @@ -1,5 +1,5 @@ import assert from "assert"; -import translateElement from "../src/overlay.js"; +import translateElement from "../src/overlay.ts"; import { elem } from "./util.js"; import { beforeAll, vi } from "vitest"; diff --git a/fluent-dom/tsconfig.json b/fluent-dom/tsconfig.json index 0225d6717..d3d83334d 100644 --- a/fluent-dom/tsconfig.json +++ b/fluent-dom/tsconfig.json @@ -1,8 +1,7 @@ { "extends": "../tsconfig.base.json", "compilerOptions": { - "allowJs": true, - "outDir": "./esm" + "outDir": "./dist" }, - "include": ["./src/**/*"] + "include": ["./src/**/*.ts"] } diff --git a/fluent-dom/typedoc.json b/fluent-dom/typedoc.json deleted file mode 100644 index 75dac08ab..000000000 --- a/fluent-dom/typedoc.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "entryPoints": ["src/index.js"] -} diff --git a/fluent-gecko/.gitignore b/fluent-gecko/.gitignore deleted file mode 100644 index 849ddff3b..000000000 --- a/fluent-gecko/.gitignore +++ /dev/null @@ -1 +0,0 @@ -dist/ diff --git a/fluent-gecko/README.md b/fluent-gecko/README.md deleted file mode 100644 index e161ed8ec..000000000 --- a/fluent-gecko/README.md +++ /dev/null @@ -1,12 +0,0 @@ -# fluent-gecko ![](https://github.com/projectfluent/fluent.js/workflows/test/badge.svg) - -`fluent-gecko` is a Gecko-compatible distribution of [Project Fluent][]. - -[project fluent]: https://projectfluent.org - -## How to use - -`fluent-gecko` can build files ready for vendoring into `mozilla-central`. - -- [`FluentSyntax.jsm`](https://searchfox.org/mozilla-central/source/intl/l10n/FluentSyntax.jsm) -- [`fluent-react.js`](https://searchfox.org/mozilla-central/source/devtools/client/shared/vendor/fluent-react.js) diff --git a/fluent-gecko/package.json b/fluent-gecko/package.json deleted file mode 100644 index f0700f03d..000000000 --- a/fluent-gecko/package.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "name": "@fluent/gecko", - "description": "Gecko bindings for Fluent", - "private": true, - "version": "0.0.1", - "homepage": "https://projectfluent.org", - "author": "Mozilla ", - "license": "Apache-2.0", - "contributors": [ - { - "name": "Zibi Braniecki", - "email": "zbraniecki@mozilla.com" - }, - { - "name": "Staś Małolepszy", - "email": "stas@mozilla.com" - } - ], - "directories": { - "lib": "./src" - }, - "repository": { - "type": "git", - "url": "https://github.com/projectfluent/fluent.js.git" - }, - "keywords": [ - "localization", - "l10n" - ], - "scripts": { - "build": "rollup --config rollup.config.mjs", - "docs": "true" - }, - "devDependencies": { - "@rollup/plugin-node-resolve": "^15.0.1" - } -} diff --git a/fluent-gecko/rollup.config.mjs b/fluent-gecko/rollup.config.mjs deleted file mode 100644 index f726f8af4..000000000 --- a/fluent-gecko/rollup.config.mjs +++ /dev/null @@ -1,56 +0,0 @@ -import { readFileSync } from "fs"; -import { nodeResolve } from "@rollup/plugin-node-resolve"; - -const vim = `/* vim: set ts=2 et sw=2 tw=80 filetype=javascript: */`; -const license = `\ -/* Copyright 2019 Mozilla Foundation and others - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -`; - -const reactPkgSrc = readFileSync("../fluent-react/package.json", "utf8"); -const reactPkg = JSON.parse(reactPkgSrc); -const syntaxPkgSrc = readFileSync("../fluent-syntax/package.json", "utf8"); -const syntaxPkg = JSON.parse(syntaxPkgSrc); - -export default [ - { - input: "src/fluent-react.js", - output: { - file: "dist/fluent-react.js", - format: "cjs", - generatedCode: { constBindings: true }, - banner: license, - intro: `/** fluent-react@${reactPkg.version} */`, - }, - context: "this", - external: ["react"], - plugins: [nodeResolve()], - }, - { - input: "src/fluent-syntax.js", - output: { - file: "dist/FluentSyntax.jsm", - format: "es", - freeze: false, - generatedCode: { constBindings: true }, - banner: `${vim}\n\n${license}`, - intro: `/** fluent-syntax@${syntaxPkg.version} */`, - }, - context: "this", - treeshake: false, - plugins: [nodeResolve()], - }, -]; diff --git a/fluent-gecko/src/fluent-react.js b/fluent-gecko/src/fluent-react.js deleted file mode 100644 index e89b7fa18..000000000 --- a/fluent-gecko/src/fluent-react.js +++ /dev/null @@ -1 +0,0 @@ -export * from "../../fluent-react/esm/index.js"; diff --git a/fluent-gecko/src/fluent-syntax.js b/fluent-gecko/src/fluent-syntax.js deleted file mode 100644 index d63e165fb..000000000 --- a/fluent-gecko/src/fluent-syntax.js +++ /dev/null @@ -1,14 +0,0 @@ -import { FluentParser } from "../../fluent-syntax/esm/parser.js"; -import { FluentSerializer } from "../../fluent-syntax/esm/serializer.js"; -import { Visitor, Transformer } from "../../fluent-syntax/esm/visitor.js"; -import * as ast from "../../fluent-syntax/esm/ast.js"; - -this.EXPORTED_SYMBOLS = [ - ...Object.keys(ast), - ...Object.keys({ - FluentParser, - FluentSerializer, - Visitor, - Transformer, - }), -]; diff --git a/fluent-langneg/.gitignore b/fluent-langneg/.gitignore deleted file mode 100644 index 0bd1f3fc5..000000000 --- a/fluent-langneg/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -esm/ -/index.js diff --git a/fluent-langneg/.npmignore b/fluent-langneg/.npmignore deleted file mode 100644 index abad613ff..000000000 --- a/fluent-langneg/.npmignore +++ /dev/null @@ -1,7 +0,0 @@ -.nyc_output -coverage -esm/.compiled -src -test -makefile -tsconfig.json diff --git a/fluent-langneg/esm/package.json b/fluent-langneg/esm/package.json deleted file mode 100644 index 3dbc1ca59..000000000 --- a/fluent-langneg/esm/package.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "type": "module" -} diff --git a/fluent-langneg/package.json b/fluent-langneg/package.json index 424f78105..34139c6a1 100644 --- a/fluent-langneg/package.json +++ b/fluent-langneg/package.json @@ -2,6 +2,14 @@ "name": "@fluent/langneg", "description": "Language Negotiation API for Fluent", "version": "0.7.0", + "type": "module", + "exports": { + ".": "./dist/index.js", + "./package.json": "./package.json" + }, + "files": [ + "./dist/" + ], "homepage": "https://projectfluent.org", "author": "Mozilla ", "license": "Apache-2.0", @@ -15,9 +23,6 @@ "email": "stas@mozilla.com" } ], - "main": "./index.js", - "module": "./esm/index.js", - "types": "./esm/index.d.ts", "repository": { "type": "git", "url": "https://github.com/projectfluent/fluent.js.git" @@ -32,8 +37,7 @@ "language-negotiation" ], "scripts": { - "build": "tsc", - "postbuild": "rollup -c ../rollup.config.mjs" + "build": "tsc" }, "engines": { "node": "^20.19 || ^22.12 || >=24" diff --git a/fluent-langneg/tsconfig.json b/fluent-langneg/tsconfig.json index 1c5501631..d3d83334d 100644 --- a/fluent-langneg/tsconfig.json +++ b/fluent-langneg/tsconfig.json @@ -1,7 +1,7 @@ { "extends": "../tsconfig.base.json", "compilerOptions": { - "outDir": "./esm" + "outDir": "./dist" }, "include": ["./src/**/*.ts"] } diff --git a/fluent-react/.gitignore b/fluent-react/.gitignore deleted file mode 100644 index 0bd1f3fc5..000000000 --- a/fluent-react/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -esm/ -/index.js diff --git a/fluent-react/.npmignore b/fluent-react/.npmignore deleted file mode 100644 index 1831c37ec..000000000 --- a/fluent-react/.npmignore +++ /dev/null @@ -1,9 +0,0 @@ -.nyc_output -coverage -esm/.compiled -example -src -test -makefile -compat_config.js -tsconfig.json diff --git a/fluent-react/esm/package.json b/fluent-react/esm/package.json deleted file mode 100644 index 3dbc1ca59..000000000 --- a/fluent-react/esm/package.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "type": "module" -} diff --git a/fluent-react/package.json b/fluent-react/package.json index c875883c3..9cdc9c96a 100644 --- a/fluent-react/package.json +++ b/fluent-react/package.json @@ -2,6 +2,16 @@ "name": "@fluent/react", "description": "Fluent bindings for React", "version": "0.15.2", + "type": "module", + "exports": { + ".": "./dist/index.js", + "./package.json": "./package.json" + }, + "files": [ + "dist/", + "!dist/fluent-react.cjs", + "vendor/" + ], "homepage": "https://projectfluent.org", "author": "Mozilla ", "license": "Apache-2.0", @@ -15,9 +25,6 @@ "email": "stas@mozilla.com" } ], - "main": "./index.js", - "module": "./esm/index.js", - "types": "./esm/index.d.ts", "repository": { "type": "git", "url": "https://github.com/projectfluent/fluent.js.git" @@ -42,7 +49,7 @@ ], "scripts": { "build": "tsc -p ./tsconfig.build.json", - "postbuild": "rollup -c ../rollup.config.mjs --globals @fluent/sequence:FluentSequence,cached-iterable:CachedIterable,react:React" + "postbuild": "rollup --config rollup.firefox.js" }, "engines": { "node": "^20.19 || ^22.12 || >=24" @@ -56,7 +63,7 @@ "react": ">=16.8.0" }, "devDependencies": { - "@fluent/bundle": "^0.19.0", + "@rollup/plugin-node-resolve": "^16.0.3", "@types/react": "^18.0.28", "react": "^18.2.0", "react-dom": "^18.2.0", diff --git a/fluent-react/rollup.firefox.js b/fluent-react/rollup.firefox.js new file mode 100644 index 000000000..f2f40c7be --- /dev/null +++ b/fluent-react/rollup.firefox.js @@ -0,0 +1,40 @@ +import { nodeResolve } from "@rollup/plugin-node-resolve"; +import pkg from "./package.json" with { type: "json" }; + +/** + * This produces a bundled version of `@fluent/react` suitable for inclusion in Firefox: + * + * https://searchfox.org/firefox-main/source/devtools/client/shared/vendor/fluent-react.js + */ + +const license = `\ +/* Copyright 2019 Mozilla Foundation and others + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +`; + +export default { + input: "dist/index.js", + output: { + file: "dist/fluent-react.cjs", + format: "cjs", + generatedCode: { constBindings: true }, + banner: license, + intro: `/** ${pkg.name}@${pkg.version} */`, + }, + context: "this", + external: ["react"], + plugins: [nodeResolve()], +}; diff --git a/fluent-react/src/index.ts b/fluent-react/src/index.ts index ccf11f45d..4842ce646 100644 --- a/fluent-react/src/index.ts +++ b/fluent-react/src/index.ts @@ -22,8 +22,8 @@ export { ReactLocalization } from "./localization.js"; export { LocalizationProvider } from "./provider.js"; export { withLocalization, - WithLocalizationProps, + type WithLocalizationProps, } from "./with_localization.js"; -export { Localized, LocalizedProps } from "./localized.js"; -export { MarkupParser } from "./markup.js"; +export { Localized, type LocalizedProps } from "./localized.js"; +export type { MarkupParser } from "./markup.js"; export { useLocalization } from "./use_localization.js"; diff --git a/fluent-react/src/localized.ts b/fluent-react/src/localized.ts index c4c59f263..6bc8e5509 100644 --- a/fluent-react/src/localized.ts +++ b/fluent-react/src/localized.ts @@ -75,5 +75,3 @@ export function Localized(props: LocalizedProps): ReactElement { return l10n.getElement(source, id, { attrs, vars, elems }); } - -export default Localized; diff --git a/fluent-react/tsconfig.build.json b/fluent-react/tsconfig.build.json index 1c5501631..d3d83334d 100644 --- a/fluent-react/tsconfig.build.json +++ b/fluent-react/tsconfig.build.json @@ -1,7 +1,7 @@ { "extends": "../tsconfig.base.json", "compilerOptions": { - "outDir": "./esm" + "outDir": "./dist" }, "include": ["./src/**/*.ts"] } diff --git a/fluent-react/vendor/voidElementTags.js b/fluent-react/vendor/voidElementTags.js index c0d36dbe7..3a3c7c24a 100644 --- a/fluent-react/vendor/voidElementTags.js +++ b/fluent-react/vendor/voidElementTags.js @@ -5,7 +5,7 @@ * LICENSE file in this directory. */ -import omittedCloseTags from "./omittedCloseTags"; +import omittedCloseTags from "./omittedCloseTags.js"; // For HTML, certain tags cannot have children. This has the same purpose as // `omittedCloseTags` except that `menuitem` should still have its closing tag. diff --git a/fluent-sequence/.gitignore b/fluent-sequence/.gitignore deleted file mode 100644 index 0bd1f3fc5..000000000 --- a/fluent-sequence/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -esm/ -/index.js diff --git a/fluent-sequence/.npmignore b/fluent-sequence/.npmignore deleted file mode 100644 index abad613ff..000000000 --- a/fluent-sequence/.npmignore +++ /dev/null @@ -1,7 +0,0 @@ -.nyc_output -coverage -esm/.compiled -src -test -makefile -tsconfig.json diff --git a/fluent-sequence/esm/package.json b/fluent-sequence/esm/package.json deleted file mode 100644 index 3dbc1ca59..000000000 --- a/fluent-sequence/esm/package.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "type": "module" -} diff --git a/fluent-sequence/package.json b/fluent-sequence/package.json index 8c14f88e7..80e4cb0bf 100644 --- a/fluent-sequence/package.json +++ b/fluent-sequence/package.json @@ -2,6 +2,14 @@ "name": "@fluent/sequence", "description": "Manage ordered sequences of FluentBundles", "version": "0.8.0", + "type": "module", + "exports": { + ".": "./dist/index.js", + "./package.json": "./package.json" + }, + "files": [ + "./dist/" + ], "homepage": "https://projectfluent.org", "author": "Mozilla ", "license": "Apache-2.0", @@ -15,9 +23,6 @@ "email": "stas@mozilla.com" } ], - "main": "./index.js", - "module": "./esm/index.js", - "types": "./esm/index.d.ts", "repository": { "type": "git", "url": "https://github.com/projectfluent/fluent.js.git" @@ -27,14 +32,12 @@ "ftl" ], "scripts": { - "build": "tsc -p ./tsconfig.build.json", - "postbuild": "rollup -c ../rollup.config.mjs" + "build": "tsc" }, "engines": { "node": "^20.19 || ^22.12 || >=24" }, "devDependencies": { - "@fluent/bundle": "^0.19.0", "cached-iterable": "^0.3.0" }, "peerDependencies": { diff --git a/fluent-sequence/tsconfig.build.json b/fluent-sequence/tsconfig.build.json deleted file mode 100644 index 1a76d9a43..000000000 --- a/fluent-sequence/tsconfig.build.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "extends": "../tsconfig.base.json", - "compilerOptions": { - "outDir": "./esm", - "rootDir": "./src" - }, - "include": ["./src/**/*.ts"] -} diff --git a/fluent-sequence/tsconfig.json b/fluent-sequence/tsconfig.json index 3c43903cf..ae18d140e 100644 --- a/fluent-sequence/tsconfig.json +++ b/fluent-sequence/tsconfig.json @@ -1,3 +1,8 @@ { - "extends": "../tsconfig.json" + "extends": "../tsconfig.base.json", + "compilerOptions": { + "outDir": "./dist", + "rootDir": "./src" + }, + "include": ["./src/**/*.ts"] } diff --git a/fluent-syntax/.gitignore b/fluent-syntax/.gitignore deleted file mode 100644 index 0bd1f3fc5..000000000 --- a/fluent-syntax/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -esm/ -/index.js diff --git a/fluent-syntax/.npmignore b/fluent-syntax/.npmignore deleted file mode 100644 index abad613ff..000000000 --- a/fluent-syntax/.npmignore +++ /dev/null @@ -1,7 +0,0 @@ -.nyc_output -coverage -esm/.compiled -src -test -makefile -tsconfig.json diff --git a/fluent-syntax/esm/package.json b/fluent-syntax/esm/package.json deleted file mode 100644 index 3dbc1ca59..000000000 --- a/fluent-syntax/esm/package.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "type": "module" -} diff --git a/fluent-syntax/package.json b/fluent-syntax/package.json index ccca0fb21..977340c99 100644 --- a/fluent-syntax/package.json +++ b/fluent-syntax/package.json @@ -2,6 +2,16 @@ "name": "@fluent/syntax", "description": "AST and parser for Fluent", "version": "0.19.0", + "type": "module", + "exports": { + ".": "./dist/index.js", + "./ast": "./dist/ast.js", + "./stream": "./dist/stream.js", + "./package.json": "./package.json" + }, + "files": [ + "./dist/" + ], "homepage": "https://projectfluent.org", "author": "Mozilla ", "license": "Apache-2.0", @@ -15,9 +25,6 @@ "email": "stas@mozilla.com" } ], - "main": "./index.js", - "module": "./esm/index.js", - "types": "./esm/index.d.ts", "repository": { "type": "git", "url": "https://github.com/projectfluent/fluent.js.git" @@ -41,13 +48,9 @@ "parser" ], "scripts": { - "build": "tsc", - "postbuild": "rollup -c ../rollup.config.mjs" + "build": "tsc" }, "engines": { "node": "^20.19 || ^22.12 || >=24" - }, - "devDependencies": { - "@fluent/dedent": "^0.5.0" } } diff --git a/fluent-syntax/src/index.ts b/fluent-syntax/src/index.ts index ebeb2ff1f..fa0432052 100644 --- a/fluent-syntax/src/index.ts +++ b/fluent-syntax/src/index.ts @@ -10,9 +10,9 @@ export { Transformer, Visitor } from "./visitor.js"; export { FluentParser, - FluentParserOptions, + type FluentParserOptions, FluentSerializer, - FluentSerializerOptions, + type FluentSerializerOptions, }; /** @category Parse */ diff --git a/fluent-syntax/tsconfig.json b/fluent-syntax/tsconfig.json index 1c5501631..d3d83334d 100644 --- a/fluent-syntax/tsconfig.json +++ b/fluent-syntax/tsconfig.json @@ -1,7 +1,7 @@ { "extends": "../tsconfig.base.json", "compilerOptions": { - "outDir": "./esm" + "outDir": "./dist" }, "include": ["./src/**/*.ts"] } diff --git a/package-lock.json b/package-lock.json index b640ec3de..05156fd30 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,19 +13,15 @@ "./fluent-langneg", "./fluent-react", "./fluent-syntax", - "./fluent-gecko" + "./tools" ], "devDependencies": { - "colors": "^1.3.3", - "commander": "^2.20", "eslint": "^9.23.0", "eslint-config-prettier": "^10.1.1", - "fuzzer": "^0.2.1", "gh-pages": "^6.1.1", "globals": "^16.0.0", "jsdom": "^27.4.0", "prettier": "^3.2.5", - "prettyjson": "^1.2.1", "rollup": "^4.12.0", "typedoc": "^0.28.1", "typedoc-plugin-redirect": "^1.2.0", @@ -39,7 +35,6 @@ "version": "0.19.1", "license": "Apache-2.0", "devDependencies": { - "@fluent/dedent": "^0.5.0", "temporal-polyfill": "^0.2.5" }, "engines": { @@ -61,21 +56,10 @@ "dependencies": { "cached-iterable": "^0.3" }, - "devDependencies": { - "@fluent/bundle": "^0.19.0" - }, "engines": { "node": "^20.19 || ^22.12 || >=24" } }, - "fluent-gecko": { - "name": "@fluent/gecko", - "version": "0.0.1", - "license": "Apache-2.0", - "devDependencies": { - "@rollup/plugin-node-resolve": "^15.0.1" - } - }, "fluent-langneg": { "name": "@fluent/langneg", "version": "0.7.0", @@ -93,7 +77,7 @@ "cached-iterable": "^0.3.0" }, "devDependencies": { - "@fluent/bundle": "^0.19.0", + "@rollup/plugin-node-resolve": "^16.0.3", "@types/react": "^18.0.28", "react": "^18.2.0", "react-dom": "^18.2.0", @@ -112,7 +96,6 @@ "version": "0.8.0", "license": "Apache-2.0", "devDependencies": { - "@fluent/bundle": "^0.19.0", "cached-iterable": "^0.3.0" }, "engines": { @@ -126,9 +109,6 @@ "name": "@fluent/syntax", "version": "0.19.0", "license": "Apache-2.0", - "devDependencies": { - "@fluent/dedent": "^0.5.0" - }, "engines": { "node": "^20.19 || ^22.12 || >=24" } @@ -959,10 +939,6 @@ "resolved": "fluent-dom", "link": true }, - "node_modules/@fluent/gecko": { - "resolved": "fluent-gecko", - "link": true - }, "node_modules/@fluent/langneg": { "resolved": "fluent-langneg", "link": true @@ -979,6 +955,10 @@ "resolved": "fluent-syntax", "link": true }, + "node_modules/@fluent/tools": { + "resolved": "tools", + "link": true + }, "node_modules/@gerrit0/mini-shiki": { "version": "3.20.0", "resolved": "https://registry.npmjs.org/@gerrit0/mini-shiki/-/mini-shiki-3.20.0.tgz", @@ -1091,9 +1071,9 @@ } }, "node_modules/@rollup/plugin-node-resolve": { - "version": "15.3.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.3.1.tgz", - "integrity": "sha512-tgg6b91pAybXHJQMAAwW9VuWBO6Thi+q7BCNARLwSqlmsHz0XYURtGvh/AuwSADXSI4h/2uHbs7s4FzlZDGSGA==", + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-16.0.3.tgz", + "integrity": "sha512-lUYM3UBGuM93CnMPG1YocWu7X802BrNF3jW2zny5gQyLQgRFJhV1Sq0Zi74+dh/6NBx1DxFC4b4GXg9wUCG5Qg==", "dev": true, "license": "MIT", "dependencies": { @@ -2056,7 +2036,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", - "dev": true, "license": "MIT", "dependencies": { "call-bound": "^1.0.3", @@ -2083,7 +2062,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", - "dev": true, "license": "MIT", "dependencies": { "array-buffer-byte-length": "^1.0.1", @@ -2122,7 +2100,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -2132,7 +2109,6 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", - "dev": true, "license": "MIT", "dependencies": { "possible-typed-array-names": "^1.0.0" @@ -2198,7 +2174,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", - "dev": true, "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.0", @@ -2217,7 +2192,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", - "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -2231,7 +2205,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", - "dev": true, "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", @@ -2305,7 +2278,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.1.90" @@ -2315,7 +2287,6 @@ "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true, "license": "MIT" }, "node_modules/commondir": { @@ -2401,7 +2372,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", - "dev": true, "license": "MIT", "dependencies": { "call-bound": "^1.0.3", @@ -2419,7 +2389,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", - "dev": true, "license": "MIT", "dependencies": { "call-bound": "^1.0.3", @@ -2437,7 +2406,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", - "dev": true, "license": "MIT", "dependencies": { "call-bound": "^1.0.2", @@ -2497,7 +2465,6 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "dev": true, "license": "MIT", "dependencies": { "es-define-property": "^1.0.0", @@ -2515,7 +2482,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "dev": true, "license": "MIT", "dependencies": { "define-data-property": "^1.0.1", @@ -2546,7 +2512,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", - "dev": true, "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.1", @@ -2581,7 +2546,6 @@ "version": "1.24.1", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.1.tgz", "integrity": "sha512-zHXBLhP+QehSSbsS9Pt23Gg964240DPd6QCf8WpkqEXxQ7fhdZzYsocOr5u7apWonsS5EjZDmTF+/slGMyasvw==", - "dev": true, "license": "MIT", "dependencies": { "array-buffer-byte-length": "^1.0.2", @@ -2650,7 +2614,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -2660,7 +2623,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -2677,7 +2639,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", - "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0" @@ -2690,7 +2651,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", - "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -2706,7 +2666,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", - "dev": true, "license": "MIT", "dependencies": { "is-callable": "^1.2.7", @@ -3137,7 +3096,6 @@ "version": "0.3.5", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", - "dev": true, "license": "MIT", "dependencies": { "is-callable": "^1.2.7" @@ -3183,7 +3141,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -3193,7 +3150,6 @@ "version": "1.1.8", "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", - "dev": true, "license": "MIT", "dependencies": { "call-bind": "^1.0.8", @@ -3214,7 +3170,6 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -3224,7 +3179,6 @@ "version": "0.2.1", "resolved": "https://registry.npmjs.org/fuzzer/-/fuzzer-0.2.1.tgz", "integrity": "sha512-LGFobvtCmAWAX6AvpmRAG60QFs+j+6APfQwPTnPt46iL21afI2Uxv1/J02szOwyAZAhIHj5BWqxdxG6zWECG6g==", - "dev": true, "license": "ISC", "dependencies": { "random-js": "1.0.2", @@ -3239,7 +3193,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -3249,7 +3202,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", - "dev": true, "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", @@ -3274,7 +3226,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "dev": true, "license": "MIT", "dependencies": { "dunder-proto": "^1.0.1", @@ -3288,7 +3239,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", - "dev": true, "license": "MIT", "dependencies": { "call-bound": "^1.0.3", @@ -3365,7 +3315,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", - "dev": true, "license": "MIT", "dependencies": { "define-properties": "^1.2.1", @@ -3403,7 +3352,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -3423,7 +3371,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -3446,7 +3393,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "dev": true, "license": "MIT", "dependencies": { "es-define-property": "^1.0.0" @@ -3459,7 +3405,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", - "dev": true, "license": "MIT", "dependencies": { "dunder-proto": "^1.0.0" @@ -3475,7 +3420,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -3488,7 +3432,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "dev": true, "license": "MIT", "dependencies": { "has-symbols": "^1.0.3" @@ -3504,7 +3447,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dev": true, "license": "MIT", "dependencies": { "function-bind": "^1.1.2" @@ -3595,7 +3537,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", - "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -3610,7 +3551,6 @@ "version": "3.0.5", "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", - "dev": true, "license": "MIT", "dependencies": { "call-bind": "^1.0.8", @@ -3628,7 +3568,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", - "dev": true, "license": "MIT", "dependencies": { "async-function": "^1.0.0", @@ -3648,7 +3587,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", - "dev": true, "license": "MIT", "dependencies": { "has-bigints": "^1.0.2" @@ -3664,7 +3602,6 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", - "dev": true, "license": "MIT", "dependencies": { "call-bound": "^1.0.3", @@ -3681,7 +3618,6 @@ "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -3710,7 +3646,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", - "dev": true, "license": "MIT", "dependencies": { "call-bound": "^1.0.2", @@ -3728,7 +3663,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", - "dev": true, "license": "MIT", "dependencies": { "call-bound": "^1.0.2", @@ -3755,7 +3689,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", - "dev": true, "license": "MIT", "dependencies": { "call-bound": "^1.0.3" @@ -3771,7 +3704,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==", - "dev": true, "license": "MIT", "dependencies": { "call-bound": "^1.0.4", @@ -3804,7 +3736,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -3824,7 +3755,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -3847,7 +3777,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", - "dev": true, "license": "MIT", "dependencies": { "call-bound": "^1.0.3", @@ -3871,7 +3800,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", - "dev": true, "license": "MIT", "dependencies": { "call-bound": "^1.0.2", @@ -3890,7 +3818,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -3903,7 +3830,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", - "dev": true, "license": "MIT", "dependencies": { "call-bound": "^1.0.3" @@ -3919,7 +3845,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", - "dev": true, "license": "MIT", "dependencies": { "call-bound": "^1.0.3", @@ -3936,7 +3861,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", - "dev": true, "license": "MIT", "dependencies": { "call-bound": "^1.0.2", @@ -3954,7 +3878,6 @@ "version": "1.1.15", "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", - "dev": true, "license": "MIT", "dependencies": { "which-typed-array": "^1.1.16" @@ -3970,7 +3893,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -3983,7 +3905,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", - "dev": true, "license": "MIT", "dependencies": { "call-bound": "^1.0.3" @@ -3999,7 +3920,6 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", - "dev": true, "license": "MIT", "dependencies": { "call-bound": "^1.0.3", @@ -4016,7 +3936,6 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true, "license": "MIT" }, "node_modules/isexe": { @@ -4245,7 +4164,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -4306,7 +4224,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -4359,7 +4276,6 @@ "version": "1.13.4", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -4372,7 +4288,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -4382,7 +4297,6 @@ "version": "4.1.7", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", - "dev": true, "license": "MIT", "dependencies": { "call-bind": "^1.0.8", @@ -4432,7 +4346,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", - "dev": true, "license": "MIT", "dependencies": { "get-intrinsic": "^1.2.6", @@ -4664,7 +4577,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -4729,7 +4641,6 @@ "version": "1.2.5", "resolved": "https://registry.npmjs.org/prettyjson/-/prettyjson-1.2.5.tgz", "integrity": "sha512-rksPWtoZb2ZpT5OVgtmy0KHVM+Dca3iVwWY9ifwhcexfjebtgjg3wmrUt9PvJ59XIYBcknQeYHD8IAnVlh9lAw==", - "dev": true, "license": "MIT", "dependencies": { "colors": "1.4.0", @@ -4784,7 +4695,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/random-js/-/random-js-1.0.2.tgz", "integrity": "sha512-IIsnMV4J4+K0CY0bDRKJTTlGwy9KUEqiqDJekfBq5iwUSa1l2C5ssml5fmP8YVS17Pry7VJbsHBebDWjcIdheQ==", - "dev": true, "license": "MIT" }, "node_modules/react": { @@ -4854,7 +4764,6 @@ "version": "1.0.10", "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", - "dev": true, "license": "MIT", "dependencies": { "call-bind": "^1.0.8", @@ -4877,7 +4786,6 @@ "version": "1.5.4", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", - "dev": true, "license": "MIT", "dependencies": { "call-bind": "^1.0.8", @@ -5016,7 +4924,6 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", - "dev": true, "license": "MIT", "dependencies": { "call-bind": "^1.0.8", @@ -5036,7 +4943,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", - "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -5053,7 +4959,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", - "dev": true, "license": "MIT", "dependencies": { "call-bound": "^1.0.2", @@ -5104,7 +5009,6 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "dev": true, "license": "MIT", "dependencies": { "define-data-property": "^1.1.4", @@ -5122,7 +5026,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", - "dev": true, "license": "MIT", "dependencies": { "define-data-property": "^1.1.4", @@ -5138,7 +5041,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", - "dev": true, "license": "MIT", "dependencies": { "dunder-proto": "^1.0.1", @@ -5176,7 +5078,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", - "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -5196,7 +5097,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", - "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -5213,7 +5113,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", - "dev": true, "license": "MIT", "dependencies": { "call-bound": "^1.0.2", @@ -5232,7 +5131,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", - "dev": true, "license": "MIT", "dependencies": { "call-bound": "^1.0.2", @@ -5293,7 +5191,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", - "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -5307,7 +5204,6 @@ "version": "1.2.10", "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", - "dev": true, "license": "MIT", "dependencies": { "call-bind": "^1.0.8", @@ -5329,7 +5225,6 @@ "version": "1.0.9", "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", - "dev": true, "license": "MIT", "dependencies": { "call-bind": "^1.0.8", @@ -5348,7 +5243,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", - "dev": true, "license": "MIT", "dependencies": { "call-bind": "^1.0.7", @@ -5586,7 +5480,6 @@ "version": "0.6.11", "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.11.tgz", "integrity": "sha512-vxXDZg8/+p3gblxB6BhhG5yWVn1kGRlaL8O78UDXc3wRnPizB5g83dcvWV1jpDMIPnjZjOFuxlMmE82XJ4407w==", - "dev": true, "license": "MIT", "dependencies": { "gopd": "^1.2.0", @@ -5653,7 +5546,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", - "dev": true, "license": "MIT", "dependencies": { "call-bound": "^1.0.3", @@ -5668,7 +5560,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", - "dev": true, "license": "MIT", "dependencies": { "call-bind": "^1.0.8", @@ -5688,7 +5579,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", - "dev": true, "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", @@ -5710,7 +5600,6 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", - "dev": true, "license": "MIT", "dependencies": { "call-bind": "^1.0.7", @@ -5731,7 +5620,6 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/typedarray.prototype.slice/-/typedarray.prototype.slice-1.0.5.tgz", "integrity": "sha512-q7QNVDGTdl702bVFiI5eY4l/HkgCM6at9KhcFbgUAzezHFbOVy4+0O/lCjsABEQwbZPravVfBIiBVGo89yzHFg==", - "dev": true, "license": "MIT", "dependencies": { "call-bind": "^1.0.8", @@ -5859,7 +5747,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", - "dev": true, "license": "MIT", "dependencies": { "call-bound": "^1.0.3", @@ -6158,7 +6045,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", - "dev": true, "license": "MIT", "dependencies": { "is-bigint": "^1.1.0", @@ -6178,7 +6064,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", - "dev": true, "license": "MIT", "dependencies": { "call-bound": "^1.0.2", @@ -6206,7 +6091,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", - "dev": true, "license": "MIT", "dependencies": { "is-map": "^2.0.3", @@ -6225,7 +6109,6 @@ "version": "1.1.19", "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", - "dev": true, "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", @@ -6313,7 +6196,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.2.0.tgz", "integrity": "sha512-SLt5uylT+4aoXxXuwtQp5ZnMMzhDb1Xkg4pEqc00WUJCQifPfV9Ub1VrNhp9kXkrjZD2I2Hl8WnjP37jzZLPZw==", - "dev": true, "engines": { "node": ">=0.4" } @@ -6346,6 +6228,15 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "tools": { + "name": "@fluent/tools", + "dependencies": { + "colors": "^1.3.3", + "commander": "^2.20", + "fuzzer": "^0.2.1", + "prettyjson": "^1.2.1" + } } } } diff --git a/package.json b/package.json index 2063d1bc7..bb330f319 100644 --- a/package.json +++ b/package.json @@ -9,13 +9,13 @@ "./fluent-langneg", "./fluent-react", "./fluent-syntax", - "./fluent-gecko" + "./tools" ], "scripts": { "predist": "npm run clean", "dist": "npm run build --workspaces", "postdist": "npm run lint && npm run test && npm run docs", - "clean": "git clean -fdxe node_modules fluent-*/{coverage,dist,esm,index.js} html", + "clean": "git clean -fdxe node_modules fluent-*/{coverage,dist} coverage html", "deploy-html": "gh-pages -d html", "docs": "typedoc", "lint": "eslint --max-warnings 0", @@ -27,16 +27,12 @@ "trailingComma": "es5" }, "devDependencies": { - "colors": "^1.3.3", - "commander": "^2.20", "eslint": "^9.23.0", "eslint-config-prettier": "^10.1.1", - "fuzzer": "^0.2.1", "gh-pages": "^6.1.1", "globals": "^16.0.0", "jsdom": "^27.4.0", "prettier": "^3.2.5", - "prettyjson": "^1.2.1", "rollup": "^4.12.0", "typedoc": "^0.28.1", "typedoc-plugin-redirect": "^1.2.0", diff --git a/rollup.config.mjs b/rollup.config.mjs deleted file mode 100644 index c910f4ccb..000000000 --- a/rollup.config.mjs +++ /dev/null @@ -1,28 +0,0 @@ -import { readFile } from "fs/promises"; - -const globalName = { - "@fluent/bundle": "FluentBundle", - "@fluent/dedent": "FluentDedent", - "@fluent/dom": "FluentDOM", - "@fluent/langneg": "FluentLangNeg", - "@fluent/react": "FluentReact", - "@fluent/sequence": "FluentSequence", - "@fluent/syntax": "FluentSyntax", -}; - -export default async function () { - // Current dir is the package's own directory here - const pkgSrc = await readFile("package.json", "utf8"); - const { name, version } = JSON.parse(pkgSrc); - - return { - input: "esm/index.js", - output: { - file: "index.js", - format: "umd", - amd: { id: name }, - name: globalName[name], - banner: `/** ${name}@${version} */`, - }, - }; -} diff --git a/tools/fluentfmt.mjs b/tools/fluentfmt.mjs index a2d3c25df..7f1f231c0 100755 --- a/tools/fluentfmt.mjs +++ b/tools/fluentfmt.mjs @@ -4,12 +4,7 @@ import { readFile } from "fs"; import program from "commander"; -import { - columnOffset, - lineOffset, - parse, - serialize, -} from "../fluent-syntax/esm/index.js"; +import { columnOffset, lineOffset, parse, serialize } from "@fluent/syntax"; program .version("0.0.1") diff --git a/tools/format.mjs b/tools/format.mjs index 2cb451d4e..9c801c321 100755 --- a/tools/format.mjs +++ b/tools/format.mjs @@ -4,7 +4,7 @@ import "colors"; import { readFile, readFileSync } from "fs"; import program from "commander"; -import { FluentBundle, FluentResource } from "../fluent-bundle/esm/index.js"; +import { FluentBundle, FluentResource } from "@fluent/bundle"; program .version("0.0.1") diff --git a/tools/fuzz.mjs b/tools/fuzz.mjs index aa50e782e..d36ec307f 100755 --- a/tools/fuzz.mjs +++ b/tools/fuzz.mjs @@ -6,8 +6,8 @@ import { readFile } from "fs"; import { cursorTo } from "readline"; import program from "commander"; import { mutate, seed } from "fuzzer"; -import { FluentResource } from "../fluent-bundle/esm/index.js"; -import { parse } from "../fluent-syntax/esm/index.js"; +import { FluentResource } from "@fluent/bundle"; +import { parse } from "@fluent/syntax"; seed(Math.random() * 1000000000); diff --git a/tools/package.json b/tools/package.json new file mode 100644 index 000000000..c5128b919 --- /dev/null +++ b/tools/package.json @@ -0,0 +1,14 @@ +{ + "name": "@fluent/tools", + "private": true, + "type": "commonjs", + "dependencies": { + "colors": "^1.3.3", + "commander": "^2.20", + "fuzzer": "^0.2.1", + "prettyjson": "^1.2.1" + }, + "scripts": { + "build": "" + } +} diff --git a/tools/parse.mjs b/tools/parse.mjs index 5eca1a856..85f00f473 100755 --- a/tools/parse.mjs +++ b/tools/parse.mjs @@ -2,8 +2,8 @@ import { readFile } from "fs"; import program from "commander"; -import { columnOffset, lineOffset, parse } from "../fluent-syntax/esm/index.js"; -import { FluentResource } from "../fluent-bundle/esm/index.js"; +import { FluentResource } from "@fluent/bundle"; +import { columnOffset, lineOffset, parse } from "@fluent/syntax"; program .version("0.0.1") diff --git a/tsconfig.base.json b/tsconfig.base.json index 2c547bfd0..f888e66a6 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -1,11 +1,10 @@ { "compilerOptions": { "target": "es2021", - "module": "es2015", + "module": "nodenext", "strict": true, "allowJs": false, "esModuleInterop": true, - "moduleResolution": "node", "noEmitHelpers": true, "declaration": true }