Skip to content

Commit

Permalink
Add internationalisation module and utilities
Browse files Browse the repository at this point in the history
  • Loading branch information
brawaru committed Jan 13, 2023
1 parent 17f00e6 commit 21c341b
Show file tree
Hide file tree
Showing 46 changed files with 7,328 additions and 578 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,8 @@ sw.*
# pnpm files
pnpm-lock.yaml
/.npmrc

# Auto-generated messages types (annoying to rebase)
types/i18n-messages.d.ts

.vercel
13 changes: 12 additions & 1 deletion .prettierrc
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
{
"semi": false,
"singleQuote": true,
"endOfLine": "auto"
"endOfLine": "auto",
"plugins": ["prettier-plugin-jsdoc"],
"overrides": [
{
"files": ["i18n/*/*.html"],
"options": {
"proseWrap": "never",
"htmlWhitespaceSensitivity": "strict",
"printWidth": 9999999999
}
}
]
}
14 changes: 14 additions & 0 deletions assets/styles/utils.scss
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,17 @@ body {
.text-container p {
line-height: 1.3;
}

.sr-only {
border: 0 !important;
clip: rect(1px, 1px, 1px, 1px) !important;
-webkit-clip-path: inset(50%) !important;
clip-path: inset(50%) !important;
height: 1px !important;
margin: -1px !important;
overflow: hidden !important;
padding: 0 !important;
position: absolute !important;
width: 1px !important;
white-space: nowrap !important;
}
120 changes: 120 additions & 0 deletions bin/i18n-config-gen.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
#!/usr/bin/env node

// @ts-check

import consola from 'consola'
import fs from 'node:fs/promises'
import path from 'node:path'
import { fileURLToPath } from 'node:url'
import yargs from 'yargs'
import { hideBin } from 'yargs/helpers'
import { generateConfig } from './i18n/configGenerator.mjs'
import { formatterFor } from './i18n/prettier.mjs'

// @ts-ignore
const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)

let parser = yargs(hideBin(process.argv))
.scriptName('i18n-config-gen')
.usage('$0', 'generate i18n configuration for knossos')
.option('output', {
describe: 'Output path where the configuration file will be written to',
alias: 'o',
default: './generated/i18n-config.json',
type: 'string',
})
.option('locales-dir', {
describe:
'Directory where the locale files are located. If relative, resolved against src-dir',
default: './i18n',
type: 'string',
})
.option('default-locale', {
describe: 'Locale to use as default',
type: 'string',
default: 'en-US',
})
.option('src-dir', {
describe: 'Directory containing source files for the app',
type: 'string',
default: '.',
})
.option('active-locales-file', {
description:
'Path to a file which contains an array of locale names. If not provided, all locales are exported.',
alias: 'r',
type: 'string',
})

parser = parser.wrap(parser.terminalWidth())

async function runProgram() {
const argv = await parser.parse()

const srcDir = path.resolve(process.cwd(), argv.srcDir)
const outFile = path.resolve(process.cwd(), argv.output)

/** @type {string[] | undefined} */
let acceptedLocales

if (argv.activeLocalesFile) {
const activeLocales = await fs
.readFile(path.resolve(srcDir, argv.activeLocalesFile), {
encoding: 'utf8',
})
.then((contents) => JSON.parse(contents))

const invariant = () => {
throw new Error(
'Malformed accepted locales file: root object was supposed to be an array of strings'
)
}

if (!Array.isArray(activeLocales)) invariant()

acceptedLocales = []

/** @type {string[]} */
let warnings = []

for (const locale of activeLocales) {
if (typeof locale !== 'string') invariant()

if (acceptedLocales.includes(locale)) {
warnings.push(
`Accepted locales file lists locale "${locale}" several times`
)

continue
}

acceptedLocales.push(locale)
}

for (const warning of warnings) consola.warn(warning)
}

const config = await generateConfig({
defaultLocale: argv.defaultLocale,
localesDir: path.resolve(srcDir, argv.localesDir),
srcDir,
acceptedLocales,
logging: true,
})

const format = await formatterFor(outFile)
const contents = format(JSON.stringify(config, null, 2))

await fs.writeFile(outFile, contents, { encoding: 'utf-8' })

consola.success('Generated new configuration at %s', outFile)
}

runProgram().then(
() => process.exit(0),
(err) => {
consola.fatal('Cannot generate configuration:', err)
process.exit(1)
}
)
Loading

0 comments on commit 21c341b

Please sign in to comment.