Skip to content

Commit f5fc338

Browse files
committed
feat: merge cmp repository with full history
2 parents 18e3f46 + 70b16a5 commit f5fc338

File tree

185 files changed

+42308
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

185 files changed

+42308
-0
lines changed

cmp/.editorconfig

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# EditorConfig is awesome: https://EditorConfig.org
2+
3+
root = true
4+
5+
[*]
6+
charset = utf-8
7+
end_of_line = lf
8+
insert_final_newline = true
9+
trim_trailing_whitespace = true
10+
11+
[*.{js,ts,json,yml,yaml}]
12+
indent_style = space
13+
indent_size = 2
14+
15+
[*.md]
16+
trim_trailing_whitespace = false

cmp/.github/workflows/ci.yml

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
jobs:
10+
lint:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v5.0.1
14+
# pnpm version is taken from package.json
15+
- name: Install pnpm
16+
uses: pnpm/action-setup@v4
17+
- name: Use Node.js 20
18+
uses: actions/setup-node@v6.0.0
19+
with:
20+
node-version: 20
21+
cache: "pnpm"
22+
- name: Install dependencies
23+
run: pnpm install
24+
- name: Lint
25+
run: pnpm lint:check
26+
- name: Check formatting
27+
run: pnpm format:check
28+
29+
test:
30+
runs-on: ubuntu-latest
31+
steps:
32+
- uses: actions/checkout@v5.0.1
33+
# pnpm version is taken from package.json
34+
- name: Install pnpm
35+
uses: pnpm/action-setup@v4
36+
- name: Use Node.js 20
37+
uses: actions/setup-node@v6.0.0
38+
with:
39+
node-version: 20
40+
cache: "pnpm"
41+
- name: Install dependencies
42+
run: pnpm install
43+
- name: Build
44+
run: pnpm build
45+
- name: Test
46+
run: pnpm test
47+
48+
playwright-e2e:
49+
timeout-minutes: 60
50+
runs-on: ubuntu-latest
51+
steps:
52+
- uses: actions/checkout@v5.0.1
53+
# pnpm version is taken from package.json
54+
- name: Install pnpm
55+
uses: pnpm/action-setup@v4
56+
- name: Use Node.js 20
57+
uses: actions/setup-node@v6.0.0
58+
with:
59+
node-version: 20
60+
cache: "pnpm"
61+
- name: Install dependencies
62+
run: pnpm install
63+
- name: Install Playwright Browsers
64+
working-directory: ./compiler
65+
run: pnpm exec playwright install --with-deps
66+
- name: Prepare tests
67+
working-directory: ./compiler
68+
run: pnpm run test:prepare
69+
- name: Run tests
70+
working-directory: ./compiler
71+
run: pnpm run test:e2e
72+
- uses: actions/upload-artifact@v4
73+
if: ${{ !cancelled() }}
74+
with:
75+
name: playwright-report
76+
path: playwright-report/
77+
retention-days: 30

cmp/.gitignore

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Dependencies
2+
node_modules/
3+
.pnpm-store/
4+
5+
# Build outputs
6+
dist/
7+
build/
8+
*.tsbuildinfo
9+
10+
# Turbo
11+
.turbo/
12+
13+
# Environment variables
14+
.env
15+
.env*.local
16+
17+
# IDE
18+
.vscode/
19+
.idea/
20+
*.swp
21+
*.swo
22+
*~
23+
24+
# OS
25+
.DS_Store
26+
Thumbs.db
27+
28+
# Logs
29+
*.log
30+
npm-debug.log*
31+
pnpm-debug.log*
32+
yarn-debug.log*
33+
yarn-error.log*
34+
35+
# Testing
36+
coverage/
37+
.nyc_output/
38+
39+
# Misc
40+
*.local

cmp/.husky/pre-commit

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
./node_modules/.bin/nano-staged

cmp/.npmrc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Use pnpm for package management
2+
shamefully-hoist=false
3+
strict-peer-dependencies=false
4+
5+
# Lockfile settings
6+
lockfile=true

