This commit is contained in:
Christian Kaisermann 2020-03-30 11:16:28 -03:00
parent 702dd1aea1
commit 39422f68c5
5 changed files with 179 additions and 9562 deletions

9555
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -58,7 +58,7 @@
]
},
"jest": {
"collectCoverage": true,
"collectCoverage": false,
"testMatch": [
"<rootDir>/test/**/*.test.ts"
],
@ -95,7 +95,7 @@
"rollup-plugin-typescript2": "^0.25.2",
"sass": "^1.23.6",
"svelte": "^3.14.1",
"svelte-preprocess": "^3.2.6",
"svelte-preprocess": "^3.7.1",
"ts-jest": "^24.1.0",
"typescript": "^3.7.2"
},
@ -103,6 +103,7 @@
"commander": "^4.0.1",
"estree-walker": "^0.9.0",
"intl-messageformat": "^7.5.2",
"intl-messageformat-parser": "^4.1.1",
"tiny-glob": "^0.2.6"
}
}

0
src/compiler/index.ts Normal file
View File

View File

@ -0,0 +1,140 @@
import {
parse,
TYPE as ICUType,
MessageFormatElement,
} from 'intl-messageformat-parser'
import { flatObj } from '../../src/runtime/includes/flatObj'
const test = {
plain: 'Some text without interpolations',
quotes: 'Some text with `quotes` and "quotes" and \'quotes\'',
interpolated: 'A text where I interpolate {count} times',
time: 'Now is {now, time}',
'time-custom-format': 'The hour is {now, time, hour}',
date: 'Today is {today, date}. Yesterday was {yesterday, date}',
'date-custom-format': 'Today is {today, date, abbr-full}',
number: 'My favorite number is {n, number}',
percent: 'My favorite number is {n, number, percent}',
pluralized:
'I have {count, plural,=0 {no cats} =1 {one cat} other {{count} cats}}',
'pluralized-with-hash':
'I have {count, plural, zero {no cats} one {just # cat} other {# cats}}',
selected:
'{gender, select, male {He is a good boy} female {She is a good girl} other {They are good fellas}}',
'nested-offsets':
'{trainers, plural, offset:1 =0 {The gym is empty} =1 {You are alone here} one {You and # trainer} other {You and # other trainers {friends, plural, offset: 4 =0 {and you need 4 more to form a basket team} =1 {and you need 3 more to play a basket game} =2 {and you need 2 more to play a basket game} =3 {and you need 1 more to play a basket game} =4 {and you have enough mates to play a basket game} one {and you can play a basket game and have # player in the bench} other {and you can play a basket game and have # players in the bench}}}}',
}
const HELPERS: Record<number, string> = {
1: '_interpolate',
2: '_number',
3: '_date',
4: '_time',
5: '_select',
6: '_plural',
}
const s = (o: any) => JSON.stringify(o)
const usedHelpers = new Set()
function buildExpression(
node: MessageFormatElement,
{ paramName }: { paramName: string }
) {
const helperFn = HELPERS[node.type]
if (node.type === ICUType.literal) {
return node.value
}
usedHelpers.add(helperFn)
const argsList = [paramName]
if (
node.type === ICUType.time ||
node.type === ICUType.date ||
node.type === ICUType.number
) {
if (node.style) {
argsList.push(s(node.style) as string)
}
} else if (node.type === ICUType.select) {
console.log(node)
argsList.push(
JSON.stringify(
Object.fromEntries(
Object.entries(node.options).map(([key, n]) => {
return [key, n.value]
})
)
)
)
}
return `${helperFn}(${argsList.join(', ')})`
}
function buildTemplateLiteral(ast: MessageFormatElement[]) {
// console.log(ast)
const parts: any[] = []
const params: any[] = []
for (const node of ast) {
if (node.type === ICUType.literal) {
parts.push(node.value)
continue
}
if (
node.type === ICUType.argument ||
node.type === ICUType.time ||
node.type === ICUType.date ||
node.type === ICUType.number ||
node.type === ICUType.select
) {
const paramName = `t${params.length}`
params.push([node.value, paramName])
parts.push(`\${${buildExpression(node, { paramName })}}`)
continue
}
}
const mappedParams = params.map(
([name, internalName]) => `${name}: ${internalName}`
)
const stringifiedParts = parts.join('').replace(/`/g, '\\`')
const functionParam =
mappedParams.length > 0 ? `{ ${mappedParams.join(', ')} }` : ''
return `(${functionParam}) => \`${stringifiedParts}\``
}
function buildFunction(ast: MessageFormatElement[]) {
return buildTemplateLiteral(ast)
}
it('foo', () => {
const obj = flatObj(test)
const result: Record<string, any> = {}
for (const [id, msg] of Object.entries(obj)) {
const parsed = parse(msg)
result[id] = buildFunction(parsed)
}
const imports = [...usedHelpers].join(', ')
const mod = `
import { ${imports} } from 'svelte-i18n/icu-helpers';
export default {
${Object.entries(result)
.map(([id, fn]) => `${s(id)}: ${fn.toString()}`)
.join(',\n ')}
}
`.trim()
console.log(mod)
// console.log(Object.entries(result).map(r => [r[0], eval(r[1]).toString()]))
})

View File

@ -731,11 +731,23 @@
"@formatjs/intl-utils" "^2.0.4"
unicode-12.1.0 "0.8"
"@formatjs/intl-unified-numberformat@^3.3.0":
version "3.3.0"
resolved "https://registry.yarnpkg.com/@formatjs/intl-unified-numberformat/-/intl-unified-numberformat-3.3.0.tgz#0692346a9cd432abb2cd9b6879ddd6592585641a"
integrity sha512-wLT3myYq6fUhJYUh53tt5fMok+sUqO3Jy1XeSqYTphP7MmQl38tHqAIL65Dxh7M6/QlDEQTOkMZNpQcnT0AzaQ==
dependencies:
"@formatjs/intl-utils" "^2.2.0"
"@formatjs/intl-utils@^2.0.4":
version "2.0.4"
resolved "https://registry.yarnpkg.com/@formatjs/intl-utils/-/intl-utils-2.0.4.tgz#936961b7eade01f6d331d31cc9fb512d1fb3981a"
integrity sha512-zd92HkqxeEprsyM3JLGr+jhhMkmY0NCYQ+Jyw/DC6qZHiFejdO19doYcH5/iMUUPEYLI2h/k7TETqAEez8Btog==
"@formatjs/intl-utils@^2.2.0":
version "2.2.0"
resolved "https://registry.yarnpkg.com/@formatjs/intl-utils/-/intl-utils-2.2.0.tgz#ba6e12fe64ff7fd160be392007c47d24b7ae5c75"
integrity sha512-+Az7tR1av1DHZu9668D8uh9atT6vp+FFmEF8BrEssv0OqzpVjpVBGVmcgPzQP8k2PQjVlm/h2w8cTt0knn132w==
"@jest/console@^24.7.1", "@jest/console@^24.9.0":
version "24.9.0"
resolved "https://registry.yarnpkg.com/@jest/console/-/console-24.9.0.tgz#79b1bc06fb74a8cfb01cbdedf945584b1b9707f0"
@ -3094,6 +3106,13 @@ intl-messageformat-parser@^3.6.2:
dependencies:
"@formatjs/intl-unified-numberformat" "^3.0.4"
intl-messageformat-parser@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/intl-messageformat-parser/-/intl-messageformat-parser-4.1.1.tgz#33a3ac1854a8b9adc18dfc73db018abf91be4c32"
integrity sha512-RDmhjncV9VOKZ5nkoeeTxVy6G2kV5ZZNtewT89vj7vkr5NAPjw8/q6xYjUxdLnxNbQPcwno6zTD6j9VC0PW+Ag==
dependencies:
"@formatjs/intl-unified-numberformat" "^3.3.0"
intl-messageformat@^7.5.2:
version "7.8.2"
resolved "https://registry.yarnpkg.com/intl-messageformat/-/intl-messageformat-7.8.2.tgz#5b0b7a5c1c5eb8792e745889fa5c3526cd801588"
@ -4306,6 +4325,11 @@ mimic-fn@^2.1.0:
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b"
integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==
min-indent@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.0.tgz#cfc45c37e9ec0d8f0a0ec3dd4ef7f7c3abe39256"
integrity sha1-z8RcN+nsDY8KDsPdTvf3w6vjklY=
minimatch@^3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
@ -5873,6 +5897,13 @@ strip-indent@^2.0.0:
resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68"
integrity sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=
strip-indent@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-3.0.0.tgz#c32e1cee940b6b3432c771bc2c54bcce73cd3001"
integrity sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==
dependencies:
min-indent "^1.0.0"
strip-json-comments@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.0.1.tgz#85713975a91fb87bf1b305cca77395e40d2a64a7"
@ -5904,15 +5935,15 @@ supports-color@^7.1.0:
dependencies:
has-flag "^4.0.0"
svelte-preprocess@^3.2.6:
version "3.3.0"
resolved "https://registry.yarnpkg.com/svelte-preprocess/-/svelte-preprocess-3.3.0.tgz#7732b0b25f02e40b518c6a3818e625f9b8ec4d14"
integrity sha512-/N7VUebaU1U8Zpv1rsmfmOPERowOwSbJVkYl/6OKYqVRAyWW76t3U9M/2Ri1FzgTghadh+XpTfLngDm5iZMSYQ==
svelte-preprocess@^3.7.1:
version "3.7.1"
resolved "https://registry.yarnpkg.com/svelte-preprocess/-/svelte-preprocess-3.7.1.tgz#d368783221f9bd2896ba47d72c534dd43c4f1a24"
integrity sha512-7Padl2rCwQAakLGnNhk52NJw4eUJHs+q432rRvcCs/Ul7pKoSoZ69HCptXTH8ChjRFl1hqrVsLVYu7wGvYgR1A==
dependencies:
"@types/pug" "^2.0.4"
"@types/sass" "^1.16.0"
detect-indent "^6.0.0"
strip-indent "^2.0.0"
strip-indent "^3.0.0"
svelte@^3.14.1:
version "3.17.1"