#
tokens: 49954/50000 117/626 files (page 2/20)
lines: on (toggle) GitHub
raw markdown copy reset
This is page 2 of 20. Use http://codebase.md/lingodotdev/lingo.dev?lines=true&page={x} to view the full context.

# Directory Structure

```
├── .changeset
│   ├── config.json
│   └── README.md
├── .claude
│   ├── agents
│   │   └── code-architect-reviewer.md
│   └── commands
│       ├── analyze-bucket-type.md
│       └── create-bucket-docs.md
├── .editorconfig
├── .github
│   ├── dependabot.yml
│   └── workflows
│       ├── docker.yml
│       ├── lingodotdev.yml
│       ├── pr-check.yml
│       ├── pr-lint.yml
│       └── release.yml
├── .gitignore
├── .husky
│   └── commit-msg
├── .npmrc
├── .prettierignore
├── .prettierrc
├── .vscode
│   ├── extensions.json
│   ├── launch.json
│   └── settings.json
├── action.yml
├── CLAUDE.md
├── CODE_OF_CONDUCT.md
├── commitlint.config.js
├── composer.json
├── content
│   ├── banner.compiler.png
│   ├── banner.dark.png
│   └── banner.launch.png
├── CONTRIBUTING.md
├── DEBUGGING.md
├── demo
│   ├── adonisjs
│   │   ├── .editorconfig
│   │   ├── .env.example
│   │   ├── .gitignore
│   │   ├── ace.js
│   │   ├── adonisrc.ts
│   │   ├── app
│   │   │   ├── exceptions
│   │   │   │   └── handler.ts
│   │   │   └── middleware
│   │   │       └── container_bindings_middleware.ts
│   │   ├── bin
│   │   │   ├── console.ts
│   │   │   ├── server.ts
│   │   │   └── test.ts
│   │   ├── CHANGELOG.md
│   │   ├── config
│   │   │   ├── app.ts
│   │   │   ├── bodyparser.ts
│   │   │   ├── cors.ts
│   │   │   ├── hash.ts
│   │   │   ├── inertia.ts
│   │   │   ├── logger.ts
│   │   │   ├── session.ts
│   │   │   ├── shield.ts
│   │   │   ├── static.ts
│   │   │   └── vite.ts
│   │   ├── eslint.config.js
│   │   ├── inertia
│   │   │   ├── app
│   │   │   │   ├── app.tsx
│   │   │   │   └── ssr.tsx
│   │   │   ├── css
│   │   │   │   └── app.css
│   │   │   ├── lingo
│   │   │   │   ├── dictionary.js
│   │   │   │   └── meta.json
│   │   │   ├── pages
│   │   │   │   ├── errors
│   │   │   │   │   ├── not_found.tsx
│   │   │   │   │   └── server_error.tsx
│   │   │   │   └── home.tsx
│   │   │   └── tsconfig.json
│   │   ├── package.json
│   │   ├── README.md
│   │   ├── resources
│   │   │   └── views
│   │   │       └── inertia_layout.edge
│   │   ├── start
│   │   │   ├── env.ts
│   │   │   ├── kernel.ts
│   │   │   └── routes.ts
│   │   ├── tests
│   │   │   └── bootstrap.ts
│   │   ├── tsconfig.json
│   │   └── vite.config.ts
│   ├── next-app
│   │   ├── .gitignore
│   │   ├── CHANGELOG.md
│   │   ├── eslint.config.mjs
│   │   ├── next.config.ts
│   │   ├── package.json
│   │   ├── postcss.config.mjs
│   │   ├── public
│   │   │   ├── file.svg
│   │   │   ├── globe.svg
│   │   │   ├── next.svg
│   │   │   ├── vercel.svg
│   │   │   └── window.svg
│   │   ├── README.md
│   │   ├── src
│   │   │   ├── app
│   │   │   │   ├── client-component.tsx
│   │   │   │   ├── favicon.ico
│   │   │   │   ├── globals.css
│   │   │   │   ├── layout.tsx
│   │   │   │   ├── lingo-dot-dev.tsx
│   │   │   │   ├── page.tsx
│   │   │   │   └── test
│   │   │   │       └── page.tsx
│   │   │   ├── components
│   │   │   │   ├── hero-actions.tsx
│   │   │   │   ├── hero-subtitle.tsx
│   │   │   │   ├── hero-title.tsx
│   │   │   │   └── index.ts
│   │   │   └── lingo
│   │   │       ├── dictionary.js
│   │   │       └── meta.json
│   │   └── tsconfig.json
│   ├── react-router-app
│   │   ├── .dockerignore
│   │   ├── .gitignore
│   │   ├── app
│   │   │   ├── app.css
│   │   │   ├── lingo
│   │   │   │   ├── dictionary.js
│   │   │   │   └── meta.json
│   │   │   ├── root.tsx
│   │   │   ├── routes
│   │   │   │   ├── home.tsx
│   │   │   │   └── test.tsx
│   │   │   ├── routes.ts
│   │   │   └── welcome
│   │   │       ├── lingo-dot-dev.tsx
│   │   │       ├── logo-dark.svg
│   │   │       ├── logo-light.svg
│   │   │       └── welcome.tsx
│   │   ├── Dockerfile
│   │   ├── package.json
│   │   ├── public
│   │   │   └── favicon.ico
│   │   ├── react-router.config.ts
│   │   ├── README.md
│   │   ├── tsconfig.json
│   │   └── vite.config.ts
│   └── vite-project
│       ├── .gitignore
│       ├── CHANGELOG.md
│       ├── eslint.config.js
│       ├── index.html
│       ├── package.json
│       ├── public
│       │   └── vite.svg
│       ├── README.md
│       ├── src
│       │   ├── App.css
│       │   ├── App.tsx
│       │   ├── assets
│       │   │   └── react.svg
│       │   ├── components
│       │   │   └── test.tsx
│       │   ├── index.css
│       │   ├── lingo
│       │   │   ├── dictionary.js
│       │   │   └── meta.json
│       │   ├── lingo-dot-dev.tsx
│       │   ├── main.tsx
│       │   └── vite-env.d.ts
│       ├── tsconfig.app.json
│       ├── tsconfig.json
│       ├── tsconfig.node.json
│       └── vite.config.ts
├── Dockerfile
├── i18n.json
├── i18n.lock
├── integrations
│   └── directus
│       ├── .gitignore
│       ├── CHANGELOG.md
│       ├── docker-compose.yml
│       ├── Dockerfile
│       ├── package.json
│       ├── README.md
│       ├── src
│       │   ├── api.ts
│       │   ├── app.ts
│       │   └── index.spec.ts
│       ├── tsconfig.json
│       ├── tsconfig.test.json
│       └── tsup.config.ts
├── ISSUE_TEMPLATE.md
├── legacy
│   ├── cli
│   │   ├── bin
│   │   │   └── cli.mjs
│   │   ├── CHANGELOG.md
│   │   ├── package.json
│   │   └── readme.md
│   └── sdk
│       ├── CHANGELOG.md
│       ├── index.d.ts
│       ├── index.js
│       ├── package.json
│       └── README.md
├── LICENSE.md
├── mcp.md
├── package.json
├── packages
│   ├── cli
│   │   ├── assets
│   │   │   ├── failure.mp3
│   │   │   └── success.mp3
│   │   ├── bin
│   │   │   └── cli.mjs
│   │   ├── CHANGELOG.md
│   │   ├── demo
│   │   │   ├── android
│   │   │   │   ├── en
│   │   │   │   │   └── example.xml
│   │   │   │   ├── es
│   │   │   │   │   └── example.xml
│   │   │   │   ├── i18n.json
│   │   │   │   └── i18n.lock
│   │   │   ├── csv
│   │   │   │   ├── example.csv
│   │   │   │   ├── i18n.json
│   │   │   │   └── i18n.lock
│   │   │   ├── demo.spec.ts
│   │   │   ├── ejs
│   │   │   │   ├── en
│   │   │   │   │   └── example.ejs
│   │   │   │   ├── es
│   │   │   │   │   └── example.ejs
│   │   │   │   ├── i18n.json
│   │   │   │   └── i18n.lock
│   │   │   ├── flutter
│   │   │   │   ├── en
│   │   │   │   │   └── example.arb
│   │   │   │   ├── es
│   │   │   │   │   └── example.arb
│   │   │   │   ├── i18n.json
│   │   │   │   └── i18n.lock
│   │   │   ├── html
│   │   │   │   ├── en
│   │   │   │   │   └── example.html
│   │   │   │   ├── es
│   │   │   │   │   └── example.html
│   │   │   │   ├── i18n.json
│   │   │   │   └── i18n.lock
│   │   │   ├── json
│   │   │   │   ├── en
│   │   │   │   │   └── example.json
│   │   │   │   ├── es
│   │   │   │   │   └── example.json
│   │   │   │   ├── i18n.json
│   │   │   │   └── i18n.lock
│   │   │   ├── json-dictionary
│   │   │   │   ├── example.json
│   │   │   │   ├── i18n.json
│   │   │   │   └── i18n.lock
│   │   │   ├── json5
│   │   │   │   ├── en
│   │   │   │   │   └── example.json5
│   │   │   │   ├── es
│   │   │   │   │   └── example.json5
│   │   │   │   ├── i18n.json
│   │   │   │   └── i18n.lock
│   │   │   ├── jsonc
│   │   │   │   ├── en
│   │   │   │   │   └── example.jsonc
│   │   │   │   ├── es
│   │   │   │   │   └── example.jsonc
│   │   │   │   ├── i18n.json
│   │   │   │   ├── i18n.lock
│   │   │   │   └── ru
│   │   │   │       └── example.jsonc
│   │   │   ├── markdoc
│   │   │   │   ├── en
│   │   │   │   │   └── example.markdoc
│   │   │   │   ├── es
│   │   │   │   │   └── example.markdoc
│   │   │   │   ├── i18n.json
│   │   │   │   └── i18n.lock
│   │   │   ├── markdown
│   │   │   │   ├── en
│   │   │   │   │   └── example.md
│   │   │   │   ├── es
│   │   │   │   │   └── example.md
│   │   │   │   ├── i18n.json
│   │   │   │   └── i18n.lock
│   │   │   ├── mdx
│   │   │   │   ├── en
│   │   │   │   │   └── example.mdx
│   │   │   │   ├── es
│   │   │   │   │   └── example.mdx
│   │   │   │   ├── i18n.json
│   │   │   │   └── i18n.lock
│   │   │   ├── php
│   │   │   │   ├── en
│   │   │   │   │   └── example.php
│   │   │   │   ├── es
│   │   │   │   │   └── example.php
│   │   │   │   ├── i18n.json
│   │   │   │   └── i18n.lock
│   │   │   ├── po
│   │   │   │   ├── en
│   │   │   │   │   └── example.po
│   │   │   │   ├── es
│   │   │   │   │   └── example.po
│   │   │   │   ├── i18n.json
│   │   │   │   └── i18n.lock
│   │   │   ├── properties
│   │   │   │   ├── en
│   │   │   │   │   └── example.properties
│   │   │   │   ├── es
│   │   │   │   │   └── example.properties
│   │   │   │   ├── i18n.json
│   │   │   │   └── i18n.lock
│   │   │   ├── run_i18n.sh
│   │   │   ├── srt
│   │   │   │   ├── en
│   │   │   │   │   └── example.srt
│   │   │   │   ├── es
│   │   │   │   │   └── example.srt
│   │   │   │   ├── i18n.json
│   │   │   │   └── i18n.lock
│   │   │   ├── txt
│   │   │   │   ├── en
│   │   │   │   │   └── example.txt
│   │   │   │   ├── es
│   │   │   │   │   └── example.txt
│   │   │   │   ├── i18n.json
│   │   │   │   └── i18n.lock
│   │   │   ├── typescript
│   │   │   │   ├── en
│   │   │   │   │   └── example.ts
│   │   │   │   ├── es
│   │   │   │   │   └── example.ts
│   │   │   │   ├── i18n.json
│   │   │   │   └── i18n.lock
│   │   │   ├── vtt
│   │   │   │   ├── en
│   │   │   │   │   └── example.vtt
│   │   │   │   ├── es
│   │   │   │   │   └── example.vtt
│   │   │   │   ├── i18n.json
│   │   │   │   └── i18n.lock
│   │   │   ├── vue-json
│   │   │   │   ├── example.vue
│   │   │   │   ├── i18n.json
│   │   │   │   └── i18n.lock
│   │   │   ├── xcode-strings
│   │   │   │   ├── en
│   │   │   │   │   └── example.strings
│   │   │   │   ├── es
│   │   │   │   │   └── example.strings
│   │   │   │   ├── i18n.json
│   │   │   │   └── i18n.lock
│   │   │   ├── xcode-stringsdict
│   │   │   │   ├── en
│   │   │   │   │   └── example.stringsdict
│   │   │   │   ├── es
│   │   │   │   │   └── example.stringsdict
│   │   │   │   ├── i18n.json
│   │   │   │   └── i18n.lock
│   │   │   ├── xcode-xcstrings
│   │   │   │   ├── example.xcstrings
│   │   │   │   ├── i18n.json
│   │   │   │   └── i18n.lock
│   │   │   ├── xcode-xcstrings-v2
│   │   │   │   ├── complex-example.xcstrings
│   │   │   │   ├── example.xcstrings
│   │   │   │   ├── i18n.json
│   │   │   │   └── i18n.lock
│   │   │   ├── xliff
│   │   │   │   ├── en
│   │   │   │   │   ├── example-v1.2.xliff
│   │   │   │   │   └── example-v2.xliff
│   │   │   │   ├── es
│   │   │   │   │   ├── example-v1.2.xliff
│   │   │   │   │   ├── example-v2.xliff
│   │   │   │   │   └── example.xliff
│   │   │   │   ├── i18n.json
│   │   │   │   └── i18n.lock
│   │   │   ├── xml
│   │   │   │   ├── en
│   │   │   │   │   └── example.xml
│   │   │   │   ├── es
│   │   │   │   │   └── example.xml
│   │   │   │   ├── i18n.json
│   │   │   │   └── i18n.lock
│   │   │   ├── yaml
│   │   │   │   ├── en
│   │   │   │   │   └── example.yml
│   │   │   │   ├── es
│   │   │   │   │   └── example.yml
│   │   │   │   ├── i18n.json
│   │   │   │   └── i18n.lock
│   │   │   └── yaml-root-key
│   │   │       ├── en
│   │   │       │   └── example.yml
│   │   │       ├── es
│   │   │       │   └── example.yml
│   │   │       ├── i18n.json
│   │   │       └── i18n.lock
│   │   ├── i18n.json
│   │   ├── i18n.lock
│   │   ├── package.json
│   │   ├── README.md
│   │   ├── src
│   │   │   ├── cli
│   │   │   │   ├── cmd
│   │   │   │   │   ├── auth.ts
│   │   │   │   │   ├── ci
│   │   │   │   │   │   ├── flows
│   │   │   │   │   │   │   ├── _base.ts
│   │   │   │   │   │   │   ├── in-branch.ts
│   │   │   │   │   │   │   └── pull-request.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── platforms
│   │   │   │   │   │       ├── _base.ts
│   │   │   │   │   │       ├── bitbucket.ts
│   │   │   │   │   │       ├── github.ts
│   │   │   │   │   │       ├── gitlab.ts
│   │   │   │   │   │       └── index.ts
│   │   │   │   │   ├── cleanup.ts
│   │   │   │   │   ├── config
│   │   │   │   │   │   ├── get.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── set.ts
│   │   │   │   │   │   └── unset.ts
│   │   │   │   │   ├── i18n.ts
│   │   │   │   │   ├── init.ts
│   │   │   │   │   ├── lockfile.ts
│   │   │   │   │   ├── login.ts
│   │   │   │   │   ├── logout.ts
│   │   │   │   │   ├── may-the-fourth.ts
│   │   │   │   │   ├── mcp.ts
│   │   │   │   │   ├── purge.ts
│   │   │   │   │   ├── run
│   │   │   │   │   │   ├── _const.ts
│   │   │   │   │   │   ├── _types.ts
│   │   │   │   │   │   ├── _utils.ts
│   │   │   │   │   │   ├── execute.spec.ts
│   │   │   │   │   │   ├── execute.ts
│   │   │   │   │   │   ├── frozen.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── plan.ts
│   │   │   │   │   │   ├── setup.ts
│   │   │   │   │   │   └── watch.ts
│   │   │   │   │   ├── show
│   │   │   │   │   │   ├── _shared-key-command.ts
│   │   │   │   │   │   ├── config.ts
│   │   │   │   │   │   ├── files.ts
│   │   │   │   │   │   ├── ignored-keys.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── locale.ts
│   │   │   │   │   │   └── locked-keys.ts
│   │   │   │   │   └── status.ts
│   │   │   │   ├── constants.ts
│   │   │   │   ├── index.spec.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── loaders
│   │   │   │   │   ├── _types.ts
│   │   │   │   │   ├── _utils.ts
│   │   │   │   │   ├── android.spec.ts
│   │   │   │   │   ├── android.ts
│   │   │   │   │   ├── csv.spec.ts
│   │   │   │   │   ├── csv.ts
│   │   │   │   │   ├── dato
│   │   │   │   │   │   ├── _base.ts
│   │   │   │   │   │   ├── _utils.ts
│   │   │   │   │   │   ├── api.ts
│   │   │   │   │   │   ├── extract.ts
│   │   │   │   │   │   ├── filter.ts
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── ejs.spec.ts
│   │   │   │   │   ├── ejs.ts
│   │   │   │   │   ├── ensure-key-order.spec.ts
│   │   │   │   │   ├── ensure-key-order.ts
│   │   │   │   │   ├── flat.spec.ts
│   │   │   │   │   ├── flat.ts
│   │   │   │   │   ├── flutter.spec.ts
│   │   │   │   │   ├── flutter.ts
│   │   │   │   │   ├── formatters
│   │   │   │   │   │   ├── _base.ts
│   │   │   │   │   │   ├── biome.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── prettier.ts
│   │   │   │   │   ├── html.ts
│   │   │   │   │   ├── icu-safety.spec.ts
│   │   │   │   │   ├── ignored-keys-buckets.spec.ts
│   │   │   │   │   ├── ignored-keys.spec.ts
│   │   │   │   │   ├── ignored-keys.ts
│   │   │   │   │   ├── index.spec.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── inject-locale.spec.ts
│   │   │   │   │   ├── inject-locale.ts
│   │   │   │   │   ├── json-dictionary.spec.ts
│   │   │   │   │   ├── json-dictionary.ts
│   │   │   │   │   ├── json-sorting.test.ts
│   │   │   │   │   ├── json-sorting.ts
│   │   │   │   │   ├── json.ts
│   │   │   │   │   ├── json5.spec.ts
│   │   │   │   │   ├── json5.ts
│   │   │   │   │   ├── jsonc.spec.ts
│   │   │   │   │   ├── jsonc.ts
│   │   │   │   │   ├── locked-keys.spec.ts
│   │   │   │   │   ├── locked-keys.ts
│   │   │   │   │   ├── locked-patterns.spec.ts
│   │   │   │   │   ├── locked-patterns.ts
│   │   │   │   │   ├── markdoc.spec.ts
│   │   │   │   │   ├── markdoc.ts
│   │   │   │   │   ├── markdown.ts
│   │   │   │   │   ├── mdx.spec.ts
│   │   │   │   │   ├── mdx.ts
│   │   │   │   │   ├── mdx2
│   │   │   │   │   │   ├── _types.ts
│   │   │   │   │   │   ├── _utils.ts
│   │   │   │   │   │   ├── code-placeholder.spec.ts
│   │   │   │   │   │   ├── code-placeholder.ts
│   │   │   │   │   │   ├── frontmatter-split.spec.ts
│   │   │   │   │   │   ├── frontmatter-split.ts
│   │   │   │   │   │   ├── localizable-document.spec.ts
│   │   │   │   │   │   ├── localizable-document.ts
│   │   │   │   │   │   ├── section-split.spec.ts
│   │   │   │   │   │   ├── section-split.ts
│   │   │   │   │   │   └── sections-split-2.ts
│   │   │   │   │   ├── passthrough.ts
│   │   │   │   │   ├── php.ts
│   │   │   │   │   ├── plutil-json-loader.ts
│   │   │   │   │   ├── po
│   │   │   │   │   │   ├── _types.ts
│   │   │   │   │   │   ├── index.spec.ts
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── properties.ts
│   │   │   │   │   ├── root-key.ts
│   │   │   │   │   ├── srt.ts
│   │   │   │   │   ├── sync.ts
│   │   │   │   │   ├── text-file.ts
│   │   │   │   │   ├── txt.ts
│   │   │   │   │   ├── typescript
│   │   │   │   │   │   ├── cjs-interop.ts
│   │   │   │   │   │   ├── index.spec.ts
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── unlocalizable.spec.ts
│   │   │   │   │   ├── unlocalizable.ts
│   │   │   │   │   ├── variable
│   │   │   │   │   │   ├── index.spec.ts
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── vtt.ts
│   │   │   │   │   ├── vue-json.ts
│   │   │   │   │   ├── xcode-strings
│   │   │   │   │   │   ├── escape.ts
│   │   │   │   │   │   ├── parser.ts
│   │   │   │   │   │   ├── tokenizer.ts
│   │   │   │   │   │   └── types.ts
│   │   │   │   │   ├── xcode-strings.spec.ts
│   │   │   │   │   ├── xcode-strings.ts
│   │   │   │   │   ├── xcode-stringsdict.ts
│   │   │   │   │   ├── xcode-xcstrings-icu.spec.ts
│   │   │   │   │   ├── xcode-xcstrings-icu.ts
│   │   │   │   │   ├── xcode-xcstrings-lock-compatibility.spec.ts
│   │   │   │   │   ├── xcode-xcstrings-v2-loader.ts
│   │   │   │   │   ├── xcode-xcstrings.spec.ts
│   │   │   │   │   ├── xcode-xcstrings.ts
│   │   │   │   │   ├── xliff.spec.ts
│   │   │   │   │   ├── xliff.ts
│   │   │   │   │   ├── xml.ts
│   │   │   │   │   └── yaml.ts
│   │   │   │   ├── localizer
│   │   │   │   │   ├── _types.ts
│   │   │   │   │   ├── explicit.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── lingodotdev.ts
│   │   │   │   ├── processor
│   │   │   │   │   ├── _base.ts
│   │   │   │   │   ├── basic.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── lingo.ts
│   │   │   │   └── utils
│   │   │   │       ├── auth.ts
│   │   │   │       ├── buckets.spec.ts
│   │   │   │       ├── buckets.ts
│   │   │   │       ├── cache.ts
│   │   │   │       ├── cloudflare-status.ts
│   │   │   │       ├── config.ts
│   │   │   │       ├── delta.spec.ts
│   │   │   │       ├── delta.ts
│   │   │   │       ├── ensure-patterns.ts
│   │   │   │       ├── errors.ts
│   │   │   │       ├── exec.spec.ts
│   │   │   │       ├── exec.ts
│   │   │   │       ├── exit-gracefully.spec.ts
│   │   │   │       ├── exit-gracefully.ts
│   │   │   │       ├── exp-backoff.ts
│   │   │   │       ├── find-locale-paths.spec.ts
│   │   │   │       ├── find-locale-paths.ts
│   │   │   │       ├── fs.ts
│   │   │   │       ├── init-ci-cd.ts
│   │   │   │       ├── key-matching.spec.ts
│   │   │   │       ├── key-matching.ts
│   │   │   │       ├── lockfile.ts
│   │   │   │       ├── md5.ts
│   │   │   │       ├── observability.ts
│   │   │   │       ├── plutil-formatter.spec.ts
│   │   │   │       ├── plutil-formatter.ts
│   │   │   │       ├── settings.ts
│   │   │   │       ├── ui.ts
│   │   │   │       └── update-gitignore.ts
│   │   │   ├── compiler
│   │   │   │   └── index.ts
│   │   │   ├── locale-codes
│   │   │   │   └── index.ts
│   │   │   ├── react
│   │   │   │   ├── client.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── react-router.ts
│   │   │   │   └── rsc.ts
│   │   │   ├── sdk
│   │   │   │   └── index.ts
│   │   │   └── spec
│   │   │       └── index.ts
│   │   ├── tests
│   │   │   └── mock-storage.ts
│   │   ├── troubleshooting.md
│   │   ├── tsconfig.json
│   │   ├── tsconfig.test.json
│   │   ├── tsup.config.ts
│   │   ├── types
│   │   │   ├── vtt.d.ts
│   │   │   └── xliff.d.ts
│   │   ├── vitest.config.ts
│   │   └── WATCH_MODE.md
│   ├── compiler
│   │   ├── CHANGELOG.md
│   │   ├── package.json
│   │   ├── README.md
│   │   ├── src
│   │   │   ├── _base.ts
│   │   │   ├── _const.ts
│   │   │   ├── _loader-utils.spec.ts
│   │   │   ├── _loader-utils.ts
│   │   │   ├── _utils.spec.ts
│   │   │   ├── _utils.ts
│   │   │   ├── client-dictionary-loader.ts
│   │   │   ├── i18n-directive.spec.ts
│   │   │   ├── i18n-directive.ts
│   │   │   ├── index.spec.ts
│   │   │   ├── index.ts
│   │   │   ├── jsx-attribute-flag.spec.ts
│   │   │   ├── jsx-attribute-flag.ts
│   │   │   ├── jsx-attribute-scope-inject.spec.ts
│   │   │   ├── jsx-attribute-scope-inject.ts
│   │   │   ├── jsx-attribute-scopes-export.spec.ts
│   │   │   ├── jsx-attribute-scopes-export.ts
│   │   │   ├── jsx-attribute.spec.ts
│   │   │   ├── jsx-attribute.ts
│   │   │   ├── jsx-fragment.spec.ts
│   │   │   ├── jsx-fragment.ts
│   │   │   ├── jsx-html-lang.spec.ts
│   │   │   ├── jsx-html-lang.ts
│   │   │   ├── jsx-provider.spec.ts
│   │   │   ├── jsx-provider.ts
│   │   │   ├── jsx-remove-attributes.spec.ts
│   │   │   ├── jsx-remove-attributes.ts
│   │   │   ├── jsx-root-flag.spec.ts
│   │   │   ├── jsx-root-flag.ts
│   │   │   ├── jsx-scope-flag.spec.ts
│   │   │   ├── jsx-scope-flag.ts
│   │   │   ├── jsx-scope-inject.spec.ts
│   │   │   ├── jsx-scope-inject.ts
│   │   │   ├── jsx-scopes-export.spec.ts
│   │   │   ├── jsx-scopes-export.ts
│   │   │   ├── lib
│   │   │   │   └── lcp
│   │   │   │       ├── api
│   │   │   │       │   ├── index.ts
│   │   │   │       │   ├── prompt.spec.ts
│   │   │   │       │   ├── prompt.ts
│   │   │   │       │   ├── provider-details.spec.ts
│   │   │   │       │   ├── provider-details.ts
│   │   │   │       │   ├── shots.ts
│   │   │   │       │   ├── xml2obj.spec.ts
│   │   │   │       │   └── xml2obj.ts
│   │   │   │       ├── api.spec.ts
│   │   │   │       ├── cache.spec.ts
│   │   │   │       ├── cache.ts
│   │   │   │       ├── index.spec.ts
│   │   │   │       ├── index.ts
│   │   │   │       ├── schema.ts
│   │   │   │       ├── server.spec.ts
│   │   │   │       └── server.ts
│   │   │   ├── lingo-turbopack-loader.ts
│   │   │   ├── react-router-dictionary-loader.ts
│   │   │   ├── rsc-dictionary-loader.ts
│   │   │   └── utils
│   │   │       ├── ast-key.spec.ts
│   │   │       ├── ast-key.ts
│   │   │       ├── create-locale-import-map.spec.ts
│   │   │       ├── create-locale-import-map.ts
│   │   │       ├── env.spec.ts
│   │   │       ├── env.ts
│   │   │       ├── hash.spec.ts
│   │   │       ├── hash.ts
│   │   │       ├── index.spec.ts
│   │   │       ├── index.ts
│   │   │       ├── invokations.spec.ts
│   │   │       ├── invokations.ts
│   │   │       ├── jsx-attribute-scope.ts
│   │   │       ├── jsx-attribute.spec.ts
│   │   │       ├── jsx-attribute.ts
│   │   │       ├── jsx-content-whitespace.spec.ts
│   │   │       ├── jsx-content.spec.ts
│   │   │       ├── jsx-content.ts
│   │   │       ├── jsx-element.spec.ts
│   │   │       ├── jsx-element.ts
│   │   │       ├── jsx-expressions.test.ts
│   │   │       ├── jsx-expressions.ts
│   │   │       ├── jsx-functions.spec.ts
│   │   │       ├── jsx-functions.ts
│   │   │       ├── jsx-scope.spec.ts
│   │   │       ├── jsx-scope.ts
│   │   │       ├── jsx-variables.spec.ts
│   │   │       ├── jsx-variables.ts
│   │   │       ├── llm-api-key.ts
│   │   │       ├── llm-api-keys.spec.ts
│   │   │       ├── locales.spec.ts
│   │   │       ├── locales.ts
│   │   │       ├── module-params.spec.ts
│   │   │       ├── module-params.ts
│   │   │       ├── observability.spec.ts
│   │   │       ├── observability.ts
│   │   │       ├── rc.spec.ts
│   │   │       └── rc.ts
│   │   ├── tsconfig.json
│   │   ├── tsup.config.ts
│   │   └── vitest.config.ts
│   ├── locales
│   │   ├── CHANGELOG.md
│   │   ├── package.json
│   │   ├── README.md
│   │   ├── src
│   │   │   ├── constants.ts
│   │   │   ├── index.ts
│   │   │   ├── names
│   │   │   │   ├── index.spec.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── integration.spec.ts
│   │   │   │   └── loader.ts
│   │   │   ├── parser.spec.ts
│   │   │   ├── parser.ts
│   │   │   ├── types.ts
│   │   │   ├── validation.spec.ts
│   │   │   └── validation.ts
│   │   ├── tsconfig.json
│   │   └── tsup.config.ts
│   ├── react
│   │   ├── build.config.ts
│   │   ├── CHANGELOG.md
│   │   ├── package.json
│   │   ├── README.md
│   │   ├── src
│   │   │   ├── client
│   │   │   │   ├── attribute-component.spec.tsx
│   │   │   │   ├── attribute-component.tsx
│   │   │   │   ├── component.lingo-component.spec.tsx
│   │   │   │   ├── component.spec.tsx
│   │   │   │   ├── component.tsx
│   │   │   │   ├── context.spec.tsx
│   │   │   │   ├── context.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── loader.spec.ts
│   │   │   │   ├── loader.ts
│   │   │   │   ├── locale-switcher.spec.tsx
│   │   │   │   ├── locale-switcher.tsx
│   │   │   │   ├── locale.spec.ts
│   │   │   │   ├── locale.ts
│   │   │   │   ├── provider.spec.tsx
│   │   │   │   ├── provider.tsx
│   │   │   │   ├── utils.spec.ts
│   │   │   │   └── utils.ts
│   │   │   ├── core
│   │   │   │   ├── attribute-component.spec.tsx
│   │   │   │   ├── attribute-component.tsx
│   │   │   │   ├── component.spec.tsx
│   │   │   │   ├── component.tsx
│   │   │   │   ├── const.ts
│   │   │   │   ├── get-dictionary.spec.ts
│   │   │   │   ├── get-dictionary.ts
│   │   │   │   └── index.ts
│   │   │   ├── react-router
│   │   │   │   ├── index.ts
│   │   │   │   ├── loader.spec.ts
│   │   │   │   └── loader.ts
│   │   │   ├── rsc
│   │   │   │   ├── attribute-component.tsx
│   │   │   │   ├── component.lingo-component.spec.tsx
│   │   │   │   ├── component.spec.tsx
│   │   │   │   ├── component.tsx
│   │   │   │   ├── index.ts
│   │   │   │   ├── loader.spec.ts
│   │   │   │   ├── loader.ts
│   │   │   │   ├── provider.spec.tsx
│   │   │   │   ├── provider.tsx
│   │   │   │   ├── utils.spec.ts
│   │   │   │   └── utils.ts
│   │   │   └── test
│   │   │       └── setup.ts
│   │   ├── tsconfig.json
│   │   └── vitest.config.ts
│   ├── sdk
│   │   ├── CHANGELOG.md
│   │   ├── package.json
│   │   ├── README.md
│   │   ├── src
│   │   │   ├── abort-controller.specs.ts
│   │   │   ├── index.spec.ts
│   │   │   └── index.ts
│   │   ├── tsconfig.json
│   │   ├── tsconfig.test.json
│   │   └── tsup.config.ts
│   └── spec
│       ├── CHANGELOG.md
│       ├── package.json
│       ├── README.md
│       ├── src
│       │   ├── config.spec.ts
│       │   ├── config.ts
│       │   ├── formats.ts
│       │   ├── index.spec.ts
│       │   ├── index.ts
│       │   ├── json-schema.ts
│       │   ├── locales.spec.ts
│       │   └── locales.ts
│       ├── tsconfig.json
│       ├── tsconfig.test.json
│       └── tsup.config.ts
├── pnpm-lock.yaml
├── pnpm-workspace.yaml
├── readme
│   ├── ar.md
│   ├── bn.md
│   ├── de.md
│   ├── en.md
│   ├── es.md
│   ├── fa.md
│   ├── fr.md
│   ├── he.md
│   ├── hi.md
│   ├── it.md
│   ├── ja.md
│   ├── ko.md
│   ├── pl.md
│   ├── pt-BR.md
│   ├── ru.md
│   ├── tr.md
│   ├── uk-UA.md
│   └── zh-Hans.md
├── readme.md
├── scripts
│   ├── docs
│   │   ├── package.json
│   │   ├── README.md
│   │   ├── src
│   │   │   ├── generate-cli-docs.ts
│   │   │   ├── generate-config-docs.ts
│   │   │   ├── json-schema
│   │   │   │   ├── markdown-renderer.test.ts
│   │   │   │   ├── markdown-renderer.ts
│   │   │   │   ├── parser.test.ts
│   │   │   │   ├── parser.ts
│   │   │   │   └── types.ts
│   │   │   ├── utils.test.ts
│   │   │   └── utils.ts
│   │   ├── tsconfig.json
│   │   └── vitest.config.ts
│   └── packagist-publish.php
└── turbo.json
```

