canopy-i18n 0.0.1
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.
- package/README.md +178 -0
- package/dist/applyLocaleDeep.d.ts +2 -0
- package/dist/applyLocaleDeep.js +24 -0
- package/dist/builder.d.ts +6 -0
- package/dist/builder.js +10 -0
- package/dist/createBuilder.d.ts +29 -0
- package/dist/createBuilder.js +70 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +10 -0
- package/dist/message.d.ts +16 -0
- package/dist/message.js +41 -0
- package/dist/test.d.ts +1 -0
- package/dist/test.js +10 -0
- package/dist/testData.d.ts +9 -0
- package/dist/testData.js +23 -0
- package/dist/types.d.ts +1 -0
- package/dist/types.js +2 -0
- package/package.json +47 -0
package/README.md
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
## canopy-i18n
|
|
2
|
+
|
|
3
|
+
A tiny, type-safe i18n helper for building localized messages and applying a locale across nested data structures.
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
- **Type-safe locales**: Compile-time safety for allowed locale keys.
|
|
7
|
+
- **Per-message fallback**: Each message knows its default and fallback locale.
|
|
8
|
+
- **Template or string**: Use plain strings or `(ctx) => string` templates.
|
|
9
|
+
- **Flexible templating**: Since templates are plain functions, you can freely use JavaScript template literals, conditionals, helpers, or any formatting library. This library does not provide a tagged template literal API.
|
|
10
|
+
- **Deep locale application**: Switch locale across entire object/array trees.
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npm install canopy-i18n
|
|
16
|
+
# or
|
|
17
|
+
pnpm add canopy-i18n
|
|
18
|
+
# or
|
|
19
|
+
yarn add canopy-i18n
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Quick start
|
|
23
|
+
|
|
24
|
+
```ts
|
|
25
|
+
import { createMessageBuilder, applyLocaleDeep } from 'canopy-i18n';
|
|
26
|
+
|
|
27
|
+
// 1) Declare allowed locales and defaults
|
|
28
|
+
const builder = createMessageBuilder(['ja', 'en'] as const, 'ja', 'ja');
|
|
29
|
+
|
|
30
|
+
// 2) Define messages
|
|
31
|
+
const title = builder({
|
|
32
|
+
ja: 'タイトルテスト',
|
|
33
|
+
en: 'Title Test',
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
const msg = builder<{ name: string; age: number }>({
|
|
37
|
+
ja: c => `こんにちは、${c.name}さん。あなたは${c.age}歳です。`,
|
|
38
|
+
en: c => `Hello, ${c.name}. You are ${c.age} years old.`,
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
// 3) Compose nested data structures
|
|
42
|
+
const data = {
|
|
43
|
+
title,
|
|
44
|
+
nested: {
|
|
45
|
+
hello: builder({ ja: 'こんにちは', en: 'Hello' }),
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
// 4) Apply locale across the tree
|
|
50
|
+
const localized = applyLocaleDeep(data, 'en');
|
|
51
|
+
|
|
52
|
+
console.log(localized.title.render()); // "Title Test"
|
|
53
|
+
console.log(localized.nested.hello.render()); // "Hello"
|
|
54
|
+
console.log(msg.setLocale('en').render({ name: 'Tanaka', age: 20 }));
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## API
|
|
58
|
+
|
|
59
|
+
### createMessageBuilder(locales, locale, fallbackLocale)
|
|
60
|
+
Returns a `builder` function to create localized messages.
|
|
61
|
+
|
|
62
|
+
- **locales**: `readonly string[]` — Allowed locale keys (e.g. `['ja', 'en'] as const`).
|
|
63
|
+
- **locale**: default active locale for new messages.
|
|
64
|
+
- **fallbackLocale**: fallback locale when the active locale value is missing.
|
|
65
|
+
|
|
66
|
+
Overloads:
|
|
67
|
+
- `builder<Record<L[number], string>>() -> I18nMessage<L, void>`
|
|
68
|
+
- `builder<Record<L[number], Template<C>>>() -> I18nMessage<L, C>`
|
|
69
|
+
|
|
70
|
+
### I18nMessage<L, C>
|
|
71
|
+
Represents a single localized message.
|
|
72
|
+
|
|
73
|
+
- **properties**
|
|
74
|
+
- `locales: L`
|
|
75
|
+
- `locale: L[number]` (getter)
|
|
76
|
+
- `fallbackLocale: L[number]` (getter)
|
|
77
|
+
- `data: Record<L[number], Template<C>>`
|
|
78
|
+
- **methods**
|
|
79
|
+
- `setLocale(locale: L[number]): this`
|
|
80
|
+
- `setFallbackLocale(locale: L[number]): this`
|
|
81
|
+
- `render(ctx?: C): string` — If the value for the active locale is a function, it’s invoked with `ctx`; otherwise the string is returned. Falls back to `fallbackLocale` if needed.
|
|
82
|
+
|
|
83
|
+
### applyLocaleDeep(obj, locale)
|
|
84
|
+
Recursively traverses arrays/objects and sets the given `locale` on all `I18nMessage` instances encountered.
|
|
85
|
+
|
|
86
|
+
- Returns a new container (arrays/objects are cloned), but reuses the same message instances after updating their locale.
|
|
87
|
+
|
|
88
|
+
## Types
|
|
89
|
+
|
|
90
|
+
```ts
|
|
91
|
+
export type Template<C> = string | ((ctx: C) => string);
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Exports
|
|
95
|
+
|
|
96
|
+
```ts
|
|
97
|
+
export { I18nMessage, isI18nMessage } from 'canopy-i18n';
|
|
98
|
+
export { createMessageBuilder } from 'canopy-i18n';
|
|
99
|
+
export { applyLocaleDeep } from 'canopy-i18n';
|
|
100
|
+
export type { Template } from 'canopy-i18n';
|
|
101
|
+
export type { LocalizedMessage } from 'canopy-i18n';
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Notes
|
|
105
|
+
- CommonJS build (`main: dist/index.js`) with TypeScript type declarations (`types: dist/index.d.ts`).
|
|
106
|
+
- Works in Node or bundlers; recommended usage is TypeScript/ESM import via your build tool.
|
|
107
|
+
- License: MIT.
|
|
108
|
+
- Not a tagged template library: you write plain functions (examples use JS template literals inside those functions).
|
|
109
|
+
|
|
110
|
+
### Split files example (namespace import)
|
|
111
|
+
|
|
112
|
+
Import all message exports as a namespace and set the locale across the whole tree.
|
|
113
|
+
|
|
114
|
+
```ts
|
|
115
|
+
// messages.ts
|
|
116
|
+
import { createMessageBuilder } from 'canopy-i18n';
|
|
117
|
+
const builder = createMessageBuilder(['ja', 'en'] as const, 'ja', 'ja');
|
|
118
|
+
|
|
119
|
+
export const title = builder({
|
|
120
|
+
ja: 'タイトルテスト',
|
|
121
|
+
en: 'Title Test',
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
export const msg = builder<{ name: string; age: number }>({
|
|
125
|
+
ja: c => `こんにちは、${c.name}さん。あなたは${c.age}歳です。`,
|
|
126
|
+
en: c => `Hello, ${c.name}. You are ${c.age} years old.`,
|
|
127
|
+
});
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
```ts
|
|
131
|
+
// usage.ts
|
|
132
|
+
import * as messages from './messages';
|
|
133
|
+
import { applyLocaleDeep } from 'canopy-i18n';
|
|
134
|
+
|
|
135
|
+
const m = applyLocaleDeep(messages, 'en');
|
|
136
|
+
|
|
137
|
+
console.log(m.title.render()); // "Title Test"
|
|
138
|
+
console.log(m.msg.render({ name: 'Tanaka', age: 20 }));
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
#### Multi-file structure
|
|
142
|
+
|
|
143
|
+
```ts
|
|
144
|
+
// i18n/builder.ts
|
|
145
|
+
import { createMessageBuilder } from 'canopy-i18n';
|
|
146
|
+
export const builder = createMessageBuilder(['ja', 'en'] as const, 'ja', 'ja');
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
```ts
|
|
150
|
+
// i18n/messages/common.ts
|
|
151
|
+
import { builder } from '../builder';
|
|
152
|
+
export const hello = builder({ ja: 'こんにちは', en: 'Hello' });
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
```ts
|
|
156
|
+
// i18n/messages/home.ts
|
|
157
|
+
import { builder } from '../builder';
|
|
158
|
+
export const title = builder({ ja: 'タイトル', en: 'Title' });
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
```ts
|
|
162
|
+
// i18n/messages/index.ts
|
|
163
|
+
export * as common from './common';
|
|
164
|
+
export * as home from './home';
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
```ts
|
|
168
|
+
// usage.ts
|
|
169
|
+
import * as msgs from './i18n/messages';
|
|
170
|
+
import { applyLocaleDeep } from 'canopy-i18n';
|
|
171
|
+
|
|
172
|
+
const m = applyLocaleDeep(msgs, 'en');
|
|
173
|
+
|
|
174
|
+
console.log(m.common.hello.render()); // "Hello"
|
|
175
|
+
console.log(m.home.title.render()); // "Title"
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Note: Module namespace objects are read-only; `applyLocaleDeep` returns a cloned plain object while updating each `I18nMessage` instance's locale in place.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.applyLocaleDeep = applyLocaleDeep;
|
|
4
|
+
const message_1 = require("./message");
|
|
5
|
+
function applyLocaleDeep(obj, locale) {
|
|
6
|
+
function visit(v) {
|
|
7
|
+
if ((0, message_1.isI18nMessage)(v)) {
|
|
8
|
+
v.setLocale(locale);
|
|
9
|
+
return v;
|
|
10
|
+
}
|
|
11
|
+
if (Array.isArray(v)) {
|
|
12
|
+
return v.map(visit);
|
|
13
|
+
}
|
|
14
|
+
if (v && typeof v === 'object') {
|
|
15
|
+
const out = {};
|
|
16
|
+
for (const k of Object.keys(v)) {
|
|
17
|
+
out[k] = visit(v[k]);
|
|
18
|
+
}
|
|
19
|
+
return out;
|
|
20
|
+
}
|
|
21
|
+
return v;
|
|
22
|
+
}
|
|
23
|
+
return visit(obj);
|
|
24
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Template } from "./types";
|
|
2
|
+
import { LocalizedMessage } from "./message";
|
|
3
|
+
export declare function createMessageBuilder<const Ls extends readonly string[]>(locales: Ls, locale: Ls[number], fallbackLocale: Ls[number]): {
|
|
4
|
+
<C>(data: Record<Ls[number], Template<C>>): LocalizedMessage<Ls, C>;
|
|
5
|
+
(data: Record<Ls[number], string>): LocalizedMessage<Ls, void>;
|
|
6
|
+
};
|
package/dist/builder.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createMessageBuilder = createMessageBuilder;
|
|
4
|
+
const message_1 = require("./message");
|
|
5
|
+
function createMessageBuilder(locales, locale, fallbackLocale) {
|
|
6
|
+
function builder(data) {
|
|
7
|
+
return new message_1.I18nMessage(locales, locale, fallbackLocale, data);
|
|
8
|
+
}
|
|
9
|
+
return builder;
|
|
10
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export type Template<C> = string | ((ctx: C) => string);
|
|
2
|
+
export declare class Li18nMessage<Ls extends readonly string[], C> {
|
|
3
|
+
readonly locales: Ls;
|
|
4
|
+
private _locale;
|
|
5
|
+
private _fallbackLocale;
|
|
6
|
+
readonly data: Record<Ls[number], Template<C>>;
|
|
7
|
+
constructor(locales: Ls, _locale: Ls[number], _fallbackLocale: Ls[number], data: Record<Ls[number], Template<C>>);
|
|
8
|
+
get locale(): Ls[number];
|
|
9
|
+
get fallbackLocale(): Ls[number];
|
|
10
|
+
setLocale(locale: Ls[number]): this;
|
|
11
|
+
setFallbackLocale(locale: Ls[number]): this;
|
|
12
|
+
render(this: Li18nMessage<Ls, void>): string;
|
|
13
|
+
render(ctx: C): string;
|
|
14
|
+
}
|
|
15
|
+
export type LocalizedMessage<Ls extends readonly string[], C> = Li18nMessage<Ls, C>;
|
|
16
|
+
export declare function createMessageBuilder<const Ls extends readonly string[]>(locales: Ls, locale: Ls[number], fallbackLocale: Ls[number]): {
|
|
17
|
+
<C>(data: Record<Ls[number], Template<C>>): LocalizedMessage<Ls, C>;
|
|
18
|
+
(data: Record<Ls[number], string>): LocalizedMessage<Ls, void>;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Recursively apply locale for any Li18nMessage instances found in the given value.
|
|
22
|
+
* Always deep; does not change fallback locale (keeps builder defaults).
|
|
23
|
+
*
|
|
24
|
+
* Example:
|
|
25
|
+
* import * as trs from './testData';
|
|
26
|
+
* applyLocaleDeep(trs, 'en');
|
|
27
|
+
*/
|
|
28
|
+
export declare function applyLocaleDeep<T extends Record<string, unknown>>(obj: T, locale: string): T;
|
|
29
|
+
export declare function applyLocaleDeep<T extends unknown[]>(obj: T, locale: string): T;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Li18nMessage = void 0;
|
|
4
|
+
exports.createMessageBuilder = createMessageBuilder;
|
|
5
|
+
exports.applyLocaleDeep = applyLocaleDeep;
|
|
6
|
+
function isTemplateFunction(t) {
|
|
7
|
+
return typeof t === 'function';
|
|
8
|
+
}
|
|
9
|
+
class Li18nMessage {
|
|
10
|
+
locales;
|
|
11
|
+
_locale;
|
|
12
|
+
_fallbackLocale;
|
|
13
|
+
data;
|
|
14
|
+
constructor(locales, _locale, _fallbackLocale, data) {
|
|
15
|
+
this.locales = locales;
|
|
16
|
+
this._locale = _locale;
|
|
17
|
+
this._fallbackLocale = _fallbackLocale;
|
|
18
|
+
this.data = data;
|
|
19
|
+
}
|
|
20
|
+
get locale() {
|
|
21
|
+
return this._locale;
|
|
22
|
+
}
|
|
23
|
+
get fallbackLocale() {
|
|
24
|
+
return this._fallbackLocale;
|
|
25
|
+
}
|
|
26
|
+
setLocale(locale) {
|
|
27
|
+
this._locale = locale;
|
|
28
|
+
return this;
|
|
29
|
+
}
|
|
30
|
+
setFallbackLocale(locale) {
|
|
31
|
+
this._fallbackLocale = locale;
|
|
32
|
+
return this;
|
|
33
|
+
}
|
|
34
|
+
render(ctx) {
|
|
35
|
+
const v = this.data[this._locale] ?? this.data[this._fallbackLocale];
|
|
36
|
+
return isTemplateFunction(v) ? v(ctx) : v;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
exports.Li18nMessage = Li18nMessage;
|
|
40
|
+
function createMessageBuilder(locales, locale, fallbackLocale) {
|
|
41
|
+
function builder(data) {
|
|
42
|
+
return new Li18nMessage(locales, locale, fallbackLocale, data);
|
|
43
|
+
}
|
|
44
|
+
return builder;
|
|
45
|
+
}
|
|
46
|
+
function isLi18nMessage(x) {
|
|
47
|
+
return x instanceof Li18nMessage;
|
|
48
|
+
}
|
|
49
|
+
function applyLocaleDeep(obj, locale) {
|
|
50
|
+
function visit(v) {
|
|
51
|
+
if (isLi18nMessage(v)) {
|
|
52
|
+
v.setLocale(locale);
|
|
53
|
+
return v;
|
|
54
|
+
}
|
|
55
|
+
if (Array.isArray(v)) {
|
|
56
|
+
return v.map(visit);
|
|
57
|
+
}
|
|
58
|
+
// Traverse any non-null object (including module namespace objects),
|
|
59
|
+
// but avoid special handling already covered above.
|
|
60
|
+
if (v && typeof v === 'object') {
|
|
61
|
+
const out = {};
|
|
62
|
+
for (const k of Object.keys(v)) {
|
|
63
|
+
out[k] = visit(v[k]);
|
|
64
|
+
}
|
|
65
|
+
return out;
|
|
66
|
+
}
|
|
67
|
+
return v;
|
|
68
|
+
}
|
|
69
|
+
return visit(obj);
|
|
70
|
+
}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.applyLocaleDeep = exports.createMessageBuilder = exports.isI18nMessage = exports.I18nMessage = void 0;
|
|
4
|
+
var message_1 = require("./message");
|
|
5
|
+
Object.defineProperty(exports, "I18nMessage", { enumerable: true, get: function () { return message_1.I18nMessage; } });
|
|
6
|
+
Object.defineProperty(exports, "isI18nMessage", { enumerable: true, get: function () { return message_1.isI18nMessage; } });
|
|
7
|
+
var builder_1 = require("./builder");
|
|
8
|
+
Object.defineProperty(exports, "createMessageBuilder", { enumerable: true, get: function () { return builder_1.createMessageBuilder; } });
|
|
9
|
+
var applyLocaleDeep_1 = require("./applyLocaleDeep");
|
|
10
|
+
Object.defineProperty(exports, "applyLocaleDeep", { enumerable: true, get: function () { return applyLocaleDeep_1.applyLocaleDeep; } });
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Template } from "./types";
|
|
2
|
+
export declare class I18nMessage<Ls extends readonly string[], C> {
|
|
3
|
+
readonly locales: Ls;
|
|
4
|
+
private _locale;
|
|
5
|
+
private _fallbackLocale;
|
|
6
|
+
readonly data: Record<Ls[number], Template<C>>;
|
|
7
|
+
constructor(locales: Ls, _locale: Ls[number], _fallbackLocale: Ls[number], data: Record<Ls[number], Template<C>>);
|
|
8
|
+
get locale(): Ls[number];
|
|
9
|
+
get fallbackLocale(): Ls[number];
|
|
10
|
+
setLocale(locale: Ls[number]): this;
|
|
11
|
+
setFallbackLocale(locale: Ls[number]): this;
|
|
12
|
+
render(this: I18nMessage<Ls, void>): string;
|
|
13
|
+
render(ctx: C): string;
|
|
14
|
+
}
|
|
15
|
+
export type LocalizedMessage<Ls extends readonly string[], C> = I18nMessage<Ls, C>;
|
|
16
|
+
export declare function isI18nMessage(x: unknown): x is I18nMessage<any, any>;
|
package/dist/message.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.I18nMessage = void 0;
|
|
4
|
+
exports.isI18nMessage = isI18nMessage;
|
|
5
|
+
function isTemplateFunction(t) {
|
|
6
|
+
return typeof t === 'function';
|
|
7
|
+
}
|
|
8
|
+
class I18nMessage {
|
|
9
|
+
locales;
|
|
10
|
+
_locale;
|
|
11
|
+
_fallbackLocale;
|
|
12
|
+
data;
|
|
13
|
+
constructor(locales, _locale, _fallbackLocale, data) {
|
|
14
|
+
this.locales = locales;
|
|
15
|
+
this._locale = _locale;
|
|
16
|
+
this._fallbackLocale = _fallbackLocale;
|
|
17
|
+
this.data = data;
|
|
18
|
+
}
|
|
19
|
+
get locale() {
|
|
20
|
+
return this._locale;
|
|
21
|
+
}
|
|
22
|
+
get fallbackLocale() {
|
|
23
|
+
return this._fallbackLocale;
|
|
24
|
+
}
|
|
25
|
+
setLocale(locale) {
|
|
26
|
+
this._locale = locale;
|
|
27
|
+
return this;
|
|
28
|
+
}
|
|
29
|
+
setFallbackLocale(locale) {
|
|
30
|
+
this._fallbackLocale = locale;
|
|
31
|
+
return this;
|
|
32
|
+
}
|
|
33
|
+
render(ctx) {
|
|
34
|
+
const v = this.data[this._locale] ?? this.data[this._fallbackLocale];
|
|
35
|
+
return isTemplateFunction(v) ? v(ctx) : v;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
exports.I18nMessage = I18nMessage;
|
|
39
|
+
function isI18nMessage(x) {
|
|
40
|
+
return x instanceof I18nMessage;
|
|
41
|
+
}
|
package/dist/test.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/test.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const index_1 = require("./index");
|
|
4
|
+
const trs = require("./testData");
|
|
5
|
+
for (const locale of ['ja', 'en']) {
|
|
6
|
+
const { msg, title, nested } = (0, index_1.applyLocaleDeep)(trs, locale);
|
|
7
|
+
console.log(msg.render({ name: '田中', age: 20 }));
|
|
8
|
+
console.log(title.render());
|
|
9
|
+
console.log(nested.hello.render());
|
|
10
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare const title: import("./message").LocalizedMessage<readonly ["ja", "en"], unknown>;
|
|
2
|
+
export declare const msg: import("./message").LocalizedMessage<readonly ["ja", "en"], {
|
|
3
|
+
name: string;
|
|
4
|
+
age: number;
|
|
5
|
+
}>;
|
|
6
|
+
export declare const nested: {
|
|
7
|
+
hello: import("./message").LocalizedMessage<readonly ["ja", "en"], unknown>;
|
|
8
|
+
world: import("./message").LocalizedMessage<readonly ["ja", "en"], unknown>;
|
|
9
|
+
};
|
package/dist/testData.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.nested = exports.msg = exports.title = void 0;
|
|
4
|
+
const index_1 = require("./index");
|
|
5
|
+
const builder = (0, index_1.createMessageBuilder)(['ja', 'en'], 'ja', 'ja');
|
|
6
|
+
exports.title = builder({
|
|
7
|
+
ja: 'タイトルテスト',
|
|
8
|
+
en: 'Title Test'
|
|
9
|
+
});
|
|
10
|
+
exports.msg = builder({
|
|
11
|
+
ja: c => `こんにちは、${c.name}さん、あなたは${c.age}歳です。来年は${c.age + 1}歳です。`,
|
|
12
|
+
en: c => `Hello, ${c.name}. You are ${c.age} years old. Next year you will be ${c.age + 1} years old.`
|
|
13
|
+
});
|
|
14
|
+
exports.nested = {
|
|
15
|
+
hello: builder({
|
|
16
|
+
ja: 'こんにちは',
|
|
17
|
+
en: 'Hello'
|
|
18
|
+
}),
|
|
19
|
+
world: builder({
|
|
20
|
+
ja: '世界',
|
|
21
|
+
en: 'World'
|
|
22
|
+
})
|
|
23
|
+
};
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type Template<C> = string | ((ctx: C) => string);
|
package/dist/types.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "canopy-i18n",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "A tiny, type-safe i18n helper",
|
|
5
|
+
"type": "commonjs",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"require": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"sideEffects": false,
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
18
|
+
"publishConfig": {
|
|
19
|
+
"access": "public"
|
|
20
|
+
},
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"@tsconfig/node20": "^20.1.6",
|
|
23
|
+
"@types/node": "^24.3.3",
|
|
24
|
+
"typescript": "^5.9.2"
|
|
25
|
+
},
|
|
26
|
+
"keywords": [
|
|
27
|
+
"i18n",
|
|
28
|
+
"internationalization",
|
|
29
|
+
"localization",
|
|
30
|
+
"l10n",
|
|
31
|
+
"messages",
|
|
32
|
+
"template"
|
|
33
|
+
],
|
|
34
|
+
"engines": {
|
|
35
|
+
"node": ">=20"
|
|
36
|
+
},
|
|
37
|
+
"license": "MIT",
|
|
38
|
+
"repository": {
|
|
39
|
+
"type": "git",
|
|
40
|
+
"url": "https://github.com/MOhhh-ok/canopy-i18n"
|
|
41
|
+
},
|
|
42
|
+
"scripts": {
|
|
43
|
+
"dev": "tsc --watch",
|
|
44
|
+
"build": "tsc",
|
|
45
|
+
"check": "tsc -p . --noEmit"
|
|
46
|
+
}
|
|
47
|
+
}
|