Skip to content

Commit

Permalink
Merge pull request #3 from gmaxlev/website
Browse files Browse the repository at this point in the history
Features:
- Added a website
- Changed README
  • Loading branch information
gmaxlev authored Jul 21, 2024
2 parents ab07f0b + 544c8ff commit 7a53c5a
Show file tree
Hide file tree
Showing 58 changed files with 15,990 additions and 104 deletions.
56 changes: 56 additions & 0 deletions .github/workflows/website-deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
name: Deploy to GitHub Pages

defaults:
run:
shell: bash
working-directory: ./web

on:
push:
branches:
- main
# Review gh actions docs if you want to further define triggers, paths, etc
# https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#on

jobs:
build:
name: Build Docusaurus
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: 18
cache: npm

- name: Install dependencies
run: npm ci
- name: Build website
run: npm run build

- name: Upload Build Artifact
uses: actions/upload-pages-artifact@v3
with:
path: ./web/build

deploy:
name: Deploy to GitHub Pages
needs: build

# Grant GITHUB_TOKEN the permissions required to make a Pages deployment
permissions:
pages: write # to deploy to Pages
id-token: write # to verify the deployment originates from an appropriate source

# Deploy to the github-pages environment
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}

runs-on: ubuntu-latest
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
3 changes: 2 additions & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
__mocks__
coverage
lib
lib
web
30 changes: 14 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# 🈯️️ i18n-collector

A tool that makes it easy to manage many translation files in your application.
A tool for managing and compiling locale files.

![CLI watch mode example](./docs/cli-example.jpg)
![CLI watch mode example](./docs/cli-example.png)

## Installation

Expand All @@ -28,7 +28,7 @@ There are many problems you can face with:
- ❌ You have large translation files with many keys from different domain areas that are hard to manage.
- ❌ You have to control that each translation key is unique manually.
- ❌ You have to import many translation files into your app manually.
-**You have to keep track of too much information about your translations.**
- ❌ You have to keep track of too much information about your translations.

This tool allows you to split your translations into any number of files and collect them into one file per language in the automatic mode.

Expand All @@ -41,8 +41,6 @@ With this tool, you can:

> ⚠️ This tool is designed to help you manage many translation files and merge them into one file per language. It is recommended that you use an i18n library or framework to make use of these merged files.
We recommend using [i18next](https://www.i18next.com), which has excellent support for TypeScript. When used together with i18n-collector, it will be a perfect match.

## Usage with React and i18next

This is a simple example of how to use this tool with `i18next` in React.
Expand All @@ -64,19 +62,19 @@ Let's take a closer look at each of these dependencies.

### 1. Configure i18next

Let's assume that our app needs to support two languages: `🇬🇧English` and `🇺🇦Ukrainian`.
Let's assume that our app needs to support two languages: `🇬🇧 English` and `🇩🇪 German`.

`/src/i18n.js`

```js
import i18n from "i18next";
import uk from "./locales/uk.json";
import en from "./locales/en.json";
import de from "./locales/de.json";

i18n.use(initReactI18next).init({
resources: {
en,
uk,
de,
},
lng: "en",
fallbackLng: "en",
Expand All @@ -86,10 +84,10 @@ i18n.use(initReactI18next).init({
});
```

We've created a configuration file for i18next and imported `./locales/en.json` and `./locales/uk.json` files.
We've created a configuration file for i18next and imported `./locales/en.json` and `./locales/de.json` files.
These files will be generated by i18n-collector later, and it is important that you **do not create them manually**.

> The configuration we've provided for i18next is a simple one that may not meet all of your needs. You may need to configure i18next differently depending on your specific requirements. For more information about i18next configuration options, please refer to [the official i18next documentation](https://www.i18next.com/overview/configuration-options).
> The configuration we've provided for i18next is a simple one that may not meet all of your needs. You may need to configure i18next differently depending on your specific requirements. For more information about i18next configuration options, please refer to [the official i18next documentation](https://www.i18next.com/overview/configuration-options).
### 2. Add new scripts to package.json

Expand Down Expand Up @@ -146,11 +144,11 @@ Now, let's prepare some translations for our Product component.
"price": "Price",
"buy": "Add to cart"
},
"uk": {
"name": "Назва товару",
"description": "Опис",
"price": "Ціна",
"buy": "Додати в кошик"
"de": {
"name": "Produktname",
"description": "Beschreibung",
"price": "Preis",
"buy": "In den Warenkorb"
}
}
```
Expand Down Expand Up @@ -201,7 +199,7 @@ As a result, we now have two files in the `./locales` directory that were genera
```
locales
├── en.json
└── uk.json
└── de.json
```

Let's take a look at the `en.json` file.
Expand Down
Binary file removed docs/cli-example.jpg
Binary file not shown.
Binary file added docs/cli-example.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@
"author": "Maksym Levytskyi https://github.com/gmaxlev",
"license": "MIT",
"scripts": {
"test": "npm run prettier && npm run lint && jest . --silent",
"test": "npm run lint && jest . --silent",
"test:watch": "jest . --watch --silent",
"dev": "nodemon --watch './**/*.ts' --exec 'node --experimental-specifier-resolution=node --loader ts-node/esm' src/index.ts",
"build:dts": "tsc --declaration --emitDeclarationOnly -p . --outDir dts",
"build": "rm -rf lib && rm -rf dts && npm run build:dts && rollup -c rollup.config.cjs --bundleConfigAsCjs && rm -rf dts",
"lint": "eslint .",
"prettier": "prettier --check .",
"prettier": "npx prettier --check src",
"prepare": "husky install"
},
"lint-staged": {
Expand Down
4 changes: 2 additions & 2 deletions src/bin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ program
"-r, --recursive [value]",
"whether to scan the directory recursively",
parseBooleanInput,
true
true,
)
.option("-c, --clear [value]", "clear output path", parseBooleanInput, false)
.option(
"-m, --merge [value]",
"allow merging the same namespace from different files",
parseBooleanInput,
false
false,
)
.option("-i, --input <value>", "input path")
.action(async (output, options) => {
Expand Down
12 changes: 6 additions & 6 deletions src/compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export interface CompilerOptions {
function findIdInLocales(
locales: ParseResult[],
language: string,
namespace?: LocaleNamespace
namespace?: LocaleNamespace,
) {
for (const locale of locales) {
if (locale === null) {
Expand Down Expand Up @@ -53,11 +53,11 @@ function join(locales: ParseResult[], merge = true): CompiledLocales {
const conflictedLocaleId = findIdInLocales(
locales.filter((item) => item !== locale),
language,
namespace
namespace,
);

throw new Error(
`Locales [${id}] and [${conflictedLocaleId}] have the same namespace. If you want to allow merging, set the "merge" option to true`
`Locales [${id}] and [${conflictedLocaleId}] have the same namespace. If you want to allow merging, set the "merge" option to true`,
);
}

Expand All @@ -68,7 +68,7 @@ function join(locales: ParseResult[], merge = true): CompiledLocales {

isRecord.assert(
namespaceTranslations,
`Translations for language [${language}] and namespace [${namespace}]`
`Translations for language [${language}] and namespace [${namespace}]`,
);

namespaceRecord = {
Expand Down Expand Up @@ -156,8 +156,8 @@ export async function compile(options: CompilerOptions) {
parser({
filePath: file.filePath,
fileContent: file.content,
})
)
}),
),
);

return join(parsed, options.merge);
Expand Down
6 changes: 3 additions & 3 deletions src/emitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ function log(outputPath: string, stats: Stats[]) {
stats.forEach((item, index) => {
const relativePath = path.basename(item.filePath);
const fileNameLog = `${chalk.white.bold(`${index + 1}`)}. ${chalk.blue.bold(
relativePath
relativePath,
)}`;

if (item.isNew) {
Expand All @@ -55,7 +55,7 @@ function log(outputPath: string, stats: Stats[]) {
const fileSizeNew = Number(item.localeFileNew?.bytes);
const sizeAfterLog = chalk.white(getStringFilesize(fileSizeNew));
console.log(
`${fileNameLog} ${changedLog} ${sizeBeforeLog} ${dividerLog} ${sizeAfterLog}`
`${fileNameLog} ${changedLog} ${sizeBeforeLog} ${dividerLog} ${sizeAfterLog}`,
);
} else if (item.isDeleted) {
const unchangedLog = chalk.bgRed("deleted");
Expand All @@ -75,7 +75,7 @@ function log(outputPath: string, stats: Stats[]) {

async function emitFile(
filePath: string,
content: Buffer
content: Buffer,
): Promise<LocaleFile> {
await fsp.access(filePath).catch((e) => {
if (!isEnoentError(e)) {
Expand Down
2 changes: 1 addition & 1 deletion src/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ function getNamespace(filePath: string) {
result[0][1].trim() === ""
) {
throw new Error(
`Filename ${filePath} has an invalid name. Filename should contain language code in format "[namespace].locale.json"`
`Filename ${filePath} has an invalid name. Filename should contain language code in format "[namespace].locale.json"`,
);
}

Expand Down
8 changes: 4 additions & 4 deletions src/runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export interface ValidRunnerOptions {
}

export function validateRunnerOptions(
options: RunnerOptions
options: RunnerOptions,
): ValidRunnerOptions {
isRecord.assert(options, "options");

Expand Down Expand Up @@ -112,7 +112,7 @@ export async function run(options: RunnerOptions) {

if (!inputPathExists) {
throw new Error(
`inputPath "${validOptions.inputPath}" does not exist or it is not a directory`
`inputPath "${validOptions.inputPath}" does not exist or it is not a directory`,
);
}

Expand All @@ -133,8 +133,8 @@ export async function run(options: RunnerOptions) {

console.log(
`📝 Found ${chalk.yellow(files.length)} files in ${chalk.blue.bold(
validOptions.inputPath
)} to process`
validOptions.inputPath,
)} to process`,
);

let compilerOptions: CompilerOptions = {
Expand Down
4 changes: 2 additions & 2 deletions src/scan.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ async function scanDirectory(
from: string,
match: Matcher,
recursive = true,
collection: LocaleFile[] = []
collection: LocaleFile[] = [],
) {
const result = await fsp.readdir(from).catch((e) => {
console.error("Error while reading directory", from);
Expand Down Expand Up @@ -87,7 +87,7 @@ export async function scan(options: ScanOptions) {

if (!exist) {
throw new Error(
`Path "${options.path}" does not exist or it is not a directory`
`Path "${options.path}" does not exist or it is not a directory`,
);
}

Expand Down
Loading

0 comments on commit 7a53c5a

Please sign in to comment.