# Files

--------------------------------------------------------------------------------
/demo/adonisjs/app/middleware/container_bindings_middleware.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { Logger } from '@adonisjs/core/logger'
 2 | import { HttpContext } from '@adonisjs/core/http'
 3 | import { NextFn } from '@adonisjs/core/types/http'
 4 | 
 5 | /**
 6 |  * The container bindings middleware binds classes to their request
 7 |  * specific value using the container resolver.
 8 |  *
 9 |  * - We bind "HttpContext" class to the "ctx" object
10 |  * - And bind "Logger" class to the "ctx.logger" object
11 |  */
12 | export default class ContainerBindingsMiddleware {
13 |   handle(ctx: HttpContext, next: NextFn) {
14 |     ctx.containerResolver.bindValue(HttpContext, ctx)
15 |     ctx.containerResolver.bindValue(Logger, ctx.logger)
16 | 
17 |     return next()
18 |   }
19 | }
20 | 
```

--------------------------------------------------------------------------------
/demo/next-app/package.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "name": "next-app",
 3 |   "version": "0.2.79",
 4 |   "private": true,
 5 |   "scripts": {
 6 |     "dev": "next dev",
 7 |     "build": "NODE_ENV=production next build",
 8 |     "start": "next start",
 9 |     "lint": "next lint"
10 |   },
11 |   "dependencies": {
12 |     "lingo.dev": "workspace:*",
13 |     "react": "^19.0.0",
14 |     "react-dom": "^19.0.0",
15 |     "next": "15.3.1"
16 |   },
17 |   "devDependencies": {
18 |     "typescript": "^5",
19 |     "@types/node": "^20",
20 |     "@types/react": "^19",
21 |     "@types/react-dom": "^19",
22 |     "@tailwindcss/postcss": "^4",
23 |     "tailwindcss": "^4",
24 |     "eslint": "^9",
25 |     "eslint-config-next": "15.3.1",
26 |     "@eslint/eslintrc": "^3"
27 |   }
28 | }
29 | 
```

--------------------------------------------------------------------------------
/demo/adonisjs/config/vite.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { defineConfig } from '@adonisjs/vite'
 2 | 
 3 | const viteBackendConfig = defineConfig({
 4 |   /**
 5 |    * The output of vite will be written inside this
 6 |    * directory. The path should be relative from
 7 |    * the application root.
 8 |    */
 9 |   buildDirectory: 'public/assets',
10 | 
11 |   /**
12 |    * The path to the manifest file generated by the
13 |    * "vite build" command.
14 |    */
15 |   manifestFile: 'public/assets/.vite/manifest.json',
16 | 
17 |   /**
18 |    * Feel free to change the value of the "assetsUrl" to
19 |    * point to a CDN in production.
20 |    */
21 |   assetsUrl: '/assets',
22 | 
23 |   scriptAttributes: {
24 |     defer: true,
25 |   },
26 | })
27 | 
28 | export default viteBackendConfig
29 | 
```

--------------------------------------------------------------------------------
/legacy/sdk/package.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "name": "@replexica/sdk",
 3 |   "version": "0.7.11",
 4 |   "description": "[DEPRECATED] Replexica SDK (now Lingo.dev) - Please use lingo.dev instead",
 5 |   "private": false,
 6 |   "type": "module",
 7 |   "sideEffects": false,
 8 |   "types": "index.d.ts",
 9 |   "module": "index.js",
10 |   "main": "index.js",
11 |   "files": [
12 |     "index.js",
13 |     "index.d.ts"
14 |   ],
15 |   "keywords": [],
16 |   "author": "",
17 |   "license": "Apache-2.0",
18 |   "dependencies": {
19 |     "lingo.dev": "*"
20 |   },
21 |   "deprecated": "Replexica is now Lingo.dev! Please use our new SDK package by running: npm install lingo.dev. Visit https://lingo.dev for the latest features and documentation."
22 | }
23 | 
```

--------------------------------------------------------------------------------
/packages/cli/src/cli/utils/fs.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import * as fs from "fs";
 2 | import * as path from "path";
 3 | 
 4 | export function tryReadFile(
 5 |   filePath: string,
 6 |   defaultValue: string | null = null,
 7 | ): string | null {
 8 |   try {
 9 |     const content = fs.readFileSync(filePath, "utf-8");
10 |     return content;
11 |   } catch (error) {
12 |     return defaultValue;
13 |   }
14 | }
15 | 
16 | export function writeFile(filePath: string, content: string) {
17 |   // create dirs
18 |   const dir = path.dirname(filePath);
19 |   if (!fs.existsSync(dir)) {
20 |     fs.mkdirSync(dir, { recursive: true });
21 |   }
22 |   fs.writeFileSync(filePath, content);
23 | }
24 | 
25 | export function checkIfFileExists(filePath: string) {
26 |   return fs.existsSync(filePath);
27 | }
28 | 
```

--------------------------------------------------------------------------------
/demo/vite-project/tsconfig.node.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "compilerOptions": {
 3 |     "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
 4 |     "target": "ES2022",
 5 |     "lib": ["ES2023"],
 6 |     "module": "ESNext",
 7 |     "skipLibCheck": true,
 8 | 
 9 |     /* Bundler mode */
10 |     "moduleResolution": "bundler",
11 |     "allowImportingTsExtensions": true,
12 |     "verbatimModuleSyntax": true,
13 |     "moduleDetection": "force",
14 |     "noEmit": true,
15 | 
16 |     /* Linting */
17 |     "strict": true,
18 |     "noUnusedLocals": true,
19 |     "noUnusedParameters": true,
20 |     "erasableSyntaxOnly": true,
21 |     "noFallthroughCasesInSwitch": true,
22 |     "noUncheckedSideEffectImports": true
23 |   },
24 |   "include": ["vite.config.ts"]
25 | }
26 | 
```

--------------------------------------------------------------------------------
/demo/adonisjs/inertia/app/ssr.tsx:
--------------------------------------------------------------------------------

```typescript
 1 | import ReactDOMServer from 'react-dom/server'
 2 | import { createInertiaApp } from '@inertiajs/react'
 3 | import { LingoProviderWrapper, loadDictionary } from 'lingo.dev/react/client'
 4 | 
 5 | export default function render(page: any) {
 6 |   return createInertiaApp({
 7 |     page,
 8 |     render: ReactDOMServer.renderToString,
 9 |     resolve: (name) => {
10 |       const pages = import.meta.glob('../pages/**/*.tsx', { eager: true })
11 |       return pages[`../pages/${name}.tsx`]
12 |     },
13 |     setup: ({ App, props }) => (
14 |       <LingoProviderWrapper loadDictionary={(locale) => loadDictionary(locale)}>
15 |         <App {...props} />
16 |       </LingoProviderWrapper>
17 |     ),
18 |   })
19 | }
20 | 
```

--------------------------------------------------------------------------------
/packages/compiler/src/_utils.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import path from "path";
 2 | 
 3 | import { LCP_DICTIONARY_FILE_NAME } from "./_const";
 4 | 
 5 | export type GetDictionaryPathParams = {
 6 |   sourceRoot: string;
 7 |   lingoDir: string;
 8 |   relativeFilePath: string;
 9 | };
10 | export const getDictionaryPath = (params: GetDictionaryPathParams) => {
11 |   const toFile = path.resolve(
12 |     params.sourceRoot,
13 |     params.lingoDir,
14 |     LCP_DICTIONARY_FILE_NAME,
15 |   );
16 |   const fromDir = path.dirname(
17 |     path.resolve(params.sourceRoot, params.relativeFilePath),
18 |   );
19 |   const relativePath = path.relative(fromDir, toFile);
20 |   const normalizedPath = relativePath.split(path.sep).join(path.posix.sep);
21 |   return `./${normalizedPath}`;
22 | };
23 | 
```

--------------------------------------------------------------------------------
/packages/cli/src/cli/loaders/mdx2/localizable-document.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { ILoader } from "../_types";
 2 | import { createLoader } from "../_utils";
 3 | import { LocalizableMdxDocument, SectionedMdx } from "./_types";
 4 | 
 5 | export default function createLocalizableMdxDocumentLoader(): ILoader<
 6 |   SectionedMdx,
 7 |   LocalizableMdxDocument
 8 | > {
 9 |   return createLoader({
10 |     async pull(_locale, input) {
11 |       return {
12 |         meta: input.frontmatter,
13 |         content: input.sections,
14 |       };
15 |     },
16 | 
17 |     async push(_locale, data, originalInput, _originalLocale, pullInput) {
18 |       const result: SectionedMdx = {
19 |         frontmatter: data.meta || {},
20 |         sections: data.content || {},
21 |       };
22 | 
23 |       return result;
24 |     },
25 |   });
26 | }
27 | 
```

--------------------------------------------------------------------------------
/packages/cli/src/cli/loaders/json.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { jsonrepair } from "jsonrepair";
 2 | import { ILoader } from "./_types";
 3 | import { createLoader } from "./_utils";
 4 | 
 5 | export default function createJsonLoader(): ILoader<
 6 |   string,
 7 |   Record<string, any>
 8 | > {
 9 |   return createLoader({
10 |     pull: async (locale, input) => {
11 |       const jsonString = input || "{}";
12 |       let result: Record<string, any>;
13 |       try {
14 |         result = JSON.parse(jsonString);
15 |       } catch (error) {
16 |         result = JSON.parse(jsonrepair(jsonString));
17 |       }
18 |       return result;
19 |     },
20 |     push: async (locale, data) => {
21 |       const serializedData = JSON.stringify(data, null, 2);
22 |       return serializedData;
23 |     },
24 |   });
25 | }
26 | 
```

--------------------------------------------------------------------------------
/packages/react/src/client/attribute-component.tsx:
--------------------------------------------------------------------------------

```typescript
 1 | "use client";
 2 | 
 3 | import {
 4 |   LingoAttributeComponent as LingoCoreAttributeComponent,
 5 |   LingoAttributeComponentProps as LingoCoreAttributeComponentProps,
 6 | } from "../core";
 7 | import { useLingo } from "./context";
 8 | 
 9 | export type LingoAttributeComponentProps = Omit<
10 |   LingoCoreAttributeComponentProps,
11 |   "$dictionary"
12 | >;
13 | 
14 | export function LingoAttributeComponent(props: LingoAttributeComponentProps) {
15 |   const { $attrAs, $attributes, $fileKey, ...rest } = props;
16 |   const lingo = useLingo();
17 |   return (
18 |     <LingoCoreAttributeComponent
19 |       $dictionary={lingo.dictionary}
20 |       $as={$attrAs}
21 |       $attributes={$attributes}
22 |       $fileKey={$fileKey}
23 |       {...rest}
24 |     />
25 |   );
26 | }
27 | 
```

--------------------------------------------------------------------------------
/demo/next-app/src/components/hero-actions.tsx:
--------------------------------------------------------------------------------

```typescript
 1 | "use client";
 2 | 
 3 | export function HeroActions() {
 4 |   return (
 5 |     <div className="flex flex-row gap-4 justify-center items-center">
 6 |       <button className="px-8 py-3 bg-indigo-600 hover:bg-indigo-700 text-white font-medium rounded-lg transition-colors duration-200 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2">
 7 |         Get Started
 8 |       </button>
 9 | 
10 |       <button className="px-8 py-3 bg-white hover:bg-gray-50 text-gray-700 font-medium rounded-lg border border-gray-300 hover:border-gray-400 transition-colors duration-200 focus:outline-none focus:ring-2 focus:ring-gray-500 focus:ring-offset-2">
11 |         Learn More
12 |       </button>
13 |     </div>
14 |   );
15 | }
16 | 
```

--------------------------------------------------------------------------------
/demo/next-app/tsconfig.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "compilerOptions": {
 3 |     "target": "ES2017",
 4 |     "lib": ["dom", "dom.iterable", "esnext"],
 5 |     "allowJs": true,
 6 |     "skipLibCheck": true,
 7 |     "strict": true,
 8 |     "noEmit": true,
 9 |     "esModuleInterop": true,
10 |     "module": "esnext",
11 |     "moduleResolution": "bundler",
12 |     "resolveJsonModule": true,
13 |     "isolatedModules": true,
14 |     "jsx": "preserve",
15 |     "incremental": true,
16 |     "plugins": [
17 |       {
18 |         "name": "next"
19 |       }
20 |     ],
21 |     "paths": {
22 |       "@/*": ["./src/*"]
23 |     }
24 |   },
25 |   "include": [
26 |     "next-env.d.ts",
27 |     "**/*.ts",
28 |     "**/*.tsx",
29 |     ".next/types/**/*.ts",
30 |     "../react-router-app/app/welcome/lingo-dot-dev.tsx"
31 |   ],
32 |   "exclude": ["node_modules"]
33 | }
34 | 
```