cmp/.prettierignore

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
pnpm-lock.yaml
2+
.changeset/
3+
packages/cli/demo/
4+
build/
5+
dist/
6+
.react-router/
7+
.turbo/
8+
.next/
9+
CLAUDE.md
10+
**/routeTree.gen.ts

cmp/.prettierrc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"trailingComma": "all",
3+
"singleQuote": false,
4+
"semi": true,
5+
"printWidth": 80,
6+
"tabWidth": 2,
7+
"useTabs": false
8+
}

cmp/README.md

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
# Lingo.dev compiler
2+
3+
Lingo.dev compiler with automatic translation support for React applications.
4+
5+
This package provides plugins for multiple bundlers (Vite, Webpack) and Next.js that
6+
automatically transforms React components to inject translation calls.
7+
8+
## Features
9+
10+
- **Automatic JSX text transformation** - Automatically detects and transforms translatable text in JSX
11+
- **Opt-in or automatic** - Configure whether to require `'use i18n'` directive or transform all files
12+
- **Multi-bundler support** - Works with Vite, Webpack and Next.js (both Webpack and Turbopack builds)
13+
- **Translation server** - On-demand translation generation during development
14+
- **AI-powered translations** - Support for multiple LLM providers and Lingo.dev Engine
15+
16+
## Getting started
17+
18+
Install the package - `pnpm install @lingo.dev/compiler`
19+
20+
### Vite
21+
22+
- Configure the plugin in your vite config.
23+
24+
```ts
25+
import { defineConfig } from "vite";
26+
import { lingoCompilerPlugin } from "@lingo.dev/compiler/vite";
27+
28+
export default defineConfig({
29+
plugins: [
30+
lingoCompilerPlugin({
31+
sourceRoot: "src",
32+
sourceLocale: "en",
33+
targetLocales: ["es", "de", "fr"],
34+
models: "lingo.dev",
35+
dev: {
36+
usePseudotranslator: true,
37+
},
38+
}), // ...other plugins
39+
],
40+
});
41+
```
42+
43+
- Wrap your app with `LingoProvider`. It should be used as early as possible in your app.
44+
e.g. in vite example with tanstack-router `LingoProvider` should be above `RouterProvider`, otherwise code-splitting breaks contexts.
45+
```tsx
46+
// Imports and other tanstack router setup
47+
if (rootElement && !rootElement.innerHTML) {
48+
const root = ReactDOM.createRoot(rootElement);
49+
root.render(
50+
<StrictMode>
51+
<LingoProvider>
52+
<RouterProvider router={router} />
53+
</LingoProvider>
54+
</StrictMode>,
55+
);
56+
}
57+
```
58+
59+
See `demo/vite-react-spa` for the working example
60+
61+
### Next.js
62+
63+
- Use `withLingo` function to wrap your existing next config. You will have to make your config async.
64+
65+
```ts
66+
import type { NextConfig } from "next";
67+
import { withLingo } from "@lingo.dev/compiler/next";
68+
69+
const nextConfig: NextConfig = {};
70+
71+
export default async function (): Promise<NextConfig> {
72+
return await withLingo(nextConfig, {
73+
sourceRoot: "./app",
74+
sourceLocale: "en",
75+
targetLocales: ["es", "de", "ru"],
76+
models: "lingo.dev",
77+
dev: {
78+
usePseudotranslator: true,
79+
},
80+
buildMode: "cache-only",
81+
});
82+
}
83+
```
84+
85+
- Wrap your app with `LingoProvider`. It should be used as early as possible in your app, root `Layout` is a good place.
86+
```tsx
87+
export default function RootLayout({
88+
children,
89+
}: Readonly<{ children: React.ReactNode }>) {
90+
return (
91+
<LingoProvider>
92+
<html>
93+
<body className="antialiased">{children}</body>
94+
</html>
95+
</LingoProvider>
96+
);
97+
}
98+
```
99+
100+
## Development
101+
102+
`pnpm install` from project root
103+
`pnpm turbo dev --filter=@lingo.dev/compile` to compile and watch for compiler changes
104+
105+
Choose the demo you want to work with and run it from the corresponding folder.
106+
`tsdown` in compiler is configured to cleanup the output folder before compilation, which works fine with next, but vite
107+
seems to be dead every time and has to be restarted.

