Skip to content

Commit d723938

Browse files
committed
feat: add i18next-type-generator
1 parent c715214 commit d723938

File tree

17 files changed

+361
-15
lines changed

17 files changed

+361
-15
lines changed

.npm-deprecaterc.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ package:
44
- '@skyra/http-framework'
55
- '@skyra/http-framework-i18n'
66
- '@skyra/i18next-backend'
7+
- '@skyra/i18next-type-generator'
78
- '@skyra/logger'
89
- '@skyra/shared-http-pieces'
910
- '@skyra/start-banner'

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
[![npm](https://img.shields.io/npm/v/@skyra/http-framework?color=crimson&logo=npm&style=flat-square&label=@skyra/http-framework)](https://www.npmjs.com/package/@skyra/http-framework)
1616
[![npm](https://img.shields.io/npm/v/@skyra/http-framework-i18n?color=crimson&logo=npm&style=flat-square&label=@skyra/http-framework-i18n)](https://www.npmjs.com/package/@skyra/http-framework-i18n)
1717
[![npm](https://img.shields.io/npm/v/@skyra/i18next-backend?color=crimson&logo=npm&style=flat-square&label=@skyra/i18next-backend)](https://www.npmjs.com/package/@skyra/i18next-backend)
18+
[![npm](https://img.shields.io/npm/v/@skyra/i18next-type-generator?color=crimson&logo=npm&style=flat-square&label=@skyra/i18next-type-generator)](https://www.npmjs.com/package/@skyra/i18next-type-generator)
1819
[![npm](https://img.shields.io/npm/v/@skyra/logger?color=crimson&logo=npm&style=flat-square&label=@skyra/logger)](https://www.npmjs.com/package/@skyra/logger)
1920
[![npm](https://img.shields.io/npm/v/@skyra/shared-http-pieces?color=crimson&logo=npm&style=flat-square&label=@skyra/shared-http-pieces)](https://www.npmjs.com/package/@skyra/shared-http-pieces)
2021
[![npm](https://img.shields.io/npm/v/@skyra/start-banner?color=crimson&logo=npm&style=flat-square&label=@skyra/start-banner)](https://www.npmjs.com/package/@skyra/start-banner)

packages/http-framework-i18n/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
"@sapphire/utilities": "^3.13.0",
2828
"@skyra/i18next-backend": "workspace:^",
2929
"discord-api-types": "^0.37.50",
30-
"i18next": "^22.5.1",
30+
"i18next": "^23.2.11",
3131
"tslib": "^2.6.0"
3232
},
3333
"repository": {

packages/i18next-backend/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
"devDependencies": {
3030
"@favware/cliff-jumper": "^2.1.1",
3131
"@types/node": "^18.17.0",
32-
"i18next": "^22.5.1",
32+
"i18next": "^23.2.11",
3333
"tsup": "^7.1.0",
3434
"typescript": "^5.1.6"
3535
},
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
name: i18next-type-generator
2+
org: skyra
3+
install: true
4+
packagePath: packages/i18next-type-generator
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Changelog
2+
3+
All notable changes to this project will be documented in this file.
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# `@skyra/i18next-type-generator`
2+
3+
A fast and modern type augmentation generator for the [`@skyra/i18next-backend`](https://www.npmjs.com/package/@skyra/i18next-backend) filesystem-based [`i18next`](https://www.npmjs.com/package/i18next) backend for Node.js.
4+
5+
## Usage
6+
7+
```bash
8+
$ i18next-type-generator [options] [source] [destination]
9+
10+
# Arguments:
11+
# source The directory to generate types from (default: "./src/locales/en-US/")
12+
# destination The directory to generate types to (default: "./src/@types/i18next.d.ts")
13+
#
14+
# Options:
15+
# -V, --version output the version number
16+
# -v, --verbose Verbose output
17+
# --no-prettier Disable prettier
18+
# -h, --help display help for command
19+
```
20+
21+
This CLI tool generates a `.d.ts` file with the following structure:
22+
23+
```typescript
24+
// This file is automatically generated, do not edit it.
25+
import 'i18next';
26+
27+
declare module 'i18next' {
28+
interface CustomTypeOptions {
29+
resources: {
30+
'commands/choice': {
31+
name: 'choice';
32+
description: 'Get a random value from a set of choices';
33+
// ...
34+
};
35+
// ...
36+
};
37+
}
38+
}
39+
```
40+
41+
The command reads the JSON files inside a directory writes their contents into the `.d.ts` file. This is needed because `typeof import(pathToJSON)` requires the JSON files to be included in `tsconfig.json`, which may be undesirable, and because it types the keys and their inferred types, but does not load the exact values, which breaks i18next's ability to extract arguments from strings.
42+
43+
This utility does not provide formatting options, so `prettier` is used under the hood to format it before writing to a file, you may opt-out using `--no-prettier` if you want to use a different tool.
44+
45+
> **Note**: If you want to customize `i18next`'s `CustomTypeOptions` to add [extra options](https://www.i18next.com/overview/typescript), create a different file, TypeScript will merge the two of them.
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
[changelog]
2+
header = """
3+
# Changelog
4+
5+
All notable changes to this project will be documented in this file.\n
6+
"""
7+
body = """
8+
{% if version %}\
9+
# [{{ version | trim_start_matches(pat="v") }}]\
10+
{% if previous %}\
11+
{% if previous.version %}\
12+
(https://github.com/skyra-project/archid-components/compare/{{ previous.version }}...{{ version }})\
13+
{% else %}\
14+
(https://github.com/skyra-project/archid-components/tree/{{ version }})\
15+
{% endif %}\
16+
{% endif %} \
17+
- ({{ timestamp | date(format="%Y-%m-%d") }})
18+
{% else %}\
19+
# [unreleased]
20+
{% endif %}\
21+
{% for group, commits in commits | group_by(attribute="group") %}
22+
## {{ group | upper_first }}
23+
{% for commit in commits %}
24+
- {% if commit.scope %}\
25+
**{{commit.scope}}:** \
26+
{% endif %}\
27+
{{ commit.message | upper_first }} ([{{ commit.id | truncate(length=7, end="") }}](https://github.com/skyra-project/archid-components/commit/{{ commit.id }}))\
28+
{% if commit.breaking %}\
29+
{% for breakingChange in commit.footers %}\
30+
\n{% raw %} {% endraw %}- 💥 **{{ breakingChange.token }}{{ breakingChange.separator }}** {{ breakingChange.value }}\
31+
{% endfor %}\
32+
{% endif %}\
33+
{% endfor %}
34+
{% endfor %}\n
35+
"""
36+
trim = true
37+
footer = ""
38+
39+
[git]
40+
conventional_commits = true
41+
filter_unconventional = true
42+
commit_parsers = [
43+
{ message = "^feat", group = "🚀 Features"},
44+
{ message = "^fix", group = "🐛 Bug Fixes"},
45+
{ message = "^docs", group = "📝 Documentation"},
46+
{ message = "^perf", group = "🏃 Performance"},
47+
{ message = "^refactor", group = "🏠 Refactor"},
48+
{ message = "^typings", group = "⌨️ Typings"},
49+
{ message = "^types", group = "⌨️ Typings"},
50+
{ message = ".*deprecated", body = ".*deprecated", group = "🚨 Deprecation"},
51+
{ message = "^revert", skip = true},
52+
{ message = "^style", group = "🪞 Styling"},
53+
{ message = "^test", group = "🧪 Testing"},
54+
{ message = "^chore", skip = true},
55+
{ message = "^ci", skip = true},
56+
{ message = "^build", skip = true},
57+
{ body = ".*security", group = "🛡️ Security"},
58+
]
59+
filter_commits = true
60+
tag_pattern = "@skyra/i18next-type-generator@[0-9]*"
61+
ignore_tags = ""
62+
topo_order = false
63+
sort_commits = "newest"
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
{
2+
"name": "@skyra/i18next-type-generator",
3+
"version": "1.0.0",
4+
"description": "A fast utility that generates the TypeScript augmentation for i18next.",
5+
"author": "@skyra",
6+
"license": "Apache-2.0",
7+
"type": "module",
8+
"main": "dist/cli.js",
9+
"bin": {
10+
"i18next-type-generator": "./dist/cli.js"
11+
},
12+
"sideEffects": false,
13+
"scripts": {
14+
"build": "tsup",
15+
"watch": "tsup --watch",
16+
"typecheck": "tsc -p tsconfig.eslint.json",
17+
"lint": "eslint src --ext ts --fix -c ../../package.json",
18+
"prepack": "yarn build",
19+
"bump": "cliff-jumper",
20+
"check-update": "cliff-jumper --dry-run"
21+
},
22+
"dependencies": {
23+
"colorette": "^2.0.20",
24+
"commander": "^11.0.0",
25+
"tslib": "^2.6.0"
26+
},
27+
"optionalDependencies": {
28+
"prettier": "^3.0.0"
29+
},
30+
"devDependencies": {
31+
"@favware/cliff-jumper": "^2.1.1",
32+
"@types/node": "^18.17.0",
33+
"i18next": "^23.2.11",
34+
"tsup": "^7.1.0",
35+
"typescript": "^5.1.6"
36+
},
37+
"repository": {
38+
"type": "git",
39+
"url": "git+https://github.com/skyra-project/archid-components.git",
40+
"directory": "packages/i18next-type-generator"
41+
},
42+
"files": [
43+
"dist/"
44+
],
45+
"engines": {
46+
"node": ">=16.9.0",
47+
"npm": ">=8.0.0"
48+
},
49+
"keywords": [
50+
"discord",
51+
"api",
52+
"http",
53+
"skyra",
54+
"typescript",
55+
"ts",
56+
"yarn"
57+
],
58+
"bugs": {
59+
"url": "https://github.com/skyra-project/archid-components/issues"
60+
},
61+
"publishConfig": {
62+
"access": "public"
63+
}
64+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#!/usr/bin/env node
2+
3+
import { Command, InvalidArgumentError } from 'commander';
4+
import { readFile } from 'node:fs/promises';
5+
import { generate } from './generate.js';
6+
7+
const cli = new Command();
8+
9+
const packageFile = new URL('../package.json', import.meta.url);
10+
const packageJson = JSON.parse(await readFile(packageFile, 'utf-8'));
11+
12+
const indentationParser = (value: string) => {
13+
if (value === 'tabs') return '\t';
14+
15+
const parsed = Number(value);
16+
if (Number.isNaN(parsed)) throw new InvalidArgumentError('The indentation must be a number or "tabs"');
17+
return ' '.repeat(parsed);
18+
};
19+
20+
cli.name('i18next-type-generator') //
21+
.version(packageJson.version)
22+
.argument('[source]', 'The directory to generate types from', './src/locales/en-US/')
23+
.argument('[destination]', 'The directory to generate types to', './src/@types/i18next.d.ts')
24+
.option('-i, --indentation <value>', 'The indentation to use', indentationParser, '\t')
25+
.option('-v, --verbose', 'Verbose output')
26+
.option('--no-prettier', 'Disable prettier')
27+
.action((...args) => generate(args, cli.opts()));
28+
29+
cli.parse(process.argv);

0 commit comments

Comments
 (0)