--------------------------------------------------------------------------------
/packages/react/src/core/attribute-component.tsx:
--------------------------------------------------------------------------------

```typescript
 1 | import { createElement } from "react";
 2 | import _ from "lodash";
 3 | import React from "react";
 4 | 
 5 | export type LingoAttributeComponentProps = {
 6 |   $as: string;
 7 |   $attributes: Record<string, string>;
 8 |   $fileKey: string;
 9 |   [key: string]: any;
10 | };
11 | 
12 | export const LingoAttributeComponent = React.forwardRef(
13 |   (props: Omit<LingoAttributeComponentProps, "ref">, ref: React.Ref<any>) => {
14 |     const { $as, $attributes, $fileKey, $dictionary, ...rest } = props;
15 | 
16 |     const localizedAttributes = _.mapValues($attributes, (v, k) => {
17 |       return $dictionary?.files?.[$fileKey]?.entries?.[v] ?? k;
18 |     });
19 | 
20 |     return createElement($as, {
21 |       ...rest,
22 |       ...localizedAttributes,
23 |       ref,
24 |     });
25 |   },
26 | );
27 | 
```

--------------------------------------------------------------------------------
/packages/cli/demo/xml/es/example.xml:
--------------------------------------------------------------------------------

```
1 | <root><title>¡Hola, mundo!</title><description><summary>Aplicación de demostración simple</summary><details>Contenido de ejemplo básico</details></description><image src="photo.jpg" alt="Foto de ejemplo" title="Haz clic para ver"/><link href="example.com" label="Haz clic aquí">Más información</link><button type="submit" value="Enviar" placeholder="Introduce texto">Enviar</button><section><article><paragraph><sentence>Contenido anidado</sentence></paragraph></article></section><meta name="description" content="Metadatos de la aplicación de demostración"/><message><greeting>¡Hola!</greeting><body>Bienvenido a la aplicación</body><signature>Gracias, Equipo de MyApp</signature></message></root>
```

--------------------------------------------------------------------------------
/demo/vite-project/tsconfig.app.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "compilerOptions": {
 3 |     "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
 4 |     "target": "ES2020",
 5 |     "useDefineForClassFields": true,
 6 |     "lib": ["ES2020", "DOM", "DOM.Iterable"],
 7 |     "module": "ESNext",
 8 |     "skipLibCheck": true,
 9 | 
10 |     /* Bundler mode */
11 |     "moduleResolution": "bundler",
12 |     "allowImportingTsExtensions": true,
13 |     "verbatimModuleSyntax": true,
14 |     "moduleDetection": "force",
15 |     "noEmit": true,
16 |     "jsx": "react-jsx",
17 | 
18 |     /* Linting */
19 |     "strict": true,
20 |     "noUnusedLocals": true,
21 |     "noUnusedParameters": true,
22 |     "erasableSyntaxOnly": true,
23 |     "noFallthroughCasesInSwitch": true,
24 |     "noUncheckedSideEffectImports": true
25 |   },
26 |   "include": ["src"]
27 | }
28 | 
```

--------------------------------------------------------------------------------
/packages/cli/demo/json/es/example.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "title": "¡Hola, mundo!",
 3 |   "description": "Una aplicación de demostración simple",
 4 |   "version": "1.0.0",
 5 |   "support_email": "[email protected]",
 6 |   "homepage": "https://lingo.dev",
 7 |   "deprecated": null,
 8 |   "empty": "",
 9 |   "emoji": "🚀",
10 |   "author": {
11 |     "name": "Juan Pérez"
12 |   },
13 |   "contributors": [
14 |     {
15 |       "name": "Alicia"
16 |     },
17 |     {
18 |       "name": "Roberto"
19 |     }
20 |   ],
21 |   "messages": ["Bienvenido a Mi aplicación", "¡Hola, mundo!"],
22 |   "config": {
23 |     "theme": {
24 |       "primary": "Tema Azul"
25 |     }
26 |   },
27 |   "mixed_array": [
28 |     "Contenido mixto aquí",
29 |     42,
30 |     true,
31 |     {
32 |       "nested_message": "Texto anidado"
33 |     }
34 |   ],
35 |   "locked_key_1": "This value is locked and should not be changed"
36 | }
```

--------------------------------------------------------------------------------
/packages/cli/src/cli/loaders/_types.ts:
--------------------------------------------------------------------------------

```typescript
 1 | export interface ILoaderDefinition<I, O, C> {
 2 |   init?(): Promise<C>;
 3 |   pull(
 4 |     locale: string,
 5 |     input: I,
 6 |     initCtx: C,
 7 |     originalLocale: string,
 8 |     originalInput: I,
 9 |   ): Promise<O>;
10 |   push(
11 |     locale: string,
12 |     data: O,
13 |     originalInput: I | null,
14 |     originalLocale: string,
15 |     pullInput: I | null,
16 |     pullOutput: O | null,
17 |   ): Promise<I>;
18 |   pullHints?(originalInput: I): Promise<O | undefined>;
19 | }
20 | 
21 | export interface ILoader<I, O, C = void> extends ILoaderDefinition<I, O, C> {
22 |   setDefaultLocale(locale: string): this;
23 |   init(): Promise<C>;
24 |   pull(locale: string, input: I): Promise<O>;
25 |   push(locale: string, data: O): Promise<I>;
26 |   pullHints(originalInput: I): Promise<O | undefined>;
27 | }
28 | 
```

--------------------------------------------------------------------------------
/packages/cli/src/cli/loaders/locked-keys.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { ILoader } from "./_types";
 2 | import { createLoader } from "./_utils";
 3 | import _ from "lodash";
 4 | import { matchesKeyPattern } from "../utils/key-matching";
 5 | 
 6 | export default function createLockedKeysLoader(
 7 |   lockedKeys: string[],
 8 | ): ILoader<Record<string, any>, Record<string, any>> {
 9 |   return createLoader({
10 |     pull: async (locale, data) => {
11 |       return _.pickBy(
12 |         data,
13 |         (value, key) => !matchesKeyPattern(key, lockedKeys),
14 |       );
15 |     },
16 |     push: async (locale, data, originalInput) => {
17 |       const lockedSubObject = _.chain(originalInput)
18 |         .pickBy((value, key) => matchesKeyPattern(key, lockedKeys))
19 |         .value();
20 | 
21 |       return _.merge({}, data, lockedSubObject);
22 |     },
23 |   });
24 | }
25 | 
```

--------------------------------------------------------------------------------
/demo/adonisjs/config/inertia.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { defineConfig } from '@adonisjs/inertia'
 2 | import type { InferSharedProps } from '@adonisjs/inertia/types'
 3 | 
 4 | const inertiaConfig = defineConfig({
 5 |   /**
 6 |    * Path to the Edge view that will be used as the root view for Inertia responses
 7 |    */
 8 |   rootView: 'inertia_layout',
 9 | 
10 |   /**
11 |    * Data that should be shared with all rendered pages
12 |    */
13 |   sharedData: {
14 |     // user: (ctx) => ctx.inertia.always(() => ctx.auth.user),
15 |   },
16 | 
17 |   /**
18 |    * Options for the server-side rendering
19 |    */
20 |   ssr: {
21 |     enabled: true,
22 |     entrypoint: 'inertia/app/ssr.tsx',
23 |   },
24 | })
25 | 
26 | export default inertiaConfig
27 | 
28 | declare module '@adonisjs/inertia/types' {
29 |   export interface SharedProps extends InferSharedProps<typeof inertiaConfig> {}
30 | }
31 | 
```

--------------------------------------------------------------------------------
/packages/locales/package.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "name": "@lingo.dev/_locales",
 3 |   "version": "0.1.0",
 4 |   "description": "Lingo.dev locales",
 5 |   "private": false,
 6 |   "publishConfig": {
 7 |     "access": "public"
 8 |   },
 9 |   "type": "module",
10 |   "sideEffects": false,
11 |   "main": "build/index.cjs",
12 |   "module": "build/index.mjs",
13 |   "types": "build/index.d.ts",
14 |   "files": [
15 |     "build",
16 |     "localenames-data"
17 |   ],
18 |   "scripts": {
19 |     "dev": "tsup --watch",
20 |     "build": "pnpm typecheck && tsup",
21 |     "typecheck": "tsc --noEmit",
22 |     "test": "vitest run",
23 |     "test:watch": "vitest"
24 |   },
25 |   "keywords": [],
26 |   "author": "",
27 |   "license": "Apache-2.0",
28 |   "devDependencies": {
29 |     "@types/node": "^22.13.5",
30 |     "tsup": "^8.3.5",
31 |     "typescript": "^5.8.3",
32 |     "vitest": "^3.2.4"
33 |   }
34 | }
35 | 
```

--------------------------------------------------------------------------------
/packages/cli/troubleshooting.md:
--------------------------------------------------------------------------------

```markdown
 1 | ## Troubleshooting
 2 | 
 3 | ### Error: Dynamic require of "module_name" is not supported
 4 | 
 5 | If you encounter this error when running the cli, it typically means that a dependency is trying to dynamically `require()` a Node.js built-in module or another dependency in a way that's incompatible with the ESM bundle format (`.mjs`).
 6 | 
 7 | The solution is to identify the problematic dependency mentioned in the error stack trace and exclude it from the bundle by adding it to the `external` array in `tsup.config.ts`.
 8 | 
 9 | For example, we encountered this issue with the `debug` package (a dependency of `@babel/traverse`) trying to dynamically require `"tty"`. We resolved it by adding `@babel/*` to the `external` array in `tsup.config.ts`.
10 | 
```

--------------------------------------------------------------------------------
/packages/cli/src/cli/loaders/sync.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import _ from "lodash";
 2 | 
 3 | import { ILoader } from "./_types";
 4 | import { createLoader } from "./_utils";
 5 | 
 6 | export default function createSyncLoader(): ILoader<
 7 |   Record<string, string>,
 8 |   Record<string, string>
 9 | > {
10 |   return createLoader({
11 |     async pull(locale, input, initCtx, originalLocale, originalInput) {
12 |       if (!originalInput) {
13 |         return input;
14 |       }
15 | 
16 |       return _.chain(originalInput)
17 |         .mapValues((value, key) => input[key])
18 |         .value() as Record<string, string>;
19 |     },
20 |     async push(locale, data, originalInput) {
21 |       if (!originalInput) {
22 |         return data;
23 |       }
24 | 
25 |       return _.chain(originalInput || {})
26 |         .mapValues((value, key) => data[key])
27 |         .value();
28 |     },
29 |   });
30 | }
31 | 
```

--------------------------------------------------------------------------------
/legacy/cli/package.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "name": "replexica",
 3 |   "version": "0.71.0",
 4 |   "description": "[DEPRECATED] Replexica CLI (now Lingo.dev) - Please use lingo.dev instead",
 5 |   "private": false,
 6 |   "type": "module",
 7 |   "sideEffects": false,
 8 |   "types": "build/index.d.ts",
 9 |   "module": "build/index.mjs",
10 |   "main": "build/index.cjs",
11 |   "bin": {
12 |     "replexica": "./bin/cli.mjs"
13 |   },
14 |   "files": [
15 |     "bin",
16 |     "build"
17 |   ],
18 |   "scripts": {
19 |     "replexica": "./bin/cli.mjs"
20 |   },
21 |   "keywords": [],
22 |   "author": "",
23 |   "license": "Apache-2.0",
24 |   "dependencies": {
25 |     "lingo.dev": "*"
26 |   },
27 |   "deprecated": "Replexica is now Lingo.dev! Please use our new CLI package by running: npx lingo.dev@latest. Visit https://lingo.dev for the latest features and documentation."
28 | }
29 | 
```

--------------------------------------------------------------------------------
/packages/cli/demo/json5/es/example.json5:
--------------------------------------------------------------------------------

```
 1 | {
 2 |   title: '¡Hola, mundo!',
 3 |   description: 'Una aplicación de demostración simple con características JSON5',
 4 |   version: '1.0.0',
 5 |   support_email: '[email protected]',
 6 |   homepage: 'https://lingo.dev',
 7 |   deprecated: null,
 8 |   empty: '',
 9 |   emoji: '🚀',
10 |   author: {
11 |     name: 'Juan Pérez',
12 |   },
13 |   contributors: [
14 |     {
15 |       name: 'Alicia',
16 |     },
17 |     {
18 |       name: 'Roberto',
19 |     },
20 |   ],
21 |   messages: [
22 |     'Bienvenido a MiApp',
23 |     '¡Hola, mundo!',
24 |   ],
25 |   config: {
26 |     theme: {
27 |       primary: 'Tema azul',
28 |     },
29 |   },
30 |   mixed_array: [
31 |     'Contenido mixto aquí',
32 |     42,
33 |     true,
34 |     {
35 |       nested_message: 'Texto anidado',
36 |     },
37 |   ],
38 |   hex_value: 3735928559,
39 |   locked_key_1: 'This value is locked and should not be changed',
40 | }
```

--------------------------------------------------------------------------------
/packages/cli/tsup.config.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { defineConfig } from "tsup";
 2 | 
 3 | export default defineConfig({
 4 |   clean: true,
 5 |   entry: {
 6 |     cli: "src/cli/index.ts",
 7 |     sdk: "src/sdk/index.ts",
 8 |     spec: "src/spec/index.ts",
 9 |     react: "src/react/index.ts",
10 |     "react/client": "src/react/client.ts",
11 |     "react/rsc": "src/react/rsc.ts",
12 |     "react/react-router": "src/react/react-router.ts",
13 |     compiler: "src/compiler/index.ts",
14 |     "locale-codes": "src/locale-codes/index.ts",
15 |   },
16 |   outDir: "build",
17 |   format: ["cjs", "esm"],
18 |   dts: true,
19 |   cjsInterop: true,
20 |   splitting: true,
21 |   bundle: true,
22 |   sourcemap: true,
23 |   external: ["readline/promises", "@babel/traverse", "node-machine-id"],
24 |   outExtension: (ctx) => ({
25 |     js: ctx.format === "cjs" ? ".cjs" : ".mjs",
26 |   }),
27 | });
28 | 
```

--------------------------------------------------------------------------------
/demo/vite-project/eslint.config.js:
--------------------------------------------------------------------------------

```javascript
 1 | import js from "@eslint/js";
 2 | import globals from "globals";
 3 | import reactHooks from "eslint-plugin-react-hooks";
 4 | import reactRefresh from "eslint-plugin-react-refresh";
 5 | import tseslint from "typescript-eslint";
 6 | 
 7 | export default tseslint.config(
 8 |   { ignores: ["dist"] },
 9 |   {
10 |     extends: [js.configs.recommended, ...tseslint.configs.recommended],
11 |     files: ["**/*.{ts,tsx}"],
12 |     languageOptions: {
13 |       ecmaVersion: 2020,
14 |       globals: globals.browser,
15 |     },
16 |     plugins: {
17 |       "react-hooks": reactHooks,
18 |       "react-refresh": reactRefresh,
19 |     },
20 |     rules: {
21 |       ...reactHooks.configs.recommended.rules,
22 |       "react-refresh/only-export-components": [
23 |         "warn",
24 |         { allowConstantExport: true },
25 |       ],
26 |     },
27 |   },
28 | );
29 | 
```

--------------------------------------------------------------------------------
/packages/cli/demo/json/en/example.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "title": "Hello, world!",
 3 |   "description": "A simple demo app",
 4 |   "version": "1.0.0",
 5 |   "support_email": "[email protected]",
 6 |   "homepage": "https://lingo.dev",
 7 |   "deprecated": null,
 8 |   "empty": "",
 9 |   "emoji": "🚀",
10 |   "author": {
11 |     "name": "John Doe"
12 |   },
13 |   "contributors": [
14 |     { "name": "Alice" },
15 |     { "name": "Bob" }
16 |   ],
17 |   "messages": [
18 |     "Welcome to MyApp",
19 |     "Hello, world!"
20 |   ],
21 |   "config": {
22 |     "theme": {
23 |       "primary": "Blue theme"
24 |     }
25 |   },
26 |   "mixed_array": [
27 |     "Mixed content here",
28 |     42,
29 |     true,
30 |     {
31 |       "nested_message": "Nested text"
32 |     }
33 |   ],
34 |   "locked_key_1": "This value is locked and should not be changed",
35 |   "ignored_key_1": "This value is ignored and should not appear in target locales"
36 | 
37 | }
```

--------------------------------------------------------------------------------
/packages/cli/src/cli/loaders/txt.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { ILoader } from "./_types";
 2 | import { createLoader } from "./_utils";
 3 | 
 4 | export default function createTxtLoader(): ILoader<
 5 |   string,
 6 |   Record<string, string>
 7 | > {
 8 |   return createLoader({
 9 |     async pull(locale, input) {
10 |       const result: Record<string, string> = {};
11 | 
12 |       if (input !== undefined && input !== null && input !== "") {
13 |         const lines = input.split("\n");
14 |         lines.forEach((line, index) => {
15 |           result[String(index + 1)] = line;
16 |         });
17 |       }
18 | 
19 |       return result;
20 |     },
21 | 
22 |     async push(locale, payload) {
23 |       const sortedEntries = Object.entries(payload).sort(
24 |         ([a], [b]) => parseInt(a) - parseInt(b),
25 |       );
26 |       return sortedEntries.map(([_, value]) => value).join("\n");
27 |     },
28 |   });
29 | }
30 | 
```

--------------------------------------------------------------------------------
/demo/next-app/src/app/test/page.tsx:
--------------------------------------------------------------------------------

```typescript
 1 | import Link from "next/link";
 2 | 
 3 | export default function Test() {
 4 |   return (
 5 |     <div className="grid grid-rows-[20px_1fr_20px] items-center justify-items-center min-h-screen p-8 pb-20 gap-16 sm:p-20 font-[family-name:var(--font-geist-sans)]">
 6 |       <main className="flex flex-col gap-[32px] row-start-2 items-center sm:items-start">
 7 |         <Link href="/" className="text-primary underline">
 8 |           Navigate home
 9 |         </Link>
10 |         <div className="flex flex-col justify-center items-center gap-4 w-100">
11 |           <h1 className="text-4xl">Testing this thing now</h1>
12 |           <p>
13 |             Hello, this is a non-interactive test. Please do not try to interact
14 |             with it.
15 |           </p>
16 |         </div>
17 |       </main>
18 |     </div>
19 |   );
20 | }
21 | 
```

--------------------------------------------------------------------------------
/packages/cli/demo/php/en/example.php:
--------------------------------------------------------------------------------

```php
 1 | <?php
 2 | 
 3 | return [
 4 |     'Hello, world!',
 5 |     'Welcome to MyApp',
 6 | 
 7 |     "It's \"simple\" with a backslash \\ and newline\nAll text here",
 8 | 
 9 |     'welcome_message' => 'Welcome!',
10 |     'error_text'      => 'Something went wrong',
11 | 
12 |     'navigation' => [
13 |         'home'    => 'Home',
14 |         'about'   => 'About',
15 |         'contact' => 'Contact',
16 |     ],
17 | 
18 |     'forms' => [
19 |         'login' => [
20 |             'username_label' => 'Username',
21 |             'password_label' => 'Password',
22 |             'submit_button'  => 'Sign In',
23 |         ],
24 |     ],
25 | 
26 |     'mixed_content' => [
27 |         'title'        => 'Settings',
28 |         'count'        => 42,
29 |         'enabled'      => true,
30 |         'nothing_here' => null,
31 |         'description'  => 'App settings and preferences',
32 |     ],
33 | ];
34 | 
```

--------------------------------------------------------------------------------
/demo/vite-project/package.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "name": "vite-project",
 3 |   "private": true,
 4 |   "version": "0.0.3",
 5 |   "type": "module",
 6 |   "scripts": {
 7 |     "dev": "vite",
 8 |     "build": "tsc -b && vite build",
 9 |     "lint": "eslint .",
10 |     "preview": "vite preview"
11 |   },
12 |   "dependencies": {
13 |     "@vitejs/plugin-react": "^4.4.1",
14 |     "react": "^19.1.0",
15 |     "react-dom": "^19.1.0"
16 |   },
17 |   "devDependencies": {
18 |     "@eslint/js": "^9.25.0",
19 |     "@types/react": "^19.1.2",
20 |     "@types/react-dom": "^19.1.2",
21 |     "@vitejs/plugin-react-swc": "^3.9.0",
22 |     "eslint": "^9.25.0",
23 |     "eslint-plugin-react-hooks": "^5.2.0",
24 |     "eslint-plugin-react-refresh": "^0.4.19",
25 |     "globals": "^16.0.0",
26 |     "lingo.dev": "workspace:*",
27 |     "typescript": "~5.8.3",
28 |     "typescript-eslint": "^8.30.1",
29 |     "vite": "^6.3.5"
30 |   }
31 | }
32 | 
```

--------------------------------------------------------------------------------
/scripts/docs/src/json-schema/types.ts:
--------------------------------------------------------------------------------

```typescript
 1 | export type PropertyInfo = {
 2 |   name: string;
 3 |   fullPath: string;
 4 |   type: string;
 5 |   required: boolean;
 6 |   description?: string;
 7 |   defaultValue?: unknown;
 8 |   allowedValues?: unknown[];
 9 |   allowedKeys?: string[];
10 |   children?: PropertyInfo[];
11 | };
12 | 
13 | export type JSONSchemaObject = {
14 |   type?: string | string[];
15 |   properties?: Record<string, unknown>;
16 |   required?: string[];
17 |   items?: unknown;
18 |   anyOf?: unknown[];
19 |   $ref?: string;
20 |   description?: string;
21 |   markdownDescription?: string;
22 |   default?: unknown;
23 |   enum?: unknown[];
24 |   propertyNames?: {
25 |     enum?: string[];
26 |   };
27 |   additionalProperties?: unknown;
28 |   definitions?: Record<string, unknown>;
29 | };
30 | 
31 | export type SchemaParsingOptions = {
32 |   customOrder?: string[];
33 |   parentPath?: string;
34 |   rootSchema?: unknown;
35 | };
36 | 
```

--------------------------------------------------------------------------------
/demo/react-router-app/Dockerfile:
--------------------------------------------------------------------------------

```dockerfile
 1 | FROM node:20-alpine AS development-dependencies-env
 2 | COPY . /app
 3 | WORKDIR /app
 4 | RUN npm ci
 5 | 
 6 | FROM node:20-alpine AS production-dependencies-env
 7 | COPY ./package.json package-lock.json /app/
 8 | WORKDIR /app
 9 | RUN npm ci --omit=dev
