sheet-i18n 1.6.0 β 1.7.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 +322 -290
- package/package.json +14 -5
package/README.md
CHANGED
|
@@ -1,156 +1,33 @@
|
|
|
1
|
-
# sheet-i18n
|
|
1
|
+
# sheet-i18n [](https://www.npmjs.com/package/sheet-i18n)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
<img src="https://raw.githubusercontent.com/chltjdrhd777/image-hosting/refs/heads/main/sheet-i18n/banner_horizontal_sharp.png" />
|
|
4
|
+
|
|
5
|
+
<br/>
|
|
4
6
|
|
|
5
|
-
[](https://www.npmjs.com/package/sheet-i18n)
|
|
6
7
|
<a href="https://sheet-i18n.vercel.app/en" target="_blank">
|
|
7
8
|
|
|
8
9
|
<!-- <img height="20px" src="https://img.shields.io/badge/π-%20Docs-%23000000"/> -->
|
|
9
10
|
</a>
|
|
10
11
|
|
|
11
|
-
## Installation π οΈ
|
|
12
|
-
|
|
13
|
-
You can install **sheet-i18n** via npm:
|
|
14
|
-
|
|
15
|
-
```bash
|
|
16
|
-
npm install sheet-i18n
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
## Usage π
|
|
20
|
-
|
|
21
|
-
### π Main Package - `sheet-i18n`
|
|
22
|
-
|
|
23
12
|
`sheet-i18n` is a **powerful and flexible library** designed to streamline the process of managing and utilizing translations stored in **Google Sheets** _(planned to support other spreadsheets soon)_.
|
|
24
13
|
|
|
25
14
|
It serves as a bridge between your translation data and your application, offering an **end-to-end solution** for exporting, managing, and integrating translations into your projects.
|
|
26
15
|
|
|
27
16
|
The `sheet-i18n` ecosystem is divided into three main packages:
|
|
28
17
|
|
|
29
|
-
- `sheet-i18n/importer`
|
|
30
18
|
- `sheet-i18n/react`
|
|
31
19
|
- `@sheet-i18n/cli`
|
|
20
|
+
- `sheet-i18n/importer`
|
|
32
21
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
<details open>
|
|
36
|
-
<summary>π Server Export Function - sheet-i18n/importer</summary>
|
|
37
|
-
|
|
38
|
-
#### `sheet-i18n/importer`
|
|
39
|
-
|
|
40
|
-
The **server-side importer** subpackage allows you to interact with Google Sheets and export translations directly into your project. This is primarily used in server-side environments, such as Next.js API routes or other backend frameworks, where you want to fetch and store translations from a Google Spreadsheet to be served to clients or used within your server application.
|
|
41
|
-
|
|
42
|
-
```jsx
|
|
43
|
-
import { googleSheetImporter } from 'sheet-i18n/importer';
|
|
44
|
-
|
|
45
|
-
const importer = await googleSheetImporter({
|
|
46
|
-
credentials: {
|
|
47
|
-
sheetId: 'your-google-sheet-id',
|
|
48
|
-
clientEmail: 'your-client-email',
|
|
49
|
-
privateKey: 'your-private-key',
|
|
50
|
-
},
|
|
51
|
-
defaultLocale: 'default-language-in-sheet-header',
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
await importer.importTranslations();
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
### Configuration βοΈ
|
|
58
|
-
|
|
59
|
-
The configuration object required for using the importer is as follows:
|
|
60
|
-
|
|
61
|
-
#### Required π
|
|
62
|
-
|
|
63
|
-
- **`credentials`**: Google Sheets API credentials:
|
|
64
|
-
- `sheetId`: The ID of your Google Spreadsheet (extracted from the URL).
|
|
65
|
-
- `clientEmail`: The email of the Google Sheets API client.
|
|
66
|
-
- `privateKey`: The private key associated with the client.
|
|
67
|
-
- **`defaultLocale`**: The default locale/language specified in your Google Sheet header.
|
|
68
|
-
|
|
69
|
-
#### Optional π§
|
|
70
|
-
|
|
71
|
-
- **`headerStartRowNumber`**: Specifies the row number where the headers begin (if not at the top).
|
|
72
|
-
- **`ignoredSheets`**: A list of sheets to exclude by title. By default, sheets without the `defaultLocale` in headers will be ignored.
|
|
73
|
-
- **`importPath`**: Path to save exported translations from your sheet. This is the location where the exported translations will be saved. By default, it will use the current working directory (cwd). This option is only used when calling the `importTranslations` method.
|
|
74
|
-
|
|
75
|
-
### Importer Methods π οΈ
|
|
76
|
-
|
|
77
|
-
#### `getTranslations` π
|
|
78
|
-
|
|
79
|
-
- **Description**: This function retrieves the translation data, which is structured by locale keys (such as "ko", "en", etc.). It collects all translations from the specified sheet, replaces any placeholders, and prepares them to be sent to the client in the response body. Each key corresponds to a language, and the value for each key is an object containing the translated text for that locale.
|
|
80
|
-
|
|
81
|
-
- **Type**: Function
|
|
82
|
-
- **Parameters**: None
|
|
83
|
-
- **Returns**: An object where each key is a locale (e.g., "ko", "en"), and the value is the respective translation data for that locale.
|
|
84
|
-
|
|
85
|
-
#### Example:
|
|
86
|
-
|
|
87
|
-
If the headers in your Google Sheets are `["ko", "en", ...]`, the result returned by `getTranslations` will look like this:
|
|
88
|
-
|
|
89
|
-
```ts
|
|
90
|
-
{
|
|
91
|
-
"ko": {
|
|
92
|
-
"greeting": "μλ
νμΈμ",
|
|
93
|
-
"farewell": "μλ
ν κ°μΈμ"
|
|
94
|
-
},
|
|
95
|
-
"en": {
|
|
96
|
-
"greeting": "Hello",
|
|
97
|
-
"farewell": "Goodbye"
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
...
|
|
101
|
-
}
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
In this example:
|
|
105
|
-
|
|
106
|
-
- `"ko"` contains the translations for Korean.
|
|
107
|
-
- `"en"` contains the translations for English.
|
|
108
|
-
Each localeβs object contains key-value pairs for individual translations.
|
|
109
|
-
|
|
110
|
-
#### `importTranslations` π€
|
|
111
|
-
|
|
112
|
-
- **Description**: This asynchronous function is used in a Node.js environment to export translations directly into your project. It is especially useful if your project includes server-side APIs (like Next.js API routes) and you need to update the locale JSON data in your project. It can be invoked to update or create the locale files within your project, ensuring that the translation data is synced with the local environment.
|
|
113
|
-
|
|
114
|
-
- **Type**: Function
|
|
115
|
-
- **Parameters**: None
|
|
116
|
-
- **Returns**: `void`
|
|
117
|
-
|
|
118
|
-
#### Example:
|
|
119
|
-
|
|
120
|
-
If you call the `importTranslations` function, it will update or create JSON files in your project for each locale. The result could look like this:
|
|
22
|
+
### Installation
|
|
121
23
|
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
"greeting": "μλ
νμΈμ",
|
|
126
|
-
"farewell": "μλ
ν κ°μΈμ"
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
// en.json
|
|
130
|
-
{
|
|
131
|
-
"greeting": "Hello",
|
|
132
|
-
"farewell": "Goodbye"
|
|
133
|
-
}
|
|
24
|
+
```shell
|
|
25
|
+
npm install sheet-i18n
|
|
26
|
+
npm install @sheet-i18n/cli -D
|
|
134
27
|
```
|
|
135
28
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
This package provides a streamlined way to export data using sheets API. It is designed to simplify the integration of spreadsheet data into your applications, particularly for translation workflows and internationalization (i18n).
|
|
139
|
-
|
|
140
|
-
[Google Sheets API Documentation](https://developers.google.com/sheets/api)<br>
|
|
141
|
-
[Google Auth Library](https://www.npmjs.com/package/google-auth-library)<br>
|
|
142
|
-
[Google Spreadsheet](https://www.npmjs.com/package/google-spreadsheet)
|
|
143
|
-
|
|
144
|
-
### Exporting Data Format ποΈ
|
|
145
|
-
|
|
146
|
-
The exported translations will be saved in a format that is easy to use for localization purposes. Each translation is stored in its respective locale folder, with a structured format.
|
|
147
|
-
|
|
148
|
-
</details>
|
|
149
|
-
|
|
150
|
-
---
|
|
151
|
-
|
|
152
|
-
<details>
|
|
153
|
-
<summary>βοΈ Frontend Translation Provider - sheet-i18n/react</summary>
|
|
29
|
+
<details open>
|
|
30
|
+
<summary><strong>βοΈ Frontend Translation Provider - sheet-i18n/react</strong></summary>
|
|
154
31
|
|
|
155
32
|
### `@sheet-i18n/react`
|
|
156
33
|
|
|
@@ -160,17 +37,20 @@ This package provides tools to handle translations in React applications using c
|
|
|
160
37
|
|
|
161
38
|
## β¨ Package Introduction
|
|
162
39
|
|
|
163
|
-
- **`I18nStore`**:
|
|
40
|
+
- **`I18nStore`**: _Core Store Creation Class_ for managing translation data.
|
|
164
41
|
- **`createI18nContext`**: _React Context_ to generate providers and hooks for translation.
|
|
165
42
|
- **`IntlProvider`**: _React Translation Provider_ for managing current locale.
|
|
166
43
|
- **`useTranslation`**: _Client Side Translation Hook_ for easy access to translation messages on the client side.
|
|
167
44
|
- **`getTranslation`**: _Static Translation Function_ for easy access to translation messages on Static module files.
|
|
168
45
|
|
|
169
|
-
## π Getting Started
|
|
46
|
+
## π Getting Started(Manually)
|
|
170
47
|
|
|
171
|
-
|
|
48
|
+
> β‘ **Strongly recommended to use the init CLI for setup**
|
|
49
|
+
> π [Please follow the Init CLI section](#initial-setup-anchor)
|
|
50
|
+
>
|
|
51
|
+
> If you don't want to use the CLI, you can follow the `Manual Setup` below.
|
|
172
52
|
|
|
173
|
-
|
|
53
|
+
### step 1. Define Translation Data
|
|
174
54
|
|
|
175
55
|
Prepare locale JSON files:
|
|
176
56
|
|
|
@@ -192,13 +72,13 @@ Prepare locale JSON files:
|
|
|
192
72
|
}
|
|
193
73
|
```
|
|
194
74
|
|
|
195
|
-
|
|
75
|
+
### step 2. Initialize i18nStore
|
|
196
76
|
|
|
197
77
|
this store will be used as a core translations module.
|
|
198
78
|
|
|
199
79
|
```tsx
|
|
200
|
-
import en from './en.json';
|
|
201
80
|
import ko from './ko.json';
|
|
81
|
+
import en from './en.json';
|
|
202
82
|
|
|
203
83
|
import { I18nStore } from '@sheet-i18n/react';
|
|
204
84
|
|
|
@@ -216,11 +96,13 @@ export const i18nStore = new I18nStore({
|
|
|
216
96
|
// dynamicLoaders: {
|
|
217
97
|
// ko: () => import('./ko.json'),
|
|
218
98
|
// en: () => import('./en.json'),
|
|
99
|
+
// jp: () => import('./jp.json'),
|
|
100
|
+
// cn: () => import('./cn.json'),
|
|
219
101
|
// },
|
|
220
102
|
});
|
|
221
103
|
```
|
|
222
104
|
|
|
223
|
-
|
|
105
|
+
### step 3. Create i18n Context
|
|
224
106
|
|
|
225
107
|
```tsx
|
|
226
108
|
import { i18nStore } from './file-path-of-i18nStore-initiated';
|
|
@@ -230,22 +112,24 @@ export const { IntlProvider, useTranslation, getTranslation } =
|
|
|
230
112
|
createI18nContext(i18nStore);
|
|
231
113
|
```
|
|
232
114
|
|
|
233
|
-
|
|
115
|
+
### step 4. Mount Intl Context Provider in your App
|
|
234
116
|
|
|
235
117
|
```tsx
|
|
236
118
|
import React from 'react';
|
|
237
119
|
import { IntlProvider } from './i18nContext';
|
|
238
120
|
|
|
239
121
|
const App = () => {
|
|
122
|
+
const [locale, setLocale] = useState('en');
|
|
123
|
+
|
|
240
124
|
return (
|
|
241
|
-
<IntlProvider>
|
|
125
|
+
<IntlProvider currentLocale={locale}>
|
|
242
126
|
<YourComponent />
|
|
243
127
|
</IntlProvider>
|
|
244
128
|
);
|
|
245
129
|
};
|
|
246
130
|
```
|
|
247
131
|
|
|
248
|
-
|
|
132
|
+
### step 5. Use Translations
|
|
249
133
|
|
|
250
134
|
```tsx
|
|
251
135
|
import React from 'react';
|
|
@@ -269,27 +153,28 @@ const YourComponent = () => {
|
|
|
269
153
|
|
|
270
154
|
### `I18nStore(core)`
|
|
271
155
|
|
|
272
|
-
The `I18nStore` manages
|
|
156
|
+
The `I18nStore` manages translation states, ensuring consistency across locales.
|
|
273
157
|
|
|
274
158
|
#### Parameters:
|
|
275
159
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
- **`dynamicLoaders(optional. choice 2)`**: An object where keys match `supportedLocales`, and values are dynamic translation loader functions.
|
|
286
|
-
<br/>
|
|
287
|
-
<br/>
|
|
288
|
-
- **`typeSafe(optional, default = false)`**: An optional boolean indicating whether to use type-safe translations.
|
|
160
|
+
### π§ I18nStore Configuration Options
|
|
161
|
+
|
|
162
|
+
| Option | Type | Required | Description |
|
|
163
|
+
| ------------------ | ---------------------------------- | -------- | --------------------------------------------------------------------------------------------------------------------- |
|
|
164
|
+
| `supportedLocales` | string[] | β
| List of supported locale codes. |
|
|
165
|
+
| `defaultLocale` | string | β
| Default locale to use when no match is found. Must be included in `supportedLocales`. |
|
|
166
|
+
| localeSet | Record<string, object> | | _(Static Loading Option)_ Preload all translation data for each locale in memory. Keys must match `supportedLocales`. |
|
|
167
|
+
| dynamicLoaders | Record<string, () => Promise<any>> | | _(Recommended for large locale sets)_ Dynamically load translation data on demand, reducing initial bundle size. |
|
|
168
|
+
| typeSafe | boolean | | Enable strict key checking and autocompletion (default: `false`). |
|
|
289
169
|
|
|
290
170
|
> π‘ **typeSafe?** <br/>
|
|
291
171
|
> I18nStore doesn't enforce adherence to your locale JSON definitions by default. This means that you can add translation data even if it isnβt pre-defined in your locale JSON files. However, if you prefer to enforce strict type-safety, you can manually enable the typeSafe option which allows you to notice the auto-completed list in translation data.
|
|
292
172
|
>
|
|
173
|
+
> But to enable correct type checking, `the full localeSet must be defined according to the
|
|
174
|
+
supportedLocales in i18nStore`
|
|
175
|
+
>
|
|
176
|
+
> As a result, type auto-completion relies on having the complete localeSet defined at initialization. This means that using dynamicLoaders to fetch locales conditionally at runtime can be limiting when strict type-safety is enabled.
|
|
177
|
+
>
|
|
293
178
|
> ```tsx
|
|
294
179
|
> // typeSafe: true
|
|
295
180
|
> const YourComponent = () => {
|
|
@@ -304,16 +189,54 @@ The `I18nStore` manages type-safe translation states, ensuring consistency acros
|
|
|
304
189
|
> );
|
|
305
190
|
> };
|
|
306
191
|
> ```
|
|
307
|
-
|
|
192
|
+
>
|
|
308
193
|
> β οΈ Caveats:
|
|
309
194
|
>
|
|
310
195
|
> 1. `supportedLocales` must be an array of locale strings.
|
|
311
196
|
> 2. `defaultLocale` must exist in `supportedLocales`.
|
|
312
|
-
|
|
197
|
+
|
|
198
|
+
### π Static vs Dynamic Loading
|
|
199
|
+
|
|
200
|
+
You can configure how translations are loaded:
|
|
201
|
+
|
|
202
|
+
- **Static (`localeSet`)**
|
|
203
|
+
Load all translations at once. Ideal for small projects or limited locale sets.
|
|
204
|
+
|
|
205
|
+
- **Dynamic (`dynamicLoaders`)** β
_Recommended_
|
|
206
|
+
Load only the locale needed, reducing the bundle size dramatically.
|
|
207
|
+
Useful when supporting many languages or large translation files.
|
|
208
|
+
|
|
209
|
+
```ts
|
|
210
|
+
export const i18nStore = new I18nStore({
|
|
211
|
+
supportedLocales: ['en', 'fr', 'ko'],
|
|
212
|
+
defaultLocale: 'en',
|
|
213
|
+
dynamicLoaders: {
|
|
214
|
+
en: () => import('./en.json'),
|
|
215
|
+
fr: () => import('./fr.json'),
|
|
216
|
+
ko: () => import('./ko.json'),
|
|
217
|
+
},
|
|
218
|
+
});
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
π‘ When both `localeSet` and `dynamicLoaders` are defined, sheet-i18n **automatically merges** both sources β static data loads immediately, while dynamic data supplements on-demand.
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
### π― Why Dynamic Loaders?
|
|
226
|
+
|
|
227
|
+
For projects with many locale datasets, it's often preferable to load translation data on demand rather than all at once. It is better using `dynamicLoaders` to enable this conditional loading strategy.
|
|
228
|
+
|
|
229
|
+
- β
Reduces the initial JavaScript bundle size.
|
|
230
|
+
- β
Keeps only required locales in memory.
|
|
231
|
+
- β
Works well with code-splitting and SSR/CSR.
|
|
232
|
+
- β
Enables **lazy-loading** for translations.
|
|
313
233
|
|
|
314
234
|
#### Example:
|
|
315
235
|
|
|
316
236
|
```tsx
|
|
237
|
+
import ko from './locales/ko.json';
|
|
238
|
+
import en from './locales/en.json';
|
|
239
|
+
|
|
317
240
|
export const i18nStore = new I18nStore({
|
|
318
241
|
supportedLocales: ['ko', 'en'],
|
|
319
242
|
defaultLocale: 'ko',
|
|
@@ -327,6 +250,8 @@ export const i18nStore = new I18nStore({
|
|
|
327
250
|
// dynamicLoaders: {
|
|
328
251
|
// ko: () => import('./ko.json'),
|
|
329
252
|
// en: () => import('./en.json'),
|
|
253
|
+
// jp: () => import('./jp.json'),
|
|
254
|
+
// cn: () => import('./cn.json'),
|
|
330
255
|
// },
|
|
331
256
|
});
|
|
332
257
|
```
|
|
@@ -360,7 +285,7 @@ A Context provider to provide translations to child components.
|
|
|
360
285
|
|
|
361
286
|
- A key representing the current locale to use for translations.
|
|
362
287
|
- If not provided, the user's preferred language is automatically detected based on the browser setting.
|
|
363
|
-
- The fallback is the default locale in **i18nStore** if the detected language is unsupported
|
|
288
|
+
- The fallback is the default locale in **i18nStore** if the detected user-preferred language is not unsupported in the `supportedLocales`.
|
|
364
289
|
|
|
365
290
|
- **`children`**: React children.
|
|
366
291
|
|
|
@@ -496,7 +421,7 @@ It provide two possible supports
|
|
|
496
421
|
|
|
497
422
|
#### **β
Usage Scenarios**
|
|
498
423
|
|
|
499
|
-
#### **Scenario 1: Context where the
|
|
424
|
+
#### **[Scenario 1]: Context where the call expression of `t` function is evaluated at runtime**
|
|
500
425
|
|
|
501
426
|
- For the common example, **t** call expression in a **function module**
|
|
502
427
|
- This behaves the same as `useTranslation`'s `t` function.
|
|
@@ -524,7 +449,7 @@ export default function App() {
|
|
|
524
449
|
|
|
525
450
|
**Result:** The translation is resolved **immediately** during runtime.
|
|
526
451
|
|
|
527
|
-
####
|
|
452
|
+
#### **[Scenario 2]: Context where the translation value is evaluated immediately**
|
|
528
453
|
|
|
529
454
|
- If the module is **imported dynamically in a client-side component**, the evaluation order of `getTranslation` and `t` call expression may not be guaranteed.
|
|
530
455
|
- Since JavaScript **evaluates modules at import time**, it may attempt to access translation values before `IntlProvider` has fully initialized the locale.
|
|
@@ -560,39 +485,15 @@ export default function App() {
|
|
|
560
485
|
}
|
|
561
486
|
```
|
|
562
487
|
|
|
563
|
-
## π Error Handling
|
|
564
|
-
|
|
565
|
-
Custom error messages help identify misconfigurations:
|
|
566
|
-
|
|
567
|
-
1. **Invalid Params**: Ensure `supportedLocales`, `defaultLocale`, and `localeSet` are correctly provided.
|
|
568
|
-
2. **Missing Default Locale**: The `defaultLocale` must exist in `supportedLocales`.
|
|
569
|
-
3. **Invalid LocaleSet**: Ensure the `localeSet` keys match `supportedLocales`.
|
|
570
|
-
|
|
571
|
-
## π Library Versions π’
|
|
572
|
-
|
|
573
|
-
This package supports the following library versions:
|
|
574
|
-
|
|
575
|
-
- **React**: `^19.0.0`
|
|
576
|
-
- **React Intl**: `^7.0.4`
|
|
577
|
-
|
|
578
|
-
## π License
|
|
579
|
-
|
|
580
|
-
This project is licensed under the ISC License.
|
|
581
|
-
|
|
582
|
-
## π€ Author
|
|
583
|
-
|
|
584
|
-
**devAnderson**
|
|
585
|
-
[GitHub](https://github.com/chltjdrhd777)
|
|
586
|
-
[chltjdrhd777@gmail.com](mailto:chltjdrhd777@gmail.com)
|
|
587
|
-
|
|
588
488
|
</details>
|
|
589
489
|
|
|
590
490
|
---
|
|
591
491
|
|
|
592
|
-
<details>
|
|
593
|
-
<summary
|
|
492
|
+
<details open>
|
|
493
|
+
<summary><strong>
|
|
494
|
+
π§ CLI for easy bidirectional syncing - @sheet-i18n/cli</strong></summary>
|
|
594
495
|
|
|
595
|
-
|
|
496
|
+
### `@sheet-i18n/cli`
|
|
596
497
|
|
|
597
498
|
A CLI tool for efficient translation management using Google Sheets, with a focus on developer experience (DX).
|
|
598
499
|
|
|
@@ -605,7 +506,7 @@ A CLI tool for efficient translation management using Google Sheets, with a focu
|
|
|
605
506
|
|
|
606
507
|
## Core Concepts π
|
|
607
508
|
|
|
608
|
-
### π
|
|
509
|
+
### π General Translation Workflow
|
|
609
510
|
|
|
610
511
|
The traditional process of managing translations with Google Spreadsheets often includes these steps:
|
|
611
512
|
|
|
@@ -631,78 +532,80 @@ This CLI streamlines the process by shifting the focus to developers:
|
|
|
631
532
|
|
|
632
533
|
With this approach, unnecessary back-and-forth is eliminated, and translations align seamlessly with code.
|
|
633
534
|
|
|
634
|
-
##
|
|
535
|
+
## π Initial Setup with CLI
|
|
635
536
|
|
|
636
|
-
|
|
537
|
+
<a id="initial-setup-anchor"></a>
|
|
637
538
|
|
|
638
|
-
|
|
539
|
+
`@sheet-i18n/cli` provides a fully automated setup for React applications.
|
|
540
|
+
Once installed, you can bootstrap the required i18n context, store, and folder structure by simply running:
|
|
639
541
|
|
|
640
|
-
|
|
542
|
+
```bash
|
|
543
|
+
npx sheet-i18n init
|
|
544
|
+
```
|
|
641
545
|
|
|
642
|
-
|
|
643
|
-
import en from './en.json';
|
|
644
|
-
import ko from './ko.json';
|
|
546
|
+
This will automatically generate:
|
|
645
547
|
|
|
646
|
-
|
|
548
|
+
- A preconfigured `i18nStore` using `@sheet-i18n/react`
|
|
549
|
+
- A ready-to-use `i18nContext.ts` that exports `IntlProvider`, `useTranslation`, and `getTranslation`
|
|
550
|
+
- Example locale JSON files (e.g., `en.json`, `ko.json`)
|
|
551
|
+
- The `sheet.config.json` file for managing your CLI behavior and Google Sheets credentials
|
|
647
552
|
|
|
648
|
-
|
|
649
|
-
supportedLocales: ['ko', 'en'],
|
|
650
|
-
defaultLocale: 'ko',
|
|
651
|
-
localeSet: {
|
|
652
|
-
ko,
|
|
653
|
-
en,
|
|
654
|
-
},
|
|
655
|
-
typeSafe: false, // optional (default: true)
|
|
656
|
-
});
|
|
657
|
-
```
|
|
553
|
+
> π‘ All files will be created in the recommended structure (e.g. `src/i18n`, `src/locales`), and safely skipped if they already exist.
|
|
658
554
|
|
|
659
|
-
|
|
660
|
-
> I18nStore doesn't enforce adherence to your locale JSON definitions by default. This means that you can add translation data even if it isnβt pre-defined in your locale JSON files. However, if you prefer to enforce strict type-safety, you can manually enable the typeSafe option which allows you to notice the auto-completed list in translation data.
|
|
661
|
-
>
|
|
662
|
-
> ```tsx
|
|
663
|
-
> // typeSafe: true
|
|
664
|
-
> const YourComponent = () => {
|
|
665
|
-
> // "useTranslation" shows the autocompletion suggestions
|
|
666
|
-
> const { t } = useTranslation('header');
|
|
667
|
-
>
|
|
668
|
-
> return (
|
|
669
|
-
> <div>
|
|
670
|
-
> {/* "t" function shows the autocompletion suggestions */}
|
|
671
|
-
> <button>{t('login')}</button>
|
|
672
|
-
> </div>
|
|
673
|
-
> );
|
|
674
|
-
> };
|
|
675
|
-
> ```
|
|
555
|
+
---
|
|
676
556
|
|
|
677
|
-
|
|
557
|
+
### β
What You No Longer Have to Do Manually
|
|
678
558
|
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
559
|
+
- You donβt need to manually initiate `I18nStore` or set up the React context.
|
|
560
|
+
- You donβt need to manually prepare locale JSON templates.
|
|
561
|
+
- You donβt need to manually configure `sheet.config.json`.
|
|
682
562
|
|
|
683
|
-
|
|
563
|
+
Just run the init command and youβre ready to use `useTranslation()` in your components.
|
|
564
|
+
|
|
565
|
+
---
|
|
566
|
+
|
|
567
|
+
### ποΈ Example Output:
|
|
568
|
+
|
|
569
|
+
```bash
|
|
570
|
+
π¦ your-project/
|
|
571
|
+
βββ π .gitignore # Automatically appends 'sheet.config.json' to ignore list
|
|
572
|
+
βββ π sheet.config.json # CLI configuration file (contains Google Sheet credentials & options)
|
|
573
|
+
βββ π src/
|
|
574
|
+
βββ π i18n/
|
|
575
|
+
βββ π i18nContext.tsx # React context for IntlProvider, useTranslation, and getTranslation
|
|
576
|
+
βββ π i18nStore.ts # Initializes I18nStore with supported locales and translation data
|
|
577
|
+
βββ π en.json # Placeholder for English translation strings
|
|
578
|
+
βββ π ko.json # Placeholder for Korean translation strings
|
|
684
579
|
```
|
|
685
580
|
|
|
686
|
-
|
|
581
|
+
β
The CLI automatically creates this structure after running `npx sheet-i18n init`.
|
|
582
|
+
π‘οΈ If `sheet.config.json` or `src/i18n` already exist, the CLI will skip the creation of these files.
|
|
583
|
+
|
|
584
|
+
after running `npx sheet-i18n init`, you can mount the IntlProvider in your app.
|
|
585
|
+
|
|
586
|
+
#### Mount Intl Context Provider in your App
|
|
687
587
|
|
|
688
588
|
```tsx
|
|
689
589
|
import React from 'react';
|
|
690
|
-
import
|
|
590
|
+
import I18nContextProvider from './i18n/i18nContext';
|
|
691
591
|
|
|
692
592
|
const App = () => {
|
|
593
|
+
const [locale, setLocale] = useState('en');
|
|
594
|
+
|
|
693
595
|
return (
|
|
694
|
-
<
|
|
596
|
+
<I18nContextProvider currentLocale={locale}>
|
|
695
597
|
<YourComponent />
|
|
696
|
-
</
|
|
598
|
+
</I18nContextProvider>
|
|
697
599
|
);
|
|
698
600
|
};
|
|
699
601
|
```
|
|
700
602
|
|
|
701
|
-
####
|
|
603
|
+
#### Use Translations
|
|
702
604
|
|
|
703
605
|
```tsx
|
|
606
|
+
// YourComponent.tsx
|
|
704
607
|
import React from 'react';
|
|
705
|
-
import { useTranslation } from './i18nContext';
|
|
608
|
+
import { useTranslation } from './i18n/i18nContext';
|
|
706
609
|
|
|
707
610
|
const YourComponent = () => {
|
|
708
611
|
const { t } = useTranslation('header');
|
|
@@ -716,31 +619,11 @@ const YourComponent = () => {
|
|
|
716
619
|
};
|
|
717
620
|
```
|
|
718
621
|
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
## Base workflow
|
|
722
|
-
|
|
723
|
-
Install the CLI tool globally or as a dev dependency:
|
|
622
|
+
### That's it! <br/>
|
|
724
623
|
|
|
725
|
-
|
|
726
|
-
npm install -g @sheet-i18n/cli
|
|
727
|
-
```
|
|
728
|
-
|
|
729
|
-
or
|
|
730
|
-
|
|
731
|
-
```shell
|
|
732
|
-
npm install --save-dev @sheet-i18n/cli
|
|
733
|
-
```
|
|
734
|
-
|
|
735
|
-
Initialize the CLI in your project:
|
|
736
|
-
|
|
737
|
-
```shell
|
|
738
|
-
npx sheet-i18n init
|
|
739
|
-
```
|
|
624
|
+
your translations are now ready to use in your application.
|
|
740
625
|
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
### Configuration βοΈ
|
|
626
|
+
### βοΈ sheet.config.json
|
|
744
627
|
|
|
745
628
|
The CLI requires a `sheet.config.json` file in the root of your project. Run `sheet-i18n init` to generate this file automatically.
|
|
746
629
|
|
|
@@ -760,26 +643,38 @@ Example `sheet.config.json`:
|
|
|
760
643
|
"defaultLocale": "en",
|
|
761
644
|
"supportedLocales": ["en", "fr", "es"],
|
|
762
645
|
"ignoredSheets": ["BASE"],
|
|
763
|
-
"importPath": "./src/locales"
|
|
646
|
+
"importPath": "./src/locales",
|
|
647
|
+
"autoAppendFilePathColumn": {
|
|
648
|
+
"enabled": true,
|
|
649
|
+
"columnName": "__filePath",
|
|
650
|
+
"fullFilePath": false
|
|
651
|
+
}
|
|
764
652
|
}
|
|
765
653
|
}
|
|
766
654
|
```
|
|
767
655
|
|
|
768
|
-
|
|
656
|
+
### 1. File change monitoring configuration
|
|
657
|
+
|
|
658
|
+
| Option | Type | Required | Default | Description |
|
|
659
|
+
| ------------------ | -------- | -------- | -------------------------- | ------------------------------------------------------------------------------ |
|
|
660
|
+
| `watchEntry` | string | | "src" | Entry path to monitor file changes, relative to the current working directory. |
|
|
661
|
+
| `detectExtensions` | string[] | | ["jsx", "js", "tsx", "ts"] | List of file extensions to watch. |
|
|
769
662
|
|
|
770
|
-
|
|
771
|
-
- `detectExtensions` (optional): File extensions to monitor (default: `jsx`, `js`, `tsx`, `ts`).
|
|
663
|
+
### 2. Register command configuration
|
|
772
664
|
|
|
773
|
-
|
|
665
|
+
### π `googleSheetConfig` Options
|
|
774
666
|
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
667
|
+
| Option | Type | Required | Default | Description |
|
|
668
|
+
| -------------------------- | -------- | -------- | ---------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
669
|
+
| `credentials.sheetId` | string | β
| | The same ID as `spreadsheetId` (for API auth). |
|
|
670
|
+
| `credentials.clientEmail` | string | β
| | Client email from your Google Service Account credentials. |
|
|
671
|
+
| `credentials.privateKey` | string | β
| | Private key from your Google Service Account credentials. |
|
|
672
|
+
| `defaultLocale` | string | β
| | The default language/locale used in the sheet's header row. |
|
|
673
|
+
| `supportedLocales` | string[] | β
| | Array of all supported locale codes (e.g., `["en", "ko"]`). |
|
|
674
|
+
| `headerStartRowNumber` | number | | 1 | Row number where sheet headers begin. |
|
|
675
|
+
| `ignoredSheets` | string[] | | | Titles of sheets to ignore during register/import (e.g., `["BASE"]`). |
|
|
676
|
+
| `importPath` | string | | current working directory | Directory path to export translation JSON files. |
|
|
677
|
+
| `autoAppendFilePathColumn` | object | | <strong>enabled: </strong>true<br/><strong>columnName: </strong>"\_\_filePath"<br/><strong>fullFilePath:</strong>false | Configuration for appending reference file path to each translation row. This indicates where the translation key is located in your source code.<br><br>- `enabled`: Whether to append the file path column<br>- `columnName`: Column name to use for file path<br>- `fullFilePath`: Show full path or mask intermediate folders (e.g., `"*******/folder1/folder2/file.ts"`) |
|
|
783
678
|
|
|
784
679
|
## Commands
|
|
785
680
|
|
|
@@ -829,13 +724,18 @@ function Component (){
|
|
|
829
724
|
}
|
|
830
725
|
```
|
|
831
726
|
|
|
832
|
-
The
|
|
727
|
+
The _watched result_ is
|
|
833
728
|
|
|
834
729
|
```shell
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
730
|
+
Detected Translations:
|
|
731
|
+
|
|
732
|
+
π [Sheet Title]: environment
|
|
733
|
+
- over
|
|
734
|
+
- under
|
|
735
|
+
|
|
736
|
+
# You can proceed using the shortcuts below:
|
|
737
|
+
- Press <Shift + R> to register the detected changes.
|
|
738
|
+
- Press <Ctrl + C> to cancel the watch command.
|
|
839
739
|
```
|
|
840
740
|
|
|
841
741
|
</br>
|
|
@@ -843,7 +743,7 @@ The _watch result_ is
|
|
|
843
743
|
### π€ register
|
|
844
744
|
|
|
845
745
|
```shell
|
|
846
|
-
sheet-i18n register [options]
|
|
746
|
+
npx sheet-i18n register [options]
|
|
847
747
|
```
|
|
848
748
|
|
|
849
749
|
Registers translation data to Google Sheets.
|
|
@@ -860,15 +760,18 @@ Registers translation data to Google Sheets.
|
|
|
860
760
|
|
|
861
761
|
- `-s, --scope <scope>`
|
|
862
762
|
Define the scope of the registration process:
|
|
763
|
+
|
|
863
764
|
- **`diff`**: Only scans translation keys that have been modified in the Git history (based on `git diff`).
|
|
864
|
-
- **`total`**: Scans the entire directory for all translation keys and updates the spreadsheet, regardless of Git changes.
|
|
865
|
-
|
|
765
|
+
- **`total`**: Scans the entire directory for all translation keys and updates the spreadsheet, regardless of Git changes.
|
|
766
|
+
- **`select`**: User selection mode which allows you to choose the sheets to register.
|
|
767
|
+
|
|
768
|
+
- **Default**: `diff`
|
|
866
769
|
|
|
867
770
|
---
|
|
868
771
|
|
|
869
|
-
#### Detailed description of the `scope` option:
|
|
772
|
+
#### π Detailed description of the `scope` option:
|
|
870
773
|
|
|
871
|
-
|
|
774
|
+
#### Scope: `diff`
|
|
872
775
|
|
|
873
776
|
- The CLI identifies changes in translation keys by comparing the current state of the codebase with the latest Git commit.
|
|
874
777
|
- It only processes translation keys added, removed, or modified since the last commit.
|
|
@@ -881,9 +784,7 @@ Registers translation data to Google Sheets.
|
|
|
881
784
|
npx sheet-i18n register
|
|
882
785
|
```
|
|
883
786
|
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
##### Scope: `total`
|
|
787
|
+
#### Scope: `total`
|
|
887
788
|
|
|
888
789
|
- The CLI scans the entire specified directory for all translation keys from the directory path you provide.
|
|
889
790
|
- This is useful for full synchronization, ensuring all keys are registered in the spreadsheet.
|
|
@@ -892,7 +793,23 @@ npx sheet-i18n register
|
|
|
892
793
|
##### Example:
|
|
893
794
|
|
|
894
795
|
```shell
|
|
895
|
-
sheet-i18n register --scope total
|
|
796
|
+
npx sheet-i18n register --scope total
|
|
797
|
+
```
|
|
798
|
+
|
|
799
|
+
#### Scope: `select`
|
|
800
|
+
|
|
801
|
+
- The CLI prompts you to manually select which sheets you want to update.
|
|
802
|
+
|
|
803
|
+
- Once the selection is made, only the chosen sheets will have their translation data updated in the Google Spreadsheet.
|
|
804
|
+
|
|
805
|
+
- This mode is especially useful for partial updates, allowing you to skip scanning the entire directory and focus on specific sheets.
|
|
806
|
+
|
|
807
|
+
- Itβs also helpful in cases where youβve committed changes without registering translation data during development β instead of syncing all translations, you can update only the relevant sheets as needed.
|
|
808
|
+
|
|
809
|
+
##### Example:
|
|
810
|
+
|
|
811
|
+
```shell
|
|
812
|
+
npx sheet-i18n register --scope select
|
|
896
813
|
```
|
|
897
814
|
|
|
898
815
|
</br>
|
|
@@ -921,8 +838,125 @@ The configuration of export command is based on **`sheet.config.json`** on your
|
|
|
921
838
|
}
|
|
922
839
|
```
|
|
923
840
|
|
|
841
|
+
</details>
|
|
842
|
+
|
|
924
843
|
---
|
|
925
844
|
|
|
845
|
+
<details open>
|
|
846
|
+
<summary><strong>π Server Export Function - sheet-i18n/importer</strong></summary>
|
|
847
|
+
|
|
848
|
+
### `sheet-i18n/importer`
|
|
849
|
+
|
|
850
|
+
The **server-side importer** subpackage allows you to interact with Google Sheets and export translations directly into your project. This is primarily used in server-side environments, such as Next.js API routes or other backend frameworks, where you want to fetch and store translations from a Google Spreadsheet to be served to clients or used within your server application.
|
|
851
|
+
|
|
852
|
+
```jsx
|
|
853
|
+
import { googleSheetImporter } from 'sheet-i18n/importer';
|
|
854
|
+
|
|
855
|
+
const importer = await googleSheetImporter({
|
|
856
|
+
credentials: {
|
|
857
|
+
sheetId: 'your-google-sheet-id',
|
|
858
|
+
clientEmail: 'your-client-email',
|
|
859
|
+
privateKey: 'your-private-key',
|
|
860
|
+
},
|
|
861
|
+
defaultLocale: 'default-language-in-sheet-header',
|
|
862
|
+
});
|
|
863
|
+
|
|
864
|
+
await importer.importTranslations();
|
|
865
|
+
```
|
|
866
|
+
|
|
867
|
+
### Configuration βοΈ
|
|
868
|
+
|
|
869
|
+
The configuration object required for using the importer is as follows:
|
|
870
|
+
|
|
871
|
+
#### Required π
|
|
872
|
+
|
|
873
|
+
- **`credentials`**: Google Sheets API credentials:
|
|
874
|
+
- `sheetId`: The ID of your Google Spreadsheet (extracted from the URL).
|
|
875
|
+
- `clientEmail`: The email of the Google Sheets API client.
|
|
876
|
+
- `privateKey`: The private key associated with the client.
|
|
877
|
+
- **`defaultLocale`**: The default locale/language specified in your Google Sheet header.
|
|
878
|
+
|
|
879
|
+
#### Optional π§
|
|
880
|
+
|
|
881
|
+
- **`headerStartRowNumber`**: Specifies the row number where the headers begin (if not at the top).
|
|
882
|
+
- **`ignoredSheets`**: A list of sheets to exclude by title. By default, sheets without the `defaultLocale` in headers will be ignored.
|
|
883
|
+
- **`importPath`**: Path to save exported translations from your sheet. This is the location where the exported translations will be saved. By default, it will use the current working directory (cwd). This option is only used when calling the `importTranslations` method.
|
|
884
|
+
|
|
885
|
+
### Importer Methods π οΈ
|
|
886
|
+
|
|
887
|
+
#### `getTranslations` π
|
|
888
|
+
|
|
889
|
+
- **Description**: This function retrieves the translation data, which is structured by locale keys (such as "ko", "en", etc.). It collects all translations from the specified sheet, replaces any placeholders, and prepares them to be sent to the client in the response body. Each key corresponds to a language, and the value for each key is an object containing the translated text for that locale.
|
|
890
|
+
|
|
891
|
+
- **Type**: Function
|
|
892
|
+
- **Parameters**: None
|
|
893
|
+
- **Returns**: An object where each key is a locale (e.g., "ko", "en"), and the value is the respective translation data for that locale.
|
|
894
|
+
|
|
895
|
+
#### Example:
|
|
896
|
+
|
|
897
|
+
If the headers in your Google Sheets are `["ko", "en", ...]`, the result returned by `getTranslations` will look like this:
|
|
898
|
+
|
|
899
|
+
```ts
|
|
900
|
+
{
|
|
901
|
+
"ko": {
|
|
902
|
+
"greeting": "μλ
νμΈμ",
|
|
903
|
+
"farewell": "μλ
ν κ°μΈμ"
|
|
904
|
+
},
|
|
905
|
+
"en": {
|
|
906
|
+
"greeting": "Hello",
|
|
907
|
+
"farewell": "Goodbye"
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
...
|
|
911
|
+
}
|
|
912
|
+
```
|
|
913
|
+
|
|
914
|
+
In this example:
|
|
915
|
+
|
|
916
|
+
- `"ko"` contains the translations for Korean.
|
|
917
|
+
- `"en"` contains the translations for English.
|
|
918
|
+
Each localeβs object contains key-value pairs for individual translations.
|
|
919
|
+
|
|
920
|
+
#### `importTranslations` π€
|
|
921
|
+
|
|
922
|
+
- **Description**: This asynchronous function is used in a Node.js environment to export translations directly into your project. It is especially useful if your project includes server-side APIs (like Next.js API routes) and you need to update the locale JSON data in your project. It can be invoked to update or create the locale files within your project, ensuring that the translation data is synced with the local environment.
|
|
923
|
+
|
|
924
|
+
- **Type**: Function
|
|
925
|
+
- **Parameters**: None
|
|
926
|
+
- **Returns**: `void`
|
|
927
|
+
|
|
928
|
+
#### Example:
|
|
929
|
+
|
|
930
|
+
If you call the `importTranslations` function, it will update or create JSON files in your project for each locale. The result could look like this:
|
|
931
|
+
|
|
932
|
+
```ts
|
|
933
|
+
// ko.json
|
|
934
|
+
{
|
|
935
|
+
"greeting": "μλ
νμΈμ",
|
|
936
|
+
"farewell": "μλ
ν κ°μΈμ"
|
|
937
|
+
}
|
|
938
|
+
|
|
939
|
+
// en.json
|
|
940
|
+
{
|
|
941
|
+
"greeting": "Hello",
|
|
942
|
+
"farewell": "Goodbye"
|
|
943
|
+
}
|
|
944
|
+
```
|
|
945
|
+
|
|
946
|
+
### API Documentation π
|
|
947
|
+
|
|
948
|
+
This package provides a streamlined way to export data using sheets API. It is designed to simplify the integration of spreadsheet data into your applications, particularly for translation workflows and internationalization (i18n).
|
|
949
|
+
|
|
950
|
+
[Google Sheets API Documentation](https://developers.google.com/sheets/api)<br>
|
|
951
|
+
[Google Auth Library](https://www.npmjs.com/package/google-auth-library)<br>
|
|
952
|
+
[Google Spreadsheet](https://www.npmjs.com/package/google-spreadsheet)
|
|
953
|
+
|
|
954
|
+
### Exported Data Format ποΈ
|
|
955
|
+
|
|
956
|
+
The exported translations will be saved in a format that is easy to use for localization purposes. Each translation is stored in its respective locale folder, with a structured format.
|
|
957
|
+
|
|
958
|
+
</details>
|
|
959
|
+
|
|
926
960
|
## License π
|
|
927
961
|
|
|
928
962
|
This project is licensed under the ISC License. See the LICENSE file for details.
|
|
@@ -930,5 +964,3 @@ This project is licensed under the ISC License. See the LICENSE file for details
|
|
|
930
964
|
## Author βοΈ
|
|
931
965
|
|
|
932
966
|
Created by [devAnderson](https://github.com/chltjdrhd777).
|
|
933
|
-
|
|
934
|
-
</details>
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sheet-i18n",
|
|
3
|
-
"
|
|
3
|
+
"description": "All-in-one i18n toolchain: seamlessly integrate Google Sheets, CLI, and react-i18n for easy translation workflows.",
|
|
4
|
+
"version": "1.7.1",
|
|
4
5
|
"repository": {
|
|
5
6
|
"type": "git",
|
|
6
7
|
"url": "https://github.com/chltjdrhd777/sheet-i18n"
|
|
@@ -27,7 +28,14 @@
|
|
|
27
28
|
"sheet-i18n",
|
|
28
29
|
"spreadsheet",
|
|
29
30
|
"i18n",
|
|
30
|
-
"translation"
|
|
31
|
+
"translation",
|
|
32
|
+
"internationalization",
|
|
33
|
+
"localization",
|
|
34
|
+
"i18n workflow",
|
|
35
|
+
"spreadsheet i18n",
|
|
36
|
+
"i18n management",
|
|
37
|
+
"translation management",
|
|
38
|
+
"google spreadsheet"
|
|
31
39
|
],
|
|
32
40
|
"author": {
|
|
33
41
|
"name": "devAnderson",
|
|
@@ -35,14 +43,15 @@
|
|
|
35
43
|
"url": "https://github.com/chltjdrhd777"
|
|
36
44
|
},
|
|
37
45
|
"license": "ISC",
|
|
46
|
+
"homepage": "https://github.com/chltjdrhd777/sheet-i18n",
|
|
38
47
|
"dependencies": {
|
|
39
|
-
"@sheet-i18n/react": "1.
|
|
40
|
-
"@sheet-i18n/importer": "1.
|
|
48
|
+
"@sheet-i18n/react": "1.4.1",
|
|
49
|
+
"@sheet-i18n/importer": "1.7.1"
|
|
41
50
|
},
|
|
42
51
|
"devDependencies": {
|
|
43
52
|
"tsup": "^6.0.0",
|
|
44
53
|
"typescript": "^5.0.0",
|
|
45
|
-
"@sheet-i18n/typescript-config": "1.
|
|
54
|
+
"@sheet-i18n/typescript-config": "1.7.1"
|
|
46
55
|
},
|
|
47
56
|
"scripts": {
|
|
48
57
|
"build": "tsup",
|