fluent-transpiler 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cli.js +61 -29
- package/index.js +12 -1
- package/package.json +10 -7
package/cli.js
CHANGED
|
@@ -6,10 +6,10 @@ import { Command, Option } from 'commander'
|
|
|
6
6
|
import compile from './index.js'
|
|
7
7
|
|
|
8
8
|
const fileExists = async (filepath) => {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
const stats = await stat(filepath)
|
|
10
|
+
if (!stats.isFile()) {
|
|
11
|
+
throw new Error(`${filepath} is not a file`)
|
|
12
|
+
}
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
new Command()
|
|
@@ -17,38 +17,70 @@ new Command()
|
|
|
17
17
|
.description('Compile Fluent (.ftl) files to JavaScript (.js or .mjs)')
|
|
18
18
|
//.version(package.version)
|
|
19
19
|
.argument('<input>', 'Path to the Fluent file to compile')
|
|
20
|
-
.requiredOption(
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
.requiredOption(
|
|
21
|
+
'--locale <locale...>',
|
|
22
|
+
'What locale(s) to be used. Multiple can be set to allow for fallback. i.e. en-CA'
|
|
23
|
+
)
|
|
24
|
+
.addOption(
|
|
25
|
+
new Option('--comments', 'Include comments in output file.').preset(true)
|
|
26
|
+
)
|
|
27
|
+
.addOption(
|
|
28
|
+
new Option(
|
|
29
|
+
'--include <includeMessages...>',
|
|
30
|
+
'Allowed messages to be included. Default to include all.'
|
|
31
|
+
)
|
|
32
|
+
)
|
|
33
|
+
.addOption(
|
|
34
|
+
new Option(
|
|
35
|
+
'--exclude <excludeMessages...>',
|
|
36
|
+
'Ignored messages to be excluded. Default to exclude none.'
|
|
37
|
+
)
|
|
38
|
+
)
|
|
39
|
+
.addOption(
|
|
40
|
+
new Option(
|
|
41
|
+
'--exclude-value <excludeMessageValue...>',
|
|
42
|
+
'Set message to an empty string when it contains this value. Default to not allowing empty strings.'
|
|
43
|
+
)
|
|
23
44
|
)
|
|
24
|
-
.addOption(new Option('--include <includeMessages...>', 'Allowed messages to be included. Default to include all.'))
|
|
25
|
-
.addOption(new Option('--exclude <excludeMessages...>', 'Ignored messages to be excluded. Default to exclude none.'))
|
|
26
45
|
/*.addOption(new Option('--tree-shaking', 'Export all messages to allow tree shaking')
|
|
27
46
|
.preset(true)
|
|
28
47
|
)*/
|
|
29
|
-
.addOption(
|
|
30
|
-
|
|
31
|
-
|
|
48
|
+
.addOption(
|
|
49
|
+
new Option(
|
|
50
|
+
'--variable-notation <variableNotation>',
|
|
51
|
+
'What variable notation to use with exports'
|
|
52
|
+
)
|
|
53
|
+
.choices(['camelCase', 'pascalCase', 'constantCase', 'snakeCase'])
|
|
54
|
+
.default('camelCase')
|
|
32
55
|
)
|
|
33
|
-
.addOption(
|
|
34
|
-
|
|
56
|
+
.addOption(
|
|
57
|
+
new Option(
|
|
58
|
+
'--disable-minify',
|
|
59
|
+
'If disabled, all exported messages will have the same interface `(params) => ({value, attributes})`.'
|
|
60
|
+
).preset(true)
|
|
35
61
|
)
|
|
36
|
-
.addOption(
|
|
37
|
-
|
|
62
|
+
.addOption(
|
|
63
|
+
new Option(
|
|
64
|
+
'--use-isolating',
|
|
65
|
+
'Wrap placeable with \\u2068 and \\u2069.'
|
|
66
|
+
).preset(true)
|
|
67
|
+
)
|
|
68
|
+
.addOption(
|
|
69
|
+
new Option(
|
|
70
|
+
'-o, --output <output>',
|
|
71
|
+
'Path to store the resulting JavaScript file. Will be in ESM.'
|
|
72
|
+
)
|
|
38
73
|
)
|
|
39
|
-
.addOption(new Option('-o, --output <output>', 'Path to store the resulting JavaScript file. Will be in ESM.'))
|
|
40
74
|
.action(async (input, options) => {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
75
|
+
await fileExists(input)
|
|
76
|
+
|
|
77
|
+
const ftl = await readFile(input, { encoding: 'utf8' })
|
|
78
|
+
|
|
79
|
+
const js = compile(ftl, options)
|
|
80
|
+
if (options.output) {
|
|
81
|
+
await writeFile(options.output, js, 'utf8')
|
|
82
|
+
} else {
|
|
83
|
+
console.log(js)
|
|
84
|
+
}
|
|
52
85
|
})
|
|
53
86
|
.parse()
|
|
54
|
-
|
package/index.js
CHANGED
|
@@ -14,6 +14,7 @@ export const compile = (src, opts) => {
|
|
|
14
14
|
errorOnJunk: true,
|
|
15
15
|
includeMessages: [],
|
|
16
16
|
excludeMessages: [],
|
|
17
|
+
excludeMessageValue: undefined,
|
|
17
18
|
//treeShaking: false,
|
|
18
19
|
variableNotation: 'camelCase',
|
|
19
20
|
disableMinify: false, // TODO needs better name strictInterface?
|
|
@@ -27,6 +28,10 @@ export const compile = (src, opts) => {
|
|
|
27
28
|
options.includeMessages = [options.includeMessages]
|
|
28
29
|
if (!Array.isArray(options.excludeMessages))
|
|
29
30
|
options.excludeMessages = [options.excludeMessages]
|
|
31
|
+
if (options.excludeMessageValue) {
|
|
32
|
+
// cast to template literal
|
|
33
|
+
options.excludeMessageValue = '`' + options.excludeMessageValue + '`'
|
|
34
|
+
}
|
|
30
35
|
|
|
31
36
|
const metadata = {}
|
|
32
37
|
const exports = []
|
|
@@ -128,6 +133,11 @@ export const compile = (src, opts) => {
|
|
|
128
133
|
|
|
129
134
|
const templateStringLiteral =
|
|
130
135
|
data.value && compileType(data.value, data.type)
|
|
136
|
+
|
|
137
|
+
if (options.excludeMessageValue === templateStringLiteral) {
|
|
138
|
+
templateStringLiteral = '``'
|
|
139
|
+
}
|
|
140
|
+
|
|
131
141
|
metadata[assignment].attributes = data.attributes.length
|
|
132
142
|
let attributes = {}
|
|
133
143
|
if (metadata[assignment].attributes) {
|
|
@@ -202,7 +212,8 @@ export const compile = (src, opts) => {
|
|
|
202
212
|
},
|
|
203
213
|
// Element
|
|
204
214
|
TextElement: (data) => {
|
|
205
|
-
|
|
215
|
+
if (data.value === options.emptyString) return
|
|
216
|
+
return data.value.replaceAll('`', '\\`') // escape string literal
|
|
206
217
|
},
|
|
207
218
|
Placeable: (data, parent) => {
|
|
208
219
|
return `${options.useIsolating ? '\u2068' : ''}\${${compileType(
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fluent-transpiler",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Transpile Fluent (ftl) files into optimized, tree-shakable, JavaScript EcmaScript Modules (esm).",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"scripts": {
|
|
15
15
|
"test": "npm run test:cli && npm run test:unit",
|
|
16
16
|
"test:cli": "./cli.js --locale en-CA --locale en --use-isolating --variable-notation camelCase test/files/index.ftl --output test/files/index.mjs",
|
|
17
|
-
"test:unit": "
|
|
17
|
+
"test:unit": "node --test"
|
|
18
18
|
},
|
|
19
19
|
"repository": {
|
|
20
20
|
"type": "git",
|
|
@@ -39,12 +39,15 @@
|
|
|
39
39
|
},
|
|
40
40
|
"homepage": "https://github.com/willfarrell/fluent-transpiler",
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@fluent/syntax": "0.
|
|
43
|
-
"change-case": "4.
|
|
44
|
-
"commander": "
|
|
42
|
+
"@fluent/syntax": "0.19.0",
|
|
43
|
+
"change-case": "5.4.4",
|
|
44
|
+
"commander": "13.1.0"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
|
-
"@fluent/bundle": "^0.
|
|
48
|
-
|
|
47
|
+
"@fluent/bundle": "^0.19.0"
|
|
48
|
+
},
|
|
49
|
+
"funding": {
|
|
50
|
+
"type": "github",
|
|
51
|
+
"url": "https://github.com/sponsors/willfarrell"
|
|
49
52
|
}
|
|
50
53
|
}
|