10 | 
11 | FROM node:20-alpine AS build-env
12 | COPY . /app/
13 | COPY --from=development-dependencies-env /app/node_modules /app/node_modules
14 | WORKDIR /app
15 | RUN npm run build
16 | 
17 | FROM node:20-alpine
18 | COPY ./package.json package-lock.json /app/
19 | COPY --from=production-dependencies-env /app/node_modules /app/node_modules
20 | COPY --from=build-env /app/build /app/build
21 | WORKDIR /app
22 | 
23 | # Create non-root user, set ownership, switch to user before running the app
24 | RUN adduser -D nodeuser && \
25 |     chown -R nodeuser:nodeuser /app
26 | USER nodeuser
27 | 
28 | CMD ["npm", "run", "start"]
```

--------------------------------------------------------------------------------
/packages/cli/src/cli/loaders/ignored-keys.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { ILoader } from "./_types";
 2 | import { createLoader } from "./_utils";
 3 | import _ from "lodash";
 4 | import { matchesKeyPattern } from "../utils/key-matching";
 5 | 
 6 | export default function createIgnoredKeysLoader(
 7 |   ignoredKeys: string[],
 8 | ): ILoader<Record<string, any>, Record<string, any>> {
 9 |   return createLoader({
10 |     pull: async (locale, data) => {
11 |       const result = _.omitBy(data, (value, key) =>
12 |         matchesKeyPattern(key, ignoredKeys),
13 |       );
14 |       return result;
15 |     },
16 |     push: async (locale, data, originalInput, originalLocale, pullInput) => {
17 |       // Remove ignored keys from the data being pushed
18 |       const result = _.omitBy(data, (value, key) =>
19 |         matchesKeyPattern(key, ignoredKeys),
20 |       );
21 |       return result;
22 |     },
23 |   });
24 | }
25 | 
```

--------------------------------------------------------------------------------
/demo/next-app/src/lingo/meta.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "version": 0.1,
 3 |   "files": {
 4 |     "components/hero-subtitle.tsx": {
 5 |       "scopes": {
 6 |         "0/declaration/body/0/argument": {
 7 |           "type": "element",
 8 |           "hash": "75cc719ebad12413e5fa788174d4d4ec",
 9 |           "context": "",
10 |           "skip": false,
11 |           "overrides": {},
12 |           "content": "Localize your React app in every language in minutes.<element:br></element:br> Scale to millions from day one<element:sup>*</element:sup>."
13 |         },
14 |         "0/declaration/body/0/argument/3-title": {
15 |           "type": "attribute",
16 |           "hash": "ce9b34049534ad201aef501f2a224a9d",
17 |           "context": "",
18 |           "skip": false,
19 |           "overrides": {},
20 |           "content": "supports many popular frameworks"
21 |         }
22 |       }
23 |     }
24 |   }
25 | }
26 | 
```

--------------------------------------------------------------------------------
/scripts/docs/package.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "name": "docs",
 3 |   "private": true,
 4 |   "type": "module",
 5 |   "scripts": {
 6 |     "generate-cli-docs": "tsx ./src/generate-cli-docs.ts",
 7 |     "generate-config-docs": "tsx ./src/generate-config-docs.ts",
 8 |     "test": "vitest run",
 9 |     "test:watch": "vitest",
10 |     "test:ui": "vitest --ui",
11 |     "test:coverage": "vitest run --coverage"
12 |   },
13 |   "devDependencies": {
14 |     "@lingo.dev/_spec": "workspace:*",
15 |     "@octokit/rest": "^20.1.2",
16 |     "@types/mdast": "^4.0.4",
17 |     "@types/node": "^24.0.10",
18 |     "@vitest/ui": "^3.2.4",
19 |     "commander": "^12.0.0",
20 |     "remark-stringify": "^11.0.0",
21 |     "tsx": "^4.7.1",
22 |     "typescript": "^5.8.3",
23 |     "unified": "^11.0.4",
24 |     "vitest": "^3.2.4"
25 |   },
26 |   "dependencies": {
27 |     "zod": "^3.25.76",
28 |     "zod-to-json-schema": "^3.24.5"
29 |   }
30 | }
31 | 
```

--------------------------------------------------------------------------------
/packages/react/src/rsc/component.spec.tsx:
--------------------------------------------------------------------------------

```typescript
 1 | import { describe, it, expect, vi } from "vitest";
 2 | import React from "react";
 3 | import { renderToStaticMarkup } from "react-dom/server";
 4 | import { LingoHtmlComponent } from "./component";
 5 | 
 6 | vi.mock("./utils", () => {
 7 |   return {
 8 |     loadLocaleFromCookies: vi.fn(async () => "nl"),
 9 |     loadDictionaryFromRequest: vi.fn(),
10 |   };
11 | });
12 | 
13 | describe("rsc/component", () => {
14 |   describe("LingoHtmlComponent", () => {
15 |     it("sets lang and data-lingodotdev-compiler from cookies-derived locale", async () => {
16 |       const element = await LingoHtmlComponent({});
17 |       const markup = renderToStaticMarkup(element);
18 |       expect(markup).toContain("<html");
19 |       expect(markup).toContain('lang="nl"');
20 |       expect(markup).toContain('data-lingodotdev-compiler="nl"');
21 |     });
22 |   });
23 | });
24 | 
```

--------------------------------------------------------------------------------
/packages/cli/demo/json-dictionary/example.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "navigation": {
 3 |     "en": "Home",
 4 |     "es": "Inicio"
 5 |   },
 6 |   "buttons": {
 7 |     "submit": {
 8 |       "en": "Submit",
 9 |       "es": "Enviar"
10 |     },
11 |     "cancel": {
12 |       "en": "Cancel",
13 |       "es": "Cancelar"
14 |     }
15 |   },
16 |   "messages": {
17 |     "welcome": {
18 |       "en": "Welcome to our application",
19 |       "es": "Bienvenido a nuestra aplicación"
20 |     },
21 |     "error": {
22 |       "en": "An error occurred",
23 |       "es": "Ha ocurrido un error"
24 |     }
25 |   },
26 |   "forms": {
27 |     "login": {
28 |       "title": {
29 |         "en": "Login",
30 |         "es": "Iniciar sesión"
31 |       },
32 |       "fields": {
33 |         "username": {
34 |           "en": "Username",
35 |           "es": "Nombre de usuario"
36 |         },
37 |         "password": {
38 |           "en": "Password",
39 |           "es": "Contraseña"
40 |         }
41 |       }
42 |     }
43 |   }
44 | }
45 | 
```

--------------------------------------------------------------------------------
/packages/cli/src/cli/loaders/json-sorting.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { ILoader } from "./_types";
 2 | import { createLoader } from "./_utils";
 3 | 
 4 | export default function createJsonSortingLoader(): ILoader<
 5 |   Record<string, any>,
 6 |   Record<string, any>
 7 | > {
 8 |   return createLoader({
 9 |     async pull(locale, input) {
10 |       return input;
11 |     },
12 |     async push(locale, data, originalInput) {
13 |       return sortObjectDeep(data);
14 |     },
15 |   });
16 | }
17 | 
18 | function sortObjectDeep(obj: any): any {
19 |   if (Array.isArray(obj)) {
20 |     return obj.map(sortObjectDeep);
21 |   }
22 | 
23 |   if (obj !== null && typeof obj === "object") {
24 |     return Object.keys(obj)
25 |       .sort((a, b) => a.localeCompare(b, undefined, { numeric: true }))
26 |       .reduce((result: any, key) => {
27 |         result[key] = sortObjectDeep(obj[key]);
28 |         return result;
29 |       }, {});
30 |   }
31 | 
32 |   return obj;
33 | }
34 | 
```

--------------------------------------------------------------------------------
/packages/react/src/rsc/attribute-component.tsx:
--------------------------------------------------------------------------------

```typescript
 1 | import {
 2 |   LingoAttributeComponent as LingoCoreAttributeComponent,
 3 |   LingoAttributeComponentProps as LingoCoreAttributeComponentProps,
 4 | } from "../core";
 5 | import { loadDictionaryFromRequest } from "./utils";
 6 | 
 7 | export type LingoAttributeComponentProps = Omit<
 8 |   LingoCoreAttributeComponentProps,
 9 |   "$dictionary"
10 | >;
11 | 
12 | export async function LingoAttributeComponent(
13 |   props: LingoAttributeComponentProps,
14 | ) {
15 |   const {
16 |     $attrAs,
17 |     $attributes,
18 |     $fileKey,
19 |     $entryKey,
20 |     $loadDictionary,
21 |     ...rest
22 |   } = props;
23 |   const dictionary = await loadDictionaryFromRequest($loadDictionary);
24 |   return (
25 |     <LingoCoreAttributeComponent
26 |       $dictionary={dictionary}
27 |       $as={$attrAs}
28 |       $attributes={$attributes}
29 |       $fileKey={$fileKey}
30 |       {...rest}
31 |     />
32 |   );
33 | }
34 | 
```

--------------------------------------------------------------------------------
/demo/react-router-app/app/routes/test.tsx:
--------------------------------------------------------------------------------

```typescript
 1 | import type { Route } from "./+types/home";
 2 | import { Link } from "react-router";
 3 | 
 4 | export function meta({}: Route.MetaArgs) {
 5 |   return [
 6 |     { title: "New React Router App" },
 7 |     { name: "description", content: "Welcome to React Router!" },
 8 |   ];
 9 | }
10 | 
11 | export default function Test() {
12 |   return (
13 |     <main className="flex items-center justify-center pt-16 pb-4">
14 |       <div className="flex-1 flex flex-col items-center gap-4 min-h-0">
15 |         <Link to="/" className="text-blue-500 hover:underline">
16 |           Go back home
17 |         </Link>
18 |         <h1 className="text-2xl font-bold">This is a test page</h1>
19 |         <p>Welcome to non-interactive testing page.</p>
20 |         <p>Please do not try to interact with this page for your own safety.</p>
21 |       </div>
22 |     </main>
23 |   );
24 | }
25 | 
```

--------------------------------------------------------------------------------
/packages/cli/demo/xml/en/example.xml:
--------------------------------------------------------------------------------

```
 1 | <?xml version="1.0" encoding="UTF-8"?>
 2 | <root>
 3 |   <title>Hello, world!</title>
 4 |   
 5 |   <description>
 6 |     <summary>Simple demo app</summary>
 7 |     <details>Basic example content</details>
 8 |   </description>
 9 |   
10 |   <image src="photo.jpg" alt="Example photo" title="Click to view"/>
11 |   
12 |   <link href="example.com" label="Click here">Learn more</link>
13 |   
14 |   <button type="submit" value="Submit" placeholder="Enter text">Submit</button>
15 |   
16 |   <section>
17 |     <article>
18 |       <paragraph>
19 |         <sentence>Nested content</sentence>
20 |       </paragraph>
21 |     </article>
22 |   </section>
23 |   
24 |   <meta name="description" content="Demo app metadata"/>
25 |   
26 |   <message>
27 |     <greeting>Hello there!</greeting>
28 |     <body>Welcome to the app</body>
29 |     <signature>Thanks, MyApp Team</signature>
30 |   </message>
31 | </root>
```

--------------------------------------------------------------------------------
/packages/cli/src/cli/cmd/ci/flows/_base.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { Ora } from "ora";
 2 | import { PlatformKit } from "../platforms/_base";
 3 | 
 4 | export type IIntegrationFlowOptions = {
 5 |   parallel?: boolean;
 6 |   force?: boolean;
 7 | };
 8 | 
 9 | export interface IIntegrationFlow {
10 |   preRun?(): Promise<boolean>;
11 |   run(options: IIntegrationFlowOptions): Promise<boolean>;
12 |   postRun?(): Promise<void>;
13 | }
14 | 
15 | export abstract class IntegrationFlow implements IIntegrationFlow {
16 |   protected i18nBranchName?: string;
17 | 
18 |   constructor(
19 |     protected ora: Ora,
20 |     protected platformKit: PlatformKit,
21 |   ) {}
22 | 
23 |   abstract run(options: IIntegrationFlowOptions): Promise<boolean>;
24 | }
25 | 
26 | export const gitConfig = {
27 |   userName: "Lingo.dev",
28 |   userEmail: "[email protected]",
29 | };
30 | 
31 | export function escapeShellArg(arg: string): string {
32 |   return `'${arg.replace(/'/g, "'\\''")}'`;
33 | }
34 | 
```

--------------------------------------------------------------------------------
/packages/locales/src/types.ts:
--------------------------------------------------------------------------------

```typescript
 1 | /**
 2 |  * Represents the components of a locale string
 3 |  */
 4 | export interface LocaleComponents {
 5 |   /** The language code (e.g., "en", "zh", "es") */
 6 |   language: string;
 7 |   /** The script code (e.g., "Hans", "Hant", "Cyrl") - optional */
 8 |   script?: string;
 9 |   /** The region/country code (e.g., "US", "CN", "RS") - optional */
10 |   region?: string;
11 | }
12 | 
13 | /**
14 |  * Locale delimiter types
15 |  */
16 | export type LocaleDelimiter = "-" | "_";
17 | 
18 | /**
19 |  * Validation result for locale parsing
20 |  */
21 | export interface ParseResult {
22 |   /** The parsed locale components */
23 |   components: LocaleComponents;
24 |   /** The delimiter used in the original string */
25 |   delimiter: LocaleDelimiter | null;
26 |   /** Whether the locale string was valid */
27 |   isValid: boolean;
28 |   /** Error message if parsing failed */
29 |   error?: string;
30 | }
31 | 
```

--------------------------------------------------------------------------------
/packages/react/src/client/component.spec.tsx:
--------------------------------------------------------------------------------

```typescript
 1 | import { describe, it, expect } from "vitest";
 2 | import { renderToStaticMarkup } from "react-dom/server";
 3 | import React from "react";
 4 | import { LingoHtmlComponent } from "./component";
 5 | import { LingoContext } from "./context";
 6 | 
 7 | describe("client/component", () => {
 8 |   describe("LingoHtmlComponent", () => {
 9 |     it("sets lang and data-lingodotdev-compiler from context dictionary locale", () => {
10 |       const dictionary = { locale: "ja" } as any;
11 |       const markup = renderToStaticMarkup(
12 |         <LingoContext.Provider value={{ dictionary }}>
13 |           <LingoHtmlComponent />
14 |         </LingoContext.Provider>,
15 |       );
16 |       expect(markup).toContain("<html");
17 |       expect(markup).toContain('lang="ja"');
18 |       expect(markup).toContain('data-lingodotdev-compiler="ja"');
19 |     });
20 |   });
21 | });
22 | 
```

--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   // Use IntelliSense to learn about possible attributes.
 3 |   // Hover to view descriptions of existing attributes.
 4 |   // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
 5 |   "version": "0.2.0",
 6 |   "configurations": [
 7 |     {
 8 |       "name": "Attach to CLI",
 9 |       "processId": "${command:PickProcess}",
10 |       "request": "attach",
11 |       "skipFiles": ["<node_internals>/**"],
12 |       "type": "node",
13 |       "sourceMaps": true,
14 |       "outFiles": ["${workspaceFolder}/packages/cli/build/**/*.mjs"],
15 |       "resolveSourceMapLocations": [
16 |         "${workspaceFolder}/packages/cli/build/**/*.mjs",
17 |         "!**/node_modules/**"
18 |       ],
19 |       "remoteRoot": "${workspaceFolder}/packages/cli",
20 |       "localRoot": "${workspaceFolder}/packages/cli",
21 |       "port": 9229
22 |     }
23 |   ]
24 | }
25 | 
```

--------------------------------------------------------------------------------
/packages/spec/package.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "name": "@lingo.dev/_spec",
 3 |   "version": "0.41.1",
 4 |   "description": "Lingo.dev open specification",
 5 |   "private": false,
 6 |   "publishConfig": {
 7 |     "access": "public"
 8 |   },
 9 |   "type": "module",
10 |   "sideEffects": false,
11 |   "types": "build/index.d.ts",
12 |   "module": "build/index.mjs",
13 |   "main": "build/index.cjs",
14 |   "files": [
15 |     "build"
16 |   ],
17 |   "scripts": {
18 |     "dev": "tsup --watch",
19 |     "build": "pnpm typecheck && tsup",
20 |     "typecheck": "tsc --noEmit",
21 |     "test": "vitest run",
22 |     "test:watch": "vitest"
23 |   },
24 |   "keywords": [],
25 |   "author": "",
26 |   "license": "Apache-2.0",
27 |   "dependencies": {
28 |     "zod": "^3.25.76",
29 |     "zod-to-json-schema": "^3.24.5"
30 |   },
31 |   "devDependencies": {
32 |     "@types/node": "^22.13.5",
33 |     "tsup": "^8.3.5",
34 |     "typescript": "^5.8.3",
35 |     "vitest": "^3.1.2"
36 |   }
37 | }
38 | 
```

--------------------------------------------------------------------------------
/packages/cli/src/cli/loaders/flutter.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import _ from "lodash";
 2 | import { ILoader } from "./_types";
 3 | import { createLoader } from "./_utils";
 4 | 
 5 | export default function createFlutterLoader(): ILoader<
 6 |   Record<string, any>,
 7 |   Record<string, any>
 8 | > {
 9 |   return createLoader({
10 |     async pull(locale, input) {
11 |       // skip all metadata (keys starting with @)
12 |       const result = _.pickBy(input, (value, key) => !_isMetadataKey(key));
13 |       return result;
14 |     },
15 |     async push(locale, data, originalInput) {
16 |       // find all metadata keys in originalInput
17 |       const metadata = _.pickBy(originalInput, (value, key) =>
18 |         _isMetadataKey(key),
19 |       );
20 |       const result = _.merge({}, metadata, { "@@locale": locale }, data);
21 |       return result;
22 |     },
23 |   });
24 | }
25 | 
26 | function _isMetadataKey(key: string) {
27 |   return key.startsWith("@");
28 | }
29 | 
```

--------------------------------------------------------------------------------
/packages/react/src/rsc/provider.spec.tsx:
--------------------------------------------------------------------------------

```typescript
 1 | import { describe, it, expect, vi } from "vitest";
 2 | import { render, screen } from "@testing-library/react";
 3 | 
 4 | vi.mock("./utils", () => {
 5 |   return {
 6 |     loadDictionaryFromRequest: vi.fn(async (loader: any) => loader("en")),
 7 |   };
 8 | });
 9 | 
10 | describe("rsc/provider", () => {
11 |   describe("LingoProvider", () => {
12 |     it("loads dictionary via helper and renders children through client provider", async () => {
13 |       const { LingoProvider } = await import("./provider");
14 |       const loadDictionary = vi.fn(async () => ({ locale: "en" }));
15 |       render(
16 |         await LingoProvider({
17 |           loadDictionary,
18 |           children: <div data-testid="child" />,
19 |         }),
20 |       );
21 |       expect(screen.getByTestId("child")).toBeTruthy();
22 |       expect(loadDictionary).toHaveBeenCalledWith("en");
23 |     });
24 |   });
25 | });
26 | 
```

--------------------------------------------------------------------------------
/demo/vite-project/CHANGELOG.md:
--------------------------------------------------------------------------------

```markdown
 1 | # vite-project
 2 | 
 3 | ## 0.0.3
 4 | 
 5 | ### Patch Changes
 6 | 
 7 | - [`76cbd9b`](https://github.com/lingodotdev/lingo.dev/commit/76cbd9b2f2e1217421ad1f671bed5b3d64b43333) Thanks [@maxprilutskiy](https://github.com/maxprilutskiy)! - dictionary merging
 8 | 
 9 | ## 0.0.2
10 | 
11 | ### Patch Changes
12 | 
13 | - [`8e97256`](https://github.com/lingodotdev/lingo.dev/commit/8e97256ca4e78dd09a967539ca9dec359bd558ef) Thanks [@maxprilutskiy](https://github.com/maxprilutskiy)! - fix dictionary merging
14 | 
15 | ## 0.0.1
16 | 
17 | ### Patch Changes
18 | 
19 | - [#925](https://github.com/lingodotdev/lingo.dev/pull/925) [`215af19`](https://github.com/lingodotdev/lingo.dev/commit/215af1944667cce66e9c5966f4fb627186687b74) Thanks [@maxprilutskiy](https://github.com/maxprilutskiy)! - improved compiler concurrency, caching, added lingo.dev engine to the compiler, and updated demo apps
20 | 
```

--------------------------------------------------------------------------------
/demo/react-router-app/package.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "name": "react-router-app",
 3 |   "private": true,
 4 |   "type": "module",
 5 |   "scripts": {
 6 |     "build": "react-router build",
 7 |     "dev": "react-router dev",
 8 |     "start": "react-router-serve ./build/server/index.js",
 9 |     "typecheck": "react-router typegen && tsc"
10 |   },
11 |   "dependencies": {
12 |     "lingo.dev": "workspace:*",
13 |     "@react-router/node": "^7.5.3",
14 |     "@react-router/serve": "^7.5.3",
15 |     "isbot": "^5.1.27",
16 |     "react": "^19.1.0",
17 |     "react-dom": "^19.1.0",
18 |     "react-router": "^7.5.3"
19 |   },
20 |   "devDependencies": {
21 |     "@react-router/dev": "^7.5.3",
22 |     "@tailwindcss/vite": "^4.1.4",
23 |     "@types/node": "^20",
24 |     "@types/react": "^19.1.2",
25 |     "@types/react-dom": "^19.1.2",
26 |     "tailwindcss": "^4.1.4",
27 |     "typescript": "^5.8.3",
28 |     "vite": "^6.3.3",
29 |     "vite-tsconfig-paths": "^5.1.4"
30 |   }
31 | }
32 | 
```

--------------------------------------------------------------------------------
/integrations/directus/package.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "name": "@replexica/integration-directus",
 3 |   "version": "0.1.10",
 4 |   "description": "Lingo.dev integration for Directus",
 5 |   "private": false,
 6 |   "sideEffects": false,
 7 |   "directus:extension": {
 8 |     "type": "operation",
 9 |     "path": {
10 |       "app": "build/app.mjs",
11 |       "api": "build/api.mjs"
12 |     },
13 |     "source": {
14 |       "app": "src/app.ts",
15 |       "api": "src/api.ts"
16 |     },
17 |     "host": "^10.10.0"
18 |   },
19 |   "files": [
20 |     "build",
21 |     "readme.md",
22 |     "changelog.md"
23 |   ],
24 |   "scripts": {
25 |     "dev": "tsup --watch",
26 |     "build": "tsc --noEmit && tsup",
27 |     "test": "vitest run"
28 |   },
29 |   "license": "Apache-2.0",
30 |   "dependencies": {
31 |     "@replexica/sdk": "^0.7.7"
32 |   },
33 |   "devDependencies": {
34 |     "@directus/extensions-sdk": "12.1.4",
35 |     "tsup": "^8.3.5",
36 |     "typescript": "^5.8.3",
37 |     "vitest": "^2.1.8"
38 |   }
39 | }
40 | 
```

--------------------------------------------------------------------------------
/packages/sdk/package.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "name": "@lingo.dev/_sdk",
 3 |   "version": "0.12.6",
 4 |   "description": "Lingo.dev JS SDK",
 5 |   "private": false,
 6 |   "publishConfig": {
 7 |     "access": "public"
 8 |   },
 9 |   "type": "module",
