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.
Files changed (3) hide show
  1. package/cli.js +61 -29
  2. package/index.js +12 -1
  3. 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
- const stats = await stat(filepath)
10
- if (!stats.isFile()) {
11
- throw new Error(`${filepath} is not a file`)
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('--locale <locale...>', 'What locale(s) to be used. Multiple can be set to allow for fallback. i.e. en-CA')
21
- .addOption(new Option('--comments', 'Include comments in output file.')
22
- .preset(true)
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(new Option('--variable-notation <variableNotation>', 'What variable notation to use with exports')
30
- .choices(['camelCase','pascalCase','constantCase','snakeCase'])
31
- .default('camelCase')
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(new Option('--disable-minify', 'If disabled, all exported messages will have the same interface `(params) => ({value, attributes})`.')
34
- .preset(true)
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(new Option('--use-isolating', 'Wrap placeable with \\u2068 and \\u2069.')
37
- .preset(true)
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
- await fileExists(input)
42
-
43
- const ftl = await readFile(input, {encoding:'utf8'})
44
-
45
- const js = compile(ftl, options)
46
- if (options.output) {
47
- await writeFile(options.output, js, 'utf8')
48
- } else {
49
- console.log(js)
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
- return data.value
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.2.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": "c8 node --test"
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.18.1",
43
- "change-case": "4.1.2",
44
- "commander": "9.4.0"
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.17.1",
48
- "c8": "^7.12.0"
47
+ "@fluent/bundle": "^0.19.0"
48
+ },
49
+ "funding": {
50
+ "type": "github",
51
+ "url": "https://github.com/sponsors/willfarrell"
49
52
  }
50
53
  }