@od-oneapp/internationalization 2026.1.1301
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 +164 -0
- package/dist/client-next.d.mts +4 -0
- package/dist/client-next.mjs +4 -0
- package/dist/client.d.mts +24 -0
- package/dist/client.d.mts.map +1 -0
- package/dist/client.mjs +16 -0
- package/dist/client.mjs.map +1 -0
- package/dist/en-BG_-Eo3m.mjs +192 -0
- package/dist/en-BG_-Eo3m.mjs.map +1 -0
- package/dist/middleware-DgXJ2JFB.mjs +10 -0
- package/dist/middleware-DgXJ2JFB.mjs.map +1 -0
- package/dist/middleware.d.mts +10 -0
- package/dist/middleware.d.mts.map +1 -0
- package/dist/middleware.mjs +17 -0
- package/dist/middleware.mjs.map +1 -0
- package/dist/navigation-BCo6Vugt.mjs +39 -0
- package/dist/navigation-BCo6Vugt.mjs.map +1 -0
- package/dist/navigation-BSuDX6-H.d.mts +20 -0
- package/dist/navigation-BSuDX6-H.d.mts.map +1 -0
- package/dist/navigation-Di2SkyuD.mjs +20 -0
- package/dist/navigation-Di2SkyuD.mjs.map +1 -0
- package/dist/next-intl-server-CnBEO3Z3.mjs +25 -0
- package/dist/next-intl-server-CnBEO3Z3.mjs.map +1 -0
- package/dist/react19-cache-DHL04P0L.mjs +485 -0
- package/dist/react19-cache-DHL04P0L.mjs.map +1 -0
- package/dist/request.d.mts +5 -0
- package/dist/request.d.mts.map +1 -0
- package/dist/request.mjs +114 -0
- package/dist/request.mjs.map +1 -0
- package/dist/routing-CK71AHzC.mjs +80 -0
- package/dist/routing-CK71AHzC.mjs.map +1 -0
- package/dist/routing-Cqn-FuJK.mjs +9 -0
- package/dist/routing-Cqn-FuJK.mjs.map +1 -0
- package/dist/routing.d.mts +13 -0
- package/dist/routing.d.mts.map +1 -0
- package/dist/routing.mjs +3 -0
- package/dist/server-CiAHG84s.d.mts +167 -0
- package/dist/server-CiAHG84s.d.mts.map +1 -0
- package/dist/server-next.d.mts +37 -0
- package/dist/server-next.d.mts.map +1 -0
- package/dist/server-next.mjs +52 -0
- package/dist/server-next.mjs.map +1 -0
- package/dist/server.d.mts +3 -0
- package/dist/server.mjs +12 -0
- package/dist/server.mjs.map +1 -0
- package/package.json +104 -0
- package/src/__tests__/client.test.ts +37 -0
- package/src/__tests__/dictionary-loader.test.ts +228 -0
- package/src/__tests__/exports.test.ts +76 -0
- package/src/__tests__/extend.test.ts +55 -0
- package/src/__tests__/integration.test.ts +341 -0
- package/src/__tests__/middleware.test.ts +38 -0
- package/src/__tests__/navigation.test.ts +64 -0
- package/src/__tests__/request.test.ts +151 -0
- package/src/__tests__/routing.test.ts +39 -0
- package/src/__tests__/security.test.ts +293 -0
- package/src/__tests__/test-utils.ts +28 -0
- package/src/__tests__/vitest.d.ts +13 -0
- package/src/client-next.ts +31 -0
- package/src/client.ts +27 -0
- package/src/dictionaries/de.json +193 -0
- package/src/dictionaries/en.json +193 -0
- package/src/dictionaries/es.json +193 -0
- package/src/dictionaries/fr.json +193 -0
- package/src/dictionaries/pt.json +193 -0
- package/src/index.ts +24 -0
- package/src/middleware.ts +27 -0
- package/src/navigation.ts +91 -0
- package/src/request.ts +126 -0
- package/src/routing.export.ts +11 -0
- package/src/routing.ts +63 -0
- package/src/server-next.ts +57 -0
- package/src/server.ts +39 -0
- package/src/shared/constants.ts +42 -0
- package/src/shared/dictionary-loader.ts +599 -0
- package/src/shared/next-intl-adapter.ts +80 -0
- package/src/shared/next-intl-server.ts +45 -0
- package/src/shared/react19-cache.ts +132 -0
- package/src/types.ts +55 -0
- package/src/utils/extend.ts +48 -0
package/README.md
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
# @repo/internationalization
|
|
2
|
+
|
|
3
|
+
- _Can build:_ **NO**
|
|
4
|
+
|
|
5
|
+
- _Exports:_
|
|
6
|
+
- **Core**: `./client`, `./server`, `./client/next`, `./server/next`
|
|
7
|
+
- **Middleware**: `./middleware`
|
|
8
|
+
- **Navigation**: `./navigation`
|
|
9
|
+
- **Routing**: `./routing`
|
|
10
|
+
- **Request**: `./request`
|
|
11
|
+
- **Types**: `./types`
|
|
12
|
+
|
|
13
|
+
- _AI Hints:_
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
// Primary: Next.js App Router i18n with next-intl v4
|
|
17
|
+
import { createMiddleware } from "next-intl/middleware";
|
|
18
|
+
import { routing } from "#/i18n/routing";
|
|
19
|
+
import { getTranslations } from "@repo/internationalization/server/next";
|
|
20
|
+
import { Link, useRouter } from "@repo/internationalization/client/next";
|
|
21
|
+
// ❌ NEVER: Hardcode strings or ignore locale routing
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
- _Key Features:_
|
|
25
|
+
- **next-intl v4**: Full compatibility with next-intl v4 features
|
|
26
|
+
- **Next.js App Router**: Built for App Router with static rendering support
|
|
27
|
+
- **Type-Safe Routing**: Centralized routing configuration with TypeScript support
|
|
28
|
+
- **Dictionary System**: Type-safe dictionary loading with automatic fallbacks to English
|
|
29
|
+
- **Automated Translation**: AI-powered translation generation with Languine
|
|
30
|
+
- **Locale-Aware Navigation**: Link, redirect, and router with automatic locale handling
|
|
31
|
+
- **5 Supported Languages**: English (default), Spanish, French, German, Portuguese
|
|
32
|
+
- **SEO Support**: Automatic alternate links generation for better SEO
|
|
33
|
+
- **Advanced Features**: Domain-based routing and pathname localization ready
|
|
34
|
+
|
|
35
|
+
- _Supported Locales:_
|
|
36
|
+
- `en` (English - default), `es` (Spanish), `fr` (French), `de` (German), `pt` (Portuguese)
|
|
37
|
+
|
|
38
|
+
- _Environment Variables:_
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
# Optional - for automated AI translations
|
|
42
|
+
DEEPSEEK_API_KEY=your_deepseek_api_key
|
|
43
|
+
|
|
44
|
+
# Environment detection
|
|
45
|
+
NODE_ENV=development
|
|
46
|
+
NEXT_PUBLIC_NODE_ENV=development
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
- _Quick Setup:_
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
// 1. Create routing configuration (src/i18n/routing.ts)
|
|
53
|
+
export { routing, locales, type Locale } from '@repo/internationalization/routing';
|
|
54
|
+
|
|
55
|
+
// 2. Middleware setup (middleware.ts)
|
|
56
|
+
import createMiddleware from 'next-intl/middleware';
|
|
57
|
+
import { routing } from './routing';
|
|
58
|
+
|
|
59
|
+
export default createMiddleware(routing);
|
|
60
|
+
export const config = {
|
|
61
|
+
matcher: ['/((?!api|trpc|_next|_vercel|.*\\..*).*)', '/']
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
// 3. Layout with static rendering (app/[locale]/layout.tsx)
|
|
65
|
+
import { setRequestLocale, hasLocale } from '@repo/internationalization/server/next';
|
|
66
|
+
import { routing } from './routing';
|
|
67
|
+
import { notFound } from 'next/navigation';
|
|
68
|
+
|
|
69
|
+
export function generateStaticParams() {
|
|
70
|
+
return routing.locales.map((locale) => ({ locale }));
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export default async function LocaleLayout({ params }) {
|
|
74
|
+
const { locale } = await params;
|
|
75
|
+
if (!hasLocale(routing.locales, locale)) notFound();
|
|
76
|
+
setRequestLocale(locale);
|
|
77
|
+
// ...
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// 4. Server component usage
|
|
81
|
+
import { getTranslations } from "@repo/internationalization/server/next";
|
|
82
|
+
export default async function Page() {
|
|
83
|
+
const t = await getTranslations('HomePage');
|
|
84
|
+
return <h1>{t('title')}</h1>;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// 5. Client component with navigation
|
|
88
|
+
import { Link, useRouter, usePathname } from "@repo/internationalization/client/next";
|
|
89
|
+
import { useTranslations } from "@repo/internationalization/client/next";
|
|
90
|
+
|
|
91
|
+
export default function Navigation() {
|
|
92
|
+
const t = useTranslations('Navigation');
|
|
93
|
+
const router = useRouter();
|
|
94
|
+
const pathname = usePathname();
|
|
95
|
+
|
|
96
|
+
return (
|
|
97
|
+
<>
|
|
98
|
+
<Link href="/products">{t('products')}</Link>
|
|
99
|
+
<button onClick={() => router.replace(pathname, { locale: 'es' })}>
|
|
100
|
+
Español
|
|
101
|
+
</button>
|
|
102
|
+
</>
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
- _Dictionary Structure:_
|
|
108
|
+
|
|
109
|
+
```json
|
|
110
|
+
{
|
|
111
|
+
"common": { "locale": "English", "language": "Language" },
|
|
112
|
+
"web": {
|
|
113
|
+
"global": { "primaryCta": "Book a call" },
|
|
114
|
+
"header": { "home": "Home", "product": { "title": "Product" } },
|
|
115
|
+
"home": { "meta": { "title": "Transform Your Business" } }
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
- _Automated Translation:_
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
# Generate translations using Languine AI
|
|
124
|
+
pnpm translate
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
- _Testing:_
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
pnpm test # Run all tests
|
|
131
|
+
pnpm test:watch # Watch mode for development
|
|
132
|
+
pnpm test:coverage # Generate coverage report
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
- _Quality Checks:_
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
pnpm typecheck # TypeScript type checking
|
|
139
|
+
pnpm lint # ESLint checks
|
|
140
|
+
pnpm circular # Check for circular dependencies
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
- _Security & Best Practices:_
|
|
144
|
+
- ✅ **Input Validation**: All locale inputs validated against whitelist
|
|
145
|
+
- ✅ **Path Traversal Protection**: Comprehensive validation prevents file system attacks
|
|
146
|
+
- ✅ **Type Safety**: No `any` types, strict TypeScript throughout
|
|
147
|
+
- ✅ **Error Handling**: Nested fallbacks ensure graceful degradation
|
|
148
|
+
- ✅ **Server-Only Code**: Protected with `server-only` package
|
|
149
|
+
|
|
150
|
+
- _Documentation:_
|
|
151
|
+
- **[Internationalization Package](../../apps/docs/packages/internationalization.mdx)**
|
|
152
|
+
- **[next-intl v4 Documentation](https://next-intl-docs.vercel.app/)**
|
|
153
|
+
- **[Audit Findings](./AUDIT_FINDINGS.md)** - Comprehensive security and quality audit
|
|
154
|
+
|
|
155
|
+
## 📚 Comprehensive Documentation
|
|
156
|
+
|
|
157
|
+
For detailed documentation, see:
|
|
158
|
+
|
|
159
|
+
- **[Audit Reports](../../apps/docs/content/docs/audits/internationalization/)** - Comprehensive audits, fixes, and
|
|
160
|
+
security reviews
|
|
161
|
+
- **[Technical Guides](../../apps/docs/content/docs/packages/internationalization/)** - Implementation guides and best
|
|
162
|
+
practices
|
|
163
|
+
|
|
164
|
+
All comprehensive documentation has been centralized in the docs app.
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { n as usePathname, r as useRouter, t as Link } from "./navigation-BSuDX6-H.mjs";
|
|
2
|
+
import { Locale } from "./routing.mjs";
|
|
3
|
+
import { NextIntlClientProvider, useFormatter, useLocale, useLocale as useCurrentLocale, useMessages, useNow, useTimeZone, useTranslations, useTranslations as useI18n } from "next-intl";
|
|
4
|
+
export { Link, type Locale, NextIntlClientProvider, useCurrentLocale, useFormatter, useI18n, useLocale, useMessages, useNow, usePathname, useRouter, useTimeZone, useTranslations };
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { n as usePathname, r as useRouter, t as Link } from "./navigation-BCo6Vugt.mjs";
|
|
2
|
+
import { NextIntlClientProvider, useFormatter, useLocale, useLocale as useCurrentLocale, useMessages, useNow, useTimeZone, useTranslations, useTranslations as useI18n } from "next-intl";
|
|
3
|
+
|
|
4
|
+
export { Link, NextIntlClientProvider, useCurrentLocale, useFormatter, useI18n, useLocale, useMessages, useNow, usePathname, useRouter, useTimeZone, useTranslations };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { t as Link } from "./navigation-BSuDX6-H.mjs";
|
|
2
|
+
import { ReactNode } from "react";
|
|
3
|
+
|
|
4
|
+
//#region src/client.d.ts
|
|
5
|
+
declare const I18nLink: (props: {
|
|
6
|
+
href: string;
|
|
7
|
+
children?: unknown;
|
|
8
|
+
}) => {
|
|
9
|
+
href: string;
|
|
10
|
+
children?: unknown;
|
|
11
|
+
};
|
|
12
|
+
type I18nLinkProps = Parameters<typeof Link>[0] & {
|
|
13
|
+
children?: ReactNode;
|
|
14
|
+
};
|
|
15
|
+
declare const InternationalizationLink: (props: {
|
|
16
|
+
href: string;
|
|
17
|
+
children?: unknown;
|
|
18
|
+
}) => {
|
|
19
|
+
href: string;
|
|
20
|
+
children?: unknown;
|
|
21
|
+
};
|
|
22
|
+
//#endregion
|
|
23
|
+
export { I18nLink, I18nLinkProps, InternationalizationLink };
|
|
24
|
+
//# sourceMappingURL=client.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.mts","names":[],"sources":["../src/client.ts"],"mappings":";;;;cAgBa,QAAA,GAAQ,KAAA;;;;;;;KAKT,aAAA,GAAgB,UAAA,QAAkB,IAAA;EAAa,QAAA,GAAW,SAAA;AAAA;AAAA,cAKzD,wBAAA,GAAwB,KAAA"}
|
package/dist/client.mjs
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { t as Link } from "./navigation-BCo6Vugt.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/client.ts
|
|
4
|
+
/**
|
|
5
|
+
* I18nLink - Internationalized Link component
|
|
6
|
+
* Alias for the Link component from navigation.ts for backwards compatibility
|
|
7
|
+
*/
|
|
8
|
+
const I18nLink = Link;
|
|
9
|
+
/**
|
|
10
|
+
* InternationalizationLink - Alternative export name
|
|
11
|
+
*/
|
|
12
|
+
const InternationalizationLink = Link;
|
|
13
|
+
|
|
14
|
+
//#endregion
|
|
15
|
+
export { I18nLink, InternationalizationLink };
|
|
16
|
+
//# sourceMappingURL=client.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.mjs","names":[],"sources":["../src/client.ts"],"sourcesContent":["/**\n * @fileoverview Internationalized Link component for Next.js\n *\n * Provides locale-aware navigation with automatic locale prefixing.\n * Client-side exports for non-Next.js environments.\n *\n * @module @repo/internationalization/client\n */\nimport type { ReactNode } from 'react';\n\nimport { Link } from './navigation';\n\n/**\n * I18nLink - Internationalized Link component\n * Alias for the Link component from navigation.ts for backwards compatibility\n */\nexport const I18nLink = Link;\n\n/**\n * Type export for I18nLink props\n */\nexport type I18nLinkProps = Parameters<typeof Link>[0] & { children?: ReactNode };\n\n/**\n * InternationalizationLink - Alternative export name\n */\nexport const InternationalizationLink = Link;\n"],"mappings":";;;;;;;AAgBA,MAAa,WAAW;;;;AAUxB,MAAa,2BAA2B"}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
//#region src/dictionaries/en.json
|
|
2
|
+
var en_default = {
|
|
3
|
+
common: {
|
|
4
|
+
"locale": "English",
|
|
5
|
+
"language": "Language"
|
|
6
|
+
},
|
|
7
|
+
web: {
|
|
8
|
+
"global": {
|
|
9
|
+
"primaryCta": "Book a call",
|
|
10
|
+
"secondaryCta": "Sign up"
|
|
11
|
+
},
|
|
12
|
+
"header": {
|
|
13
|
+
"home": "Home",
|
|
14
|
+
"product": {
|
|
15
|
+
"title": "Product",
|
|
16
|
+
"description": "Managing a small business today is already tough.",
|
|
17
|
+
"pricing": "Pricing"
|
|
18
|
+
},
|
|
19
|
+
"blog": "Blog",
|
|
20
|
+
"docs": "Docs",
|
|
21
|
+
"contact": "Contact",
|
|
22
|
+
"signIn": "Sign in",
|
|
23
|
+
"signUp": "Get started"
|
|
24
|
+
},
|
|
25
|
+
"home": {
|
|
26
|
+
"meta": {
|
|
27
|
+
"title": "Transform Your Business Operations Today",
|
|
28
|
+
"description": "In today's fast-paced world, your business deserves better than outdated trading systems. Our innovative platform streamlines operations, reduces complexity, and helps small businesses thrive in the modern economy."
|
|
29
|
+
},
|
|
30
|
+
"hero": { "announcement": "Read our latest article" },
|
|
31
|
+
"cases": { "title": "Empowering Success Stories Across the Globe" },
|
|
32
|
+
"features": {
|
|
33
|
+
"title": "Powerful Tools for Modern Business",
|
|
34
|
+
"description": "Discover how our cutting-edge features can revolutionize your daily operations.",
|
|
35
|
+
"items": [
|
|
36
|
+
{
|
|
37
|
+
"title": "Streamlined Operations",
|
|
38
|
+
"description": "Our platform streamlines operations, reduces complexity, and helps small businesses thrive in the modern economy."
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"title": "Real-Time Analytics",
|
|
42
|
+
"description": "Get instant insights into your business performance with comprehensive analytics and reporting tools."
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"title": "Automated Workflows",
|
|
46
|
+
"description": "Save time and reduce errors with intelligent automation that handles repetitive tasks for you."
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"title": "Secure Transactions",
|
|
50
|
+
"description": "Rest easy knowing your business operations are protected by enterprise-grade security and encryption."
|
|
51
|
+
}
|
|
52
|
+
]
|
|
53
|
+
},
|
|
54
|
+
"stats": {
|
|
55
|
+
"title": "Real Results, Real Impact",
|
|
56
|
+
"description": "Join thousands of businesses that have transformed their operations with our platform. Our solutions have helped companies reduce administrative overhead by 60% and increase trading efficiency by 45% on average.",
|
|
57
|
+
"items": [
|
|
58
|
+
{
|
|
59
|
+
"title": "Monthly active users",
|
|
60
|
+
"metric": "100000",
|
|
61
|
+
"delta": "10",
|
|
62
|
+
"type": "unit"
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"title": "Daily active users",
|
|
66
|
+
"metric": "10000",
|
|
67
|
+
"delta": "-5",
|
|
68
|
+
"type": "unit"
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
"title": "Monthly recurring revenue",
|
|
72
|
+
"metric": "100000",
|
|
73
|
+
"delta": "20",
|
|
74
|
+
"type": "currency"
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"title": "Cost per acquisition",
|
|
78
|
+
"metric": "100",
|
|
79
|
+
"delta": "-10",
|
|
80
|
+
"type": "currency"
|
|
81
|
+
}
|
|
82
|
+
]
|
|
83
|
+
},
|
|
84
|
+
"testimonials": {
|
|
85
|
+
"title": "Hear from Our Thriving Community",
|
|
86
|
+
"items": [
|
|
87
|
+
{
|
|
88
|
+
"title": "Best decision",
|
|
89
|
+
"description": "Our goal was to streamline SMB trade, making it easier and faster than ever and we did it together.",
|
|
90
|
+
"author": {
|
|
91
|
+
"name": "Hayden Bleasel",
|
|
92
|
+
"image": "https://github.com/haydenbleasel.png"
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
"title": "Game changer",
|
|
97
|
+
"description": "This platform revolutionized how we handle our day-to-day operations. The efficiency gains have been remarkable.",
|
|
98
|
+
"author": {
|
|
99
|
+
"name": "Lee Robinson",
|
|
100
|
+
"image": "https://github.com/leerob.png"
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
"title": "Exceeded expectations",
|
|
105
|
+
"description": "Implementation was smooth and the results were immediate. Our team adapted quickly and productivity soared.",
|
|
106
|
+
"author": {
|
|
107
|
+
"name": "shadcn",
|
|
108
|
+
"image": "https://github.com/shadcn.png"
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
"title": "Outstanding support",
|
|
113
|
+
"description": "Not only is the platform powerful, but the customer support team has been exceptional in helping us maximize its potential.",
|
|
114
|
+
"author": {
|
|
115
|
+
"name": "Pontus Abrahamsson",
|
|
116
|
+
"image": "https://github.com/pontusab.png"
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
]
|
|
120
|
+
},
|
|
121
|
+
"faq": {
|
|
122
|
+
"title": "Common Questions, Expert Answers",
|
|
123
|
+
"description": "Get quick answers to your most pressing questions about our platform. We've compiled everything you need to know about transforming your business operations and getting started with modern trading solutions.",
|
|
124
|
+
"cta": "Any questions? Reach out",
|
|
125
|
+
"items": [
|
|
126
|
+
{
|
|
127
|
+
"question": "What is the platform?",
|
|
128
|
+
"answer": "The platform is a trading platform that allows you to trade with confidence."
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
"question": "How secure is the platform?",
|
|
132
|
+
"answer": "Our platform employs enterprise-grade security measures, including end-to-end encryption and multi-factor authentication, to ensure your trading activities remain completely secure."
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
"question": "What trading features are available?",
|
|
136
|
+
"answer": "The platform offers comprehensive trading tools including real-time market data, advanced charting, automated trading strategies, and detailed analytics to support informed decision-making."
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
"question": "How does pricing work?",
|
|
140
|
+
"answer": "We offer flexible pricing tiers designed to scale with your business needs, from starter plans for individual traders to enterprise solutions for large organizations."
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
"question": "What kind of support do you provide?",
|
|
144
|
+
"answer": "Our dedicated support team is available 24/7 through multiple channels including live chat, email, and phone. We also provide extensive documentation and training resources."
|
|
145
|
+
}
|
|
146
|
+
]
|
|
147
|
+
},
|
|
148
|
+
"cta": {
|
|
149
|
+
"title": "Start Your Business Transformation",
|
|
150
|
+
"description": "Join thousands of forward-thinking businesses who have already modernized their operations. Our platform offers the tools, support, and efficiency you need to succeed in today's competitive market. Get started in minutes."
|
|
151
|
+
}
|
|
152
|
+
},
|
|
153
|
+
"blog": { "meta": {
|
|
154
|
+
"title": "Blog",
|
|
155
|
+
"description": "Thoughts, ideas, and opinions."
|
|
156
|
+
} },
|
|
157
|
+
"contact": {
|
|
158
|
+
"meta": {
|
|
159
|
+
"title": "Let's Talk About Your Business",
|
|
160
|
+
"description": "Schedule a consultation with our team to discuss how we can help streamline your operations and drive growth for your business."
|
|
161
|
+
},
|
|
162
|
+
"hero": {
|
|
163
|
+
"benefits": [
|
|
164
|
+
{
|
|
165
|
+
"title": "Personalized Consultation",
|
|
166
|
+
"description": "Get tailored solutions and expert advice specific to your business needs."
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
"title": "Seamless Integration",
|
|
170
|
+
"description": "We seamlessly integrate with your existing systems to ensure a smooth transition and minimal disruption."
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
"title": "Expert Guidance",
|
|
174
|
+
"description": "Our team of experts will guide you through the process, ensuring you get the most out of our platform."
|
|
175
|
+
}
|
|
176
|
+
],
|
|
177
|
+
"form": {
|
|
178
|
+
"title": "Book a meeting",
|
|
179
|
+
"date": "Date",
|
|
180
|
+
"firstName": "First name",
|
|
181
|
+
"lastName": "Last name",
|
|
182
|
+
"resume": "Upload resume",
|
|
183
|
+
"cta": "Book the meeting"
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
//#endregion
|
|
191
|
+
export { en_default as default };
|
|
192
|
+
//# sourceMappingURL=en-BG_-Eo3m.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"en-BG_-Eo3m.mjs","names":[],"sources":["../src/dictionaries/en.json"],"sourcesContent":[""],"mappings":""}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
//#region test/mocks/next-intl/middleware.ts
|
|
2
|
+
/**
|
|
3
|
+
* @fileoverview middleware.ts
|
|
4
|
+
*/
|
|
5
|
+
const middlewareHandler = (_request) => {};
|
|
6
|
+
const createMiddleware = (_config) => middlewareHandler;
|
|
7
|
+
|
|
8
|
+
//#endregion
|
|
9
|
+
export { createMiddleware as default };
|
|
10
|
+
//# sourceMappingURL=middleware-DgXJ2JFB.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middleware-DgXJ2JFB.mjs","names":[],"sources":["../test/mocks/next-intl/middleware.ts"],"sourcesContent":["/**\n * @fileoverview middleware.ts\n */\n\nconst middlewareHandler = (_request?: any) => {};\nconst createMiddleware = (_config?: any) => middlewareHandler;\n\nexport default createMiddleware;\n"],"mappings":";;;;AAIA,MAAM,qBAAqB,aAAmB;AAC9C,MAAM,oBAAoB,YAAkB"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { NextRequest, NextResponse } from "next/server";
|
|
2
|
+
|
|
3
|
+
//#region src/middleware.d.ts
|
|
4
|
+
declare const internationalizationMiddleware: (request: NextRequest) => NextResponse | undefined;
|
|
5
|
+
declare const config: {
|
|
6
|
+
matcher: string[];
|
|
7
|
+
};
|
|
8
|
+
//#endregion
|
|
9
|
+
export { config, internationalizationMiddleware };
|
|
10
|
+
//# sourceMappingURL=middleware.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middleware.d.mts","names":[],"sources":["../src/middleware.ts"],"mappings":";;;cAgBa,8BAAA,GACX,OAAA,EAAS,WAAA,KACN,YAAA;AAAA,cAGQ,MAAA;EAKZ,OAAA;AAAA"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { n as routing, r as createMiddleware } from "./routing-CK71AHzC.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/middleware.ts
|
|
4
|
+
/**
|
|
5
|
+
* @fileoverview Internationalization middleware for Next.js
|
|
6
|
+
*
|
|
7
|
+
* Handles locale detection and routing using next-intl.
|
|
8
|
+
* Automatically detects user locale and redirects to appropriate locale-prefixed routes.
|
|
9
|
+
*
|
|
10
|
+
* @module @od-oneapp/internationalization/middleware
|
|
11
|
+
*/
|
|
12
|
+
const internationalizationMiddleware = createMiddleware(routing);
|
|
13
|
+
const config = { matcher: ["/((?!api|trpc|_next|_vercel|.*\\..*).*)", "/"] };
|
|
14
|
+
|
|
15
|
+
//#endregion
|
|
16
|
+
export { config, internationalizationMiddleware };
|
|
17
|
+
//# sourceMappingURL=middleware.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middleware.mjs","names":[],"sources":["../src/middleware.ts"],"sourcesContent":["/**\n * @fileoverview Internationalization middleware for Next.js\n *\n * Handles locale detection and routing using next-intl.\n * Automatically detects user locale and redirects to appropriate locale-prefixed routes.\n *\n * @module @repo/internationalization/middleware\n */\n\nimport { routing } from './routing';\nimport { createMiddleware } from './shared/next-intl-adapter';\n\nimport type { NextRequest, NextResponse } from 'next/server';\n\n// Create the internationalization middleware with our routing configuration\n// The middleware may return undefined when no locale redirect is needed\nexport const internationalizationMiddleware = createMiddleware(routing) as (\n request: NextRequest,\n) => NextResponse | undefined;\n\n// Export the middleware configuration for Next.js\nexport const config = {\n // Match all pathnames except for\n // - … if they start with `/api`, `/trpc`, `/_next` or `/_vercel`\n // - … the ones containing a dot (e.g. `favicon.ico`)\n matcher: ['/((?!api|trpc|_next|_vercel|.*\\\\..*).*)', '/'],\n};\n"],"mappings":";;;;;;;;;;;AAgBA,MAAa,iCAAiC,iBAAiB,QAAQ;AAKvE,MAAa,SAAS,EAIpB,SAAS,CAAC,2CAA2C,IAAI,EAC1D"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { i as createNavigation, n as routing } from "./routing-CK71AHzC.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/navigation.ts
|
|
4
|
+
/**
|
|
5
|
+
* @fileoverview Internationalized navigation APIs for next-intl
|
|
6
|
+
*
|
|
7
|
+
* These wrappers around Next.js navigation automatically handle locale prefixes.
|
|
8
|
+
* Provides locale-aware Link, redirect, and router utilities.
|
|
9
|
+
*
|
|
10
|
+
* @module @od-oneapp/internationalization/navigation
|
|
11
|
+
*/
|
|
12
|
+
const { Link, redirect: baseRedirect, permanentRedirect: basePermanentRedirect, usePathname: baseUsePathname, getPathname: baseGetPathname, useRouter: baseUseRouter } = createNavigation(routing);
|
|
13
|
+
/**
|
|
14
|
+
* Hook to get the current pathname without locale prefix.
|
|
15
|
+
*
|
|
16
|
+
* @returns The current pathname without locale prefix
|
|
17
|
+
* @example
|
|
18
|
+
* ```tsx
|
|
19
|
+
* import { usePathname } from '@od-oneapp/internationalization/client/next';
|
|
20
|
+
* const pathname = usePathname(); // '/about' even if URL is '/es/about'
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
const usePathname = () => baseUsePathname();
|
|
24
|
+
/**
|
|
25
|
+
* Hook to get locale-aware router instance.
|
|
26
|
+
*
|
|
27
|
+
* @returns Router instance with locale-aware navigation methods
|
|
28
|
+
* @example
|
|
29
|
+
* ```tsx
|
|
30
|
+
* import { useRouter } from '@od-oneapp/internationalization/client/next';
|
|
31
|
+
* const router = useRouter();
|
|
32
|
+
* router.push('/products', { locale: 'es' });
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
const useRouter = () => baseUseRouter();
|
|
36
|
+
|
|
37
|
+
//#endregion
|
|
38
|
+
export { usePathname as n, useRouter as r, Link as t };
|
|
39
|
+
//# sourceMappingURL=navigation-BCo6Vugt.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"navigation-BCo6Vugt.mjs","names":[],"sources":["../src/navigation.ts"],"sourcesContent":["/**\n * @fileoverview Internationalized navigation APIs for next-intl\n *\n * These wrappers around Next.js navigation automatically handle locale prefixes.\n * Provides locale-aware Link, redirect, and router utilities.\n *\n * @module @repo/internationalization/navigation\n */\n\nimport { routing } from './routing';\nimport { createNavigation } from './shared/next-intl-adapter';\n\nconst {\n Link,\n redirect: baseRedirect,\n permanentRedirect: basePermanentRedirect,\n usePathname: baseUsePathname,\n getPathname: baseGetPathname,\n useRouter: baseUseRouter,\n} = createNavigation(routing);\n\n/**\n * Locale-aware Link component that automatically handles locale prefixes.\n * Use this instead of Next.js Link for internationalized navigation.\n *\n * @example\n * ```tsx\n * import { Link } from '@repo/internationalization/client/next';\n * <Link href=\"/about\">About</Link> // Renders as /es/about when locale is 'es'\n * ```\n */\nexport { Link };\n\n/**\n * Redirects to a locale-aware path.\n *\n * @param args - Arguments passed to next-intl's redirect function\n * @example\n * ```tsx\n * import { redirect } from '@repo/internationalization/client/next';\n * redirect('/products');\n * ```\n */\nexport const redirect = (...args: Parameters<typeof baseRedirect>) => baseRedirect(...args);\n\n/**\n * Permanently redirects to a locale-aware path (HTTP 308).\n *\n * @param args - Arguments passed to next-intl's permanentRedirect function\n * @example\n * ```tsx\n * import { permanentRedirect } from '@repo/internationalization/client/next';\n * permanentRedirect('/products');\n * ```\n */\nexport const permanentRedirect = (...args: Parameters<typeof basePermanentRedirect>) =>\n basePermanentRedirect(...args);\n\n/**\n * Hook to get the current pathname without locale prefix.\n *\n * @returns The current pathname without locale prefix\n * @example\n * ```tsx\n * import { usePathname } from '@repo/internationalization/client/next';\n * const pathname = usePathname(); // '/about' even if URL is '/es/about'\n * ```\n */\nexport const usePathname = () => baseUsePathname();\n\n/**\n * Server-side function to get pathname without locale prefix.\n *\n * @param args - Arguments passed to next-intl's getPathname function\n * @returns The pathname without locale prefix\n */\nexport const getPathname = (...args: Parameters<typeof baseGetPathname>) =>\n baseGetPathname(...args);\n\n/**\n * Hook to get locale-aware router instance.\n *\n * @returns Router instance with locale-aware navigation methods\n * @example\n * ```tsx\n * import { useRouter } from '@repo/internationalization/client/next';\n * const router = useRouter();\n * router.push('/products', { locale: 'es' });\n * ```\n */\nexport const useRouter = () => baseUseRouter();\n"],"mappings":";;;;;;;;;;;AAYA,MAAM,EACJ,MACA,UAAU,cACV,mBAAmB,uBACnB,aAAa,iBACb,aAAa,iBACb,WAAW,kBACT,iBAAiB,QAAQ;;;;;;;;;;;AAiD7B,MAAa,oBAAoB,iBAAiB;;;;;;;;;;;;AAsBlD,MAAa,kBAAkB,eAAe"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
//#region src/navigation.d.ts
|
|
2
|
+
declare const Link: (props: {
|
|
3
|
+
href: string;
|
|
4
|
+
children?: unknown;
|
|
5
|
+
}) => {
|
|
6
|
+
href: string;
|
|
7
|
+
children?: unknown;
|
|
8
|
+
}, baseRedirect: (...args: unknown[]) => void, basePermanentRedirect: (...args: unknown[]) => void, baseGetPathname: (...args: unknown[]) => string;
|
|
9
|
+
declare const usePathname: () => string;
|
|
10
|
+
declare const useRouter: () => {
|
|
11
|
+
push: (href: string) => void;
|
|
12
|
+
replace: (href: string) => void;
|
|
13
|
+
back: () => void;
|
|
14
|
+
forward: () => void;
|
|
15
|
+
refresh: () => void;
|
|
16
|
+
prefetch: (href: string) => void;
|
|
17
|
+
};
|
|
18
|
+
//#endregion
|
|
19
|
+
export { usePathname as n, useRouter as r, Link as t };
|
|
20
|
+
//# sourceMappingURL=navigation-BSuDX6-H.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"navigation-BSuDX6-H.d.mts","names":[],"sources":["../src/navigation.ts"],"mappings":";cAaE,IAAA,GAAI,KAAA;;;;;;KACM,YAAA,MAAY,IAAA,sBACH,qBAAA,MAAqB,IAAA,sBAE3B,eAAA,MAAe,IAAA;AAAA,cAmDjB,WAAA;AAAA,cAsBA,SAAA"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
//#region test/mocks/next-intl/navigation.ts
|
|
2
|
+
const createNavigation = (_config) => ({
|
|
3
|
+
Link: (props) => props,
|
|
4
|
+
redirect: () => {},
|
|
5
|
+
permanentRedirect: () => {},
|
|
6
|
+
usePathname: () => "/",
|
|
7
|
+
getPathname: () => "/",
|
|
8
|
+
useRouter: () => ({
|
|
9
|
+
push: () => {},
|
|
10
|
+
replace: () => {},
|
|
11
|
+
back: () => {},
|
|
12
|
+
forward: () => {},
|
|
13
|
+
refresh: () => {},
|
|
14
|
+
prefetch: () => {}
|
|
15
|
+
})
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
//#endregion
|
|
19
|
+
export { createNavigation };
|
|
20
|
+
//# sourceMappingURL=navigation-Di2SkyuD.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"navigation-Di2SkyuD.mjs","names":[],"sources":["../test/mocks/next-intl/navigation.ts"],"sourcesContent":["/**\n * @fileoverview navigation.ts\n */\n\ntype NavigationResult = {\n Link: (props: { href: string; children?: unknown }) => { href: string; children?: unknown };\n redirect: (...args: unknown[]) => void;\n permanentRedirect: (...args: unknown[]) => void;\n usePathname: () => string;\n getPathname: (...args: unknown[]) => string;\n useRouter: () => {\n push: (href: string) => void;\n replace: (href: string) => void;\n back: () => void;\n forward: () => void;\n refresh: () => void;\n prefetch: (href: string) => void;\n };\n};\n\nexport const createNavigation = (_config?: unknown): NavigationResult => ({\n Link: props => props,\n redirect: () => {},\n permanentRedirect: () => {},\n usePathname: () => '/',\n getPathname: () => '/',\n useRouter: () => ({\n push: () => {},\n replace: () => {},\n back: () => {},\n forward: () => {},\n refresh: () => {},\n prefetch: () => {},\n }),\n});\n"],"mappings":";AAoBA,MAAa,oBAAoB,aAAyC;CACxE,OAAM,UAAS;CACf,gBAAgB;CAChB,yBAAyB;CACzB,mBAAmB;CACnB,mBAAmB;CACnB,kBAAkB;EAChB,YAAY;EACZ,eAAe;EACf,YAAY;EACZ,eAAe;EACf,eAAe;EACf,gBAAgB;EACjB;CACF"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
//#region src/shared/next-intl-server.ts
|
|
2
|
+
const isTestEnv = process.env.VITEST === "true";
|
|
3
|
+
const serverModuleId = isTestEnv ? "../../test/stubs/next-intl-server" : "next-intl/server";
|
|
4
|
+
const mainModuleId = isTestEnv ? "../../test/stubs/next-intl" : "next-intl";
|
|
5
|
+
const serverModule = await import(
|
|
6
|
+
/** @vite-ignore */
|
|
7
|
+
serverModuleId
|
|
8
|
+
);
|
|
9
|
+
const mainModule = await import(
|
|
10
|
+
/** @vite-ignore */
|
|
11
|
+
mainModuleId
|
|
12
|
+
);
|
|
13
|
+
const { getFormatter } = serverModule;
|
|
14
|
+
const { getI18n } = serverModule;
|
|
15
|
+
const { getMessages } = serverModule;
|
|
16
|
+
const { getNow } = serverModule;
|
|
17
|
+
const { getRequestConfig } = serverModule;
|
|
18
|
+
const { getTimeZone } = serverModule;
|
|
19
|
+
const { getTranslations } = serverModule;
|
|
20
|
+
const { setRequestLocale } = serverModule;
|
|
21
|
+
const { hasLocale } = mainModule;
|
|
22
|
+
|
|
23
|
+
//#endregion
|
|
24
|
+
export { getTimeZone as a, setRequestLocale as c, getRequestConfig as i, getMessages as n, getTranslations as o, getNow as r, hasLocale as s, getFormatter as t };
|
|
25
|
+
//# sourceMappingURL=next-intl-server-CnBEO3Z3.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"next-intl-server-CnBEO3Z3.mjs","names":[],"sources":["../src/shared/next-intl-server.ts"],"sourcesContent":["/**\n * @fileoverview next-intl-server.ts\n */\n\nimport type { hasLocale as HasLocale } from 'next-intl';\nimport type {\n getFormatter as GetFormatter,\n getI18n as GetI18n,\n getMessages as GetMessages,\n getNow as GetNow,\n getRequestConfig as GetRequestConfig,\n getTimeZone as GetTimeZone,\n getTranslations as GetTranslations,\n setRequestLocale as SetRequestLocale,\n} from 'next-intl/server';\n\nconst isTestEnv = process.env.NODE_ENV === 'test' || process.env.VITEST === 'true';\nconst serverModuleId = isTestEnv ? '../../test/stubs/next-intl-server' : 'next-intl/server';\nconst mainModuleId = isTestEnv ? '../../test/stubs/next-intl' : 'next-intl';\n\nconst serverModule = (await import(/** @vite-ignore */ serverModuleId)) as {\n getFormatter: typeof GetFormatter;\n getI18n: typeof GetI18n;\n getMessages: typeof GetMessages;\n getNow: typeof GetNow;\n getRequestConfig: typeof GetRequestConfig;\n getTimeZone: typeof GetTimeZone;\n getTranslations: typeof GetTranslations;\n setRequestLocale: typeof SetRequestLocale;\n};\n\nconst mainModule = (await import(/** @vite-ignore */ mainModuleId)) as {\n hasLocale: typeof HasLocale;\n};\n\n// Explicitly typed exports to ensure type safety\nexport const { getFormatter } = serverModule;\nexport const { getI18n } = serverModule;\nexport const { getMessages } = serverModule;\nexport const { getNow } = serverModule;\nexport const { getRequestConfig } = serverModule;\nexport const { getTimeZone } = serverModule;\nexport const { getTranslations } = serverModule;\nexport const { setRequestLocale } = serverModule;\nexport const { hasLocale } = mainModule;\n"],"mappings":";AAgBA,MAAM,YAA+C,QAAQ,IAAI,WAAW;AAC5E,MAAM,iBAAiB,YAAY,sCAAsC;AACzE,MAAM,eAAe,YAAY,+BAA+B;AAEhE,MAAM,eAAgB,MAAM;;CAA2B;;AAWvD,MAAM,aAAc,MAAM;;CAA2B;;AAKrD,MAAa,EAAE,iBAAiB;AAChC,MAAa,EAAE,YAAY;AAC3B,MAAa,EAAE,gBAAgB;AAC/B,MAAa,EAAE,WAAW;AAC1B,MAAa,EAAE,qBAAqB;AACpC,MAAa,EAAE,gBAAgB;AAC/B,MAAa,EAAE,oBAAoB;AACnC,MAAa,EAAE,qBAAqB;AACpC,MAAa,EAAE,cAAc"}
|