10 |   "sideEffects": false,
11 |   "types": "build/index.d.ts",
12 |   "module": "build/index.mjs",
13 |   "main": "build/index.cjs",
14 |   "files": [
15 |     "build"
16 |   ],
17 |   "scripts": {
18 |     "dev": "tsup --watch",
19 |     "build": "pnpm typecheck && tsup",
20 |     "typecheck": "tsc --noEmit",
21 |     "test": "vitest run"
22 |   },
23 |   "keywords": [],
24 |   "author": "",
25 |   "license": "Apache-2.0",
26 |   "dependencies": {
27 |     "@lingo.dev/_spec": "workspace:*",
28 |     "@paralleldrive/cuid2": "^2.2.2",
29 |     "jsdom": "^25.0.1",
30 |     "zod": "^3.25.76"
31 |   },
32 |   "devDependencies": {
33 |     "@types/jsdom": "^21.1.7",
34 |     "tsup": "^8.3.5",
35 |     "typescript": "^5.8.3",
36 |     "vitest": "^3.1.2"
37 |   }
38 | }
39 | 
```

--------------------------------------------------------------------------------
/packages/cli/demo/json5/en/example.json5:
--------------------------------------------------------------------------------

```
 1 | {
 2 |   // JSON5 allows comments!
 3 |   title: "Hello, world!",
 4 |   description: "A simple demo app with JSON5 features",
 5 |   version: "1.0.0",
 6 |   support_email: "[email protected]",
 7 |   homepage: "https://lingo.dev",
 8 |   deprecated: null,
 9 |   empty: "",
10 |   emoji: "🚀",
11 |   
12 |   // Unquoted keys are allowed
13 |   author: {
14 |     name: "John Doe"
15 |   },
16 |   
17 |   contributors: [
18 |     { name: "Alice" },
19 |     { name: "Bob" }
20 |   ],
21 |   
22 |   messages: [
23 |     "Welcome to MyApp",
24 |     "Hello, world!"
25 |   ],
26 |   
27 |   config: {
28 |     theme: {
29 |       primary: "Blue theme"
30 |     }
31 |   },
32 |   
33 |   mixed_array: [
34 |     "Mixed content here",
35 |     42,
36 |     true,
37 |     {
38 |       nested_message: "Nested text"
39 |     }
40 |   ],
41 |   
42 |   // Hexadecimal numbers work in JSON5
43 |   hex_value: 0xDEADBEEF,
44 |   
45 |   // Trailing commas are allowed
46 |   locked_key_1: "This value is locked and should not be changed",
47 | }
```

--------------------------------------------------------------------------------
/packages/cli/src/cli/utils/cloudflare-status.ts:
--------------------------------------------------------------------------------

```typescript
 1 | export interface CloudflareStatusResponse {
 2 |   status: {
 3 |     indicator: "none" | "minor" | "major" | "critical";
 4 |     description: string;
 5 |   };
 6 | }
 7 | 
 8 | export async function checkCloudflareStatus(): Promise<CloudflareStatusResponse | null> {
 9 |   try {
10 |     const response = await fetch(
11 |       "https://www.cloudflarestatus.com/api/v2/status.json",
12 |       {
13 |         signal: AbortSignal.timeout(5000),
14 |       },
15 |     );
16 |     if (response.ok) {
17 |       return await response.json();
18 |     }
19 |   } catch (error) {}
20 |   return null;
21 | }
22 | 
23 | export function formatCloudflareStatusMessage(
24 |   status: CloudflareStatusResponse,
25 | ): string {
26 |   if (status.status.indicator === "none") {
27 |     return "";
28 |   }
29 |   return `Cloudflare is experiencing ${status.status.indicator} issues: ${status.status.description}. This may be affecting the API connection.`;
30 | }
31 | 
```

--------------------------------------------------------------------------------
/demo/adonisjs/ace.js:
--------------------------------------------------------------------------------

```javascript
 1 | /*
 2 | |--------------------------------------------------------------------------
 3 | | JavaScript entrypoint for running ace commands
 4 | |--------------------------------------------------------------------------
 5 | |
 6 | | DO NOT MODIFY THIS FILE AS IT WILL BE OVERRIDDEN DURING THE BUILD
 7 | | PROCESS.
 8 | |
 9 | | See docs.adonisjs.com/guides/typescript-build-process#creating-production-build
10 | |
11 | | Since, we cannot run TypeScript source code using "node" binary, we need
12 | | a JavaScript entrypoint to run ace commands.
13 | |
14 | | This file registers the "ts-node/esm" hook with the Node.js module system
15 | | and then imports the "bin/console.ts" file.
16 | |
17 | */
18 | 
19 | /**
20 |  * Register hook to process TypeScript files using ts-node-maintained
21 |  */
22 | import 'ts-node-maintained/register/esm'
23 | 
24 | /**
25 |  * Import ace console entrypoint
26 |  */
27 | await import('./bin/console.js')
28 | 
```

--------------------------------------------------------------------------------
/packages/cli/demo/php/es/example.php:
--------------------------------------------------------------------------------

```php
 1 | <?php
 2 | 
 3 | return [
 4 |   '0' => '¡Hola, mundo!',
 5 |   '1' => 'Bienvenido a MyApp',
 6 |   '2' => 'Es "simple\\" con una barra invertida \\ y salto de línea\\nTodo el texto aquí',
 7 |   '3' => [
 8 |     'welcome_message' => '¡Bienvenido!'
 9 |   ],
10 |   '4' => [
11 |     'error_text' => 'Algo salió mal'
12 |   ],
13 |   '5' => [
14 |     'navigation' => [
15 |       'home' => 'Inicio',
16 |       'about' => 'Acerca de',
17 |       'contact' => 'Contacto'
18 |     ]
19 |   ],
20 |   '6' => [
21 |     'forms' => [
22 |       'login' => [
23 |         'username_label' => 'Nombre de usuario',
24 |         'password_label' => 'Contraseña',
25 |         'submit_button' => 'Iniciar sesión'
26 |       ]
27 |     ]
28 |   ],
29 |   '7' => [
30 |     'mixed_content' => [
31 |       'title' => 'Ajustes',
32 |       'count' => 42,
33 |       'enabled' => true,
34 |       'nothing_here' => null,
35 |       'description' => 'Ajustes y preferencias de la aplicación'
36 |     ]
37 |   ]
38 | ];
```

--------------------------------------------------------------------------------
/packages/cli/src/cli/localizer/_types.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { I18nConfig } from "@lingo.dev/_spec";
 2 | 
 3 | export type LocalizerData = {
 4 |   sourceLocale: string;
 5 |   sourceData: Record<string, any>;
 6 |   processableData: Record<string, any>;
 7 |   targetLocale: string;
 8 |   targetData: Record<string, any>;
 9 |   hints: Record<string, string[]>;
10 | };
11 | 
12 | export type LocalizerProgressFn = (
13 |   progress: number,
14 |   sourceChunk: Record<string, string>,
15 |   processedChunk: Record<string, string>,
16 | ) => void;
17 | 
18 | export interface ILocalizer {
19 |   id: "Lingo.dev" | NonNullable<I18nConfig["provider"]>["id"];
20 |   checkAuth: () => Promise<{
21 |     authenticated: boolean;
22 |     username?: string;
23 |     error?: string;
24 |   }>;
25 |   validateSettings?: () => Promise<{ valid: boolean; error?: string }>;
26 |   localize: (
27 |     input: LocalizerData,
28 |     onProgress?: LocalizerProgressFn,
29 |   ) => Promise<LocalizerData["processableData"]>;
30 | }
31 | 
```

--------------------------------------------------------------------------------
/packages/cli/src/cli/cmd/logout.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { Command } from "interactive-commander";
 2 | import Ora from "ora";
 3 | import { getSettings, saveSettings } from "../utils/settings";
 4 | import {
 5 |   renderClear,
 6 |   renderSpacer,
 7 |   renderBanner,
 8 |   renderHero,
 9 | } from "../utils/ui";
10 | 
11 | export default new Command()
12 |   .command("logout")
13 |   .description("Log out by removing saved authentication credentials")
14 |   .helpOption("-h, --help", "Show help")
15 |   .action(async () => {
16 |     try {
17 |       await renderClear();
18 |       await renderSpacer();
19 |       await renderBanner();
20 |       await renderHero();
21 |       await renderSpacer();
22 | 
23 |       const settings = await getSettings(undefined);
24 |       settings.auth.apiKey = "";
25 |       await saveSettings(settings);
26 |       Ora().succeed("Successfully logged out");
27 |     } catch (error: any) {
28 |       Ora().fail(error.message);
29 |       process.exit(1);
30 |     }
31 |   });
32 | 
```

--------------------------------------------------------------------------------
/packages/react/src/client/component.tsx:
--------------------------------------------------------------------------------

```typescript
 1 | "use client";
 2 | 
 3 | import {
 4 |   LingoComponent as LingoCoreComponent,
 5 |   LingoComponentProps as LingoCoreComponentProps,
 6 | } from "../core";
 7 | import { useLingo } from "./context";
 8 | 
 9 | export type LingoComponentProps = Omit<LingoCoreComponentProps, "$dictionary">;
10 | 
11 | export function LingoComponent(props: LingoComponentProps) {
12 |   const { $as, $fileKey, $entryKey, ...rest } = props;
13 |   const lingo = useLingo();
14 |   return (
15 |     <LingoCoreComponent
16 |       $dictionary={lingo.dictionary}
17 |       $as={$as}
18 |       $fileKey={$fileKey}
19 |       $entryKey={$entryKey}
20 |       {...rest}
21 |     />
22 |   );
23 | }
24 | 
25 | export function LingoHtmlComponent(
26 |   props: React.HTMLAttributes<HTMLHtmlElement>,
27 | ) {
28 |   const lingo = useLingo();
29 |   return (
30 |     <html
31 |       {...props}
32 |       lang={lingo?.dictionary?.locale}
33 |       data-lingodotdev-compiler={lingo?.dictionary?.locale}
34 |     />
35 |   );
36 | }
37 | 
```

--------------------------------------------------------------------------------
/.github/workflows/docker.yml:
--------------------------------------------------------------------------------

```yaml
 1 | name: Build Docker Image
 2 | 
 3 | on:
 4 |   workflow_dispatch:
 5 |   push:
 6 |     paths:
 7 |       - Dockerfile
 8 |     branches:
 9 |       - main
