Skip to content

Commit 09e5d1f

Browse files
committed
Merge branch 'main' into use-intl-locale
2 parents 173c7d8 + f9ed46e commit 09e5d1f

File tree

87 files changed

+3472
-8225
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

87 files changed

+3472
-8225
lines changed

.github/workflows/test.yml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,17 @@ on:
33
push:
44
branches: [main]
55
pull_request:
6-
branches: [main]
76
workflow_dispatch:
87
jobs:
98
dist:
109
runs-on: ubuntu-latest
1110
strategy:
1211
matrix:
13-
node: [18, 20, latest]
12+
node: [20.19.0, 22, latest]
1413
steps:
15-
- uses: actions/checkout@v4
14+
- uses: actions/checkout@v6
1615
- name: Use Node.js ${{matrix.node}}
17-
uses: actions/setup-node@v4
16+
uses: actions/setup-node@v6
1817
with:
1918
node-version: ${{matrix.node}}
2019
- run: npm ci

.mocharc.yaml

Lines changed: 0 additions & 4 deletions
This file was deleted.

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ Hacking on `fluent.js` is easy! To quickly get started clone the repo:
6363
$ git clone https://github.com/projectfluent/fluent.js.git
6464
$ cd fluent.js
6565

66-
You'll need at least **Node.js 14.18** and **npm 7**.
66+
You'll need at least **Node.js 20.19**.
6767
Older versions are not supported.
6868

6969
Install the dependencies used by all packages, which are managed as

eslint.config.mjs

Lines changed: 3 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import js from "@eslint/js";
22
import eslintConfigPrettier from "eslint-config-prettier";
3-
import mochaPlugin from "eslint-plugin-mocha";
43
import globals from "globals";
54