cmp/compiler/.gitignore

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
2+
# Playwright
3+
node_modules/
4+
/test-results/
5+
/playwright-report/
6+
/blob-report/
7+
/playwright/.cache/
8+
/playwright/.auth/
9+
10+
# Translation server logs
11+
translation-server.log

cmp/compiler/README.md

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
# @lingo.dev/compiler
2+
3+
See the main [README](../README.md) for general information.
4+
5+
## Structure
6+
7+
The compiler is organized into several key modules:
8+
9+
### Core Directories
10+
11+
#### `src/plugin/` - Build-time transformation
12+
13+
- **`transform/`** - Babel AST transformation logic for JSX text extraction
14+
- **`unplugin.ts`** - Universal plugin implementation (Vite, Webpack)
15+
- **`next.ts`** - Next.js-specific plugin with Turbopack and Webpack support
16+
- **`build-translator.ts`** - Batch translation generation at build time
17+
- **`virtual-modules-code-generator.ts`** - Generates code for virtual modules, dev config and locale resolvers for client and server
18+
19+
#### `src/metadata/` - Translation metadata management
20+
21+
- **`manager.ts`** - CRUD operations for `.lingo/metadata.json`
22+
- Thread-safe metadata file operations with file locking
23+
- Manages translation entries with hash-based identifiers
24+
25+
#### `src/translators/` - Translation provider abstraction
26+
27+
- **`lcp/`** - Lingo.dev Engine integration
28+
- **`pseudotranslator/`** - Development-mode fake translator
29+
- **`pluralization/`** - Automatic ICU MessageFormat detection
30+
- **`translator-factory.ts`** - Provider selection and initialization
31+
32+
#### `src/translation-server/` - Development server
33+
34+
- **`translation-server.ts`** - HTTP server for on-demand translations
35+
- **`cli.ts`** - Standalone CLI for translation generation
36+
- WebSocket support for real-time dev widget updates
37+
- Port management (60000-60099 range)
38+
39+
#### `src/react/` - Runtime translation hooks
40+
41+
- **`client/`** - Client-side Context-based hooks
42+
- **`server/`** - Server component cache-based hooks (isomorphic)
43+
- **`server-only/`** - Async server-only API (`getServerTranslations`)
44+
- **`shared/`** - Shared utilities (RichText rendering, Context)
45+
- **`next/`** - Next.js-specific middleware and locale switcher
46+
47+
#### `src/utils/` - Shared utilities
48+
49+
- **`hash.ts`** - Stable hash generation for translation keys
50+
- **`config-factory.ts`** - Configuration defaults and merging
51+
- **`logger.ts`** - Structured logging utilities
52+
- **`path-helpers.ts`** - File path resolution
53+
54+
#### `src/widget/` - Development widget
55+
56+
- In-browser translation editor overlay for development mode
57+
58+
### Support Directories
59+
60+
#### `tests/` - End-to-end testing
61+
62+
- **`e2e/`** - Playwright tests for full build workflows
63+
- **`fixtures/`** - Test applications (Vite, Next.js)
64+
- **`helpers/`** - Test utilities and assertions
65+
66+
#### `benchmarks/` - Performance benchmarks
67+
68+
- Translation speed benchmarks
69+
- Metadata I/O performance tests
70+
71+
#### `old-docs/` - Legacy documentation
72+
73+
- Historical design documents and notes
74+
75+
### Entry Points
76+
77+
- **`src/index.ts`** - Main package exports (plugins, types)
78+
- **`src/types.ts`** - Core TypeScript types
79+
80+
## Contributing
81+
82+
This is a beta package under active development. Feedback and contributions are welcome!
83+
84+
## License
85+
86+
ISC

0 commit comments

Comments
 (0)