10 | 
11 | jobs:
12 |   docker:
13 |     runs-on: ubuntu-latest
14 |     steps:
15 |       - name: Checkout
16 |         uses: actions/checkout@v4
17 |       - name: Login to Docker Hub
18 |         uses: docker/login-action@v3
19 |         with:
20 |           username: ${{ secrets.DOCKERHUB_USERNAME }}
21 |           password: ${{ secrets.DOCKERHUB_PASSWORD }}
22 |       - name: Set up QEMU
23 |         uses: docker/setup-qemu-action@v3
24 |       - name: Set up Docker Buildx
25 |         uses: docker/setup-buildx-action@v3
26 |       - name: Build Docker image and push
27 |         uses: docker/build-push-action@v6
28 |         with:
29 |           push: true
30 |           platforms: linux/amd64
31 |           context: ./
32 |           file: ./Dockerfile
33 |           tags: ${{ secrets.DOCKERHUB_USERNAME }}/ci-action:latest
34 | 
```

--------------------------------------------------------------------------------
/demo/vite-project/src/App.css:
--------------------------------------------------------------------------------

```css
 1 | #root {
 2 |   max-width: 1280px;
 3 |   margin: 0 auto;
 4 |   padding: 2rem;
 5 |   text-align: center;
 6 | }
 7 | 
 8 | .logo-container {
 9 |   display: flex;
10 |   justify-content: center;
11 |   align-items: center;
12 |   gap: 1rem;
13 | }
14 | 
15 | .logo {
16 |   height: 6em;
17 |   padding: 1.5em;
18 |   will-change: filter;
19 |   transition: filter 300ms;
20 | }
21 | .logo:hover {
22 |   filter: drop-shadow(0 0 2em #646cffaa);
23 | }
24 | .logo.react:hover {
25 |   filter: drop-shadow(0 0 2em #61dafbaa);
26 | }
27 | 
28 | @keyframes logo-spin {
29 |   from {
30 |     transform: rotate(0deg);
31 |   }
32 |   to {
33 |     transform: rotate(360deg);
34 |   }
35 | }
36 | 
37 | @media (prefers-reduced-motion: no-preference) {
38 |   a:nth-of-type(2) .logo {
39 |     animation: logo-spin infinite 20s linear;
40 |   }
41 | }
42 | 
43 | .welcome-text {
44 |   max-width: 500px;
45 |   margin: 0 auto;
46 | }
47 | 
48 | .card {
49 |   padding: 2em;
50 | }
51 | 
52 | .read-the-docs {
53 |   color: #888;
54 | }
55 | 
56 | .locale-switcher {
57 |   position: absolute;
58 |   top: 0.5rem;
59 |   right: 1rem;
60 | }
61 | 
```

--------------------------------------------------------------------------------
/packages/cli/src/cli/processor/lingo.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { LingoDotDevEngine } from "@lingo.dev/_sdk";
 2 | import { LocalizerInput, LocalizerProgressFn } from "./_base";
 3 | 
 4 | export function createLingoLocalizer(params: {
 5 |   apiKey?: string;
 6 |   apiUrl: string;
 7 | }) {
 8 |   return async (input: LocalizerInput, onProgress: LocalizerProgressFn) => {
 9 |     if (!Object.keys(input.processableData).length) {
10 |       return input.processableData;
11 |     }
12 | 
13 |     const lingo = new LingoDotDevEngine({
14 |       apiKey: params.apiKey,
15 |       apiUrl: params.apiUrl,
16 |     });
17 | 
18 |     const result = await lingo.localizeObject(
19 |       input.processableData,
20 |       {
21 |         sourceLocale: input.sourceLocale,
22 |         targetLocale: input.targetLocale,
23 |         reference: {
24 |           [input.sourceLocale]: input.sourceData,
25 |           [input.targetLocale]: input.targetData,
26 |         },
27 |       },
28 |       onProgress,
29 |     );
30 | 
31 |     return result;
32 |   };
33 | }
34 | 
```

--------------------------------------------------------------------------------
/demo/adonisjs/inertia/app/app.tsx:
--------------------------------------------------------------------------------

```typescript
 1 | /// <reference path="../../adonisrc.ts" />
 2 | /// <reference path="../../config/inertia.ts" />
 3 | 
 4 | import '../css/app.css'
 5 | import { hydrateRoot } from 'react-dom/client'
 6 | import { createInertiaApp } from '@inertiajs/react'
 7 | import { resolvePageComponent } from '@adonisjs/inertia/helpers'
 8 | import { LingoProviderWrapper, loadDictionary } from 'lingo.dev/react/client'
 9 | 
10 | const appName = import.meta.env.VITE_APP_NAME || 'AdonisJS'
11 | 
12 | createInertiaApp({
13 |   progress: { color: '#5468FF' },
14 | 
15 |   title: (title) => `${title} - ${appName}`,
16 | 
17 |   resolve: (name) => {
18 |     return resolvePageComponent(`../pages/${name}.tsx`, import.meta.glob('../pages/**/*.tsx'))
19 |   },
20 | 
21 |   setup({ el, App, props }) {
22 |     hydrateRoot(
23 |       el,
24 |       <LingoProviderWrapper loadDictionary={(locale) => loadDictionary(locale)}>
25 |         <App {...props} />
26 |       </LingoProviderWrapper>
27 |     )
28 |   },
29 | })
30 | 
```

--------------------------------------------------------------------------------
/packages/cli/src/cli/utils/key-matching.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { minimatch } from "minimatch";
 2 | 
 3 | /**
 4 |  * Checks if a key matches any of the provided patterns using prefix or glob matching
 5 |  */
 6 | export function matchesKeyPattern(key: string, patterns: string[]): boolean {
 7 |   return patterns.some(
 8 |     (pattern) => key.startsWith(pattern) || minimatch(key, pattern),
 9 |   );
10 | }
11 | 
12 | /**
13 |  * Filters entries based on key matching patterns
14 |  */
15 | export function filterEntriesByPattern(
16 |   entries: [string, any][],
17 |   patterns: string[],
18 | ): [string, any][] {
19 |   return entries.filter(([key]) => matchesKeyPattern(key, patterns));
20 | }
21 | 
22 | /**
23 |  * Formats a value for display, truncating long strings
24 |  */
25 | export function formatDisplayValue(value: any, maxLength = 50): string {
26 |   if (typeof value === "string") {
27 |     return value.length > maxLength
28 |       ? `${value.substring(0, maxLength)}...`
29 |       : value;
30 |   }
31 |   return JSON.stringify(value);
32 | }
33 | 
```

--------------------------------------------------------------------------------
/packages/compiler/src/utils/jsx-expressions.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { NodePath } from "@babel/traverse";
 2 | import * as t from "@babel/types";
 3 | import { Expression } from "@babel/types";
 4 | 
 5 | export const getJsxExpressions = (nodePath: NodePath<t.JSXElement>) => {
 6 |   const expressions: Expression[] = [];
 7 |   nodePath.traverse({
 8 |     JSXOpeningElement(path) {
 9 |       path.skip();
10 |     },
11 |     JSXExpressionContainer(path) {
12 |       const expr = path.node.expression;
13 | 
14 |       // Skip empty expressions, identifiers (variables), member expressions (object paths), and function calls
15 |       if (
16 |         !t.isJSXEmptyExpression(expr) &&
17 |         !t.isIdentifier(expr) &&
18 |         !t.isMemberExpression(expr) &&
19 |         !t.isCallExpression(expr) &&
20 |         !(t.isStringLiteral(expr) && expr.value === " ") // whitespace
21 |       ) {
22 |         expressions.push(expr);
23 |       }
24 |       path.skip();
25 |     },
26 |   });
27 | 
28 |   return t.arrayExpression(expressions);
29 | };
30 | 
```

--------------------------------------------------------------------------------
/packages/cli/demo/markdown/en/example.md:
--------------------------------------------------------------------------------

```markdown
 1 | ---
 2 | title: "Product Launch Guide"
 3 | description: "Everything you need to know about our latest product features"
 4 | author: "Product Team"
 5 | date: 2024-01-15
 6 | tags: ["apples", "bananas", "pears"]
 7 | ---
 8 | 
 9 | # Welcome to Our New Dashboard
10 | 
11 | Discover powerful new features designed to streamline your workflow and boost productivity.
12 | 
13 | ## Getting Started
14 | 
15 | Follow these simple steps to set up your account and begin using our platform effectively.
16 | 
17 | ---
18 | 
19 | Our advanced analytics help you make data-driven decisions with confidence.
20 | 
21 | ![Dashboard overview screenshot](image.jpg)
22 | 
23 | The intuitive interface makes it easy to navigate between different features and tools.
24 | 
25 | [View documentation](https://example.com)
26 | 
27 | Need help getting started? Our support team is available 24/7 to assist you.
28 | 
29 | ***
30 | 
31 | Join thousands of satisfied customers who have transformed their business with our platform.
```

--------------------------------------------------------------------------------
/packages/react/src/rsc/loader.spec.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { describe, it, expect } from "vitest";
 2 | import { loadDictionary_internal } from "./loader";
 3 | 
 4 | vi.mock("../core", () => {
 5 |   return {
 6 |     getDictionary: vi.fn(async (locale, loaders) => {
 7 |       if (locale === "es") return { hello: "Hola" };
 8 |       if (locale === "en") return { hello: "Hello" };
 9 |       return {};
10 |     }),
11 |   };
12 | });
13 | 
14 | import { getDictionary } from "../core";
15 | 
16 | describe("rsc/loader", () => {
17 |   describe("loadDictionary_internal", () => {
18 |     it("delegates to core getDictionary via internal wrapper", async () => {
19 |       const loaders = {
20 |         en: async () => ({ default: { hello: "Hello" } }),
21 |         es: async () => ({ default: { hello: "Hola" } }),
22 |       };
23 |       const result = await loadDictionary_internal("es", loaders);
24 |       expect(getDictionary).toHaveBeenCalledWith("es", loaders);
25 |       expect(result).toEqual({ hello: "Hola" });
26 |     });
27 |   });
28 | });
29 | 
```

--------------------------------------------------------------------------------
/packages/react/src/client/loader.spec.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { describe, it, expect } from "vitest";
 2 | import { loadDictionary_internal } from "./loader";
 3 | 
 4 | vi.mock("../core", () => {
 5 |   return {
 6 |     getDictionary: vi.fn(async (locale, loaders) => {
 7 |       if (locale === "es") return { hello: "Hola" };
 8 |       if (locale === "en") return { hello: "Hello" };
 9 |       return {};
10 |     }),
11 |   };
12 | });
13 | 
14 | import { getDictionary } from "../core";
15 | 
16 | describe("client/loader", () => {
17 |   describe("loadDictionary_internal", () => {
18 |     it("delegates to core getDictionary via internal wrapper", async () => {
19 |       const loaders = {
20 |         en: async () => ({ default: { hello: "Hello" } }),
21 |         es: async () => ({ default: { hello: "Hola" } }),
22 |       };
23 |       const result = await loadDictionary_internal("es", loaders);
24 |       expect(getDictionary).toHaveBeenCalledWith("es", loaders);
25 |       expect(result).toEqual({ hello: "Hola" });
26 |     });
27 |   });
28 | });
29 | 
```

--------------------------------------------------------------------------------
/demo/adonisjs/config/logger.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import env from '#start/env'
 2 | import app from '@adonisjs/core/services/app'
 3 | import { defineConfig, targets } from '@adonisjs/core/logger'
 4 | 
 5 | const loggerConfig = defineConfig({
 6 |   default: 'app',
 7 | 
 8 |   /**
 9 |    * The loggers object can be used to define multiple loggers.
10 |    * By default, we configure only one logger (named "app").
11 |    */
12 |   loggers: {
13 |     app: {
14 |       enabled: true,
15 |       name: env.get('APP_NAME'),
16 |       level: env.get('LOG_LEVEL'),
17 |       transport: {
18 |         targets: targets()
19 |           .pushIf(!app.inProduction, targets.pretty())
20 |           .pushIf(app.inProduction, targets.file({ destination: 1 }))
21 |           .toArray(),
22 |       },
23 |     },
24 |   },
25 | })
26 | 
27 | export default loggerConfig
28 | 
29 | /**
30 |  * Inferring types for the list of loggers you have configured
31 |  * in your application.
32 |  */
33 | declare module '@adonisjs/core/types' {
34 |   export interface LoggersList extends InferLoggers<typeof loggerConfig> {}
35 | }
36 | 
```

--------------------------------------------------------------------------------
/packages/cli/src/cli/cmd/show/config.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { Command } from "interactive-commander";
 2 | import _ from "lodash";
 3 | import fs from "fs";
 4 | import path from "path";
 5 | import { defaultConfig } from "@lingo.dev/_spec";
 6 | 
 7 | export default new Command()
 8 |   .command("config")
 9 |   .description("Print effective i18n.json after merging with defaults")
10 |   .helpOption("-h, --help", "Show help")
11 |   .action(async (options) => {
12 |     const fileConfig = loadReplexicaFileConfig();
13 |     const config = _.merge({}, defaultConfig, fileConfig);
14 | 
15 |     console.log(JSON.stringify(config, null, 2));
16 |   });
17 | 
18 | function loadReplexicaFileConfig(): any {
19 |   const replexicaConfigPath = path.resolve(process.cwd(), "i18n.json");
20 |   const fileExists = fs.existsSync(replexicaConfigPath);
21 |   if (!fileExists) {
22 |     return undefined;
23 |   }
24 | 
25 |   const fileContent = fs.readFileSync(replexicaConfigPath, "utf-8");
26 |   const replexicaFileConfig = JSON.parse(fileContent);
27 |   return replexicaFileConfig;
28 | }
29 | 
```

--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "name": "@lingo.dev",
 3 |   "type": "module",
 4 |   "scripts": {
 5 |     "prepare": "husky",
 6 |     "build": "turbo build",
 7 |     "typecheck": "turbo typecheck",
 8 |     "test": "turbo test",
 9 |     "new": "changeset",
10 |     "new:empty": "changeset --empty",
11 |     "format": "prettier . --write",
12 |     "format:check": "prettier . --check"
13 |   },
14 |   "devDependencies": {
15 |     "@babel/generator": "^7.27.1",
16 |     "@babel/parser": "^7.27.1",
17 |     "@babel/traverse": "^7.27.4",
18 |     "@babel/types": "^7.27.1",
19 |     "@commitlint/cli": "^19.8.0",
20 |     "@commitlint/config-conventional": "^19.8.0",
21 |     "@types/babel__traverse": "^7.20.7",
22 |     "commitlint": "^19.7.1",
23 |     "husky": "^9.1.7",
24 |     "prettier": "^3.4.2",
25 |     "turbo": "^2.5.0"
26 |   },
27 |   "dependencies": {
28 |     "@changesets/changelog-github": "^0.5.0",
29 |     "@changesets/cli": "^2.27.10",
30 |     "minimatch": "^10.0.3",
31 |     "node-machine-id": "^1.1.12"
32 |   },
33 |   "packageManager": "[email protected]"
34 | }
35 | 
```

--------------------------------------------------------------------------------
/packages/compiler/src/utils/rc.spec.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { describe, it, expect, vi, beforeEach } from "vitest";
 2 | import { getRc } from "./rc";
 3 | 
 4 | vi.mock("os", () => ({ default: { homedir: () => "/home/test" } }));
 5 | vi.mock("fs", () => {
 6 |   const mockFs = {
 7 |     existsSync: vi.fn(() => false),
 8 |     readFileSync: vi.fn(() => ""),
 9 |   } as any;
10 |   return { ...mockFs, default: mockFs };
11 | });
12 | 
13 | import fsAny from "fs";
14 | 
15 | describe("getRc", () => {
16 |   beforeEach(() => {
17 |     (fsAny as any).existsSync.mockReset().mockReturnValue(false);
18 |     (fsAny as any).readFileSync.mockReset().mockReturnValue("");
19 |   });
20 | 
21 |   it("returns empty object when rc file missing", () => {
22 |     const data = getRc();
23 |     expect(data).toEqual({});
24 |   });
25 | 
26 |   it("parses ini file when present", () => {
27 |     (fsAny as any).existsSync.mockReturnValue(true);
28 |     (fsAny as any).readFileSync.mockReturnValue("[auth]\napiKey=abc\n");
29 |     const data = getRc();
30 |     expect(data).toHaveProperty("auth.apiKey", "abc");
31 |   });
32 | });
33 | 
```

--------------------------------------------------------------------------------
/packages/cli/src/cli/loaders/dato/index.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import fs from "fs";
 2 | import JSON5 from "json5";
 3 | import { composeLoaders } from "../_utils";
 4 | import { datoConfigSchema } from "./_base";
 5 | import createDatoFilterLoader from "./filter";
 6 | import createDatoApiLoader from "./api";
 7 | import createDatoExtractLoader from "./extract";
 8 | 
 9 | export default function createDatoLoader(configFilePath: string) {
10 |   try {
11 |     const configContent = fs.readFileSync(configFilePath, "utf-8");
12 |     const datoConfig = datoConfigSchema.parse(JSON5.parse(configContent));
13 | 
14 |     return composeLoaders(
15 |       createDatoApiLoader(datoConfig, (updatedConfig) =>
16 |         fs.writeFileSync(
17 |           configFilePath,
18 |           JSON5.stringify(updatedConfig, null, 2),
19 |         ),
20 |       ),
21 |       createDatoFilterLoader(),
22 |       createDatoExtractLoader(),
23 |     );
24 |   } catch (error: any) {
25 |     throw new Error(
26 |       [`Failed to parse DatoCMS config file.`, `Error: ${error.message}`].join(
27 |         "\n\n",
28 |       ),
29 |     );
30 |   }
31 | }
32 | 
```

--------------------------------------------------------------------------------
/demo/adonisjs/start/env.ts:
--------------------------------------------------------------------------------

```typescript
 1 | /*
 2 | |--------------------------------------------------------------------------
 3 | | Environment variables service
 4 | |--------------------------------------------------------------------------
 5 | |
 6 | | The `Env.create` method creates an instance of the Env service. The
 7 | | service validates the environment variables and also cast values
 8 | | to JavaScript data types.
 9 | |
10 | */
11 | 
12 | import { Env } from '@adonisjs/core/env'
13 | 
14 | export default await Env.create(new URL('../', import.meta.url), {
15 |   NODE_ENV: Env.schema.enum(['development', 'production', 'test'] as const),
16 |   PORT: Env.schema.number(),
17 |   APP_KEY: Env.schema.string(),
18 |   HOST: Env.schema.string({ format: 'host' }),
19 |   LOG_LEVEL: Env.schema.string(),
20 | 
21 |   /*
22 |   |----------------------------------------------------------
23 |   | Variables for configuring session package
24 |   |----------------------------------------------------------
25 |   */
26 |   SESSION_DRIVER: Env.schema.enum(['cookie', 'memory'] as const),
27 | })
28 | 
```

--------------------------------------------------------------------------------
/demo/adonisjs/config/shield.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { defineConfig } from '@adonisjs/shield'
 2 | 
 3 | const shieldConfig = defineConfig({
 4 |   /**
 5 |    * Configure CSP policies for your app. Refer documentation
 6 |    * to learn more
 7 |    */
 8 |   csp: {
 9 |     enabled: false,
10 |     directives: {},
11 |     reportOnly: false,
12 |   },
13 | 
14 |   /**
15 |    * Configure CSRF protection options. Refer documentation
16 |    * to learn more
17 |    */
18 |   csrf: {
19 |     enabled: true,
20 |     exceptRoutes: [],
21 |     enableXsrfCookie: true,
22 |     methods: ['POST', 'PUT', 'PATCH', 'DELETE'],
23 |   },
24 | 
25 |   /**
26 |    * Control how your website should be embedded inside
27 |    * iFrames
28 |    */
29 |   xFrame: {
30 |     enabled: true,
31 |     action: 'DENY',
32 |   },
33 | 
34 |   /**
35 |    * Force browser to always use HTTPS
36 |    */
37 |   hsts: {
38 |     enabled: true,
39 |     maxAge: '180 days',
40 |   },
41 | 
42 |   /**
43 |    * Disable browsers from sniffing the content type of a
44 |    * response and always rely on the "content-type" header.
45 |    */
46 |   contentTypeSniffing: {
47 |     enabled: true,
48 |   },
49 | })
50 | 
51 | export default shieldConfig
52 | 
```

--------------------------------------------------------------------------------
/demo/adonisjs/vite.config.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { getDirname } from '@adonisjs/core/helpers'
 2 | import inertia from '@adonisjs/inertia/client'
 3 | import adonisjs from '@adonisjs/vite/client'
 4 | import react from '@vitejs/plugin-react'
 5 | import lingoCompiler from 'lingo.dev/compiler'
 6 | import { type UserConfig, type PluginOption } from 'vite'
 7 | 
 8 | const viteConfig: UserConfig = {
 9 |   plugins: [
10 |     inertia({
11 |       ssr: {
12 |         enabled: true,
13 |         entrypoint: 'inertia/app/ssr.tsx',
14 |       },
15 |     }),
16 |     react(),
17 |     adonisjs({
18 |       entrypoints: ['inertia/app/app.tsx'],
19 |       reload: ['resources/views/**/*.edge'],
20 |     }) as unknown as PluginOption,
21 |   ],
22 |   resolve: {
23 |     alias: {
24 |       '~/': `${getDirname(import.meta.url)}/inertia/`,
25 |     },
26 |   },
27 | }
28 | 
29 | const withLingo = lingoCompiler.vite({
30 |   sourceRoot: 'inertia',
31 |   lingoDir: 'lingo',
32 |   sourceLocale: 'en',
33 |   targetLocales: ['es'],
34 |   rsc: false,
35 |   useDirective: false,
36 |   debug: false,
37 |   models: 'lingo.dev',
38 | })
39 | 
40 | export default withLingo(viteConfig)
41 | 
```

--------------------------------------------------------------------------------
/packages/compiler/src/jsx-attribute.spec.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { describe, it, expect } from "vitest";
 2 | import { jsxAttributeMutation } from "./jsx-attribute";
 3 | import { createPayload, createOutput, defaultParams } from "./_base";
 4 | 
 5 | function runMutation(code: string) {
 6 |   const input = createPayload({ code, params: defaultParams, fileKey: "test" });
 7 |   const mutated = jsxAttributeMutation(input);
 8 |   if (!mutated) return code;
 9 |   return createOutput(mutated).code;
10 | }
11 | 
12 | describe("jsxAttributeMutation", () => {
13 |   it("should replace html element with localizable attributes with LingoAttributeComponent", () => {
14 |     const input = `
15 | <p>
16 |   Lorem ipsum <a href="https://example.com" title="Dolor link">dolor</a> sit amet.
17 | </p>
18 |     `;
19 |     const expected = `
20 | <p>
21 |   Lorem ipsum
22 |   <LingoAttributeComponent
23 |     $as="a"
24 |     $attributes={{
25 |       title: "0/body/title",
26 |       "aria-label": "0/body/aria-label"
27 |     }}
28 |     href="https://example.com"
29 |   >
30 |     dolor
31 |   </LingoAttributeComponent>
32 |   sit amet.
33 | </p>
34 |     `;
35 |   });
36 | });
37 | 
```

--------------------------------------------------------------------------------
/packages/cli/src/cli/loaders/xcode-strings.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { ILoader } from "./_types";
 2 | import { createLoader } from "./_utils";
 3 | import { Tokenizer } from "./xcode-strings/tokenizer";
 4 | import { Parser } from "./xcode-strings/parser";
 5 | import { escapeString } from "./xcode-strings/escape";
 6 | 
 7 | export default function createXcodeStringsLoader(): ILoader<
 8 |   string,
 9 |   Record<string, any>
10 | > {
11 |   return createLoader({
12 |     async pull(locale, input) {
13 |       // Tokenize the input
14 |       const tokenizer = new Tokenizer(input);
15 |       const tokens = tokenizer.tokenize();
16 | 
17 |       // Parse tokens into key-value pairs
18 |       const parser = new Parser(tokens);
19 |       const result = parser.parse();
20 | 
21 |       return result;
22 |     },
23 | 
24 |     async push(locale, payload) {
25 |       const lines = Object.entries(payload)
26 |         .filter(([_, value]) => value != null)
27 |         .map(([key, value]) => {
28 |           const escapedValue = escapeString(value);
29 |           return `"${key}" = "${escapedValue}";`;
30 |         });
31 | 
32 |       return lines.join("\n");
33 |     },
34 |   });
35 | }
36 | 
```

--------------------------------------------------------------------------------
/packages/cli/src/cli/loaders/mdx2/sections-split-2.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { ILoader } from "../_types";
 2 | import { createLoader } from "../_utils";
 3 | import { PlaceholderedMdx, SectionedMdx } from "./_types";
 4 | import _ from "lodash";
 5 | 
 6 | export default function createMdxSectionsSplit2Loader(): ILoader<
 7 |   PlaceholderedMdx,
 8 |   SectionedMdx
 9 | > {
10 |   return createLoader({
11 |     async pull(locale, input) {
12 |       const sections = _.chain(input.content)
13 |         .split("\n\n")
14 |         .filter(Boolean)
15 |         .map((section, index) => [index, section])
16 |         .fromPairs()
17 |         .value();
18 | 
19 |       const result: SectionedMdx = {
20 |         frontmatter: input.frontmatter,
21 |         sections,
22 |       };
23 | 
24 |       return result;
25 |     },
26 | 
27 |     async push(locale, data, originalInput, _originalLocale, pullInput) {
28 |       const content = _.chain(data.sections).values().join("\n\n").value();
29 | 
30 |       const result: PlaceholderedMdx = {
31 |         frontmatter: data.frontmatter,
32 |         codePlaceholders: pullInput?.codePlaceholders || {},
33 |         content,
34 |       };
35 | 
36 |       return result;
37 |     },
38 |   });
39 | }
40 | 
```

--------------------------------------------------------------------------------
/packages/compiler/src/jsx-remove-attributes.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { createCodeMutation, CompilerPayload } from "./_base";
 2 | import * as t from "@babel/types";
 3 | import traverse from "@babel/traverse";
 4 | import { NodePath } from "@babel/traverse";
 5 | 
 6 | /**
 7 |  * This mutation identifies JSX elements with data-jsx-* attributes and removes them
 8 |  */
 9 | export const jsxRemoveAttributesMutation = createCodeMutation(
10 |   (payload: CompilerPayload) => {
11 |     const ATTRIBUTES_TO_REMOVE = [
12 |       "data-jsx-root",
13 |       "data-jsx-scope",
14 |       "data-jsx-attribute-scope",
15 |     ];
16 | 
17 |     traverse(payload.ast, {
18 |       JSXElement(path: NodePath<t.JSXElement>) {
19 |         const openingElement = path.node.openingElement;
20 |         openingElement.attributes = openingElement.attributes.filter((attr) => {
21 |           const removeAttr =
22 |             t.isJSXAttribute(attr) &&
23 |             t.isJSXIdentifier(attr.name) &&
24 |             ATTRIBUTES_TO_REMOVE.includes(attr.name.name as string);
25 |           return !removeAttr;
26 |         });
27 |       },
28 |     });
29 | 
30 |     return {
31 |       ...payload,
32 |     };
33 |   },
34 | );
35 | 
```

--------------------------------------------------------------------------------
/packages/cli/demo/markdown/es/example.md:
--------------------------------------------------------------------------------

```markdown
 1 | ---
 2 | title: Guía de lanzamiento de producto
 3 | description: Todo lo que necesitas saber sobre las últimas características de
 4 |   nuestro producto
 5 | author: Equipo de producto
 6 | date: 2024-01-15
 7 | tags:
 8 |   - apples
 9 |   - bananas
10 |   - pears
11 | ---
12 | 
13 | # Bienvenido a nuestro nuevo panel de control
14 | 
15 | Descubre nuevas y potentes funciones diseñadas para optimizar tus flujos de trabajo y aumentar la productividad.
16 | 
17 | ## Primeros pasos
18 | 
19 | Sigue estos sencillos pasos para configurar tu cuenta y comenzar a utilizar nuestra plataforma de manera efectiva.
20 | 
21 | ---
22 | 
23 | Nuestros análisis avanzados te ayudan a tomar decisiones basadas en datos con confianza.
24 | 
25 | ![Captura de pantalla de la visión general del panel](image.jpg)
26 | 
27 | La interfaz intuitiva facilita la navegación entre diferentes funciones y herramientas.
28 | 
29 | [Ver documentación](https://example.com)
30 | 
31 | ¿Necesitas ayuda para empezar? Nuestro equipo de soporte está disponible 24/7 para asistirte.
32 | 
33 | ---
34 | 
35 | Únete a miles de clientes satisfechos que han transformado su negocio con nuestra plataforma.
```

--------------------------------------------------------------------------------
/demo/adonisjs/config/session.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import env from '#start/env'
 2 | import app from '@adonisjs/core/services/app'
 3 | import { defineConfig, stores } from '@adonisjs/session'
 4 | 
 5 | const sessionConfig = defineConfig({
 6 |   enabled: true,
 7 |   cookieName: 'adonis-session',
 8 | 
 9 |   /**
10 |    * When set to true, the session id cookie will be deleted
11 |    * once the user closes the browser.
12 |    */
13 |   clearWithBrowser: false,
14 | 
15 |   /**
16 |    * Define how long to keep the session data alive without
17 |    * any activity.
18 |    */
19 |   age: '2h',
20 | 
21 |   /**
22 |    * Configuration for session cookie and the
23 |    * cookie store
24 |    */
25 |   cookie: {
26 |     path: '/',
27 |     httpOnly: true,
28 |     secure: app.inProduction,
29 |     sameSite: 'lax',
30 |   },
31 | 
32 |   /**
33 |    * The store to use. Make sure to validate the environment
34 |    * variable in order to infer the store name without any
35 |    * errors.
36 |    */
37 |   store: env.get('SESSION_DRIVER'),
38 | 
39 |   /**
40 |    * List of configured stores. Refer documentation to see
41 |    * list of available stores and their config.
42 |    */
43 |   stores: {
44 |     cookie: stores.cookie(),
45 |   },
46 | })
47 | 
48 | export default sessionConfig
49 | 
```

--------------------------------------------------------------------------------
/packages/compiler/src/jsx-html-lang.spec.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { describe, it, expect } from "vitest";
 2 | import { createPayload, createOutput, defaultParams } from "./_base";
 3 | import { jsxHtmlLangMutation } from "./jsx-html-lang";
 4 | 
 5 | function run(code: string, rsc = true) {
 6 |   const input = createPayload({
 7 |     code,
 8 |     params: { ...defaultParams, rsc },
 9 |     relativeFilePath: "app/layout.tsx",
10 |   } as any);
11 |   const mutated = jsxHtmlLangMutation(input);
12 |   return createOutput(mutated!).code.trim();
13 | }
14 | 
15 | describe("jsxHtmlLangMutation", () => {
16 |   it("replaces html tag with framework component in server mode", () => {
17 |     const input = `
18 | export default function Root() {
19 |   return <html><body>Hi</body></html>
20 | }`.trim();
21 |     const out = run(input, true);
22 |     expect(out).toMatch(/LingoHtmlComponent/);
23 |   });
24 | 
25 |   it("replaces html tag with framework component in client mode", () => {
26 |     const input = `
27 | "use client";
28 | export default function Root() {
29 |   return <html><body>Hi</body></html>
30 | }`.trim();
31 |     const out = run(input, false);
32 |     expect(out).toMatch(/LingoHtmlComponent/);
33 |   });
34 | });
35 | 
```

--------------------------------------------------------------------------------
/packages/cli/src/cli/utils/config.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import _ from "lodash";
 2 | import fs from "fs";
 3 | import path from "path";
 4 | import { I18nConfig, parseI18nConfig } from "@lingo.dev/_spec";
 5 | 
 6 | export function getConfig(resave = true): I18nConfig | null {
 7 |   const configFilePath = _getConfigFilePath();
 8 | 
 9 |   const configFileExists = fs.existsSync(configFilePath);
10 |   if (!configFileExists) {
11 |     return null;
12 |   }
13 | 
14 |   const fileContents = fs.readFileSync(configFilePath, "utf8");
15 |   const rawConfig = JSON.parse(fileContents);
16 | 
17 |   const result = parseI18nConfig(rawConfig);
18 |   const didConfigChange = !_.isEqual(rawConfig, result);
19 | 
20 |   if (resave && didConfigChange) {
21 |     // Ensure the config is saved with the latest version / schema
22 |     saveConfig(result);
23 |   }
24 | 
25 |   return result;
26 | }
27 | 
28 | export function saveConfig(config: I18nConfig) {
29 |   const configFilePath = _getConfigFilePath();
30 | 
31 |   const serialized = JSON.stringify(config, null, 2);
32 |   fs.writeFileSync(configFilePath, serialized);
33 | 
34 |   return config;
35 | }
36 | 
37 | // Private
38 | 
39 | function _getConfigFilePath() {
40 |   return path.join(process.cwd(), "i18n.json");
41 | }
42 | 
```

--------------------------------------------------------------------------------
/demo/next-app/public/globe.svg:
--------------------------------------------------------------------------------

```
1 | <svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><g clip-path="url(#a)"><path fill-rule="evenodd" clip-rule="evenodd" d="M10.27 14.1a6.5 6.5 0 0 0 3.67-3.45q-1.24.21-2.7.34-.31 1.83-.97 3.1M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.48-1.52a7 7 0 0 1-.96 0H7.5a4 4 0 0 1-.84-1.32q-.38-.89-.63-2.08a40 40 0 0 0 3.92 0q-.25 1.2-.63 2.08a4 4 0 0 1-.84 1.31zm2.94-4.76q1.66-.15 2.95-.43a7 7 0 0 0 0-2.58q-1.3-.27-2.95-.43a18 18 0 0 1 0 3.44m-1.27-3.54a17 17 0 0 1 0 3.64 39 39 0 0 1-4.3 0 17 17 0 0 1 0-3.64 39 39 0 0 1 4.3 0m1.1-1.17q1.45.13 2.69.34a6.5 6.5 0 0 0-3.67-3.44q.65 1.26.98 3.1M8.48 1.5l.01.02q.41.37.84 1.31.38.89.63 2.08a40 40 0 0 0-3.92 0q.25-1.2.63-2.08a4 4 0 0 1 .85-1.32 7 7 0 0 1 .96 0m-2.75.4a6.5 6.5 0 0 0-3.67 3.44 29 29 0 0 1 2.7-.34q.31-1.83.97-3.1M4.58 6.28q-1.66.16-2.95.43a7 7 0 0 0 0 2.58q1.3.27 2.95.43a18 18 0 0 1 0-3.44m.17 4.71q-1.45-.12-2.69-.34a6.5 6.5 0 0 0 3.67 3.44q-.65-1.27-.98-3.1" fill="#666"/></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h16v16H0z"/></clipPath></defs></svg>
```

--------------------------------------------------------------------------------
/legacy/cli/bin/cli.mjs:
--------------------------------------------------------------------------------

```
 1 | #!/usr/bin/env node
 2 | 
 3 | import CLI from "lingo.dev/cli";
 4 | 
 5 | const envVarConfigWarning = process.env.LINGODOTDEV_API_KEY
 6 |   ? "\nThis version is not compatible with LINGODOTDEV_API_KEY env variable."
 7 |   : "";
 8 | 
 9 | console.warn(
10 |   "\x1b[33m%s\x1b[0m",
11 |   `
12 | ⚠️  WARNING: NEW PACKAGE AVAILABLE ⚠️
13 | ================================================================================
14 | This CLI version is deprecated.${envVarConfigWarning}
15 | Please use lingo.dev instead:
16 | 
17 | npx lingo.dev@latest
18 | 
19 | Visit https://lingo.dev for more information.
20 | ================================================================================
21 | `,
22 | );
23 | 
24 | process.env.LINGODOTDEV_API_KEY = process.env.REPLEXICA_API_KEY;
25 | process.env.LINGODOTDEV_PULL_REQUEST = process.env.REPLEXICA_PULL_REQUEST;
26 | process.env.LINGODOTDEV_PULL_REQUEST_TITLE =
27 |   process.env.REPLEXICA_PULL_REQUEST_TITLE;
28 | process.env.LINGODOTDEV_COMMIT_MESSAGE = process.env.REPLEXICA_COMMIT_MESSAGE;
29 | process.env.LINGODOTDEV_WORKING_DIRECTORY =
30 |   process.env.REPLEXICA_WORKING_DIRECTORY;
31 | 
32 | await CLI.parseAsync(process.argv);
33 | 
```

--------------------------------------------------------------------------------
/packages/cli/src/cli/loaders/formatters/_base.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import path from "path";
 2 | import { ILoader } from "../_types";
 3 | import { createLoader } from "../_utils";
 4 | 
 5 | export type BaseFormatterOptions = {
 6 |   bucketPathPattern: string;
 7 |   stage?: "pull" | "push" | "both";
 8 |   alwaysFormat?: boolean;
 9 | };
10 | 
11 | export function createBaseFormatterLoader(
12 |   options: BaseFormatterOptions,
13 |   formatFn: (data: string, filePath: string) => Promise<string>,
14 | ): ILoader<string, string> {
15 |   const stage = options.stage || "both";
16 | 
17 |   const formatData = async (locale: string, data: string) => {
18 |     const draftPath = options.bucketPathPattern.replaceAll("[locale]", locale);
19 |     const finalPath = path.resolve(draftPath);
20 |     return await formatFn(data, finalPath);
21 |   };
22 | 
23 |   return createLoader({
24 |     async pull(locale, data) {
25 |       if (!["pull", "both"].includes(stage)) {
26 |         return data;
27 |       }
28 |       return await formatData(locale, data);
29 |     },
30 |     async push(locale, data) {
31 |       if (!["push", "both"].includes(stage)) {
32 |         return data;
33 |       }
34 |       return await formatData(locale, data);
35 |     },
36 |   });
37 | }
38 | 
```

--------------------------------------------------------------------------------
/packages/react/src/rsc/component.tsx:
--------------------------------------------------------------------------------

```typescript
 1 | import {
 2 |   LingoComponent as LingoCoreComponent,
 3 |   LingoComponentProps as LingoCoreComponentProps,
 4 | } from "../core";
 5 | import { loadDictionaryFromRequest, loadLocaleFromCookies } from "./utils";
 6 | 
 7 | export type LingoComponentProps = Omit<
 8 |   LingoCoreComponentProps,
 9 |   "$dictionary"
10 | > & {
11 |   $loadDictionary: (locale: string | null) => Promise<any>;
12 | };
13 | 
14 | export async function LingoComponent(props: LingoComponentProps) {
15 |   const { $as, $fileKey, $entryKey, $loadDictionary, ...rest } = props;
16 |   const dictionary = await loadDictionaryFromRequest($loadDictionary);
17 | 
18 |   if ($as.name === "LingoAttributeComponent") {
19 |     rest.$loadDictionary = $loadDictionary;
20 |   }
21 | 
22 |   return (
23 |     <LingoCoreComponent
24 |       {...rest}
25 |       $dictionary={dictionary}
26 |       $as={$as}
27 |       $fileKey={$fileKey}
28 |       $entryKey={$entryKey}
29 |     />
30 |   );
31 | }
32 | 
33 | export async function LingoHtmlComponent(
34 |   props: React.HTMLAttributes<HTMLHtmlElement>,
35 | ) {
36 |   const locale = await loadLocaleFromCookies();
37 |   return <html {...props} lang={locale} data-lingodotdev-compiler={locale} />;
38 | }
39 | 
```

--------------------------------------------------------------------------------
/packages/compiler/src/jsx-provider.spec.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { describe, it, expect } from "vitest";
 2 | import { createPayload, createOutput, defaultParams } from "./_base";
 3 | import jsxProviderMutation from "./jsx-provider";
 4 | 
 5 | function run(code: string, rsc = true) {
 6 |   const input = createPayload({
 7 |     code,
 8 |     params: { ...defaultParams, rsc },
 9 |     relativeFilePath: "app/layout.tsx",
10 |   } as any);
11 |   const mutated = jsxProviderMutation(input);
12 |   return createOutput(mutated!).code.trim();
13 | }
14 | 
15 | describe("jsxProviderMutation", () => {
16 |   it("wraps <html> with LingoProvider in server mode", () => {
17 |     const input = `
18 | export default function Root() {
19 |   return <html><body>Hi</body></html>
20 | }`.trim();
21 |     const out = run(input, true);
22 |     expect(out).toContain("LingoProvider");
23 |     expect(out).toContain("loadDictionary");
24 |   });
25 | 
26 |   it("does not modify in client mode", () => {
27 |     const input = `
28 | export default function Root() {
29 |   return <html><body>Hi</body></html>
30 | }`.trim();
31 |     const out = run(input, false);
32 |     expect(out).toContain("<html>");
33 |     expect(out).not.toContain("LingoProvider");
34 |   });
35 | });
36 | 
```

--------------------------------------------------------------------------------
/packages/compiler/src/utils/env.spec.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
 2 | import { isRunningInCIOrDocker } from "./env";
 3 | 
 4 | vi.mock("fs", () => {
 5 |   const mockFs = { existsSync: vi.fn(() => false) } as any;
 6 |   return { ...mockFs, default: mockFs };
 7 | });
 8 | 
 9 | import fsAny from "fs";
10 | 
11 | describe("isRunningInCIOrDocker", () => {
12 |   const originalEnv = { ...process.env };
13 | 
14 |   beforeEach(() => {
15 |     process.env = { ...originalEnv };
16 |     (fsAny as any).existsSync.mockReset().mockReturnValue(false);
17 |   });
18 |   afterEach(() => {
19 |     process.env = originalEnv;
20 |   });
21 | 
22 |   it("returns true when CI env var is set", () => {
23 |     process.env.CI = "true";
24 |     expect(isRunningInCIOrDocker()).toBe(true);
25 |   });
26 | 
27 |   it("returns true when /.dockerenv exists", () => {
28 |     (fsAny as any).existsSync.mockReturnValueOnce(true);
29 |     delete process.env.CI;
30 |     expect(isRunningInCIOrDocker()).toBe(true);
31 |   });
32 | 
33 |   it("returns false otherwise", () => {
34 |     delete process.env.CI;
35 |     (fsAny as any).existsSync.mockReturnValueOnce(false);
36 |     expect(isRunningInCIOrDocker()).toBe(false);
37 |   });
38 | });
39 | 
```

--------------------------------------------------------------------------------
/packages/cli/src/cli/cmd/show/locale.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { Command } from "interactive-commander";
 2 | import _ from "lodash";
 3 | import Z from "zod";
 4 | import Ora from "ora";
 5 | import { localeCodes } from "@lingo.dev/_spec";
 6 | import { CLIError } from "../../utils/errors";
 7 | 
 8 | export default new Command()
 9 |   .command("locale")
10 |   .description("List supported locale codes")
11 |   .helpOption("-h, --help", "Show help")
12 |   // argument can be equal either "sources" or "targets"
13 |   .argument(
14 |     "<type>",
15 |     'Type of locales to show: "sources" or "targets" - both show the full supported locale list',
16 |   )
17 |   .action(async (type) => {
18 |     const ora = Ora();
19 |     try {
20 |       switch (type) {
21 |         default:
22 |           throw new CLIError({
23 |             message: `Invalid type: ${type}`,
24 |             docUrl: "invalidType",
25 |           });
26 |         case "sources":
27 |           localeCodes.forEach((locale) => console.log(locale));
28 |           break;
29 |         case "targets":
30 |           localeCodes.forEach((locale) => console.log(locale));
31 |           break;
32 |       }
33 |     } catch (error: any) {
34 |       ora.fail(error.message);
35 |       process.exit(1);
36 |     }
37 |   });
38 | 
```

--------------------------------------------------------------------------------
/packages/compiler/src/jsx-attribute-flag.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { createCodeMutation, CompilerPayload } from "./_base";
 2 | import * as t from "@babel/types";
 3 | import { getJsxAttributeScopes } from "./utils/jsx-attribute-scope";
 4 | import { getAstKey } from "./utils/ast-key";
 5 | 
 6 | /**
 7 |  * This mutation identifies JSX elements with localizable attributes
 8 |  * and adds a data-jsx-attributes attribute with an array of the attribute names
 9 |  */
10 | const jsxAttributeFlagMutation = createCodeMutation(
11 |   (payload: CompilerPayload) => {
12 |     const jsxScopes = getJsxAttributeScopes(payload.ast);
13 | 
14 |     for (const [jsxScope, attributes] of jsxScopes) {
15 |       const scopeKey = getAstKey(jsxScope);
16 |       jsxScope.node.openingElement.attributes.push(
17 |         t.jsxAttribute(
18 |           t.jsxIdentifier("data-jsx-attribute-scope"),
19 |           t.jsxExpressionContainer(
20 |             t.arrayExpression(
21 |               attributes.map((attr) =>
22 |                 t.stringLiteral(`${attr}:${scopeKey}-${attr}`),
23 |               ),
24 |             ),
25 |           ),
26 |         ),
27 |       );
28 |     }
29 | 
30 |     return {
31 |       ...payload,
32 |     };
33 |   },
34 | );
35 | 
36 | export default jsxAttributeFlagMutation;
37 | 
```

--------------------------------------------------------------------------------
/demo/adonisjs/config/app.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import env from '#start/env'
 2 | import app from '@adonisjs/core/services/app'
 3 | import { Secret } from '@adonisjs/core/helpers'
 4 | import { defineConfig } from '@adonisjs/core/http'
 5 | 
 6 | /**
 7 |  * The app key is used for encrypting cookies, generating signed URLs,
 8 |  * and by the "encryption" module.
 9 |  *
10 |  * The encryption module will fail to decrypt data if the key is lost or
11 |  * changed. Therefore it is recommended to keep the app key secure.
12 |  */
13 | export const appKey = new Secret(env.get('APP_KEY'))
14 | 
15 | /**
16 |  * The configuration settings used by the HTTP server
17 |  */
18 | export const http = defineConfig({
19 |   generateRequestId: true,
20 |   allowMethodSpoofing: false,
21 | 
22 |   /**
23 |    * Enabling async local storage will let you access HTTP context
24 |    * from anywhere inside your application.
25 |    */
26 |   useAsyncLocalStorage: false,
27 | 
28 |   /**
29 |    * Manage cookies configuration. The settings for the session id cookie are
30 |    * defined inside the "config/session.ts" file.
31 |    */
32 |   cookie: {
33 |     domain: '',
34 |     path: '/',
35 |     maxAge: '2h',
36 |     httpOnly: true,
37 |     secure: app.inProduction,
38 |     sameSite: 'lax',
39 |   },
40 | })
41 | 
```

--------------------------------------------------------------------------------
/packages/cli/src/cli/loaders/formatters/index.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import createPrettierLoader, { PrettierLoaderOptions } from "./prettier";
 2 | import createBiomeLoader from "./biome";
 3 | import { ILoader } from "../_types";
 4 | import { Options } from "prettier";
 5 | 
 6 | export type FormatterType = "prettier" | "biome" | undefined;
 7 | export type ParserType = Options["parser"];
 8 | 
 9 | export function createFormatterLoader(
10 |   formatterType: FormatterType,
11 |   parser: ParserType,
12 |   bucketPathPattern: string,
13 | ): ILoader<string, string> {
14 |   // If explicitly set to undefined, auto-detect (prefer prettier for backward compatibility)
15 |   if (formatterType === undefined) {
16 |     return createPrettierLoader({ parser, bucketPathPattern });
17 |   }
18 | 
19 |   if (formatterType === "prettier") {
20 |     return createPrettierLoader({ parser, bucketPathPattern });
21 |   }
22 | 
23 |   if (formatterType === "biome") {
24 |     return createBiomeLoader({ bucketPathPattern });
25 |   }
26 | 
27 |   throw new Error(`Unknown formatter: ${formatterType}`);
28 | }
29 | 
30 | // Re-export for direct access if needed
31 | export { createPrettierLoader, createBiomeLoader };
32 | export type { PrettierLoaderOptions };
33 | export type { BiomeLoaderOptions } from "./biome";
34 | 
```

--------------------------------------------------------------------------------
/packages/cli/src/cli/loaders/srt.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { ILoader } from "./_types";
 2 | import { createLoader } from "./_utils";
 3 | import srtParser from "srt-parser-2";
 4 | 
 5 | export default function createSrtLoader(): ILoader<
 6 |   string,
 7 |   Record<string, any>
 8 | > {
 9 |   const parser = new srtParser();
10 |   return createLoader({
11 |     async pull(locale, input) {
12 |       const parsed = parser.fromSrt(input) || [];
13 |       const result: Record<string, string> = {};
14 | 
15 |       parsed.forEach((entry) => {
16 |         const key = `${entry.id}#${entry.startTime}-${entry.endTime}`;
17 |         result[key] = entry.text;
18 |       });
19 | 
20 |       return result;
21 |     },
22 | 
23 |     async push(locale, payload) {
24 |       const output = Object.entries(payload).map(([key, text]) => {
25 |         const [id, timeRange] = key.split("#");
26 |         const [startTime, endTime] = timeRange.split("-");
27 | 
28 |         return {
29 |           id: id,
30 |           startTime: startTime,
31 |           startSeconds: 0,
32 |           endTime: endTime,
33 |           endSeconds: 0,
34 |           text: text,
35 |         };
36 |       });
37 | 
38 |       const srtContent = parser.toSrt(output).trim().replace(/\r?\n/g, "\n");
39 |       return srtContent;
40 |     },
41 |   });
42 | }
43 | 
```

--------------------------------------------------------------------------------
/packages/cli/src/cli/loaders/mdx2/localizable-document.spec.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { describe, it, expect } from "vitest";
 2 | import createLocalizableMdxDocumentLoader from "./localizable-document";
 3 | 
 4 | describe("mdx localizable document loader", () => {
 5 |   it("should map to meta/content on pull and reconstruct on push", async () => {
 6 |     const loader = createLocalizableMdxDocumentLoader();
 7 |     loader.setDefaultLocale("en");
 8 | 
 9 |     const headingSection = "## Heading One\nSome paragraph.";
10 |     const pulled = await loader.pull("en", {
11 |       frontmatter: {
12 |         title: "Sample",
13 |       },
14 |       sections: {
15 |         "0": headingSection,
16 |       },
17 |     });
18 | 
19 |     // Validate structure
20 |     expect(pulled).toHaveProperty("meta");
21 |     expect(pulled).toHaveProperty("content");
22 | 
23 |     // Expect meta matches frontmatter
24 |     expect(pulled.meta.title).toBe("Sample");
25 | 
26 |     // Modify
27 |     pulled.meta.title = "Hola";
28 | 
29 |     // Try push
30 |     const pushed = await loader.push("es", pulled);
31 | 
32 |     // After push we should get original MDX string reflect changes
33 |     expect(pushed.frontmatter.title).toBe("Hola");
34 |     // sections should persist
35 |     expect(pushed.sections["0"]).toBe(headingSection);
36 |   });
37 | });
38 | 
```