65
import tseslint from "typescript-eslint";
@@ -18,23 +17,6 @@ export default [
1817
"tools/",
1918
],
2019
},
21-
{
22-
languageOptions: {
23-
ecmaVersion: 2018,
24-
sourceType: "module",
25-
},
26-
},
27-
28-
// Config files
29-
{
30-
files: ["**/*.mjs"],
31-
languageOptions: { ecmaVersion: 2020 },
32-
},
33-
{
34-
files: ["**/*.cjs"],
35-
languageOptions: { globals: { ...globals.node } },
36-
},
37-
3820
js.configs.recommended,
3921
{
4022
files: ["**/*.js", "**/*.mjs", "*/src/*.ts"],
@@ -109,32 +91,24 @@ export default [
10991
{
11092
files: ["*/test/**"],
11193
languageOptions: {
112-
globals: { ...globals.mocha, ...globals.node },
113-
ecmaVersion: 2020,
94+
globals: { ...globals.node, ...globals.vitest },
11495
},
115-
plugins: { mocha: mochaPlugin },
11696
rules: {
117-
"mocha/no-exclusive-tests": "error",
118-
"mocha/no-identical-title": "error",
11997
"no-console": "off",
12098
"prefer-arrow-callback": "off",
12199
},
122100
},
123101
{
124102
files: ["fluent-dom/test/*"],
125-
languageOptions: { globals: { ...globals.browser } },
103+
languageOptions: { globals: { ...globals.browser, ...globals.vitest } },
126104
},
127105
{
128106
files: ["fluent-react/test/**"],
129107
languageOptions: {
130-
globals: { ...globals.browser, ...globals.jest },
131-
ecmaVersion: 2020,
108+
globals: { ...globals.browser, ...globals.vitest },
132109
parserOptions: { ecmaFeatures: { jsx: true } },
133110
},
134-
plugins: { mocha: mochaPlugin },
135111
rules: {
136-
"mocha/no-exclusive-tests": "error",
137-
"mocha/no-identical-title": "error",
138112
"no-unused-vars": "off",
139113
},
140114
},

fluent-bundle/CHANGELOG.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,6 @@ The undocumented `_parse` export was also removed in favor of
424424
- Rename `MessageContext` to `FluentBundle`. (#222)
425425

426426
The following renames have been made to the public API:
427-
428427
- Rename `MessageContext` to `FluentBundle`.
429428
- Rename `MessageArgument` to `FluentType`.
430429
- Rename `MessageNumberArgument` to `FluentNumber`.
@@ -492,7 +491,6 @@ The undocumented `_parse` export was also removed in favor of
492491
## fluent 0.6.0 (January 31, 2018)
493492

494493
- Implement Fluent Syntax 0.5.
495-
496494
- Add support for terms.
497495
- Add support for `#`, `##` and `###` comments.
498496
- Remove support for tags.

fluent-bundle/package.json

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,10 @@
4040
],
4141
"scripts": {
4242
"build": "tsc",
43-
"postbuild": "rollup -c ../rollup.config.mjs",
44-
"test": "mocha 'test/*_test.js'"
43+
"postbuild": "rollup -c ../rollup.config.mjs"
4544
},
4645
"engines": {
47-
"node": ">=18.0.0",
48-
"npm": ">=7.0.0"
46+
"node": "^20.19 || ^22.12 || >=24"
4947
},
5048
"devDependencies": {
5149
"@fluent/dedent": "^0.5.0",

fluent-bundle/src/resolver.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -154,15 +154,12 @@ function resolveVariableReference(
154154
let arg: FluentVariable;
155155
if (scope.params) {
156156
// We're inside a TermReference. It's OK to reference undefined parameters.
157-
if (Object.prototype.hasOwnProperty.call(scope.params, name)) {
157+
if (name in scope.params) {
158158
arg = scope.params[name];
159159
} else {
160160
return new FluentNone(`$${name}`);
161161
}
162-
} else if (
163-
scope.args &&
164-
Object.prototype.hasOwnProperty.call(scope.args, name)
165-
) {
162+
} else if (scope.args && name in scope.args) {
166163
// We're in the top-level Pattern or inside a MessageReference. Missing
167164
// variables references produce ReferenceErrors.
168165
arg = scope.args[name];

fluent-bundle/src/resource.ts

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,11 @@ import {
1919

2020
// This regex is used to iterate through the beginnings of messages and terms.
2121
// With the /m flag, the ^ matches at the beginning of every line.
22-
const RE_MESSAGE_START = /^(-?[a-zA-Z][\w-]*) *= */gm;
22+
const RE_MESSAGE_START = /^(?<!\r)(-?[a-zA-Z][\w-]*) *= */gm;
2323

2424
// Both Attributes and Variants are parsed in while loops. These regexes are
2525
// used to break out of them.
26-
const RE_ATTRIBUTE_START = /\.([a-zA-Z][\w-]*) *= */y;
26+
const RE_ATTRIBUTE_START = /(?<=\n *)\.([a-zA-Z][\w-]*) *= */y;
2727
const RE_VARIANT_START = /\*?\[/y;
2828

2929
const RE_NUMBER_LITERAL = /(-?[0-9]+(?:\.([0-9]+))?)/y;
@@ -37,8 +37,8 @@ const RE_FUNCTION_NAME = /^[A-Z][A-Z0-9_-]*$/;
3737
// if the next line is indented. For StringLiterals they are: \ (starts an
3838
// escape sequence), " (ends the literal), and line breaks which are not allowed
3939
// in StringLiterals. Note that string runs may be empty; text runs may not.
40-
const RE_TEXT_RUN = /([^{}\n\r]+)/y;
41-
const RE_STRING_RUN = /([^\\"\n\r]*)/y;
40+
const RE_TEXT_RUN = /((?:[^{}\n\r]|\r(?!\n))+)/y;
41+
const RE_STRING_RUN = /((?:[^\\"\n\r]|\r(?!\n))*)/y;
4242

4343
// Escape sequences.
4444
const RE_STRING_ESCAPE = /\\([\\"])/y;
@@ -53,17 +53,17 @@ const RE_BLANK_LINES = / *\r?\n/g;
5353
const RE_INDENT = /( *)$/;
5454

5555
// Common tokens.
56-
const TOKEN_BRACE_OPEN = /{\s*/y;
57-
const TOKEN_BRACE_CLOSE = /\s*}/y;
58-
const TOKEN_BRACKET_OPEN = /\[\s*/y;
59-
const TOKEN_BRACKET_CLOSE = /\s*] */y;
60-
const TOKEN_PAREN_OPEN = /\s*\(\s*/y;
61-
const TOKEN_ARROW = /\s*->\s*/y;
62-
const TOKEN_COLON = /\s*:\s*/y;
56+
const TOKEN_BRACE_OPEN = /{(?: |\r?\n)*/y;
57+
const TOKEN_BRACE_CLOSE = /(?: |\r?\n)*}/y;
58+
const TOKEN_BRACKET_OPEN = /\[(?: |\r?\n)*/y;
59+
const TOKEN_BRACKET_CLOSE = /(?: |\r?\n)*] */y;
60+
const TOKEN_PAREN_OPEN = /(?: |\r?\n)*\((?: |\r?\n)*/y;
61+
const TOKEN_ARROW = /(?: |\r?\n)*->(?: |\r?\n)*/y;
62+
const TOKEN_COLON = /(?: |\r?\n)*:(?: |\r?\n)*/y;
6363
// Note the optional comma. As a deviation from the Fluent EBNF, the parser
6464
// doesn't enforce commas between call arguments.
65-
const TOKEN_COMMA = /\s*,?\s*/y;
66-
const TOKEN_BLANK = /\s+/y;
65+
const TOKEN_COMMA = /(?: |\r?\n)*,?(?: |\r?\n)*/y;
66+
const TOKEN_BLANK = /(?: |\r?\n)+/y;
6767

6868
/**
6969
* Fluent Resource is a structure storing parsed localization entries.

fluent-bundle/src/types.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { Scope } from "./scope.js";
55
// In addition to this minimal interface, these objects are also expected
66
// to be supported by Intl.DateTimeFormat
77
interface TemporalInstant {
8-
epochMilliseconds: number
8+
epochMilliseconds: number;
99
toString(): string;
1010
}
1111
interface TemporalDateTypes {
@@ -14,12 +14,12 @@ interface TemporalDateTypes {
1414
toString(): string;
1515
}
1616
interface TemporalPlainTime {
17-
hour: number
18-
minute: number
19-
second: number
17+
hour: number;
18+
minute: number;
19+
second: number;
2020
toString(): string;
2121
}
22-
type TemporalObject = TemporalInstant | TemporalDateTypes | TemporalPlainTime
22+
type TemporalObject = TemporalInstant | TemporalDateTypes | TemporalPlainTime;
2323

2424
export type FluentValue = FluentType<unknown> | string;
2525

fluent-bundle/test/arguments_test.js

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
import assert from "assert";
22
import ftl from "@fluent/dedent";
33

4-
import { FluentBundle } from "../esm/bundle.js";
5-
import { FluentResource } from "../esm/resource.js";
6-
import { FluentType, FluentNumber, FluentDateTime } from "../esm/types.js";
4+
import { FluentBundle } from "../src/bundle.ts";
5+
import { FluentResource } from "../src/resource.ts";
6+
import { FluentType, FluentNumber, FluentDateTime } from "../src/types.ts";
77

88
suite("Variables", function () {
99
let bundle, errs;
1010

11-
setup(function () {
11+
beforeEach(function () {
1212
errs = [];
1313
});
1414

1515
suite("in values", function () {
16-
suiteSetup(function () {
16+
beforeAll(function () {
1717
bundle = new FluentBundle("en-US", { useIsolating: false });
1818
bundle.addResource(
1919
new FluentResource(ftl`
@@ -58,7 +58,7 @@ suite("Variables", function () {
5858
});
5959

6060
suite("in selectors", function () {
61-
suiteSetup(function () {
61+
beforeAll(function () {
6262
bundle = new FluentBundle("en-US", { useIsolating: false });
6363
bundle.addResource(
6464
new FluentResource(ftl`
@@ -78,7 +78,7 @@ suite("Variables", function () {
7878
});
7979

8080
suite("in function calls", function () {
81-
suiteSetup(function () {
81+
beforeAll(function () {
8282
bundle = new FluentBundle("en-US", { useIsolating: false });
8383
bundle.addResource(
8484
new FluentResource(ftl`
@@ -96,7 +96,7 @@ suite("Variables", function () {
9696
});
9797

9898
suite("simple errors", function () {
99-
suiteSetup(function () {
99+
beforeAll(function () {
100100
bundle = new FluentBundle("en-US", { useIsolating: false });
101101
bundle.addResource(
102102
new FluentResource(ftl`
@@ -158,7 +158,7 @@ suite("Variables", function () {
158158
suite("and strings", function () {
159159
let args;
160160

161-
suiteSetup(function () {
161+
beforeAll(function () {
162162
bundle = new FluentBundle("en-US", { useIsolating: false });
163163
bundle.addResource(
164164
new FluentResource(ftl`
@@ -179,7 +179,7 @@ suite("Variables", function () {
179179
});
180180

181181
suite("and numbers", function () {
182-
suiteSetup(function () {
182+
beforeAll(function () {
183183
bundle = new FluentBundle("en-US", { useIsolating: false });
184184
bundle.addResource(
185185
new FluentResource(ftl`
@@ -207,7 +207,7 @@ suite("Variables", function () {
207207
suite("and dates", function () {
208208
let dtf;
209209

210-
suiteSetup(function () {
210+
beforeAll(function () {
211211
dtf = new Intl.DateTimeFormat("en-US");
212212
bundle = new FluentBundle("en-US", { useIsolating: false });
213213
bundle.addResource(
@@ -243,33 +243,33 @@ suite("Variables", function () {
243243
}
244244
}
245245

246-
suiteSetup(function () {
246+
beforeAll(function () {
247247
bundle = new FluentBundle("en-US", { useIsolating: false });
248248
bundle.addResource(
249249
new FluentResource(ftl`
250250
foo = { $arg }
251251
bar = { foo }
252252
`)
253253
);
254+
});
254255

255-
const args = {
256-
// CustomType is a wrapper around the value
257-
arg: new CustomType(),
258-
};
256+
const args = {
257+
// CustomType is a wrapper around the value
258+
arg: new CustomType(),
259+
};
260+
261+
test("interpolation", function () {
262+
const msg = bundle.getMessage("foo");
263+
const value = bundle.formatPattern(msg.value, args, errs);
264+
assert.strictEqual(value, "CUSTOM");
265+
assert.strictEqual(errs.length, 0);
266+
});
259267

260-
test("interpolation", function () {
261-
const msg = bundle.getMessage("foo");
262-
const value = bundle.formatPattern(msg.value, args, errs);
263-
assert.strictEqual(value, "CUSTOM");
264-
assert.strictEqual(errs.length, 0);
265-
});
266-
267-
test("nested interpolation", function () {
268-
const msg = bundle.getMessage("bar");
269-
const value = bundle.formatPattern(msg.value, args, errs);
270-
assert.strictEqual(value, "CUSTOM");
271-
assert.strictEqual(errs.length, 0);
272-
});
268+
test("nested interpolation", function () {
269+
const msg = bundle.getMessage("bar");
270+
const value = bundle.formatPattern(msg.value, args, errs);
271+
assert.strictEqual(value, "CUSTOM");
272+
assert.strictEqual(errs.length, 0);
273273
});
274274
});
275275
});

0 commit comments

Comments
 (0)