Skip to content

Commit e992e23

Browse files
authored
Migrate @fluent/bundle to TypeScript (#436)
1 parent c7c39da commit e992e23

Some content is hidden

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

55 files changed

+735
-483
lines changed

common.mk

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,34 +14,28 @@ all: lint test build
1414
# Used for pre-publishing.
1515
dist: clean lint test build html
1616

17-
lint:
17+
_lint:
1818
@eslint --config $(ROOT)/eslint_src.json --max-warnings 0 src/
1919
@eslint --config $(ROOT)/eslint_test.json --max-warnings 0 test/
20-
@echo -e " $(OK) $@"
20+
@echo -e " $(OK) lint"
2121

22-
html:
22+
_html:
2323
ifneq (,$(wildcard ./.esdoc.json))
2424
@esdoc
25-
@echo -e " $(OK) $@ built"
25+
@echo -e " $(OK) html built"
2626
endif
2727

28+
_clean:
29+
@rm -f index.js compat.js
30+
@rm -rf .nyc_output coverage
31+
@echo -e " $(OK) clean"
32+
2833
deps:
2934
@npm install
30-
@echo -e " $(OK) $@ installed"
35+
@echo -e " $(OK) deps installed"
3136

3237
depsclean:
3338
@rm -rf node_modules
34-
@echo -e " $(OK) $@"
35-
36-
CHANGELOG.md:
37-
@if [ -z "$(SINCE)" ]; \
38-
then echo 'Specify last version with SINCE=x.y.z' && exit 1; \
39-
fi
40-
@git log $(PACKAGE)@$(SINCE) HEAD --pretty=format:' - (%h) %s' $(CURDIR) \
41-
| cat - <(echo -e "\n\n") CHANGELOG.md \
42-
| sponge CHANGELOG.md
43-
@echo -e " $(OK) $@ updated; make sure to edit it"
44-
45-
.PHONY: test html CHANGELOG.md
39+
@echo -e " $(OK) deps clean"
4640

4741
OK := \033[32;01m✓\033[0m

fluent-bundle/.esdoc.json

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

fluent-bundle/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1+
esm/
12
index.js
23
compat.js

fluent-bundle/.npmignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
.nyc_output
22
coverage
3-
docs
3+
esm/.compiled
4+
src
45
test
56
makefile
7+
tsconfig.json

fluent-bundle/eslint_src.json

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"parser": "@typescript-eslint/parser",
3+
"parserOptions": {
4+
"ecmaVersion": 9,
5+
"sourceType": "module",
6+
"project": "./tsconfig.json"
7+
},
8+
"env": {
9+
"es6": true
10+
},
11+
"extends": [
12+
"eslint:recommended",
13+
"plugin:@typescript-eslint/eslint-recommended",
14+
"plugin:@typescript-eslint/recommended",
15+
"plugin:@typescript-eslint/recommended-requiring-type-checking",
16+
"../eslint_src.json"
17+
],
18+
"rules": {
19+
"prefer-const": "off",
20+
"no-unused-vars": ["error", {"args": "none"}],
21+
"@typescript-eslint/no-inferrable-types": "off",
22+
"@typescript-eslint/no-unused-vars": ["error", {"args": "none"}],
23+
"@typescript-eslint/no-use-before-define": "off",
24+
"@typescript-eslint/explicit-function-return-type": "error"
25+
}
26+
}

fluent-bundle/makefile

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,34 +3,57 @@ GLOBAL := FluentBundle
33

44
include ../common.mk
55

6-
build: index.js compat.js
6+
lint:
7+
@eslint --config ./eslint_src.json --max-warnings 0 src/*.ts
8+
@eslint --config $(ROOT)/eslint_test.json --max-warnings 0 test/
9+
@echo -e " $(OK) lint"
710

8-
test:
9-
@nyc --reporter=text --reporter=html mocha \
10-
--recursive --ui tdd \
11-
--require esm \
12-
--require ./test/index \
13-
test/**/*_test.js
11+
compile: esm/.compiled
12+
13+
esm/.compiled: $(SOURCES)
14+
@tsc
15+
@touch $@
16+
@echo -e " $(OK) esm/ compiled"
17+
18+
build: index.js compat.js
1419

15-
index.js: $(SOURCES)
16-
@rollup $(CURDIR)/src/index.js \
20+
index.js: esm/.compiled
21+
@rollup $(CURDIR)/esm/index.js \
1722
--config $(ROOT)/bundle_config.js \
1823
--banner "/* $(PACKAGE)@$(VERSION) */" \
1924
--amd.id $(PACKAGE) \
2025
--name $(GLOBAL) \
2126
--output.file $@
2227
@echo -e " $(OK) $@ built"
2328

24-
compat.js: $(SOURCES)
25-
@rollup $(CURDIR)/src/index.js \
29+
compat.js: esm/.compiled
30+
@rollup $(CURDIR)/esm/index.js \
2631
--config $(ROOT)/compat_config.js \
2732
--banner "/* $(PACKAGE)@$(VERSION) */" \
2833
--amd.id $(PACKAGE) \
2934
--name $(GLOBAL) \
3035
--output.file $@
3136
@echo -e " $(OK) $@ built"
3237

38+
.PHONY: test
39+
test: esm/.compiled
40+
@nyc --reporter=text --reporter=html mocha \
41+
--recursive --ui tdd \
42+
--require esm \
43+
test/**/*_test.js
44+
45+
html:
46+
@typedoc src \
47+
--out ../html/bundle \
48+
--mode file \
49+
--excludeNotExported \
50+
--excludePrivate \
51+
--logger none \
52+
--hideGenerator
53+
@echo -e " $(OK) html build"
54+
3355
clean:
56+
@rm -f esm/*.js esm/*.d.ts esm/.compiled
3457
@rm -f index.js compat.js
3558
@rm -rf .nyc_output coverage
3659
@echo -e " $(OK) clean"

fluent-bundle/package.json

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,10 @@
1515
"email": "stas@mozilla.com"
1616
}
1717
],
18-
"directories": {
19-
"lib": "./src"
20-
},
18+
"type": "commonjs",
2119
"main": "./index.js",
22-
"module": "./src/index.js",
20+
"module": "./esm/index.js",
21+
"types": "./esm/index.d.ts",
2322
"repository": {
2423
"type": "git",
2524
"url": "https://github.com/projectfluent/fluent.js.git"

fluent-bundle/src/ast.ts

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
export type Message = {
2+
id: string;
3+
value: Pattern | null;
4+
attributes: Record<string, Pattern>;
5+
};
6+
7+
export type Term = {
8+
id: string;
9+
value: Pattern;
10+
attributes: Record<string, Pattern>;
11+
};
12+
13+
export type Pattern = string | ComplexPattern;
14+
15+
export type ComplexPattern = Array<PatternElement>;
16+
17+
export type PatternElement = string | Expression;
18+
19+
export type Expression =
20+
| SelectExpression
21+
| VariableReference
22+
| TermReference
23+
| MessageReference
24+
| FunctionReference
25+
| Literal;
26+
27+
export type SelectExpression = {
28+
type: "select";
29+
selector: Expression;
30+
variants: Array<Variant>;
31+
star: number;
32+
};
33+
34+
export type VariableReference = {
35+
type: "var";
36+
name: string;
37+
};
38+
39+
export type TermReference = {
40+
type: "term";
41+
name: string;
42+
attr: string | null;
43+
args: Array<Expression | NamedArgument>;
44+
};
45+
46+
export type MessageReference = {
47+
type: "mesg";
48+
name: string;
49+
attr: string | null;
50+
};
51+
52+
export type FunctionReference = {
53+
type: "func";
54+
name: string;
55+
args: Array<Expression | NamedArgument>;
56+
};
57+
58+
export type Variant = {
59+
key: Literal;
60+
value: Pattern;
61+
};
62+
63+
export type NamedArgument = {
64+
type: "narg";
65+
name: string;
66+
value: Literal;
67+
};
68+
69+
export type Literal = StringLiteral | NumberLiteral;
70+
71+
export type StringLiteral = {
72+
type: "str";
73+
value: string;
74+
};
75+
76+
export type NumberLiteral = {
77+
type: "num";
78+
value: number;
79+
precision: number;
80+
};

fluent-bundle/src/builtins.js

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

fluent-bundle/src/builtins.ts

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/**
2+
* @overview
3+
*
4+
* The FTL resolver ships with a number of functions built-in.
5+
*
6+
* Each function take two arguments:
7+
* - args - an array of positional args
8+
* - opts - an object of key-value args
9+
*
10+
* Arguments to functions are guaranteed to already be instances of
11+
* `FluentValue`. Functions must return `FluentValues` as well.
12+
*/
13+
14+
import {
15+
FluentValue,
16+
FluentNone,
17+
FluentNumber,
18+
FluentDateTime
19+
} from "./types.js";
20+
21+
function values(opts: Record<string, FluentValue>): Record<string, unknown> {
22+
const unwrapped: Record<string, unknown> = {};
23+
for (const [name, opt] of Object.entries(opts)) {
24+
unwrapped[name] = opt.valueOf();
25+
}
26+
return unwrapped;
27+
}
28+
29+
export function NUMBER(
30+
args: Array<FluentValue>,
31+
opts: Record<string, FluentValue>
32+
): FluentValue {
33+
let arg = args[0];
34+
35+
if (arg instanceof FluentNone) {
36+
return new FluentNone(`NUMBER(${arg.valueOf()})`);
37+
}
38+
39+
if (arg instanceof FluentNumber || arg instanceof FluentDateTime) {
40+
return new FluentNumber(arg.valueOf(), { ...arg.opts, ...values(opts) });
41+
}
42+
43+
throw new TypeError("Invalid argument to NUMBER");
44+
}
45+
46+
export function DATETIME(
47+
args: Array<FluentValue>,
48+
opts: Record<string, FluentValue>
49+
): FluentValue {
50+
let arg = args[0];
51+
52+
if (arg instanceof FluentNone) {
53+
return new FluentNone(`DATETIME(${arg.valueOf()})`);
54+
}
55+
56+
if (arg instanceof FluentNumber || arg instanceof FluentDateTime) {
57+
return new FluentDateTime(arg.valueOf(), { ...arg.opts, ...values(opts) });
58+
}
59+
60+
throw new TypeError("Invalid argument to DATETIME");
61+
}

0 commit comments

Comments
 (0)