--------------------------------------------------------------------------------
/packages/compiler/src/lib/lcp/api/shots.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { z } from "zod";
 2 | import { dictionarySchema } from "../schema";
 3 | 
 4 | export default [
 5 |   // Shot #1
 6 |   [
 7 |     {
 8 |       version: 0.1,
 9 |       locale: "en",
10 |       files: {
11 |         "demo-app/my-custom-header.tsx": {
12 |           entries: {
13 |             "1z2x3c4v": "Dashboard",
14 |             "5t6y7u8i": "Settings",
15 |             "9o0p1q2r": "Logout",
16 |           },
17 |         },
18 |         "demo-app/my-custom-footer.tsx": {
19 |           entries: {
20 |             "9k0l1m2n": "© 2025 Lingo.dev. All rights reserved.",
21 |           },
22 |         },
23 |       },
24 |     },
25 |     {
26 |       version: 0.1,
27 |       locale: "es",
28 |       files: {
29 |         "demo-app/my-custom-header.tsx": {
30 |           entries: {
31 |             "1z2x3c4v": "Panel de control",
32 |             "5t6y7u8i": "Configuración",
33 |             "9o0p1q2r": "Cerrar sesión",
34 |           },
35 |         },
36 |         "demo-app/my-custom-footer.tsx": {
37 |           entries: {
38 |             "9k0l1m2n": "© 2025 Lingo.dev. Todos los derechos reservados.",
39 |           },
40 |         },
41 |       },
42 |     },
43 |   ],
44 |   // More shots here...
45 | ] satisfies [
46 |   z.infer<typeof dictionarySchema>,
47 |   z.infer<typeof dictionarySchema>,
48 | ][];
49 | 
```

--------------------------------------------------------------------------------
/packages/cli/src/cli/loaders/vue-json.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { jsonrepair } from "jsonrepair";
 2 | import { ILoader } from "./_types";
 3 | import { createLoader } from "./_utils";
 4 | 
 5 | export default function createVueJsonLoader(): ILoader<
 6 |   string,
 7 |   Record<string, any>
 8 | > {
 9 |   return createLoader({
10 |     pull: async (locale, input, ctx) => {
11 |       const parsed = parseVueFile(input);
12 |       return parsed?.i18n?.[locale] ?? {};
13 |     },
14 |     push: async (locale, data, originalInput) => {
15 |       const parsed = parseVueFile(originalInput ?? "");
16 |       if (!parsed) {
17 |         return originalInput ?? "";
18 |       }
19 | 
20 |       parsed.i18n[locale] = data;
21 |       return `${parsed.before}<i18n>\n${JSON.stringify(
22 |         parsed.i18n,
23 |         null,
24 |         2,
25 |       )}\n</i18n>${parsed.after}`;
26 |     },
27 |   });
28 | }
29 | 
30 | function parseVueFile(input: string) {
31 |   const match = input.match(/^([\s\S]*)<i18n>([\s\S]*)<\/i18n>([\s\S]*)$/);
32 | 
33 |   if (!match) {
34 |     return null;
35 |   }
36 | 
37 |   const [, before, jsonString = "{}", after] = match;
38 |   let i18n: Record<string, any>;
39 |   try {
40 |     i18n = JSON.parse(jsonString);
41 |   } catch (error) {
42 |     i18n = JSON.parse(jsonrepair(jsonString));
43 |   }
44 | 
45 |   return { before, after, i18n };
46 | }
47 | 
```

--------------------------------------------------------------------------------
/packages/cli/src/cli/utils/update-gitignore.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import fs from "fs";
 2 | import path from "path";
 3 | 
 4 | export default function updateGitignore() {
 5 |   const cacheFile = "i18n.cache";
 6 |   const projectRoot = findCurrentProjectRoot();
 7 |   if (!projectRoot) {
 8 |     return;
 9 |   }
10 |   const gitignorePath = path.join(projectRoot, ".gitignore");
11 |   if (!fs.existsSync(gitignorePath)) {
12 |     return;
13 |   }
14 | 
15 |   const gitignore = fs.readFileSync(gitignorePath, "utf8").split("\n");
16 |   const cacheIsIgnored = gitignore.includes(cacheFile);
17 | 
18 |   if (!cacheIsIgnored) {
19 |     let content = "";
20 | 
21 |     // Ensure there's a trailing newline
22 |     content = fs.readFileSync(gitignorePath, "utf8");
23 |     if (content !== "" && !content.endsWith("\n")) {
24 |       content += "\n";
25 |     }
26 | 
27 |     content += `${cacheFile}\n`;
28 |     fs.writeFileSync(gitignorePath, content);
29 |   }
30 | }
31 | 
32 | function findCurrentProjectRoot() {
33 |   let currentDir = process.cwd();
34 |   while (currentDir !== path.parse(currentDir).root) {
35 |     const gitDirPath = path.join(currentDir, ".git");
36 |     if (fs.existsSync(gitDirPath) && fs.lstatSync(gitDirPath).isDirectory()) {
37 |       return currentDir;
38 |     }
39 |     currentDir = path.dirname(currentDir);
40 |   }
41 |   return null;
42 | }
43 | 
```

--------------------------------------------------------------------------------
/packages/cli/demo/vue-json/example.vue:
--------------------------------------------------------------------------------

```vue
 1 | <template>
 2 |   <div class="container">
 3 |     <h1>{{ $t('welcome') }}</h1>
 4 |     <p>{{ $t('description') }}</p>
 5 |     <button @click="handleClick">{{ $t('button.submit') }}</button>
 6 |   </div>
 7 | </template>
 8 | 
 9 | <script>
10 | export default {
11 |   name: 'ExampleComponent',
12 |   methods: {
13 |     handleClick() {
14 |       console.log('Button clicked');
15 |     }
16 |   }
17 | }
18 | </script>
19 | 
20 | <style scoped>
21 | .container {
22 |   padding: 20px;
23 |   font-family: Arial, sans-serif;
24 | }
25 | 
26 | h1 {
27 |   color: #333;
28 | }
29 | </style>
30 | 
31 | <i18n>
32 | {
33 |   "en": {
34 |     "welcome": "Hello, world!",
35 |     "description": "A simple demo app",
36 |     "button": {
37 |       "submit": "Submit",
38 |       "cancel": "Cancel"
39 |     },
40 |     "messages": [
41 |       "Hello from MyApp",
42 |       "Welcome message"
43 |     ],
44 |     "metadata": {
45 |       "active": true,
46 |       "maxItems": 10,
47 |       "note": null
48 |     }
49 |   },
50 |   "es": {
51 |     "welcome": "¡Hola, mundo!",
52 |     "description": "Una aplicación de demostración simple",
53 |     "button": {
54 |       "submit": "Enviar",
55 |       "cancel": "Cancelar"
56 |     },
57 |     "messages": [
58 |       "Hola desde MyApp",
59 |       "Mensaje de bienvenida"
60 |     ],
61 |     "metadata": {
62 |       "active": true,
63 |       "maxItems": 10,
64 |       "note": null
65 |     }
66 |   }
67 | }
68 | </i18n>
```

--------------------------------------------------------------------------------
/packages/cli/src/cli/cmd/show/locked-keys.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { Command } from "interactive-commander";
 2 | import Ora from "ora";
 3 | import { getConfig } from "../../utils/config";
 4 | import { CLIError } from "../../utils/errors";
 5 | import { getBuckets } from "../../utils/buckets";
 6 | import { executeKeyCommand } from "./_shared-key-command";
 7 | 
 8 | export default new Command()
 9 |   .command("locked-keys")
10 |   .description(
11 |     "Show which key-value pairs in source files match lockedKeys patterns",
12 |   )
13 |   .option("--bucket <name>", "Only show locked keys for a specific bucket")
14 |   .helpOption("-h, --help", "Show help")
15 |   .action(async (options) => {
16 |     const ora = Ora();
17 |     try {
18 |       const i18nConfig = await getConfig();
19 | 
20 |       if (!i18nConfig) {
21 |         throw new CLIError({
22 |           message:
23 |             "i18n.json not found. Please run `lingo.dev init` to initialize the project.",
24 |           docUrl: "i18nNotFound",
25 |         });
26 |       }
27 | 
28 |       const buckets = getBuckets(i18nConfig);
29 | 
30 |       await executeKeyCommand(i18nConfig, buckets, options, {
31 |         filterType: "lockedKeys",
32 |         displayName: "locked",
33 |       });
34 |     } catch (error: any) {
35 |       ora.fail(error.message);
36 |       process.exit(1);
37 |     }
38 |   });
39 | 
```

--------------------------------------------------------------------------------
/demo/vite-project/src/index.css:
--------------------------------------------------------------------------------

