@scopeact/autoi18n 1.1.2 → 1.2.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 +117 -256
- package/dist/chunk-36HQJSGI.cjs +40 -0
- package/dist/chunk-36HQJSGI.cjs.map +1 -0
- package/dist/chunk-NYRK5OWZ.js +40 -0
- package/dist/chunk-NYRK5OWZ.js.map +1 -0
- package/dist/chunk-RLNUAAKC.js +296 -0
- package/dist/chunk-RLNUAAKC.js.map +1 -0
- package/dist/chunk-TJT6ONON.cjs +41 -0
- package/dist/chunk-TJT6ONON.cjs.map +1 -0
- package/dist/chunk-TWTG4RTI.cjs +296 -0
- package/dist/chunk-TWTG4RTI.cjs.map +1 -0
- package/dist/chunk-VBBY4GSW.js +41 -0
- package/dist/chunk-VBBY4GSW.js.map +1 -0
- package/dist/cli.cjs +18 -0
- package/dist/cli.cjs.map +1 -0
- package/dist/cli.d.cts +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +18 -0
- package/dist/cli.js.map +1 -0
- package/dist/client.cjs +10 -0
- package/dist/client.cjs.map +1 -0
- package/dist/client.d.cts +17 -0
- package/dist/client.d.ts +17 -0
- package/dist/client.js +10 -0
- package/dist/client.js.map +1 -0
- package/dist/core/index.cjs +9 -0
- package/dist/core/index.cjs.map +1 -0
- package/dist/core/index.d.cts +4 -0
- package/dist/core/index.d.ts +4 -0
- package/dist/core/index.js +9 -0
- package/dist/core/index.js.map +1 -0
- package/dist/index.cjs +21 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +5 -0
- package/dist/index.d.ts +5 -3
- package/dist/index.js +20 -18
- package/dist/index.js.map +1 -1
- package/dist/server.cjs +9 -0
- package/dist/server.cjs.map +1 -0
- package/dist/server.d.cts +10 -0
- package/dist/server.d.ts +10 -0
- package/dist/server.js +9 -0
- package/dist/server.js.map +1 -0
- package/package.json +79 -26
- package/schema.json +51 -0
- package/dist/index.d.ts.map +0 -1
package/README.md
CHANGED
|
@@ -1,256 +1,117 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
[![
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
}
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
---
|
|
122
|
-
|
|
123
|
-
## Configuration
|
|
124
|
-
|
|
125
|
-
Example `auto-i18n.config.json`:
|
|
126
|
-
|
|
127
|
-
```json
|
|
128
|
-
{
|
|
129
|
-
"sourceLang": "pt",
|
|
130
|
-
"targetLangs": [ "en", "es", "de" ],
|
|
131
|
-
"autoInject": true,
|
|
132
|
-
"i18nLibrary": "react-i18next",
|
|
133
|
-
"provider": "ollama",
|
|
134
|
-
"localesDir": "./locales",
|
|
135
|
-
"model": "gemma3-translator",
|
|
136
|
-
"files": [ "**/*.tsx" ]
|
|
137
|
-
}
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
### Options
|
|
141
|
-
|
|
142
|
-
#### `autoInject`
|
|
143
|
-
|
|
144
|
-
```json
|
|
145
|
-
{
|
|
146
|
-
"autoInject": true
|
|
147
|
-
}
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
Automatically injects the required i18n import at the top of the file **if it does not already exist**.
|
|
151
|
-
|
|
152
|
-
This avoids manual setup and keeps the migration fully automated.
|
|
153
|
-
|
|
154
|
-
---
|
|
155
|
-
|
|
156
|
-
#### `i18nLibrary`
|
|
157
|
-
|
|
158
|
-
```json
|
|
159
|
-
{
|
|
160
|
-
"i18nLibrary": "react-i18next"
|
|
161
|
-
}
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
Defines which i18n library should be used when injecting imports and hooks.
|
|
165
|
-
|
|
166
|
-
Supported values:
|
|
167
|
-
|
|
168
|
-
* `react-i18next`
|
|
169
|
-
* `next-i18n`
|
|
170
|
-
|
|
171
|
-
This affects:
|
|
172
|
-
|
|
173
|
-
* import statements
|
|
174
|
-
* generated code structure
|
|
175
|
-
|
|
176
|
-
---
|
|
177
|
-
|
|
178
|
-
## Why keys are AI-generated (no dry-run)
|
|
179
|
-
|
|
180
|
-
Translation key naming is a **semantic problem**, not a mechanical one.
|
|
181
|
-
|
|
182
|
-
For example:
|
|
183
|
-
|
|
184
|
-
* Is `"Hello world"` a title, a CTA, or a heading?
|
|
185
|
-
* Does it belong to `home`, `layout`, or `marketing`?
|
|
186
|
-
|
|
187
|
-
These decisions cannot be inferred deterministically.
|
|
188
|
-
|
|
189
|
-
**auto-i18n intentionally requires an LLM to:**
|
|
190
|
-
|
|
191
|
-
* infer intent
|
|
192
|
-
* generate meaningful keys
|
|
193
|
-
* avoid arbitrary conventions
|
|
194
|
-
|
|
195
|
-
Because of this, a traditional dry-run would produce **misleading results** and is intentionally not supported.
|
|
196
|
-
|
|
197
|
-
This trade-off is explicit.
|
|
198
|
-
|
|
199
|
-
---
|
|
200
|
-
|
|
201
|
-
## Why AST instead of regex
|
|
202
|
-
|
|
203
|
-
Regex does not understand JSX or TypeScript.
|
|
204
|
-
|
|
205
|
-
AST parsing:
|
|
206
|
-
|
|
207
|
-
* Preserves syntax structure
|
|
208
|
-
* Avoids accidental replacements
|
|
209
|
-
* Handles real-world React code
|
|
210
|
-
* Produces predictable transformations
|
|
211
|
-
|
|
212
|
-
This tool is designed for **production codebases**, not demos.
|
|
213
|
-
|
|
214
|
-
---
|
|
215
|
-
|
|
216
|
-
## Limitations
|
|
217
|
-
|
|
218
|
-
This tool does **not** handle:
|
|
219
|
-
|
|
220
|
-
* Dynamic strings (`"Hello " + name`)
|
|
221
|
-
* Template literals with expressions
|
|
222
|
-
* Runtime-generated text
|
|
223
|
-
* Context-dependent translations
|
|
224
|
-
|
|
225
|
-
It is meant to **bootstrap i18n**, not replace human review.
|
|
226
|
-
|
|
227
|
-
---
|
|
228
|
-
|
|
229
|
-
## When you should NOT use this
|
|
230
|
-
|
|
231
|
-
* Your project already has a mature i18n setup
|
|
232
|
-
* Translations depend heavily on runtime logic
|
|
233
|
-
* You expect zero review after migration
|
|
234
|
-
|
|
235
|
-
---
|
|
236
|
-
|
|
237
|
-
## Design philosophy
|
|
238
|
-
|
|
239
|
-
* Explicit over clever
|
|
240
|
-
* Predictable over magical
|
|
241
|
-
* Narrow scope over feature bloat
|
|
242
|
-
|
|
243
|
-
This tool solves **one specific problem**, deliberately.
|
|
244
|
-
|
|
245
|
-
---
|
|
246
|
-
|
|
247
|
-
## License
|
|
248
|
-
|
|
249
|
-
Distributed under MIT license. See [LICENSE](LICENSE) for more details.
|
|
250
|
-
|
|
251
|
-
---
|
|
252
|
-
|
|
253
|
-
## 🇧🇷 Nota
|
|
254
|
-
|
|
255
|
-
README principal em inglês por usabilidade global.
|
|
256
|
-
Português aqui só pra lembrar que esse projeto nasceu no Brasil.
|
|
1
|
+
|
|
2
|
+
# @scopeact/autoi18n
|
|
3
|
+
|
|
4
|
+
[](https://www.npmjs.com/package/@scopeact/autoi18n)
|
|
5
|
+
[](https://github.com/felipevetter/auto-i18n/actions)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
[](https://github.com/felipevetter/auto-i18n/pulls)
|
|
8
|
+
|
|
9
|
+
> The only i18n tool that handles both **Extraction** (via AST + AI) and **Runtime** (Zero-Config).
|
|
10
|
+
|
|
11
|
+
**autoi18n** is a dual-purpose tool designed to take a hardcoded React/Next.js project to full internationalization in minutes, not hours.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## ⚡ The Core: CLI Migration
|
|
16
|
+
|
|
17
|
+
The CLI scans your `TSX` files, extracts hardcoded strings using **Abstract Syntax Tree (AST)**, and uses **AI to generate semantic keys**.
|
|
18
|
+
|
|
19
|
+
- **No Regex:** Safe code transformations that won't break your syntax.
|
|
20
|
+
- **AI-Powered:** Keys like `welcome_title` instead of `text_1`.
|
|
21
|
+
- **Auto-Inject:** Automatically adds imports to your files.
|
|
22
|
+
|
|
23
|
+
### Quick Start
|
|
24
|
+
```bash
|
|
25
|
+
npx @scopeact/autoi18n init
|
|
26
|
+
npx @scopeact/autoi18n run
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## 🚀 The Feature: Zero-Config Runtime
|
|
32
|
+
|
|
33
|
+
We noticed that even after extracting strings, configuring i18n in **Next.js (App Router)** is a nightmare (Middleware, `[locale]` folders, etc).
|
|
34
|
+
|
|
35
|
+
So we built a **minimalist, high-performance runtime** specifically for the CLI output.
|
|
36
|
+
|
|
37
|
+
### 1. Setup the Provider (Root Layout)
|
|
38
|
+
No need to move files into `[locale]` folders. Just wrap your layout.
|
|
39
|
+
|
|
40
|
+
```tsx
|
|
41
|
+
// app/layout.tsx
|
|
42
|
+
import { I18nProvider } from "@scopeact/autoi18n/client";
|
|
43
|
+
import { getI18nConfig } from "@scopeact/autoi18n/server";
|
|
44
|
+
|
|
45
|
+
export default async function RootLayout({ children }) {
|
|
46
|
+
const i18n = await getI18nConfig('en'); // Default language
|
|
47
|
+
|
|
48
|
+
return (
|
|
49
|
+
<html lang={i18n.locale}>
|
|
50
|
+
<body>
|
|
51
|
+
<I18nProvider locale={i18n.locale} messages={i18n.messages}>
|
|
52
|
+
{children}
|
|
53
|
+
</I18nProvider>
|
|
54
|
+
</body>
|
|
55
|
+
</html>
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### 2. Usage in Server Components
|
|
61
|
+
```tsx
|
|
62
|
+
// app/page.tsx (Server)
|
|
63
|
+
import { getI18n } from '@scopeact/autoi18n/server';
|
|
64
|
+
|
|
65
|
+
export default async function Page() {
|
|
66
|
+
const { t } = await getI18n();
|
|
67
|
+
return <h1>{t("hero_title")}</h1>;
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### 3. Usage in Client Components
|
|
72
|
+
```tsx
|
|
73
|
+
// components/Button.tsx (Client)
|
|
74
|
+
'use client';
|
|
75
|
+
import { useI18n } from '@scopeact/autoi18n/client';
|
|
76
|
+
|
|
77
|
+
export function HeroButton() {
|
|
78
|
+
const { t } = useI18n();
|
|
79
|
+
return <button>{t("get_started")}</button>;
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## 🛠 Configuration
|
|
86
|
+
|
|
87
|
+
Created via `init`, the `auto-i18n.config.json` controls the magic:
|
|
88
|
+
|
|
89
|
+
```json
|
|
90
|
+
{
|
|
91
|
+
"sourceLang": "pt",
|
|
92
|
+
"targetLangs": ["en", "es"],
|
|
93
|
+
"i18nLibrary": "@scopeact/autoi18n",
|
|
94
|
+
"provider": "openai",
|
|
95
|
+
"localesDir": "./locales",
|
|
96
|
+
"files": ["src/**/*.tsx"]
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## 💎 Why autoi18n?
|
|
103
|
+
|
|
104
|
+
| Feature | Tradicional (next-intl/i18next) | **autoi18n** |
|
|
105
|
+
| :--- | :--- | :--- |
|
|
106
|
+
| **Key Creation** | Manual (Hours of copy-paste) | **AI-Automated** (Seconds) |
|
|
107
|
+
| **Code Rewrite** | Manual | **AST-Automated** |
|
|
108
|
+
| **Folder Structure** | Forced `[locale]` nesting | **Stay as you are** |
|
|
109
|
+
| **Next.js Setup** | Complex (Middleware/Config) | **Zero-Config** |
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## 🇧🇷 Born in Brazil
|
|
114
|
+
Projeto desenvolvido com foco em resolver a dor real de desenvolvedores que precisam entregar projetos globais rápido.
|
|
115
|
+
|
|
116
|
+
## License
|
|
117
|
+
MIT © [Felipe Vetter](https://github.com/felipevetter)
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }// src/runtime/client.tsx
|
|
2
|
+
var _react = require('react'); var _react2 = _interopRequireDefault(_react);
|
|
3
|
+
var _navigation = require('next/navigation');
|
|
4
|
+
var _jsxruntime = require('react/jsx-runtime');
|
|
5
|
+
var I18nContext = _react.createContext.call(void 0, void 0);
|
|
6
|
+
function I18nProvider({
|
|
7
|
+
children,
|
|
8
|
+
locale: initialLocale,
|
|
9
|
+
messages: initialMessages
|
|
10
|
+
}) {
|
|
11
|
+
const [locale, setLocaleState] = _react.useState.call(void 0, initialLocale);
|
|
12
|
+
const [messages, setMessages] = _react.useState.call(void 0, initialMessages);
|
|
13
|
+
const router = _navigation.useRouter.call(void 0, );
|
|
14
|
+
_react2.default.useEffect(() => {
|
|
15
|
+
setLocaleState(initialLocale);
|
|
16
|
+
setMessages(initialMessages);
|
|
17
|
+
}, [initialLocale, initialMessages]);
|
|
18
|
+
const t = (key) => {
|
|
19
|
+
return messages[key] || key;
|
|
20
|
+
};
|
|
21
|
+
const setLocale = (newLocale) => {
|
|
22
|
+
document.cookie = `NEXT_LOCALE=${newLocale}; path=/; max-age=31536000`;
|
|
23
|
+
setLocaleState(newLocale);
|
|
24
|
+
router.refresh();
|
|
25
|
+
};
|
|
26
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, I18nContext.Provider, { value: { locale, messages, t, setLocale }, children });
|
|
27
|
+
}
|
|
28
|
+
function useI18n() {
|
|
29
|
+
const context = _react.useContext.call(void 0, I18nContext);
|
|
30
|
+
if (!context) {
|
|
31
|
+
throw new Error("useI18n deve ser usado dentro de um I18nProvider");
|
|
32
|
+
}
|
|
33
|
+
return context;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
exports.I18nProvider = I18nProvider; exports.useI18n = useI18n;
|
|
40
|
+
//# sourceMappingURL=chunk-36HQJSGI.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/home/runner/work/auto-i18n/auto-i18n/packages/autoi18n/dist/chunk-36HQJSGI.cjs","../src/runtime/client.tsx"],"names":[],"mappings":"AAAA;ACGA,4EAAsE;AAEtE,6CAA0B;AAwClB,+CAAA;AA/BR,IAAM,YAAA,EAAc,kCAAA,KAA2C,CAAS,CAAA;AAEjE,SAAS,YAAA,CAAa;AAAA,EACzB,QAAA;AAAA,EACA,MAAA,EAAQ,aAAA;AAAA,EACR,QAAA,EAAU;AACd,CAAA,EAIG;AACC,EAAA,MAAM,CAAC,MAAA,EAAQ,cAAc,EAAA,EAAI,6BAAA,aAAsB,CAAA;AACvD,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,EAAA,EAAI,6BAAA,eAAwB,CAAA;AACxD,EAAA,MAAM,OAAA,EAAS,mCAAA,CAAU;AAEzB,EAAA,eAAA,CAAM,SAAA,CAAU,CAAA,EAAA,GAAM;AAClB,IAAA,cAAA,CAAe,aAAa,CAAA;AAC5B,IAAA,WAAA,CAAY,eAAe,CAAA;AAAA,EAC/B,CAAA,EAAG,CAAC,aAAA,EAAe,eAAe,CAAC,CAAA;AAEnC,EAAA,MAAM,EAAA,EAAI,CAAC,GAAA,EAAA,GAAgB;AACvB,IAAA,OAAO,QAAA,CAAS,GAAG,EAAA,GAAK,GAAA;AAAA,EAC5B,CAAA;AAEA,EAAA,MAAM,UAAA,EAAY,CAAC,SAAA,EAAA,GAAsB;AACrC,IAAA,QAAA,CAAS,OAAA,EAAS,CAAA,YAAA,EAAe,SAAS,CAAA,0BAAA,CAAA;AAC1C,IAAA,cAAA,CAAe,SAAS,CAAA;AACxB,IAAA,MAAA,CAAO,OAAA,CAAQ,CAAA;AAAA,EACnB,CAAA;AAEA,EAAA,uBACI,6BAAA,WAAC,CAAY,QAAA,EAAZ,EAAqB,KAAA,EAAO,EAAE,MAAA,EAAQ,QAAA,EAAU,CAAA,EAAG,UAAU,CAAA,EACzD,SAAA,CACL,CAAA;AAER;AAEO,SAAS,OAAA,CAAA,EAAU;AACtB,EAAA,MAAM,QAAA,EAAU,+BAAA,WAAsB,CAAA;AACtC,EAAA,GAAA,CAAI,CAAC,OAAA,EAAS;AACV,IAAA,MAAM,IAAI,KAAA,CAAM,kDAAkD,CAAA;AAAA,EACtE;AACA,EAAA,OAAO,OAAA;AACX;ADvBA;AACA;AACE;AACA;AACF,+DAAC","file":"/home/runner/work/auto-i18n/auto-i18n/packages/autoi18n/dist/chunk-36HQJSGI.cjs","sourcesContent":[null,"'use client';\n\n// @ts-ignore\nimport React, { createContext, useContext, useState, ReactNode } from 'react';\n// @ts-ignore\nimport { useRouter } from 'next/navigation';\n\ntype I18nContextType = {\n locale: string;\n messages: Record<string, string>;\n t: (key: string) => string;\n setLocale: (newLocale: string) => void;\n};\n\nconst I18nContext = createContext<I18nContextType | undefined>(undefined);\n\nexport function I18nProvider({\n children,\n locale: initialLocale,\n messages: initialMessages\n}: {\n children: ReactNode;\n locale: string;\n messages: Record<string, string>;\n}) {\n const [locale, setLocaleState] = useState(initialLocale);\n const [messages, setMessages] = useState(initialMessages);\n const router = useRouter();\n\n React.useEffect(() => {\n setLocaleState(initialLocale);\n setMessages(initialMessages);\n }, [initialLocale, initialMessages]);\n\n const t = (key: string) => {\n return messages[key] || key;\n };\n\n const setLocale = (newLocale: string) => {\n document.cookie = `NEXT_LOCALE=${newLocale}; path=/; max-age=31536000`;\n setLocaleState(newLocale);\n router.refresh();\n };\n\n return (\n <I18nContext.Provider value={{ locale, messages, t, setLocale }}>\n {children}\n </I18nContext.Provider>\n );\n}\n\nexport function useI18n() {\n const context = useContext(I18nContext);\n if (!context) {\n throw new Error('useI18n deve ser usado dentro de um I18nProvider');\n }\n return context;\n}"]}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// src/runtime/client.tsx
|
|
2
|
+
import React, { createContext, useContext, useState } from "react";
|
|
3
|
+
import { useRouter } from "next/navigation";
|
|
4
|
+
import { jsx } from "react/jsx-runtime";
|
|
5
|
+
var I18nContext = createContext(void 0);
|
|
6
|
+
function I18nProvider({
|
|
7
|
+
children,
|
|
8
|
+
locale: initialLocale,
|
|
9
|
+
messages: initialMessages
|
|
10
|
+
}) {
|
|
11
|
+
const [locale, setLocaleState] = useState(initialLocale);
|
|
12
|
+
const [messages, setMessages] = useState(initialMessages);
|
|
13
|
+
const router = useRouter();
|
|
14
|
+
React.useEffect(() => {
|
|
15
|
+
setLocaleState(initialLocale);
|
|
16
|
+
setMessages(initialMessages);
|
|
17
|
+
}, [initialLocale, initialMessages]);
|
|
18
|
+
const t = (key) => {
|
|
19
|
+
return messages[key] || key;
|
|
20
|
+
};
|
|
21
|
+
const setLocale = (newLocale) => {
|
|
22
|
+
document.cookie = `NEXT_LOCALE=${newLocale}; path=/; max-age=31536000`;
|
|
23
|
+
setLocaleState(newLocale);
|
|
24
|
+
router.refresh();
|
|
25
|
+
};
|
|
26
|
+
return /* @__PURE__ */ jsx(I18nContext.Provider, { value: { locale, messages, t, setLocale }, children });
|
|
27
|
+
}
|
|
28
|
+
function useI18n() {
|
|
29
|
+
const context = useContext(I18nContext);
|
|
30
|
+
if (!context) {
|
|
31
|
+
throw new Error("useI18n deve ser usado dentro de um I18nProvider");
|
|
32
|
+
}
|
|
33
|
+
return context;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export {
|
|
37
|
+
I18nProvider,
|
|
38
|
+
useI18n
|
|
39
|
+
};
|
|
40
|
+
//# sourceMappingURL=chunk-NYRK5OWZ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/runtime/client.tsx"],"sourcesContent":["'use client';\n\n// @ts-ignore\nimport React, { createContext, useContext, useState, ReactNode } from 'react';\n// @ts-ignore\nimport { useRouter } from 'next/navigation';\n\ntype I18nContextType = {\n locale: string;\n messages: Record<string, string>;\n t: (key: string) => string;\n setLocale: (newLocale: string) => void;\n};\n\nconst I18nContext = createContext<I18nContextType | undefined>(undefined);\n\nexport function I18nProvider({\n children,\n locale: initialLocale,\n messages: initialMessages\n}: {\n children: ReactNode;\n locale: string;\n messages: Record<string, string>;\n}) {\n const [locale, setLocaleState] = useState(initialLocale);\n const [messages, setMessages] = useState(initialMessages);\n const router = useRouter();\n\n React.useEffect(() => {\n setLocaleState(initialLocale);\n setMessages(initialMessages);\n }, [initialLocale, initialMessages]);\n\n const t = (key: string) => {\n return messages[key] || key;\n };\n\n const setLocale = (newLocale: string) => {\n document.cookie = `NEXT_LOCALE=${newLocale}; path=/; max-age=31536000`;\n setLocaleState(newLocale);\n router.refresh();\n };\n\n return (\n <I18nContext.Provider value={{ locale, messages, t, setLocale }}>\n {children}\n </I18nContext.Provider>\n );\n}\n\nexport function useI18n() {\n const context = useContext(I18nContext);\n if (!context) {\n throw new Error('useI18n deve ser usado dentro de um I18nProvider');\n }\n return context;\n}"],"mappings":";AAGA,OAAO,SAAS,eAAe,YAAY,gBAA2B;AAEtE,SAAS,iBAAiB;AAwClB;AA/BR,IAAM,cAAc,cAA2C,MAAS;AAEjE,SAAS,aAAa;AAAA,EACzB;AAAA,EACA,QAAQ;AAAA,EACR,UAAU;AACd,GAIG;AACC,QAAM,CAAC,QAAQ,cAAc,IAAI,SAAS,aAAa;AACvD,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,eAAe;AACxD,QAAM,SAAS,UAAU;AAEzB,QAAM,UAAU,MAAM;AAClB,mBAAe,aAAa;AAC5B,gBAAY,eAAe;AAAA,EAC/B,GAAG,CAAC,eAAe,eAAe,CAAC;AAEnC,QAAM,IAAI,CAAC,QAAgB;AACvB,WAAO,SAAS,GAAG,KAAK;AAAA,EAC5B;AAEA,QAAM,YAAY,CAAC,cAAsB;AACrC,aAAS,SAAS,eAAe,SAAS;AAC1C,mBAAe,SAAS;AACxB,WAAO,QAAQ;AAAA,EACnB;AAEA,SACI,oBAAC,YAAY,UAAZ,EAAqB,OAAO,EAAE,QAAQ,UAAU,GAAG,UAAU,GACzD,UACL;AAER;AAEO,SAAS,UAAU;AACtB,QAAM,UAAU,WAAW,WAAW;AACtC,MAAI,CAAC,SAAS;AACV,UAAM,IAAI,MAAM,kDAAkD;AAAA,EACtE;AACA,SAAO;AACX;","names":[]}
|