```css
 1 | :root {
 2 |   font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
 3 |   line-height: 1.5;
 4 |   font-weight: 400;
 5 | 
 6 |   color-scheme: light dark;
 7 |   color: rgba(255, 255, 255, 0.87);
 8 |   background-color: #242424;
 9 | 
10 |   font-synthesis: none;
11 |   text-rendering: optimizeLegibility;
12 |   -webkit-font-smoothing: antialiased;
13 |   -moz-osx-font-smoothing: grayscale;
14 | }
15 | 
16 | a {
17 |   font-weight: 500;
18 |   color: #646cff;
19 |   text-decoration: inherit;
20 | }
21 | a:hover {
22 |   color: #535bf2;
23 | }
24 | 
25 | body {
26 |   margin: 0;
27 |   display: flex;
28 |   place-items: center;
29 |   min-width: 320px;
30 |   min-height: 100vh;
31 | }
32 | 
33 | h1 {
34 |   font-size: 3.2em;
35 |   line-height: 1.1;
36 | }
37 | 
38 | button {
39 |   border-radius: 8px;
40 |   border: 1px solid transparent;
41 |   padding: 0.6em 1.2em;
42 |   font-size: 1em;
43 |   font-weight: 500;
44 |   font-family: inherit;
45 |   background-color: #1a1a1a;
46 |   cursor: pointer;
47 |   transition: border-color 0.25s;
48 | }
49 | button:hover {
50 |   border-color: #646cff;
51 | }
52 | button:focus,
53 | button:focus-visible {
54 |   outline: 4px auto -webkit-focus-ring-color;
55 | }
56 | 
57 | @media (prefers-color-scheme: light) {
58 |   :root {
59 |     color: #213547;
60 |     background-color: #ffffff;
61 |   }
62 |   a:hover {
63 |     color: #747bff;
64 |   }
65 |   button {
66 |     background-color: #f9f9f9;
67 |   }
68 | }
69 | 
```

--------------------------------------------------------------------------------
/packages/cli/src/cli/cmd/show/ignored-keys.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { Command } from "interactive-commander";
 2 | import Ora from "ora";
 3 | import { getConfig } from "../../utils/config";
 4 | import { CLIError } from "../../utils/errors";
 5 | import { getBuckets } from "../../utils/buckets";
 6 | import { executeKeyCommand } from "./_shared-key-command";
 7 | 
 8 | export default new Command()
 9 |   .command("ignored-keys")
10 |   .description(
11 |     "Show which key-value pairs in source files match ignoredKeys patterns",
12 |   )
13 |   .option("--bucket <name>", "Only show ignored keys for a specific bucket")
14 |   .helpOption("-h, --help", "Show help")
15 |   .action(async (options) => {
16 |     const ora = Ora();
17 |     try {
18 |       const i18nConfig = await getConfig();
19 | 
20 |       if (!i18nConfig) {
21 |         throw new CLIError({
22 |           message:
23 |             "i18n.json not found. Please run `lingo.dev init` to initialize the project.",
24 |           docUrl: "i18nNotFound",
25 |         });
26 |       }
27 | 
28 |       const buckets = getBuckets(i18nConfig);
29 | 
30 |       await executeKeyCommand(i18nConfig, buckets, options, {
31 |         filterType: "ignoredKeys",
32 |         displayName: "ignored",
33 |       });
34 |     } catch (error: any) {
35 |       ora.fail(error.message);
36 |       process.exit(1);
37 |     }
38 |   });
39 | 
```

--------------------------------------------------------------------------------
/demo/adonisjs/tests/bootstrap.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { assert } from '@japa/assert'
 2 | import app from '@adonisjs/core/services/app'
 3 | import type { Config } from '@japa/runner/types'
 4 | import { pluginAdonisJS } from '@japa/plugin-adonisjs'
 5 | import testUtils from '@adonisjs/core/services/test_utils'
 6 | 
 7 | /**
 8 |  * This file is imported by the "bin/test.ts" entrypoint file
 9 |  */
10 | 
11 | /**
12 |  * Configure Japa plugins in the plugins array.
13 |  * Learn more - https://japa.dev/docs/runner-config#plugins-optional
14 |  */
15 | export const plugins: Config['plugins'] = [assert(), pluginAdonisJS(app)]
16 | 
17 | /**
18 |  * Configure lifecycle function to run before and after all the
19 |  * tests.
20 |  *
21 |  * The setup functions are executed before all the tests
22 |  * The teardown functions are executed after all the tests
23 |  */
24 | export const runnerHooks: Required<Pick<Config, 'setup' | 'teardown'>> = {
25 |   setup: [],
26 |   teardown: [],
27 | }
28 | 
29 | /**
30 |  * Configure suites by tapping into the test suite instance.
31 |  * Learn more - https://japa.dev/docs/test-suites#lifecycle-hooks
32 |  */
33 | export const configureSuite: Config['configureSuite'] = (suite) => {
34 |   if (['browser', 'functional', 'e2e'].includes(suite.name)) {
35 |     return suite.setup(() => testUtils.httpServer().start())
36 |   }
37 | }
38 | 
```

--------------------------------------------------------------------------------
/demo/adonisjs/inertia/pages/home.tsx:
--------------------------------------------------------------------------------

```typescript
 1 | import { Head } from '@inertiajs/react'
 2 | import { LocaleSwitcher } from 'lingo.dev/react/client'
 3 | 
 4 | export default function Home() {
 5 |   return (
 6 |     <>
 7 |       <Head title="Homepage" />
 8 |       <div className="min-h-screen flex items-center justify-center bg-gray-50">
 9 |         <div className="max-w-lg mx-auto p-8 bg-white rounded-lg shadow-sm text-center">
10 |           <h1 className="text-3xl font-bold text-gray-900 mb-6">Hello, world!</h1>
11 |           <p className="text-gray-700 mb-4 leading-relaxed">
12 |             This is an example app that demonstrates how{' '}
13 |             <strong className="text-gray-900">Lingo.dev Compiler</strong> can be used to localize{' '}
14 |             apps built with{' '}
15 |             <a href="https://adonisjs.com/" className="text-blue-600 hover:text-blue-800 underline">
16 |               AdonisJS
17 |             </a>
18 |             .
19 |           </p>
20 |           <p className="text-gray-700 mb-6 leading-relaxed">
21 |             To switch between locales, use the following dropdown:
22 |           </p>
23 |           <div className="flex justify-center">
24 |             <LocaleSwitcher locales={['en', 'es']} />
25 |           </div>
26 |         </div>
27 |       </div>
28 |     </>
29 |   )
30 | }
31 | 
```

--------------------------------------------------------------------------------
/packages/compiler/src/jsx-html-lang.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import traverse from "@babel/traverse";
 2 | import * as t from "@babel/types";
 3 | import { createCodeMutation } from "./_base";
 4 | import { getJsxElementName } from "./utils/jsx-element";
 5 | import { getModuleExecutionMode, getOrCreateImport } from "./utils";
 6 | import { ModuleId } from "./_const";
 7 | 
 8 | export const jsxHtmlLangMutation = createCodeMutation((payload) => {
 9 |   traverse(payload.ast, {
10 |     JSXElement: (path) => {
11 |       if (getJsxElementName(path)?.toLowerCase() === "html") {
12 |         const mode = getModuleExecutionMode(payload.ast, payload.params.rsc);
13 |         const packagePath =
14 |           mode === "client" ? ModuleId.ReactClient : ModuleId.ReactRSC;
15 |         const lingoHtmlComponentImport = getOrCreateImport(payload.ast, {
16 |           moduleName: packagePath,
17 |           exportedName: "LingoHtmlComponent",
18 |         });
19 | 
20 |         path.node.openingElement.name = t.jsxIdentifier(
21 |           lingoHtmlComponentImport.importedName,
22 |         );
23 |         if (path.node.closingElement) {
24 |           path.node.closingElement.name = t.jsxIdentifier(
25 |             lingoHtmlComponentImport.importedName,
26 |           );
27 |         }
28 | 
29 |         path.skip();
30 |       }
31 |     },
32 |   });
33 | 
34 |   return payload;
35 | });
36 | 
```

--------------------------------------------------------------------------------
/packages/locales/src/constants.ts:
--------------------------------------------------------------------------------

```typescript
 1 | /**
 2 |  * Shared constants for locale parsing and validation
 3 |  */
 4 | 
 5 | /**
 6 |  * Regular expression for parsing locale strings
 7 |  *
 8 |  * This regex is case-sensitive and expects normalized locale strings:
 9 |  * - Language code: 2-3 lowercase letters (e.g., "en", "zh", "es")
10 |  * - Script code: 4 letters with preserved case (e.g., "Hans", "hans", "Cyrl")
11 |  * - Region code: 2-3 uppercase letters or digits (e.g., "US", "CN", "123")
12 |  *
13 |  * Matches locale strings in the format: language[-_]script?[-_]region?
14 |  *
15 |  * Groups:
16 |  * 1. Language code (2-3 lowercase letters)
17 |  * 2. Script code (4 letters, optional)
18 |  * 3. Region code (2-3 letters or digits, optional)
19 |  *
20 |  * Examples:
21 |  * - "en" -> language: "en"
22 |  * - "en-US" -> language: "en", region: "US"
23 |  * - "zh-Hans-CN" -> language: "zh", script: "Hans", region: "CN"
24 |  * - "sr_Cyrl_RS" -> language: "sr", script: "Cyrl", region: "RS"
25 |  *
26 |  * Note: The parser automatically normalizes case before applying this regex:
27 |  * - Language codes are converted to lowercase
28 |  * - Script codes preserve their original case
29 |  * - Region codes are converted to uppercase
30 |  */
31 | export const LOCALE_REGEX =
32 |   /^([a-z]{2,3})(?:[-_]([A-Za-z]{4}))?(?:[-_]([A-Z]{2}|[0-9]{3}))?$/;
33 | 
```

--------------------------------------------------------------------------------
/packages/cli/src/cli/loaders/xcode-stringsdict.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import plist from "plist";
 2 | import { ILoader } from "./_types";
 3 | import { createLoader } from "./_utils";
 4 | import { CLIError } from "../utils/errors";
 5 | 
 6 | const emptyData = [
 7 |   '<?xml version="1.0" encoding="UTF-8"?>',
 8 |   '<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">',
 9 |   '<plist version="1.0">',
10 |   "<dict/>",
11 |   "</plist>",
12 | ].join("\n");
13 | 
14 | export default function createXcodeStringsdictLoader(): ILoader<
15 |   string,
16 |   Record<string, any>
17 | > {
18 |   return createLoader({
19 |     async pull(locale, input) {
20 |       try {
21 |         const parsed = plist.parse(input || emptyData);
22 |         if (typeof parsed !== "object" || parsed === null) {
23 |           throw new CLIError({
24 |             message: "Invalid .stringsdict format",
25 |             docUrl: "invalidStringDict",
26 |           });
27 |         }
28 |         return parsed as Record<string, any>;
29 |       } catch (error: any) {
30 |         throw new CLIError({
31 |           message: `Invalid .stringsdict format: ${error.message}`,
32 |           docUrl: "invalidStringDict",
33 |         });
34 |       }
35 |     },
36 |     async push(locale, payload) {
37 |       const plistContent = plist.build(payload);
38 |       return plistContent;
39 |     },
40 |   });
41 | }
42 | 
```

--------------------------------------------------------------------------------
/packages/cli/src/cli/loaders/properties.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { ILoader } from "./_types";
 2 | import { createLoader } from "./_utils";
 3 | 
 4 | export default function createPropertiesLoader(): ILoader<
 5 |   string,
 6 |   Record<string, any>
 7 | > {
 8 |   return createLoader({
 9 |     async pull(locale, text) {
10 |       const result: Record<string, string> = {};
11 |       const lines = text.split("\n");
12 | 
13 |       for (const line of lines) {
14 |         const trimmed = line.trim();
15 | 
16 |         // Skip empty lines and comments
17 |         if (isSkippableLine(trimmed)) {
18 |           continue;
19 |         }
20 | 
21 |         const { key, value } = parsePropertyLine(trimmed);
22 |         if (key) {
23 |           result[key] = value;
24 |         }
25 |       }
26 | 
27 |       return result;
28 |     },
29 |     async push(locale, payload) {
30 |       const result = Object.entries(payload)
31 |         .filter(([_, value]) => value != null)
32 |         .map(([key, value]) => `${key}=${value}`)
33 |         .join("\n");
34 | 
35 |       return result;
36 |     },
37 |   });
38 | }
39 | 
40 | function isSkippableLine(line: string): boolean {
41 |   return !line || line.startsWith("#");
42 | }
43 | 
44 | function parsePropertyLine(line: string): { key: string; value: string } {
45 |   const [key, ...valueParts] = line.split("=");
46 |   return {
47 |     key: key?.trim() || "",
48 |     value: valueParts.join("=").trim(),
49 |   };
50 | }
51 | 
```

--------------------------------------------------------------------------------
/demo/next-app/src/app/layout.tsx:
--------------------------------------------------------------------------------

```typescript
 1 | import type { Metadata } from "next";
 2 | import { Geist, Geist_Mono } from "next/font/google";
 3 | import "./globals.css";
 4 | 
 5 | // Compiler: add imports
 6 | import { LocaleSwitcher } from "lingo.dev/react/client";
 7 | import { LingoProvider, loadDictionary } from "lingo.dev/react/rsc";
 8 | 
 9 | const geistSans = Geist({
10 |   variable: "--font-geist-sans",
11 |   subsets: ["latin"],
12 | });
13 | 
14 | const geistMono = Geist_Mono({
15 |   variable: "--font-geist-mono",
16 |   subsets: ["latin"],
17 | });
18 | 
19 | export const metadata: Metadata = {
20 |   title: "Create Next App",
21 |   description: "Generated by create next app",
22 | };
23 | 
24 | export default function RootLayout({
25 |   children,
26 | }: Readonly<{
27 |   children: React.ReactNode;
28 | }>) {
29 |   // Compiler: wrap with LingoProvider and render LocaleSwitcher
30 |   return (
31 |     <LingoProvider loadDictionary={(locale) => loadDictionary(locale)}>
32 |       <html lang="en">
33 |         <body
34 |           className={`${geistSans.variable} ${geistMono.variable} antialiased`}
35 |         >
36 |           <div className="absolute top-2 right-3">
37 |             <LocaleSwitcher
38 |               locales={["en", "es", "zh", "ja", "fr", "de", "ru", "ar", "ko"]}
39 |             />
40 |           </div>
41 |           {children}
42 |         </body>
43 |       </html>
44 |     </LingoProvider>
45 |   );
46 | }
47 | 
```

--------------------------------------------------------------------------------
/packages/cli/tests/mock-storage.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { vi } from "vitest";
 2 | 
 3 | // Types
 4 | interface MockStorage {
 5 |   clear(): void;
 6 |   set(files: Record<string, string>): void;
 7 | }
 8 | 
 9 | // Global storage type
10 | declare global {
11 |   var __mockStorage: Record<string, string>;
12 | }
13 | 
14 | // Initialize global storage
15 | globalThis.__mockStorage = {};
16 | 
17 | // Create mock storage singleton
18 | export const mockStorage: MockStorage = {
19 |   clear: () => {
20 |     globalThis.__mockStorage = {};
21 |   },
22 |   set: (files: Record<string, string>) => {
23 |     mockStorage.clear();
24 |     Object.entries(files).forEach(([path, content]) => {
25 |       const fullPath = `${process.cwd()}/${path}`;
26 |       globalThis.__mockStorage[fullPath] = content;
27 |     });
28 |   },
29 | };
30 | 
31 | // Setup fs mock
32 | vi.mock("fs/promises", () => ({
33 |   default: {
34 |     readFile: vi.fn(async (path: string) => {
35 |       const content = globalThis.__mockStorage[path];
36 |       if (!content) throw new Error(`File not found: ${path}`);
37 |       return content;
38 |     }),
39 |     writeFile: vi.fn((path, content) => {
40 |       globalThis.__mockStorage[path] = content;
41 |       return Promise.resolve();
42 |     }),
43 |     mkdir: vi.fn(),
44 |     access: vi.fn((path) => {
45 |       return globalThis.__mockStorage[path]
46 |         ? Promise.resolve()
47 |         : Promise.reject(new Error("ENOENT"));
48 |     }),
49 |   },
50 | }));
51 | 
```

--------------------------------------------------------------------------------
/packages/cli/src/cli/loaders/dato/_base.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import Z from "zod";
 2 | 
 3 | // DatoCMS config
 4 | export const datoConfigSchema = Z.object({
 5 |   project: Z.string(),
 6 |   models: Z.record(
 7 |     Z.string(),
 8 |     Z.object({
 9 |       records: Z.array(Z.string()).optional(),
10 |       fields: Z.array(Z.string()).optional(),
11 |     }),
12 |   ),
13 | });
14 | 
15 | export type DatoConfig = Z.infer<typeof datoConfigSchema>;
16 | 
17 | // DatoCMS settings
18 | export const datoSettingsSchema = Z.object({
19 |   auth: Z.object({
20 |     apiKey: Z.string(),
21 |   }),
22 | });
23 | 
24 | export type DatoSettings = Z.infer<typeof datoSettingsSchema>;
25 | 
26 | export const DEFAULT_LOCALE = "en";
27 | 
28 | //
29 | 
30 | export type DatoRecordPayload = {
31 |   [field: string]: {
32 |     [locale: string]: DatoValue;
33 |   };
34 | };
35 | 
36 | export type DatoValue = DatoSimpleValue | DatoComplexValue;
37 | export type DatoSimpleValue = DatoPrimitive | DastDocument;
38 | export type DatoComplexValue = DatoBlock | DatoBlock[];
39 | 
40 | export type DatoPrimitive = null | string | boolean | number;
41 | 
42 | export type DastDocument = {
43 |   schema: "dast";
44 |   document: DastDocumentNode;
45 | };
46 | 
47 | export type DastDocumentNode = {
48 |   type: "root" | "span" | "paragraph";
49 |   value?: DatoPrimitive;
50 |   children?: DastDocumentNode[];
51 | };
52 | 
53 | export type DatoBlock = {
54 |   id?: string;
55 |   type: "item";
56 |   attributes: Record<string, DatoSimpleValue>;
57 |   relationships: any;
58 | };
59 | 
```

--------------------------------------------------------------------------------
/packages/cli/src/cli/loaders/ensure-key-order.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import _ from "lodash";
 2 | import { ILoader } from "./_types";
 3 | import { createLoader } from "./_utils";
 4 | 
 5 | export default function createEnsureKeyOrderLoader(): ILoader<
 6 |   Record<string, any>,
 7 |   Record<string, any>
 8 | > {
 9 |   return createLoader({
10 |     pull: async (_locale, input) => {
11 |       return input;
12 |     },
13 |     push: async (_locale, data, originalInput) => {
14 |       if (!originalInput || !data) {
15 |         return data;
16 |       }
17 |       return reorderKeys(data, originalInput);
18 |     },
19 |   });
20 | }
21 | 
22 | function reorderKeys(
23 |   data: Record<string, any>,
24 |   originalInput: Record<string, any>,
25 | ): Record<string, any> {
26 |   if (_.isArray(originalInput) && _.isArray(data)) {
27 |     // If both are arrays, recursively reorder keys in each element
28 |     return data.map((item, idx) => reorderKeys(item, originalInput[idx] ?? {}));
29 |   }
30 |   if (!_.isObject(data) || _.isArray(data) || _.isDate(data)) {
31 |     return data;
32 |   }
33 | 
34 |   const orderedData: Record<string, any> = {};
35 |   const originalKeys = Object.keys(originalInput);
36 |   const dataKeys = new Set(Object.keys(data));
37 | 
38 |   for (const key of originalKeys) {
39 |     if (dataKeys.has(key)) {
40 |       orderedData[key] = reorderKeys(data[key], originalInput[key]);
41 |       dataKeys.delete(key);
42 |     }
43 |   }
44 | 
45 |   return orderedData;
46 | }
47 | 
```

--------------------------------------------------------------------------------
/packages/react/src/client/context.spec.tsx:
--------------------------------------------------------------------------------

```typescript
 1 | import { describe, it, expect } from "vitest";
 2 | import React from "react";
 3 | import { render, screen } from "@testing-library/react";
 4 | import { LingoContext, useLingo } from "./context";
 5 | 
 6 | describe("client/context", () => {
 7 |   describe("useLingo", () => {
 8 |     it("has default dictionary shape and useLingo returns it", () => {
 9 |       const Probe = () => {
10 |         const lingo = useLingo();
11 |         return (
12 |           <div
13 |             data-testid="probe"
14 |             data-dict-empty={
15 |               Object.keys(lingo.dictionary).length === 0 ? "yes" : "no"
16 |             }
17 |           />
18 |         );
19 |       };
20 |       render(<Probe />);
21 |       const el = screen.getByTestId("probe");
22 |       expect(el.getAttribute("data-dict-empty")).toBe("yes");
23 |     });
24 | 
25 |     it("provides value via context provider", () => {
26 |       const Probe = () => {
27 |         const lingo = useLingo();
28 |         return (
29 |           <div data-testid="probe" data-locale={lingo.dictionary.locale} />
30 |         );
31 |       };
32 |       render(
33 |         <LingoContext.Provider value={{ dictionary: { locale: "it" } }}>
34 |           <Probe />
35 |         </LingoContext.Provider>,
36 |       );
37 |       const el = screen.getByTestId("probe");
38 |       expect(el.getAttribute("data-locale")).toBe("it");
39 |     });
40 |   });
41 | });
42 | 
```

--------------------------------------------------------------------------------
/packages/compiler/src/utils/hash.spec.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { describe, it, expect } from "vitest";
 2 | import { createPayload } from "../_base";
 3 | import traverse from "@babel/traverse";
 4 | import * as t from "@babel/types";
 5 | import { getJsxElementHash, getJsxAttributeValueHash } from "./hash";
 6 | 
 7 | function getFirstJsx(pathCode: string) {
 8 |   const payload = createPayload({
 9 |     code: pathCode,
10 |     params: {} as any,
11 |     relativeFilePath: "x.tsx",
12 |   });
13 |   let found: any;
14 |   traverse(payload.ast, {
15 |     JSXElement(p) {
16 |       if (!found) found = p;
17 |     },
18 |   });
19 |   return found as any;
20 | }
21 | 
22 | describe("utils/hash", () => {
23 |   describe("getJsxElementHash", () => {
24 |     it("produces a consistent non-empty hash for same input", () => {
25 |       const a = getFirstJsx(`const A = () => <div>hello world</div>`);
26 |       const first = getJsxElementHash(a);
27 |       const second = getJsxElementHash(a);
28 |       expect(first).toBeTypeOf("string");
29 |       expect(first.length).toBeGreaterThan(0);
30 |       expect(second).toEqual(first);
31 |     });
32 |   });
33 | 
34 |   describe("getJsxAttributeValueHash", () => {
35 |     it("attribute hash returns empty for empty string and stable otherwise", () => {
36 |       expect(getJsxAttributeValueHash("")).toBe("");
37 |       expect(getJsxAttributeValueHash("x")).toBe(getJsxAttributeValueHash("x"));
38 |     });
39 |   });
40 | });
41 | 
```
Page 2/20FirstPrevNextLast