#
tokens: 36257/50000 1/626 files (page 15/15)
lines: off (toggle) GitHub
raw markdown copy
This is page 15 of 15. Use http://codebase.md/lingodotdev/lingo.dev?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

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

```typescript
import { describe, it, expect, vi, beforeEach } from "vitest";
import dedent from "dedent";
import _ from "lodash";
import fs from "fs/promises";
import createBucketLoader from "./index";
import createTextFileLoader from "./text-file";

describe("bucket loaders", () => {
  beforeEach(() => {
    vi.clearAllMocks();
    vi.resetModules();
  });

  describe("android bucket loader", () => {
    it("should load android data", async () => {
      setupFileMocks();

      const input = `
        <resources>
          <string name="button.title">Submit</string>
        </resources>
      `.trim();
      const expectedOutput = { "button.title": "Submit" };

      mockFileOperations(input);

      const androidLoader = createBucketLoader(
        "android",
        "values-[locale]/strings.xml",
        {
          defaultLocale: "en",
        },
      );
      androidLoader.setDefaultLocale("en");
      const data = await androidLoader.pull("en");

      expect(data).toEqual(expectedOutput);
    });

    it("should skip non-translatable strings", async () => {
      setupFileMocks();

      const input = `
        <resources>
          <string name="app_name" translatable="false">MyApp</string>
          <string name="button.title">Submit</string>
          <string name="version" translatable="false">1.0.0</string>
        </resources>
      `.trim();
      const expectedOutput = { "button.title": "Submit" };

      mockFileOperations(input);

      const androidLoader = createBucketLoader(
        "android",
        "values-[locale]/strings.xml",
        {
          defaultLocale: "en",
        },
      );
      androidLoader.setDefaultLocale("en");
      const data = await androidLoader.pull("en");

      expect(data).toEqual(expectedOutput);
    });

    it("should save android data", async () => {
      setupFileMocks();

      // Use proper Android Studio format: XML declaration + 4-space indentation
      const input = `<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="button.title">Submit</string>
</resources>`;
      const payload = { "button.title": "Enviar" };
      // Output preserves XML declaration and uses 4-space indentation (Android standard)
      const expectedOutput = `<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="button.title">Enviar</string>
</resources>`;

      mockFileOperations(input);

      const androidLoader = createBucketLoader(
        "android",
        "values-[locale]/strings.xml",
        {
          defaultLocale: "en",
        },
      );
      androidLoader.setDefaultLocale("en");
      await androidLoader.pull("en");

      await androidLoader.push("es", payload);

      expect(fs.writeFile).toHaveBeenCalledWith(
        "values-es/strings.xml",
        expectedOutput,
        {
          encoding: "utf-8",
          flag: "w",
        },
      );
    });

    it("should respect locked keys (pull)", async () => {
      setupFileMocks();

      const input = `<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="locked_key">Original</string>
    <string name="unlocked_key">Hello</string>
</resources>`;

      mockFileOperations(input);

      const androidLoader = createBucketLoader(
        "android",
        "values-[locale]/strings.xml",
        { defaultLocale: "en" },
        ["locked_key"],
      );
      androidLoader.setDefaultLocale("en");
      const data = await androidLoader.pull("en");

      expect(data).toEqual({ unlocked_key: "Hello" });
    });
  });

  describe("csv bucket loader", () => {
    it("should load csv data ('KEY' as key, from automatic fallback", async () => {
      setupFileMocks();

      const input = ` ,KEY,en\n,button.title,Submit`;
      const expectedOutput = { "button.title": "Submit" };

      mockFileOperations(input);

      const csvLoader = createBucketLoader("csv", "i18n.csv", {
        defaultLocale: "en",
      });
      csvLoader.setDefaultLocale("en");
      const data = await csvLoader.pull("en");

      expect(data).toEqual(expectedOutput);
    });

    it("should load csv data ('id' as key, first cell)", async () => {
      setupFileMocks();

      const input = `id,en\nbutton.title,Submit`;
      const expectedOutput = { "button.title": "Submit" };

      mockFileOperations(input);

      const csvLoader = createBucketLoader("csv", "i18n.csv", {
        defaultLocale: "en",
      });
      csvLoader.setDefaultLocale("en");
      const data = await csvLoader.pull("en");

      expect(data).toEqual(expectedOutput);
    });

    it("should save csv data", async () => {
      setupFileMocks();

      const input = `id,en,es\nbutton.title,Submit,`;
      const payload = { "button.title": "Enviar" };
      const expectedOutput = `id,en,es\nbutton.title,Submit,Enviar`;

      mockFileOperations(input);

      const csvLoader = createBucketLoader("csv", "i18n.csv", {
        defaultLocale: "en",
      });
      csvLoader.setDefaultLocale("en");
      await csvLoader.pull("en");

      await csvLoader.push("es", payload);

      expect(fs.writeFile).toHaveBeenCalledWith("i18n.csv", expectedOutput, {
        encoding: "utf-8",
        flag: "w",
      });
    });

    it("should respect locked keys (pull)", async () => {
      setupFileMocks();

      const input = `id,en\nlocked_key,Original\nunlocked_key,Hello`;

      mockFileOperations(input);

      const csvLoader = createBucketLoader(
        "csv",
        "i18n.csv",
        {
          defaultLocale: "en",
        },
        ["locked_key"],
      );
      csvLoader.setDefaultLocale("en");
      const data = await csvLoader.pull("en");

      expect(data).toEqual({ unlocked_key: "Hello" });
    });
  });

  describe("flutter bucket loader", () => {
    it("should load flutter data", async () => {
      setupFileMocks();

      const input = `{
        "@@locale": "en",
        "greeting": "Hello, {name}!",
        "@greeting": {
          "description": "A greeting with a name placeholder",
          "placeholders": {
            "name": {
              "type": "String",
              "example": "John"
            }
          }
        }
      }`;
      const expectedOutput = { greeting: "Hello, {name}!" };

      mockFileOperations(input);

      const flutterLoader = createBucketLoader(
        "flutter",
        "lib/l10n/app_[locale].arb",
        {
          defaultLocale: "en",
        },
      );
      flutterLoader.setDefaultLocale("en");
      const data = await flutterLoader.pull("en");

      expect(data).toEqual(expectedOutput);
    });

    it("should save flutter data", async () => {
      setupFileMocks();

      const input = `{
        "@@locale": "en",
        "greeting": "Hello, {name}!",
        "@greeting": {
          "description": "A greeting with a name placeholder",
          "placeholders": {
            "name": {
              "type": "String",
              "example": "John"
            }
          }
        }
      }`;
      const payload = { greeting: "¡Hola, {name}!" };
      const expectedOutput = JSON.stringify(
        {
          "@@locale": "es",
          greeting: "¡Hola, {name}!",
          "@greeting": {
            description: "A greeting with a name placeholder",
            placeholders: {
              name: {
                type: "String",
                example: "John",
              },
            },
          },
        },
        null,
        2,
      );

      mockFileOperations(input);

      const flutterLoader = createBucketLoader(
        "flutter",
        "lib/l10n/app_[locale].arb",
        {
          defaultLocale: "en",
        },
      );
      flutterLoader.setDefaultLocale("en");
      await flutterLoader.pull("en");

      await flutterLoader.push("es", payload);

      expect(fs.writeFile).toHaveBeenCalledWith(
        "lib/l10n/app_es.arb",
        expectedOutput,
        {
          encoding: "utf-8",
          flag: "w",
        },
      );
    });

    it("should respect locked keys (pull)", async () => {
      setupFileMocks();

      const input = `{
        "@@locale": "en",
        "locked_key": "Original",
        "unlocked_key": "Hello"
      }`;

      mockFileOperations(input);

      const flutterLoader = createBucketLoader(
        "flutter",
        "lib/l10n/app_[locale].arb",
        { defaultLocale: "en" },
        ["locked_key"],
      );
      flutterLoader.setDefaultLocale("en");
      const data = await flutterLoader.pull("en");

      expect(data).toEqual({ unlocked_key: "Hello" });
    });
  });

  describe("html bucket loader", () => {
    it("should load html data", async () => {
      setupFileMocks();

      const input = `
<html>
  <head>
    <title>My Page</title>
    <meta name="description" content="Page description" />
  </head>
  <body>
    some simple text without an html tag
    <h1>Hello, world!</h1>
    <p>
      This is a paragraph with a 
      <a href="https://example.com">link</a>
      and 
      <b>
        bold and <i>italic text</i>
      </b>
      .
    </p>
  </body>
</html>
      `.trim();
      const expectedOutput = {
        "head/0/0": "My Page",
        "head/1#content": "Page description",
        "body/0": "some simple text without an html tag",
        "body/1/0": "Hello, world!",
        "body/2/0": "This is a paragraph with a",
        "body/2/1/0": "link",
        "body/2/2": "and",
        "body/2/3/0": "bold and",
        "body/2/3/1/0": "italic text",
        "body/2/4": ".",
      };

      mockFileOperations(input);

      const htmlLoader = createBucketLoader("html", "i18n/[locale].html", {
        defaultLocale: "en",
      });
      htmlLoader.setDefaultLocale("en");
      const data = await htmlLoader.pull("en");

      expect(data).toEqual(expectedOutput);
    });

    it("should save html data", async () => {
      const input = dedent`
<html>
  <head>
    <title>My Page</title>
    <meta name="description" content="Page description" />
  </head>
  <body>
    some simple text without an html tag
    <h1>Hello, world!</h1>
    <p>
      This is a paragraph with a <a href="https://example.com">link</a> and <b>bold and <i>italic text</i></b>
    </p>
  </body>
</html>
      `.trim();
      const payload = {
        "head/0/0": "Mi Página",
        "head/1#content": "Descripción de la página",
        "body/0": "texto simple sin etiqueta html",
        "body/1/0": "¡Hola, mundo!",
        "body/2/0": "Este es un párrafo con un ",
        "body/2/1/0": "enlace",
        "body/2/2": " y ",
        "body/2/3/0": "texto en negrita y ",
        "body/2/3/1/0": "texto en cursiva",
      };
      const expectedOutput = `<html lang="es">
  <head>
    <title>Mi Página</title>
    <meta name="description" content="Descripción de la página" />
  </head>
  <body>
    texto simple sin etiqueta html
    <h1>¡Hola, mundo!</h1>
    <p>
      Este es un párrafo con un
      <a href="https://example.com">enlace</a>
      y
      <b>
        texto en negrita y
        <i>texto en cursiva</i>
      </b>
    </p>
  </body>
</html>
      `.trim();

      mockFileOperations(input);

      const htmlLoader = createBucketLoader("html", "i18n/[locale].html", {
        defaultLocale: "en",
      });
      htmlLoader.setDefaultLocale("en");
      await htmlLoader.pull("en");

      await htmlLoader.push("es", payload);

      expect(fs.writeFile).toHaveBeenCalledWith(
        "i18n/es.html",
        expectedOutput,
        { encoding: "utf-8", flag: "w" },
      );
    });

    it("should respect locked keys (pull)", async () => {
      setupFileMocks();

      const input = `
<html>
  <head>
    <title>Locked Title</title>
  </head>
  <body>
    <h1>Hello</h1>
  </body>
</html>`;

      mockFileOperations(input);

      const htmlLoader = createBucketLoader(
        "html",
        "i18n/[locale].html",
        { defaultLocale: "en" },
        ["head/0/0"],
      );
      htmlLoader.setDefaultLocale("en");
      const data = await htmlLoader.pull("en");

      // Title is locked, only body text should remain
      expect(Object.values(data)).toContain("Hello");
      expect(Object.keys(data)).not.toContain("head/0/0");
    });
  });

  describe("jsonc bucket loader", () => {
    it("should load jsonc data with comments", async () => {
      setupFileMocks();

      const input = `{
        // This is a comment for title
        "title": "Submit",
        /* This is a block comment for description */
        "description": "Button description",
        "nested": {
          // Nested comment
          "key": "value"
        }
      }`;
      const expectedOutput = {
        title: "Submit",
        description: "Button description",
        "nested/key": "value",
      };

      mockFileOperations(input);

      const jsoncLoader = createBucketLoader("jsonc", "i18n/[locale].jsonc", {
        defaultLocale: "en",
      });
      jsoncLoader.setDefaultLocale("en");
      const data = await jsoncLoader.pull("en");

      expect(data).toEqual(expectedOutput);
    });

    it("should save jsonc data", async () => {
      setupFileMocks();

      const input = `{
        // This is a comment
        "title": "Submit"
      }`;
      const payload = { title: "Enviar" };
      const expectedOutput = JSON.stringify(payload, null, 2);

      mockFileOperations(input);

      const jsoncLoader = createBucketLoader("jsonc", "i18n/[locale].jsonc", {
        defaultLocale: "en",
      });
      jsoncLoader.setDefaultLocale("en");
      await jsoncLoader.pull("en");

      await jsoncLoader.push("es", payload);

      expect(fs.writeFile).toHaveBeenCalledWith(
        "i18n/es.jsonc",
        expectedOutput,
        { encoding: "utf-8", flag: "w" },
      );
    });

    it("should extract hints from jsonc comments", async () => {
      setupFileMocks();

      const input = `{
        "key1": "value1", // This is a comment for key1
        "key2": "value2" /* This is a comment for key2 */,
        // This is a comment for key3
        "key3": "value3",
        /* This is a block comment for key4 */
        "key4": "value4",
        /*
         This is a comment for key5
        */
        "key5": "value5",
        // This is a comment for key6
        "key6": {
          // This is a comment for key7
          "key7": "value7"
        }
      }`;

      mockFileOperations(input);

      const jsoncLoader = createBucketLoader("jsonc", "i18n/[locale].jsonc", {
        defaultLocale: "en",
      });
      jsoncLoader.setDefaultLocale("en");
      await jsoncLoader.pull("en");

      const hints = await jsoncLoader.pullHints();

      expect(hints).toEqual({
        key1: ["This is a comment for key1"],
        key2: ["This is a comment for key2"],
        key3: ["This is a comment for key3"],
        key4: ["This is a block comment for key4"],
        key5: ["This is a comment for key5"],
        "key6/key7": [
          "This is a comment for key6",
          "This is a comment for key7",
        ],
      });
    });

    it("should handle jsonc with trailing commas", async () => {
      setupFileMocks();

      const input = `{
        "hello": "Hello",
        "world": "World",
        "array": [
          "item1",
          "item2",
        ],
      }`;
      const expectedOutput = {
        hello: "Hello",
        world: "World",
        "array/0": "item1",
        "array/1": "item2",
      };

      mockFileOperations(input);

      const jsoncLoader = createBucketLoader("jsonc", "i18n/[locale].jsonc", {
        defaultLocale: "en",
      });
      jsoncLoader.setDefaultLocale("en");
      const data = await jsoncLoader.pull("en");

      expect(data).toEqual(expectedOutput);
    });

    it("should handle invalid jsonc gracefully", async () => {
      setupFileMocks();

      const input = `{
        "hello": "Hello"
        "world": "World" // missing comma
        invalid: syntax
      }`;

      mockFileOperations(input);

      const jsoncLoader = createBucketLoader("jsonc", "i18n/[locale].jsonc", {
        defaultLocale: "en",
      });
      jsoncLoader.setDefaultLocale("en");

      await expect(jsoncLoader.pull("en")).rejects.toThrow(
        "Failed to parse JSONC",
      );
    });

    it("should respect locked keys (pull)", async () => {
      setupFileMocks();

      const input = `{
        "locked_key": "Original",
        "unlocked_key": "Hello"
      }`;

      mockFileOperations(input);

      const jsoncLoader = createBucketLoader(
        "jsonc",
        "i18n/[locale].jsonc",
        {
          defaultLocale: "en",
        },
        ["locked_key"],
      );
      jsoncLoader.setDefaultLocale("en");
      const data = await jsoncLoader.pull("en");

      expect(data).toEqual({ unlocked_key: "Hello" });
    });
  });

  describe("json bucket loader", () => {
    it("should load json data", async () => {
      setupFileMocks();

      const input = { "button.title": "Submit" };
      mockFileOperations(JSON.stringify(input));

      const jsonLoader = createBucketLoader("json", "i18n/[locale].json", {
        defaultLocale: "en",
      });
      jsonLoader.setDefaultLocale("en");
      const data = await jsonLoader.pull("en");

      expect(data).toEqual(input);
    });

    it("should save json data", async () => {
      setupFileMocks();

      const input = { "button.title": "Submit" };
      const payload = { "button.title": "Enviar" };
      const expectedOutput = JSON.stringify(payload, null, 2);

      mockFileOperations(JSON.stringify(input));

      const jsonLoader = createBucketLoader("json", "i18n/[locale].json", {
        defaultLocale: "en",
      });
      jsonLoader.setDefaultLocale("en");
      await jsonLoader.pull("en");

      await jsonLoader.push("es", payload);

      expect(fs.writeFile).toHaveBeenCalledWith(
        "i18n/es.json",
        expectedOutput,
        { encoding: "utf-8", flag: "w" },
      );
    });

    it("should save json data with numeric keys", async () => {
      setupFileMocks();

      const input = { messages: { "1": "foo", "2": "bar", "3": "bar" } };
      const payload = {
        "messages/1": "foo",
        "messages/2": "bar",
        "messages/3": "bar",
      };
      const expectedOutput = JSON.stringify(input, null, 2);

      mockFileOperations(JSON.stringify(input));

      const jsonLoader = createBucketLoader("json", "i18n/[locale].json", {
        defaultLocale: "en",
      });
      jsonLoader.setDefaultLocale("en");
      await jsonLoader.pull("en");

      await jsonLoader.push("es", payload);

      expect(fs.writeFile).toHaveBeenCalledWith(
        "i18n/es.json",
        expectedOutput,
        { encoding: "utf-8", flag: "w" },
      );
    });

    it("should save json data with array", async () => {
      setupFileMocks();

      const input = { messages: ["foo", "bar"] };
      const payload = { "messages/0": "foo", "messages/1": "bar" };
      const expectedOutput = dedent`
        {
          "messages": ["foo", "bar"]
        }
      `.trim();

      mockFileOperations(JSON.stringify(input));

      const jsonLoader = createBucketLoader("json", "i18n/[locale].json", {
        defaultLocale: "en",
      });
      jsonLoader.setDefaultLocale("en");
      await jsonLoader.pull("en");

      await jsonLoader.push("es", payload);

      expect(fs.writeFile).toHaveBeenCalledWith(
        "i18n/es.json",
        expectedOutput,
        { encoding: "utf-8", flag: "w" },
      );
    });

    it("should return keys in correct order, should not use key values from original input for missing keys", async () => {
      setupFileMocks();

      const input = {
        "button.title": "Submit",
        "button.subtitle": "Submit subtitle",
        "button.description": "Submit description",
      };
      const payload = {
        "button.subtitle": "Subtítulo de envío",
        "button.title": "Enviar",
      };
      const expectedOutput = JSON.stringify(
        {
          "button.title": "Enviar",
          "button.subtitle": "Subtítulo de envío",
        },
        null,
        2,
      );

      mockFileOperations(JSON.stringify(input));

      const jsonLoader = createBucketLoader("json", "i18n/[locale].json", {
        defaultLocale: "en",
      });
      jsonLoader.setDefaultLocale("en");
      await jsonLoader.pull("en");

      await jsonLoader.push("es", payload);

      expect(fs.writeFile).toHaveBeenCalledWith(
        "i18n/es.json",
        expectedOutput,
        { encoding: "utf-8", flag: "w" },
      );
    });

    it("should load and save json data for paths with multiple locales", async () => {
      setupFileMocks();

      const input = { "button.title": "Submit" };
      const payload = { "button.title": "Enviar" };
      const expectedOutput = JSON.stringify(payload, null, 2);

      mockFileOperations(JSON.stringify(input));

      const jsonLoader = createBucketLoader(
        "json",
        "i18n/[locale]/[locale].json",
        {
          defaultLocale: "en",
        },
      );
      jsonLoader.setDefaultLocale("en");
      const data = await jsonLoader.pull("en");

      await jsonLoader.push("es", payload);

      expect(data).toEqual(input);
      expect(fs.access).toHaveBeenCalledWith("i18n/en/en.json");
      expect(fs.writeFile).toHaveBeenCalledWith(
        "i18n/es/es.json",
        expectedOutput,
        { encoding: "utf-8", flag: "w" },
      );
    });

    it("should remove injected locales from json data", async () => {
      setupFileMocks();

      const input = {
        "button.title": "Submit",
        settings: { locale: "en" },
        "not-a-locale": "bar",
      };
      mockFileOperations(JSON.stringify(input));

      const jsonLoader = createBucketLoader("json", "i18n/[locale].json", {
        defaultLocale: "en",
        injectLocale: ["settings/locale", "not-a-locale"],
      });
      jsonLoader.setDefaultLocale("en");
      const data = await jsonLoader.pull("en");

      expect(data).toEqual({ "button.title": "Submit", "not-a-locale": "bar" });
    });

    it("should inject locales into json data", async () => {
      setupFileMocks();

      const input = {
        "button.title": "Submit",
        "not-a-locale": "bar",
        settings: { locale: "en" },
      };
      const payload = { "button.title": "Enviar", "not-a-locale": "bar" };
      const expectedOutput = JSON.stringify(
        { ...payload, settings: { locale: "es" } },
        null,
        2,
      );

      mockFileOperations(JSON.stringify(input));

      const jsonLoader = createBucketLoader("json", "i18n/[locale].json", {
        defaultLocale: "en",
        injectLocale: ["settings/locale", "not-a-locale"],
      });
      jsonLoader.setDefaultLocale("en");
      await jsonLoader.pull("en");

      await jsonLoader.push("es", payload);

      expect(fs.writeFile).toHaveBeenCalledWith(
        "i18n/es.json",
        expectedOutput,
        { encoding: "utf-8", flag: "w" },
      );
    });
  });

  describe("locked keys functionality", () => {
    it("should respect locked keys for JSON format", async () => {
      setupFileMocks();

      const input = {
        "button.title": "Submit",
        "button.description": "Submit description",
        "locked.key": "Should not change",
        nested: {
          locked: "This is locked",
          unlocked: "This can change",
        },
      };
      const payload = {
        "button.title": "Enviar",
        "button.description": "Descripción de envío",
        "locked.key": "This should not be applied",
        "nested/locked": "This should not be applied either",
        "nested/unlocked": "Este puede cambiar",
      };

      mockFileOperations(JSON.stringify(input));

      const jsonLoader = createBucketLoader(
        "json",
        "i18n/[locale].json",
        { defaultLocale: "en" },
        ["locked.key", "nested/locked"],
      );

      jsonLoader.setDefaultLocale("en");
      await jsonLoader.pull("en");

      await jsonLoader.push("es", payload);

      expect(fs.writeFile).toHaveBeenCalled();
      const writeFileCall = (fs.writeFile as any).mock.calls[0];
      const writtenContent = JSON.parse(writeFileCall[1]);

      // Check that locked keys retain their original values
      expect(writtenContent["locked.key"]).toBe("Should not change");
      expect(writtenContent.nested.locked).toBe("This is locked");

      // Check that unlocked keys are updated
      expect(writtenContent["button.title"]).toBe("Enviar");
      expect(writtenContent["button.description"]).toBe("Descripción de envío");
      expect(writtenContent.nested.unlocked).toBe("Este puede cambiar");
    });

    it("should handle deeply nested locked keys", async () => {
      setupFileMocks();

      const input = {
        level1: {
          level2: {
            level3: {
              locked: "This is locked deep",
              unlocked: "This can change",
            },
          },
        },
      };
      const payload = {
        "level1/level2/level3/locked": "This should not be applied",
        "level1/level2/level3/unlocked": "This should change",
      };

      mockFileOperations(JSON.stringify(input));

      const jsonLoader = createBucketLoader(
        "json",
        "i18n/[locale].json",
        { defaultLocale: "en" },
        ["level1/level2/level3/locked"],
      );

      jsonLoader.setDefaultLocale("en");
      await jsonLoader.pull("en");

      await jsonLoader.push("es", payload);

      expect(fs.writeFile).toHaveBeenCalled();
      const writeFileCall = (fs.writeFile as any).mock.calls[0];
      const writtenContent = JSON.parse(writeFileCall[1]);

      // Check that deeply nested locked key retains its original value
      expect(writtenContent.level1.level2.level3.locked).toBe(
        "This is locked deep",
      );

      // Check that unlocked key is updated
      expect(writtenContent.level1.level2.level3.unlocked).toBe(
        "This should change",
      );
    });

    it("should lock keys that are arrays", async () => {
      setupFileMocks();

      const input = {
        messages: ["first", "second", "third"],
        unlocked: ["can", "be", "changed"],
      };
      const payload = {
        "messages/0": "should not change",
        "messages/1": "should not change either",
        "messages/2": "should definitely not change",
        "unlocked/0": "should",
        "unlocked/1": "definitely",
        "unlocked/2": "change",
      };

      mockFileOperations(JSON.stringify(input));

      const jsonLoader = createBucketLoader(
        "json",
        "i18n/[locale].json",
        { defaultLocale: "en" },
        ["messages/0", "messages/1", "messages/2"],
      );

      jsonLoader.setDefaultLocale("en");
      await jsonLoader.pull("en");

      await jsonLoader.push("es", payload);

      expect(fs.writeFile).toHaveBeenCalled();
      const writeFileCall = (fs.writeFile as any).mock.calls[0];
      const writtenContent = JSON.parse(writeFileCall[1]);

      // Check that locked array elements retain their original values
      expect(writtenContent.messages[0]).toBe("first");
      expect(writtenContent.messages[1]).toBe("second");
      expect(writtenContent.messages[2]).toBe("third");

      // Check that unlocked array elements are updated
      expect(writtenContent.unlocked[0]).toBe("should");
      expect(writtenContent.unlocked[1]).toBe("definitely");
      expect(writtenContent.unlocked[2]).toBe("change");
    });
  });

  describe("ignored keys functionality", () => {
    it("should omit ignored keys for JSON format", async () => {
      setupFileMocks();

      const input = {
        "button.title": "Submit",
        "button.description": "Submit description",
        "ignored.key": "Should be ignored",
        nested: {
          ignored: "This is ignored",
          kept: "This is kept",
        },
      };
      const payload = {
        "button.title": "Enviar",
        "button.description": "Descripción de envío",
        "nested/kept": "Esto se mantiene",
      };

      mockFileOperations(JSON.stringify(input));

      const jsonLoader = createBucketLoader(
        "json",
        "i18n/[locale].json",
        { defaultLocale: "en" },
        undefined, // lockedKeys
        undefined, // lockedPatterns
        ["ignored.key", "nested/ignored"], // ignoredKeys
      );

      jsonLoader.setDefaultLocale("en");
      const pulledData = await jsonLoader.pull("en");

      // Verify ignored keys are not in pulled data
      expect(pulledData).toEqual({
        "button.title": "Submit",
        "button.description": "Submit description",
        "nested/kept": "This is kept",
      });

      await jsonLoader.push("es", payload);

      expect(fs.writeFile).toHaveBeenCalled();
      const writeFileCall = (fs.writeFile as any).mock.calls[0];
      const writtenContent = JSON.parse(writeFileCall[1]);

      // Check that ignored keys are completely removed from output
      expect(writtenContent["ignored.key"]).toBeUndefined();
      expect(writtenContent.nested?.ignored).toBeUndefined();

      // Check that non-ignored keys are updated
      expect(writtenContent["button.title"]).toBe("Enviar");
      expect(writtenContent["button.description"]).toBe("Descripción de envío");
      expect(writtenContent.nested.kept).toBe("Esto se mantiene");
    });

    it("should handle wildcard patterns in ignored keys", async () => {
      setupFileMocks();

      const input = {
        "button.title": "Submit",
        wildcard_a: "Value A",
        wildcard_b: "Value B",
        other: "Other value",
      };
      const payload = {
        "button.title": "Enviar",
        other: "Otro valor",
      };

      mockFileOperations(JSON.stringify(input));

      const jsonLoader = createBucketLoader(
        "json",
        "i18n/[locale].json",
        { defaultLocale: "en" },
        undefined, // lockedKeys
        undefined, // lockedPatterns
        ["wildcard_*"], // ignoredKeys with wildcard
      );

      jsonLoader.setDefaultLocale("en");
      const pulledData = await jsonLoader.pull("en");

      // Verify wildcard ignored keys are not in pulled data
      expect(pulledData).toEqual({
        "button.title": "Submit",
        other: "Other value",
      });

      await jsonLoader.push("es", payload);

      expect(fs.writeFile).toHaveBeenCalled();
      const writeFileCall = (fs.writeFile as any).mock.calls[0];
      const writtenContent = JSON.parse(writeFileCall[1]);

      // Check that wildcard ignored keys are completely removed from output
      expect(writtenContent["wildcard_a"]).toBeUndefined();
      expect(writtenContent["wildcard_b"]).toBeUndefined();

      // Check that non-ignored keys are updated
      expect(writtenContent["button.title"]).toBe("Enviar");
      expect(writtenContent.other).toBe("Otro valor");
    });
  });

  describe("mdx bucket loader", () => {
    it("should skip locked keys", async () => {
      setupFileMocks();

      const input = dedent`
---
title: Test Mdx
category: test
---

# Heading 1
`;
      const expectedPayload = {
        "meta/title": "Test Mdx",
        "content/0": "\n# Heading 1",
      };

      mockFileOperations(input);

      const mdxLoader = createBucketLoader(
        "mdx",
        "i18n/[locale].mdx",
        { defaultLocale: "en" },
        ["meta/category"],
      );

      mdxLoader.setDefaultLocale("en");
      const data = await mdxLoader.pull("en");

      expect(data).toEqual(expectedPayload);
    });
  });

  describe("markdown bucket loader", () => {
    it("should load markdown data", async () => {
      setupFileMocks();

      const input = `---
title: Test Markdown
date: 2023-05-25
---

# Heading 1

This is a paragraph.

## Heading 2

Another paragraph with **bold** and *italic* text.`;
      const expectedOutput = {
        "fm-attr-title": "Test Markdown",
        "md-section-0": "# Heading 1",
        "md-section-1": "This is a paragraph.",
        "md-section-2": "## Heading 2",
        "md-section-3": "Another paragraph with **bold** and _italic_ text.",
      };

      mockFileOperations(input);

      const markdownLoader = createBucketLoader(
        "markdown",
        "i18n/[locale].md",
        {
          defaultLocale: "en",
        },
      );
      markdownLoader.setDefaultLocale("en");
      const data = await markdownLoader.pull("en");

      expect(data).toEqual(expectedOutput);
    });

    it("should save markdown data", async () => {
      setupFileMocks();

      const input = `---
title: Test Markdown
date: 2023-05-25
---

# Heading 1

This is a paragraph.

## Heading 2

Another paragraph with **bold** and *italic* text.`;
      const payload = {
        "fm-attr-title": "Prueba Markdown",
        "fm-attr-date": "2023-05-25",
        "md-section-0": "# Encabezado 1",
        "md-section-1": "Esto es un párrafo.",
        "md-section-2": "## Encabezado 2",
        "md-section-3": "Otro párrafo con texto en **negrita** y en _cursiva_.",
      };
      const expectedOutput = `---
title: Prueba Markdown
date: 2023-05-25
---

# Encabezado 1

Esto es un párrafo.

## Encabezado 2

Otro párrafo con texto en **negrita** y en _cursiva_.
`.trim();

      mockFileOperations(input);

      const markdownLoader = createBucketLoader(
        "markdown",
        "i18n/[locale].md",
        {
          defaultLocale: "en",
        },
      );
      markdownLoader.setDefaultLocale("en");
      await markdownLoader.pull("en");

      await markdownLoader.push("es", payload);

      expect(fs.writeFile).toHaveBeenCalledWith("i18n/es.md", expectedOutput, {
        encoding: "utf-8",
        flag: "w",
      });
    });

    it("should respect locked keys (pull)", async () => {
      setupFileMocks();

      const input = dedent`---
title: Locked Title
---

Content here.`;

      mockFileOperations(input);

      const markdownLoader = createBucketLoader(
        "markdown",
        "i18n/[locale].md",
        { defaultLocale: "en" },
        ["fm-attr-title"],
      );
      markdownLoader.setDefaultLocale("en");
      const data = await markdownLoader.pull("en");

      // frontmatter title removed
      expect(Object.keys(data)).not.toContain("fm-attr-title");
    });
  });

  describe("properties bucket loader", () => {
    it("should load properties data", async () => {
      setupFileMocks();

      const input = `
# General messages
welcome.message=Welcome to our application!
error.message=An error has occurred. Please try again later.

# User-related messages
user.login=Please enter your username and password.
user.username=Username
user.password=Password
      `.trim();
      const expectedOutput = {
        "welcome.message": "Welcome to our application!",
        "error.message": "An error has occurred. Please try again later.",
        "user.login": "Please enter your username and password.",
        "user.username": "Username",
        "user.password": "Password",
      };

      mockFileOperations(input);

      const propertiesLoader = createBucketLoader(
        "properties",
        "i18n/[locale].properties",
        {
          defaultLocale: "en",
        },
      );
      propertiesLoader.setDefaultLocale("en");
      const data = await propertiesLoader.pull("en");

      expect(data).toEqual(expectedOutput);
    });

    it("should save properties data", async () => {
      setupFileMocks();

      const input = `
# General messages
welcome.message=Welcome to our application!
error.message=An error has occurred. Please try again later.

# User-related messages
user.login=Please enter your username and password.
user.username=Username
user.password=Password
      `.trim();
      const payload = {
        "welcome.message": "Bienvenido a nuestra aplicación!",
        "error.message":
          "Se ha producido un error. Por favor, inténtelo de nuevo más tarde.",
        "user.login":
          "Por favor, introduzca su nombre de usuario y contraseña.",
        "user.username": "Nombre de usuario",
        "user.password": "Contraseña",
      };
      const expectedOutput = `
welcome.message=Bienvenido a nuestra aplicación!
error.message=Se ha producido un error. Por favor, inténtelo de nuevo más tarde.
user.login=Por favor, introduzca su nombre de usuario y contraseña.
user.username=Nombre de usuario
user.password=Contraseña
      `.trim();

      mockFileOperations(input);

      const propertiesLoader = createBucketLoader(
        "properties",
        "i18n/[locale].properties",
        {
          defaultLocale: "en",
        },
      );
      propertiesLoader.setDefaultLocale("en");
      await propertiesLoader.pull("en");

      await propertiesLoader.push("es", payload);

      expect(fs.writeFile).toHaveBeenCalledWith(
        "i18n/es.properties",
        expectedOutput,
        { encoding: "utf-8", flag: "w" },
      );
    });

    it("should respect locked keys (pull)", async () => {
      setupFileMocks();

      const input = `locked=Original\nunlocked=Hello`;

      mockFileOperations(input);

      const propertiesLoader = createBucketLoader(
        "properties",
        "i18n/[locale].properties",
        { defaultLocale: "en" },
        ["locked"],
      );
      propertiesLoader.setDefaultLocale("en");
      const data = await propertiesLoader.pull("en");

      expect(data).toEqual({ unlocked: "Hello" });
    });
  });

  describe("xcode-strings bucket loader", () => {
    it("should load xcode-strings", async () => {
      setupFileMocks();

      const input = `
"key1" = "value1";
"key2" = "value2";
"key3" = "Line 1\\nLine 2\\"quoted\\"";
      `.trim();
      const expectedOutput = {
        key1: "value1",
        key2: "value2",
        key3: 'Line 1\nLine 2"quoted"',
      };

      mockFileOperations(input);

      const xcodeStringsLoader = createBucketLoader(
        "xcode-strings",
        "i18n/[locale].strings",
        {
          defaultLocale: "en",
        },
      );
      xcodeStringsLoader.setDefaultLocale("en");
      const data = await xcodeStringsLoader.pull("en");

      expect(data).toEqual(expectedOutput);
    });

    it("should save xcode-strings", async () => {
      setupFileMocks();

      const input = `
"hello" = "Hello!";
      `.trim();
      const payload = { hello: "¡Hola!" };
      const expectedOutput = `"hello" = "¡Hola!";`;

      mockFileOperations(input);

      const xcodeStringsLoader = createBucketLoader(
        "xcode-strings",
        "i18n/[locale].strings",
        {
          defaultLocale: "en",
        },
      );
      xcodeStringsLoader.setDefaultLocale("en");
      await xcodeStringsLoader.pull("en");

      await xcodeStringsLoader.push("es", payload);

      expect(fs.writeFile).toHaveBeenCalledWith(
        "i18n/es.strings",
        expectedOutput,
        { encoding: "utf-8", flag: "w" },
      );
    });

    it("should respect locked keys (pull)", async () => {
      setupFileMocks();

      const input = `
"locked" = "Original";
"hello" = "Hello!";
      `.trim();

      mockFileOperations(input);

      const xcodeStringsLoader = createBucketLoader(
        "xcode-strings",
        "i18n/[locale].strings",
        { defaultLocale: "en" },
        ["locked"],
      );
      xcodeStringsLoader.setDefaultLocale("en");
      const data = await xcodeStringsLoader.pull("en");

      expect(data).toEqual({ hello: "Hello!" });
    });
  });

  describe("xcode-stringsdict bucket loader", () => {
    it("should load xcode-stringsdict", async () => {
      setupFileMocks();

      const input = `
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>greeting</key>
  <string>Hello!</string>
  <key>items_count</key>
  <dict>
    <key>NSStringLocalizedFormatKey</key>
    <string>%#@items@</string>
    <key>items</key>
    <dict>
      <key>NSStringFormatSpecTypeKey</key>
      <string>NSStringPluralRuleType</string>
      <key>NSStringFormatValueTypeKey</key>
      <string>d</string>
      <key>one</key>
      <string>%d item</string>
      <key>other</key>
      <string>%d items</string>
    </dict>
  </dict>
</dict>
</plist>
      `.trim();
      const expectedOutput = {
        greeting: "Hello!",
        "items_count/NSStringLocalizedFormatKey": "%#@items@",
        "items_count/items/NSStringFormatSpecTypeKey": "NSStringPluralRuleType",
        "items_count/items/NSStringFormatValueTypeKey": "d",
        "items_count/items/one": "%d item",
        "items_count/items/other": "%d items",
      };

      mockFileOperations(input);

      const xcodeStringsdictLoader = createBucketLoader(
        "xcode-stringsdict",
        "i18n/[locale].stringsdict",
        {
          defaultLocale: "en",
        },
      );
      xcodeStringsdictLoader.setDefaultLocale("en");
      const data = await xcodeStringsdictLoader.pull("en");

      expect(data).toEqual(expectedOutput);
    });

    it("should save xcode-stringsdict", async () => {
      setupFileMocks();

      const input = `
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>greeting</key>
    <string>Hello!</string>
  </dict>
</plist>
      `.trim();
      const payload = { greeting: "¡Hola!" };
      const expectedOutput = `<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>greeting</key>
    <string>¡Hola!</string>
  </dict>
</plist>
      `.trim();

      mockFileOperations(input);

      const xcodeStringsdictLoader = createBucketLoader(
        "xcode-stringsdict",
        "[locale].lproj/Localizable.stringsdict",
        {
          defaultLocale: "en",
        },
      );
      xcodeStringsdictLoader.setDefaultLocale("en");
      await xcodeStringsdictLoader.pull("en");

      await xcodeStringsdictLoader.push("es", payload);

      expect(fs.writeFile).toHaveBeenCalledWith(
        "es.lproj/Localizable.stringsdict",
        expectedOutput,
        {
          encoding: "utf-8",
          flag: "w",
        },
      );
    });

    it("should respect locked keys (pull)", async () => {
      setupFileMocks();

      const input = `
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>locked</key>
  <string>Original</string>
  <key>hello</key>
  <string>Hello!</string>
</dict>
</plist>
      `.trim();

      mockFileOperations(input);

      const xcodeStringsdictLoader = createBucketLoader(
        "xcode-stringsdict",
        "i18n/[locale].stringsdict",
        { defaultLocale: "en" },
        ["locked"],
      );
      xcodeStringsdictLoader.setDefaultLocale("en");
      const data = await xcodeStringsdictLoader.pull("en");

      expect(data).toEqual({ hello: "Hello!" });
    });
  });

  describe("xcode-xcstrings bucket loader", () => {
    it("should load xcode-xcstrings", async () => {
      setupFileMocks();

      const input = JSON.stringify({
        sourceLanguage: "en",
        strings: {
          greeting: {
            extractionState: "manual",
            localizations: {
              en: {
                stringUnit: {
                  state: "translated",
                  value: "Hello!",
                },
              },
            },
          },
          message: {
            extractionState: "manual",
            localizations: {
              en: {
                stringUnit: {
                  state: "translated",
                  value: "Welcome to our app",
                },
              },
            },
          },
          items_count: {
            extractionState: "manual",
            localizations: {
              en: {
                variations: {
                  plural: {
                    zero: {
                      stringUnit: {
                        state: "translated",
                        value: "No items",
                      },
                    },
                    one: {
                      stringUnit: {
                        state: "translated",
                        value: "%d item",
                      },
                    },
                    other: {
                      stringUnit: {
                        state: "translated",
                        value: "%d items",
                      },
                    },
                  },
                },
              },
            },
          },
        },
      });

      const expectedOutput = {
        greeting: "Hello!",
        message: "Welcome to our app",
        "items_count/zero": "No items",
        "items_count/one": "{variable:0} item",
        "items_count/other": "{variable:0} items",
      };

      mockFileOperations(input);

      const xcodeXcstringsLoader = createBucketLoader(
        "xcode-xcstrings",
        "i18n/[locale].xcstrings",
        {
          defaultLocale: "en",
        },
      );
      xcodeXcstringsLoader.setDefaultLocale("en");
      const data = await xcodeXcstringsLoader.pull("en");

      expect(data).toEqual(expectedOutput);
    });

    it("should load keys without default locale entries and use the key as value", async () => {
      setupFileMocks();

      const input = JSON.stringify({
        sourceLanguage: "en",
        strings: {
          greeting: {
            extractionState: "manual",
            localizations: {
              en: {
                stringUnit: {
                  state: "translated",
                  value: "Hello!",
                },
              },
            },
          },
          " and ": {
            extractionState: "manual",
            localizations: {
              en: {
                stringUnit: {
                  state: "translated",
                  value: " and ",
                },
              },
            },
          },
          key_with_no_default: {
            extractionState: "manual",
            localizations: {
              fr: {
                stringUnit: {
                  state: "translated",
                  value: "Valeur traduite",
                },
              },
            },
          },
        },
      });

      const expectedOutput = {
        greeting: "Hello!",
        "%20and%20": " and ",
        key_with_no_default: "key_with_no_default",
      };

      mockFileOperations(input);

      const xcodeXcstringsLoader = createBucketLoader(
        "xcode-xcstrings",
        "i18n/[locale].xcstrings",
        {
          defaultLocale: "en",
        },
      );
      xcodeXcstringsLoader.setDefaultLocale("en");
      const data = await xcodeXcstringsLoader.pull("en");

      expect(data).toEqual(expectedOutput);
    });

    it("should save xcode-xcstrings", async () => {
      setupFileMocks();

      const originalInput = {
        sourceLanguage: "en",
        strings: {
          greeting: {
            extractionState: "manual",
            localizations: {
              en: {
                stringUnit: {
                  state: "translated",
                  value: "Hello!",
                },
              },
            },
          },
        },
      };

      mockFileOperations(JSON.stringify(originalInput));

      const payload = {
        greeting: "Bonjour!",
        message: "Bienvenue dans notre application",
        "items_count/zero": "Aucun élément",
        "items_count/one": "%d élément",
        "items_count/other": "%d éléments",
      };

      const xcodeXcstringsLoader = createBucketLoader(
        "xcode-xcstrings",
        "i18n/[locale].xcstrings",
        {
          defaultLocale: "en",
        },
      );
      xcodeXcstringsLoader.setDefaultLocale("en");
      await xcodeXcstringsLoader.pull("en");
      await xcodeXcstringsLoader.push("fr", payload);

      expect(fs.writeFile).toHaveBeenCalled();
      const writeFileCall = (fs.writeFile as any).mock.calls[0];
      const writtenContent = JSON.parse(writeFileCall[1]);

      expect(writtenContent.strings.greeting.localizations.fr).toBeDefined();
      expect(
        writtenContent.strings.greeting.localizations.fr.stringUnit.value,
      ).toBe("Bonjour!");

      if (writtenContent.strings.message) {
        expect(
          writtenContent.strings.message.localizations.fr.stringUnit.value,
        ).toBe("Bienvenue dans notre application");
      }

      if (writtenContent.strings.items_count) {
        expect(
          writtenContent.strings.items_count.localizations.fr.variations.plural
            .zero.stringUnit.value,
        ).toBe("Aucun élément");
        expect(
          writtenContent.strings.items_count.localizations.fr.variations.plural
            .one.stringUnit.value,
        ).toBe("%d élément");
        expect(
          writtenContent.strings.items_count.localizations.fr.variations.plural
            .other.stringUnit.value,
        ).toBe("%d éléments");
      }
    });

    it("should maintain ASCII ordering with empty strings, whitespace, and numbers", async () => {
      setupFileMocks();

      const input = `{
  "sourceLanguage": "en",
  "strings": {
    "": {
      "extractionState": "manual",
      "localizations": {
        "en": {
          "stringUnit": {
            "state": "translated",
            "value": "Empty key"
          }
        }
      }
    },
    " ": {
      "extractionState": "manual",
      "localizations": {
        "en": {
          "stringUnit": {
            "state": "translated",
            "value": "Space key"
          }
        }
      }
    },
    "25": {
      "extractionState": "manual",
      "localizations": {
        "en": {
          "stringUnit": {
            "state": "translated",
            "value": "Numeric key"
          }
        }
      }
    },
    "apple": {
      "extractionState": "manual",
      "localizations": {
        "en": {
          "stringUnit": {
            "state": "translated",
            "value": "Apple"
          }
        }
      }
  }
}`;

      mockFileOperations(input);

      const xcodeXcstringsLoader = createBucketLoader(
        "xcode-xcstrings",
        "i18n/[locale].xcstrings",
        {
          defaultLocale: "en",
        },
      );
      xcodeXcstringsLoader.setDefaultLocale("en");
      const data = await xcodeXcstringsLoader.pull("en");

      Object.keys(data).forEach((key) => {
        if (key === "") {
          expect(data[key]).toBe("Empty key");
        } else if (key.includes("%20") || key === " ") {
          expect(data[key]).toBe("Space key");
        } else if (key === "25") {
          expect(data[key]).toBe("Numeric key");
        } else if (key === "apple") {
          expect(data[key]).toBe("Apple");
        }
      });

      const payload: Record<string, string> = {};

      Object.keys(data).forEach((key) => {
        if (key === "") {
          payload[key] = "Vide";
        } else if (key.includes("%20") || key === " ") {
          payload[key] = "Espace";
        } else if (key === "25") {
          payload[key] = "Numérique";
        } else if (key === "apple") {
          payload[key] = "Pomme";
        }
      });

      await xcodeXcstringsLoader.pull("en");
      await xcodeXcstringsLoader.push("fr", payload);

      expect(fs.writeFile).toHaveBeenCalled();
      const writeFileCall = (fs.writeFile as any).mock.calls[0];
      const writtenContent = JSON.parse(writeFileCall[1]);

      if (writtenContent.strings[""]) {
        expect(
          writtenContent.strings[""].localizations.fr.stringUnit.value,
        ).toBe("Vide");
      }

      const hasSpaceKey = Object.keys(writtenContent.strings).some(
        (key) => key === " " || key === "%20" || key.includes("%20"),
      );
      if (hasSpaceKey) {
        const spaceKey = Object.keys(writtenContent.strings).find(
          (key) => key === " " || key === "%20" || key.includes("%20"),
        );
        if (spaceKey) {
          expect(
            writtenContent.strings[spaceKey].localizations.fr.stringUnit.value,
          ).toBe("Espace");
        }
      }

      if (writtenContent.strings["25"]) {
        expect(
          writtenContent.strings["25"].localizations.fr.stringUnit.value,
        ).toBe("Numérique");
      }

      if (writtenContent.strings["apple"]) {
        expect(
          writtenContent.strings["apple"].localizations.fr.stringUnit.value,
        ).toBe("Pomme");
      }

      const stringKeys = Object.keys(writtenContent.strings);

      expect(stringKeys.includes("25")).toBe(true);
      expect(stringKeys.includes("")).toBe(true);
      expect(stringKeys.includes(" ") || stringKeys.includes("%20")).toBe(true);
      expect(stringKeys.includes("apple")).toBe(true);

      expect(stringKeys.indexOf("25")).toBeLessThan(stringKeys.indexOf(""));

      const spaceIdx =
        stringKeys.indexOf(" ") === -1
          ? stringKeys.indexOf("%20")
          : stringKeys.indexOf(" ");
      if (spaceIdx !== -1) {
        expect(stringKeys.indexOf("")).toBeLessThan(spaceIdx);
      }

      if (spaceIdx !== -1) {
        expect(spaceIdx).toBeLessThan(stringKeys.indexOf("apple"));
      }
    });

    it("should respect shouldTranslate: false flag", async () => {
      setupFileMocks();

      const input = `{
  "sourceLanguage": "en",
  "strings": {
    "do_not_translate": {
      "shouldTranslate": false,
      "localizations": {
        "en": {
          "stringUnit": {
            "state": "translated",
            "value": "This should not be translated"
          }
        }
      }
    },
    "normal_key": {
      "extractionState": "manual",
      "localizations": {
        "en": {
          "stringUnit": {
            "state": "translated",
            "value": "This should be translated"
          }
        }
      }
    }
  }
}`;

      mockFileOperations(input);

      const xcodeXcstringsLoader = createBucketLoader(
        "xcode-xcstrings",
        "i18n/[locale].xcstrings",
        {
          defaultLocale: "en",
        },
      );
      xcodeXcstringsLoader.setDefaultLocale("en");

      const data = await xcodeXcstringsLoader.pull("en");

      expect(data).toHaveProperty("normal_key", "This should be translated");
      expect(data).not.toHaveProperty("do_not_translate");

      const payload = {
        normal_key: "Ceci devrait être traduit",
      };

      await xcodeXcstringsLoader.push("fr", payload);

      expect(fs.writeFile).toHaveBeenCalled();
      const writeFileCall = (fs.writeFile as any).mock.calls[0];
      const writtenContent = JSON.parse(writeFileCall[1]);

      expect(
        writtenContent.strings.normal_key.localizations.fr.stringUnit.value,
      ).toBe("Ceci devrait être traduit");

      expect(writtenContent.strings.do_not_translate).toHaveProperty(
        "shouldTranslate",
        false,
      );

      expect(
        writtenContent.strings.do_not_translate.localizations,
      ).not.toHaveProperty("fr");

      await xcodeXcstringsLoader.push("fr", {});

      const secondWriteFileCall = (fs.writeFile as any).mock.calls[1];
      const secondWrittenContent = JSON.parse(secondWriteFileCall[1]);

      expect(secondWrittenContent.strings.do_not_translate).toHaveProperty(
        "shouldTranslate",
        false,
      );
    });

    it("should extract and restore variables during pull/push", async () => {
      setupFileMocks();

      const input = JSON.stringify({
        sourceLanguage: "en",
        strings: {
          message: {
            extractionState: "manual",
            localizations: {
              en: {
                stringUnit: {
                  state: "translated",
                  value: "Value: %d items",
                },
              },
            },
          },
        },
      });

      mockFileOperations(input);

      const xcLoader = createBucketLoader(
        "xcode-xcstrings",
        "i18n/[locale].xcstrings",
        {
          defaultLocale: "en",
        },
      );
      xcLoader.setDefaultLocale("en");

      const data = await xcLoader.pull("en");

      expect(data).toEqual({ message: "Value: {variable:0} items" });

      const payload = {
        message: "Valeur: {variable:0} éléments",
      };

      await xcLoader.push("fr", payload);

      expect(fs.writeFile).toHaveBeenCalled();
      const writeFileCall = (fs.writeFile as any).mock.calls[0];
      const writtenContent = JSON.parse(writeFileCall[1]);

      expect(
        writtenContent.strings.message.localizations.fr.stringUnit.value,
      ).toBe("Valeur: %d éléments");
    });

    it("should extract hints from xcstrings comments", async () => {
      setupFileMocks();

      const input = JSON.stringify({
        sourceLanguage: "en",
        strings: {
          welcome_message: {
            comment: "Greeting displayed on the main screen",
            extractionState: "manual",
            localizations: {
              en: {
                stringUnit: {
                  state: "translated",
                  value: "Welcome!",
                },
              },
            },
          },
          user_count: {
            comment: "Number of active users - supports pluralization",
            extractionState: "manual",
            localizations: {
              en: {
                variations: {
                  plural: {
                    one: {
                      stringUnit: {
                        state: "translated",
                        value: "1 user",
                      },
                    },
                    other: {
                      stringUnit: {
                        state: "translated",
                        value: "%d users",
                      },
                    },
                  },
                },
              },
            },
          },
          no_comment: {
            extractionState: "manual",
            localizations: {
              en: {
                stringUnit: {
                  state: "translated",
                  value: "No comment here",
                },
              },
            },
          },
        },
      });

      mockFileOperations(input);

      const xcodeXcstringsLoader = createBucketLoader(
        "xcode-xcstrings",
        "i18n/[locale].xcstrings",
        {
          defaultLocale: "en",
        },
      );
      xcodeXcstringsLoader.setDefaultLocale("en");
      await xcodeXcstringsLoader.pull("en");

      const hints = await xcodeXcstringsLoader.pullHints();

      // Note: The output is flattened because xcode-xcstrings bucket loader goes through the flat loader
      expect(hints).toEqual({
        welcome_message: ["Greeting displayed on the main screen"],
        user_count: ["Number of active users - supports pluralization"],
        "user_count/one": ["Number of active users - supports pluralization"],
        "user_count/other": ["Number of active users - supports pluralization"],
      });
    });

    it("should handle xcstrings without comments in full-stack loader", async () => {
      setupFileMocks();

      const input = JSON.stringify({
        sourceLanguage: "en",
        strings: {
          simple_key: {
            extractionState: "manual",
            localizations: {
              en: {
                stringUnit: {
                  state: "translated",
                  value: "Simple value",
                },
              },
            },
          },
        },
      });

      mockFileOperations(input);

      const xcodeXcstringsLoader = createBucketLoader(
        "xcode-xcstrings",
        "i18n/[locale].xcstrings",
        {
          defaultLocale: "en",
        },
      );
      xcodeXcstringsLoader.setDefaultLocale("en");
      await xcodeXcstringsLoader.pull("en");

      const hints = await xcodeXcstringsLoader.pullHints();

      expect(hints).toEqual({});
    });

    it("should properly filter lockedKeys from data during pull operations", async () => {
      setupFileMocks();

      const input = JSON.stringify({
        sourceLanguage: "en",
        strings: {
          welcome_message: {
            comment: "Welcome message - should be locked",
            extractionState: "manual",
            localizations: {
              en: {
                stringUnit: {
                  state: "translated",
                  value: "Hello, world!",
                },
              },
              es: {
                stringUnit: {
                  state: "translated",
                  value: "¡Hola, mundo!",
                },
              },
            },
          },
          user_count: {
            comment: "Number of users - should be translatable",
            extractionState: "manual",
            localizations: {
              en: {
                variations: {
                  plural: {
                    one: {
                      stringUnit: {
                        state: "translated",
                        value: "1 user",
                      },
                    },
                    other: {
                      stringUnit: {
                        state: "translated",
                        value: "%d users",
                      },
                    },
                  },
                },
              },
              es: {
                variations: {
                  plural: {
                    one: {
                      stringUnit: {
                        state: "translated",
                        value: "1 usuario",
                      },
                    },
                    other: {
                      stringUnit: {
                        state: "translated",
                        value: "%d usuarios",
                      },
                    },
                  },
                },
              },
            },
          },
          api_key: {
            comment: "API key - should be locked with wildcard pattern",
            extractionState: "manual",
            localizations: {
              en: {
                stringUnit: {
                  state: "translated",
                  value: "sk-1234567890abcdef",
                },
              },
            },
          },
        },
      });

      mockFileOperations(input);

      // Test with lockedKeys including both specific keys and wildcard patterns
      const xcodeXcstringsLoaderWithLockedKeys = createBucketLoader(
        "xcode-xcstrings",
        "i18n/[locale].xcstrings",
        {
          defaultLocale: "en",
        },
        ["welcome_message", "api*"], // lockedKeys parameter
      );
      xcodeXcstringsLoaderWithLockedKeys.setDefaultLocale("en");

      // First pull the default locale to initialize the loader
      await xcodeXcstringsLoaderWithLockedKeys.pull("en");

      // Pull data for translation - should filter out locked keys
      const dataForTranslation =
        await xcodeXcstringsLoaderWithLockedKeys.pull("es");

      // Locked keys should be filtered out
      expect(dataForTranslation).not.toHaveProperty("welcome_message");
      expect(dataForTranslation).not.toHaveProperty("api_key");

      // Non-locked keys should remain
      expect(dataForTranslation).toHaveProperty("user_count/one");
      expect(dataForTranslation).toHaveProperty("user_count/other");
      expect(dataForTranslation["user_count/one"]).toBe("1 usuario");
      expect(dataForTranslation["user_count/other"]).toBe(
        "{variable:0} usuarios",
      );

      // Test that push operations preserve locked keys from original

      const translationPayload = {
        "user_count/one": "1 usuario nuevo",
        "user_count/other": "{variable:0} usuarios nuevos",
        // Attempt to overwrite locked keys - should be ignored
        welcome_message: "This should be ignored",
        api_key: "This should also be ignored",
      };

      await xcodeXcstringsLoaderWithLockedKeys.push("es", translationPayload);

      expect(fs.writeFile).toHaveBeenCalled();
      const writeFileCall = (fs.writeFile as any).mock.calls[0];
      const writtenContent = JSON.parse(writeFileCall[1]);

      // Locked keys should preserve their original values from the input
      // Since welcome_message was locked, the Spanish translation should not be overwritten
      // But it might be replaced with the English value due to how the xcstrings loader works
      // The important thing is that it wasn't sent for translation
      expect(
        writtenContent.strings.welcome_message.localizations.es,
      ).toBeDefined();
      expect(
        writtenContent.strings.welcome_message.localizations.es.stringUnit
          .value,
      ).toMatch(/Hello, world!|¡Hola, mundo!/);
      expect(
        writtenContent.strings.api_key.localizations.en.stringUnit.value,
      ).toBe("sk-1234567890abcdef");
      // The api_key is locked, so it should preserve the original value even if we tried to overwrite it
      if (writtenContent.strings.api_key.localizations.es) {
        expect(
          writtenContent.strings.api_key.localizations.es.stringUnit.value,
        ).toBe("sk-1234567890abcdef");
      }

      // Non-locked keys should have new translations
      expect(
        writtenContent.strings.user_count.localizations.es.variations.plural.one
          .stringUnit.value,
      ).toBe("1 usuario nuevo");
      expect(
        writtenContent.strings.user_count.localizations.es.variations.plural
          .other.stringUnit.value,
      ).toBe("%d usuarios nuevos");
    });
  });

  describe("yaml bucket loader", () => {
    it("should load yaml", async () => {
      setupFileMocks();

      const input = `
        greeting: Hello!
      `.trim();
      const expectedOutput = { greeting: "Hello!" };

      mockFileOperations(input);

      const yamlLoader = createBucketLoader("yaml", "i18n/[locale].yaml", {
        defaultLocale: "en",
      });
      yamlLoader.setDefaultLocale("en");
      const data = await yamlLoader.pull("en");

      expect(data).toEqual(expectedOutput);
    });

    it("should respect locked keys (pull)", async () => {
      setupFileMocks();

      const input = `locked: Original\nhello: Hello!`;

      mockFileOperations(input);

      const yamlLoader = createBucketLoader(
        "yaml",
        "i18n/[locale].yaml",
        {
          defaultLocale: "en",
        },
        ["locked"],
      );
      yamlLoader.setDefaultLocale("en");
      const data = await yamlLoader.pull("en");

      expect(data).toEqual({ hello: "Hello!" });
    });

    it("should save yaml", async () => {
      setupFileMocks();

      const input = `
        greeting: Hello!
      `.trim();
      const payload = { greeting: "¡Hola!" };
      const expectedOutput = `greeting: ¡Hola!`;

      mockFileOperations(input);

      const yamlLoader = createBucketLoader("yaml", "i18n/[locale].yaml", {
        defaultLocale: "en",
      });
      yamlLoader.setDefaultLocale("en");
      await yamlLoader.pull("en");

      await yamlLoader.push("es", payload);

      expect(fs.writeFile).toHaveBeenCalledWith(
        "i18n/es.yaml",
        expectedOutput,
        { encoding: "utf-8", flag: "w" },
      );
    });

    describe("yaml with quoted keys and values", async () => {
      it.each([
        ["double quoted values", `greeting: "Hello!"`, `greeting: "¡Hola!"`],
        ["double quoted keys", `"greeting": Hello!`, `"greeting": ¡Hola!`],
        [
          "double quoted keys and values",
          `"greeting": "Hello!"`,
          `"greeting": "¡Hola!"`,
        ],
      ])(
        "should return correct value for %s",
        async (_, input, expectedOutput) => {
          const payload = { greeting: "¡Hola!" };

          mockFileOperations(input);

          const yamlLoader = createBucketLoader("yaml", "i18n/[locale].yaml", {
            defaultLocale: "en",
          });
          yamlLoader.setDefaultLocale("en");
          await yamlLoader.pull("en");

          await yamlLoader.push("es", payload);

          expect(fs.writeFile).toHaveBeenCalledWith(
            "i18n/es.yaml",
            expectedOutput,
            { encoding: "utf-8", flag: "w" },
          );
        },
      );
    });
  });

  describe("yaml-root-key bucket loader", () => {
    it("should load yaml-root-key", async () => {
      setupFileMocks();

      const input = `
      en:
        greeting: Hello!
    `.trim();
      const expectedOutput = { greeting: "Hello!" };

      mockFileOperations(input);

      const yamlRootKeyLoader = createBucketLoader(
        "yaml-root-key",
        "i18n/[locale].yaml",
        {
          defaultLocale: "en",
        },
      );
      yamlRootKeyLoader.setDefaultLocale("en");
      const data = await yamlRootKeyLoader.pull("en");

      expect(data).toEqual(expectedOutput);
    });

    it("should save yaml-root-key", async () => {
      setupFileMocks();

      const input = `
      en:
        greeting: Hello!
    `.trim();
      const payload = { greeting: "¡Hola!" };
      const expectedOutput = `es:\n  greeting: ¡Hola!`;

      mockFileOperations(input);

      const yamlRootKeyLoader = createBucketLoader(
        "yaml-root-key",
        "i18n/[locale].yaml",
        {
          defaultLocale: "en",
        },
      );
      yamlRootKeyLoader.setDefaultLocale("en");
      await yamlRootKeyLoader.pull("en");

      await yamlRootKeyLoader.push("es", payload);

      expect(fs.writeFile).toHaveBeenCalledWith(
        "i18n/es.yaml",
        expectedOutput,
        { encoding: "utf-8", flag: "w" },
      );
    });
  });

  describe("vtt bucket loader", () => {
    it("should load complex vtt data", async () => {
      setupFileMocks();

      const input = `
  WEBVTT

00:00:00.000 --> 00:00:01.000
Hello world!

00:00:30.000 --> 00:00:31.000 align:start line:0%
This is a subtitle

00:01:00.000 --> 00:01:01.000
Foo

00:01:50.000 --> 00:01:51.000
Bar
      `.trim();

      const expectedOutput = {
        "0#0-1#": "Hello world!",
        "1#30-31#": "This is a subtitle",
        "2#60-61#": "Foo",
        "3#110-111#": "Bar",
      };

      mockFileOperations(input);

      const vttLoader = createBucketLoader("vtt", "i18n/[locale].vtt", {
        defaultLocale: "en",
      });
      vttLoader.setDefaultLocale("en");
      const data = await vttLoader.pull("en");

      expect(data).toEqual(expectedOutput);
    });

    it("should save complex vtt data", async () => {
      setupFileMocks();
      const input = `
  WEBVTT

00:00:00.000 --> 00:00:01.000
Hello world!

00:00:30.000 --> 00:00:31.000 align:start line:0%
This is a subtitle

00:01:00.000 --> 00:01:01.000
Foo

00:01:50.000 --> 00:01:51.000
Bar
      `.trim();

      const payload = {
        "0#0-1#": "¡Hola mundo!",
        "1#30-31#": "Este es un subtítulo",
        "2#60-61#": "Foo",
        "3#110-111#": "Bar",
      };

      const expectedOutput = `
  WEBVTT

00:00:00.000 --> 00:00:01.000
¡Hola mundo!

00:00:30.000 --> 00:00:31.000
Este es un subtítulo

00:01:00.000 --> 00:01:01.000
Foo

00:01:50.000 --> 00:01:51.000
Bar`.trim();

      mockFileOperations(input);

      const vttLoader = createBucketLoader("vtt", "i18n/[locale].vtt", {
        defaultLocale: "en",
      });
      vttLoader.setDefaultLocale("en");
      await vttLoader.pull("en");

      await vttLoader.push("es", payload);

      expect(fs.writeFile).toHaveBeenCalledWith("i18n/es.vtt", expectedOutput, {
        encoding: "utf-8",
        flag: "w",
      });
    });

    it("should respect locked keys (pull)", async () => {
      setupFileMocks();
      const input = `
WEBVTT

00:00:00.000 --> 00:00:01.000
Hello world!

00:00:30.000 --> 00:00:31.000
Another cue
      `.trim();

      mockFileOperations(input);

      const vttLoader = createBucketLoader(
        "vtt",
        "i18n/[locale].vtt",
        {
          defaultLocale: "en",
        },
        ["0#*"],
      );
      vttLoader.setDefaultLocale("en");
      const data = await vttLoader.pull("en");

      // First cue (index 0) locked, so only second remains
      expect(Object.values(data)).toContain("Another cue");
      expect(Object.values(data)).not.toContain("Hello world!");
    });
  });

  describe("XML bucket loader", () => {
    it("should load XML data", async () => {
      setupFileMocks();

      const input = `<root>
    <title>Test XML</title>
    <date>2023-05-25</date>
    <content>
      <section>Introduction</section>
      <section>
        <text>
          Detailed text. 
        </text>
      </section>
    </content>
  </root>`;

      const expectedOutput = {
        "root/title": "Test XML",
        "root/content/section/0": "Introduction",
        "root/content/section/1/text": "Detailed text.",
      };

      mockFileOperations(input);

      const xmlLoader = createBucketLoader("xml", "i18n/[locale].xml", {
        defaultLocale: "en",
      });
      xmlLoader.setDefaultLocale("en");
      const data = await xmlLoader.pull("en");

      expect(data).toEqual(expectedOutput);
    });

    it("should save XML data", async () => {
      setupFileMocks();

      const input = `<root>
    <title>Test XML</title>
    <date>2023-05-25</date>
    <content>
      <section>Introduction</section>
      <section>
        <text>
          Detailed text.
        </text>
      </section>
    </content>
  </root>`;

      const payload = {
        "root/title": "Prueba XML",
        "root/date": "2023-05-25",
        "root/content/section/0": "Introducción",
        "root/content/section/1/text": "Detalles texto.",
      };

      let expectedOutput = `
      <root>
        <title>Prueba XML</title>
        <date>2023-05-25</date>
        <content>
          <section>Introducción</section>
          <section>
            <text>Detalles texto.</text>
          </section>
        </content>
      </root>`
        .replace(/\s+/g, " ")
        .replace(/>\s+</g, "><")
        .trim();
      mockFileOperations(input);
      const xmlLoader = createBucketLoader("xml", "i18n/[locale].xml", {
        defaultLocale: "en",
      });
      xmlLoader.setDefaultLocale("en");
      await xmlLoader.pull("en");

      await xmlLoader.push("es", payload);

      expect(fs.writeFile).toHaveBeenCalledWith("i18n/es.xml", expectedOutput, {
        encoding: "utf-8",
        flag: "w",
      });
    });

    it("should respect locked keys (pull)", async () => {
      setupFileMocks();
      const input = `<root><locked>Original</locked><hello>Hello!</hello></root>`;
      mockFileOperations(input);

      const xmlLoader = createBucketLoader(
        "xml",
        "i18n/[locale].xml",
        {
          defaultLocale: "en",
        },
        ["root/locked"],
      );
      xmlLoader.setDefaultLocale("en");
      const data = await xmlLoader.pull("en");

      expect(data).toEqual({ "root/hello": "Hello!" });
    });
  });

  describe("srt bucket loader", () => {
    it("should load srt", async () => {
      setupFileMocks();

      const input = `
1
00:00:00,000 --> 00:00:01,000
Hello!

2
00:00:01,000 --> 00:00:02,000
World!
      `.trim();
      const expectedOutput = {
        "1#00:00:00,000-00:00:01,000": "Hello!",
        "2#00:00:01,000-00:00:02,000": "World!",
      };

      mockFileOperations(input);

      const srtLoader = createBucketLoader("srt", "i18n/[locale].srt", {
        defaultLocale: "en",
      });
      srtLoader.setDefaultLocale("en");
      const data = await srtLoader.pull("en");

      expect(data).toEqual(expectedOutput);
    });

    it("should save srt", async () => {
      setupFileMocks();

      const input = `
1
00:00:00,000 --> 00:00:01,000
Hello!

2
00:00:01,000 --> 00:00:02,000
World!
  `.trim();

      const payload = {
        "1#00:00:00,000-00:00:01,000": "¡Hola!",
        "2#00:00:01,000-00:00:02,000": "Mundo!",
      };

      const expectedOutput = `1
00:00:00,000 --> 00:00:01,000
¡Hola!

2
00:00:01,000 --> 00:00:02,000
Mundo!`;

      mockFileOperations(input);

      const srtLoader = createBucketLoader("srt", "i18n/[locale].srt", {
        defaultLocale: "en",
      });
      srtLoader.setDefaultLocale("en");
      await srtLoader.pull("en");

      await srtLoader.push("es", payload);

      expect(fs.writeFile).toHaveBeenCalledWith("i18n/es.srt", expectedOutput, {
        encoding: "utf-8",
        flag: "w",
      });
    });

    it("should respect locked keys (pull)", async () => {
      setupFileMocks();
      const input = `
1
00:00:00,000 --> 00:00:01,000
Hello!

2
00:00:01,000 --> 00:00:02,000
World!
      `.trim();

      mockFileOperations(input);

      const srtLoader = createBucketLoader(
        "srt",
        "i18n/[locale].srt",
        {
          defaultLocale: "en",
        },
        ["1#00:00:00,000-00:00:01,000"],
      );
      srtLoader.setDefaultLocale("en");
      const data = await srtLoader.pull("en");

      expect(data).toEqual({ "2#00:00:01,000-00:00:02,000": "World!" });
    });
  });

  describe("xliff bucket loader", () => {
    it("should load xliff data", async () => {
      setupFileMocks();

      const input = `
  <xliff xmlns="urn:oasis:names:tc:xliff:document:2.0" version="2.0" srcLang="en-US">
    <file id="namespace1">
      <unit id="key1">
        <segment>
          <source>Hello</source>
        </segment>
      </unit>
      <unit id="key2">
        <segment>
          <source>An application to manipulate and process XLIFF documents</source>
        </segment>
      </unit>
      <unit id="key.nested">
        <segment>
          <source>XLIFF Data Manager</source>
        </segment>
      </unit>
      <group id="group">
        <unit id="groupUnit">
          <segment>
            <source>Group</source>
          </segment>
        </unit>
      </group>
    </file>
  </xliff>
      `.trim();

      // Keys must be encoded (e.g. / replaced with %2F)
      const expectedOutput = {
        "resources%2Fnamespace1%2Fgroup%2FgroupUnits%2FgroupUnit%2Fsource":
          "Group",
        "resources%2Fnamespace1%2Fkey.nested%2Fsource": "XLIFF Data Manager",
        "resources%2Fnamespace1%2Fkey1%2Fsource": "Hello",
        "resources%2Fnamespace1%2Fkey2%2Fsource":
          "An application to manipulate and process XLIFF documents",
        sourceLanguage: "en-US",
      };

      mockFileOperations(input);

      const xliffLoader = createBucketLoader("xliff", "i18n/[locale].xliff", {
        defaultLocale: "en",
      });
      xliffLoader.setDefaultLocale("en");
      const data = await xliffLoader.pull("en");

      expect(data).toEqual(expectedOutput);
    });

    it("should save xliff data", async () => {
      setupFileMocks();

      const input = `
    <xliff xmlns="urn:oasis:names:tc:xliff:document:2.0" version="2.0" srcLang="en-US">
      <file id="namespace1">
        <unit id="key1">
          <segment>
            <source>Hello</source>
          </segment>
        </unit>
        <unit id="key2">
          <segment>
            <source>An application to manipulate and process XLIFF documents</source>
          </segment>
        </unit>
        <unit id="key.nested">
          <segment>
            <source>XLIFF Data Manager</source>
          </segment>
        </unit>
        <group id="group">
          <unit id="groupUnit">
            <segment>
              <source>Group</source>
            </segment>
          </unit>
        </group>
      </file>
    </xliff>
        `.trim();
      // Keys must be encoded (e.g. / replaced with %2F)
      const payload = {
        "resources%2Fnamespace1%2Fgroup%2FgroupUnits%2FgroupUnit%2Fsource":
          "Grupo",
        "resources%2Fnamespace1%2Fkey.nested%2Fsource":
          "Administrador de Datos XLIFF",
        "resources%2Fnamespace1%2Fkey1%2Fsource": "Hola",
        "resources%2Fnamespace1%2Fkey2%2Fsource":
          "Una aplicación para manipular y procesar documentos XLIFF",
        sourceLanguage: "es-ES",
      };

      const expectedOutput = `
<xliff xmlns="urn:oasis:names:tc:xliff:document:2.0" version="2.0" srcLang="es-ES">
  <file id="namespace1">
    <unit id="key1">
      <segment>
        <source>Hola</source>
      </segment>
    </unit>
    <unit id="key2">
      <segment>
        <source>Una aplicación para manipular y procesar documentos XLIFF</source>
      </segment>
    </unit>
    <unit id="key.nested">
      <segment>
        <source>Administrador de Datos XLIFF</source>
      </segment>
    </unit>
    <group id="group">
      <unit id="groupUnit">
        <segment>
          <source>Grupo</source>
        </segment>
      </unit>
    </group>
  </file>
</xliff>`.trim();

      mockFileOperations(input);

      const xliffLoader = createBucketLoader("xliff", "i18n/[locale].xlf", {
        defaultLocale: "en",
      });
      xliffLoader.setDefaultLocale("en");
      await xliffLoader.pull("en");

      await xliffLoader.push("es", payload);

      expect(fs.writeFile).toHaveBeenCalledWith("i18n/es.xlf", expectedOutput, {
        encoding: "utf-8",
        flag: "w",
      });
    });

    it("should respect locked keys (pull)", async () => {
      setupFileMocks();

      const input = `
  <xliff xmlns="urn:oasis:names:tc:xliff:document:2.0" version="2.0" srcLang="en-US">
    <file id="namespace1">
      <unit id="locked">
        <segment>
          <source>Original</source>
        </segment>
      </unit>
      <unit id="key1">
        <segment>
          <source>Hello</source>
        </segment>
      </unit>
    </file>
  </xliff>
      `.trim();

      mockFileOperations(input);

      const xliffLoader = createBucketLoader(
        "xliff",
        "i18n/[locale].xliff",
        {
          defaultLocale: "en",
        },
        ["resources%2Fnamespace1%2Flocked%2Fsource"],
      );
      xliffLoader.setDefaultLocale("en");
      const data = await xliffLoader.pull("en");

      expect(data).toEqual({
        "resources%2Fnamespace1%2Fkey1%2Fsource": "Hello",
        sourceLanguage: "en-US",
      });
    });
  });

  describe("text-file", () => {
    describe("when there is no target locale file", () => {
      it("should preserve trailing new line based on the source locale", async () => {
        setupFileMocks();

        const input = "Hello\n";
        const expectedOutput = "Hola\n";

        mockFileOperationsForPaths({
          "i18n/en.txt": input,
          "i18n/es.txt": "",
        });

        const textFileLoader = createTextFileLoader("i18n/[locale].txt");
        textFileLoader.setDefaultLocale("en");
        await textFileLoader.pull("en");

        await textFileLoader.push("es", "Hola");

        expect(fs.writeFile).toHaveBeenCalledWith(
          "i18n/es.txt",
          expectedOutput,
          { encoding: "utf-8", flag: "w" },
        );
      });

      it("should not add trailing new line based on the source locale", async () => {
        setupFileMocks();

        const input = "Hello";
        const expectedOutput = "Hola";

        mockFileOperationsForPaths({
          "i18n/en.txt": input,
          "i18n/es.txt": "",
        });

        const textFileLoader = createTextFileLoader("i18n/[locale].txt");
        textFileLoader.setDefaultLocale("en");
        await textFileLoader.pull("en");

        await textFileLoader.push("es", "Hola");

        expect(fs.writeFile).toHaveBeenCalledWith(
          "i18n/es.txt",
          expectedOutput,
          { encoding: "utf-8", flag: "w" },
        );
      });
    });

    describe("when there is a target locale file", () => {
      it("should preserve trailing new lines based on the target locale", async () => {
        setupFileMocks();

        const input = "Hello";
        const targetInput = "Hola\n";
        const expectedOutput = "Hola (translated)\n";

        mockFileOperationsForPaths({
          "i18n/en.txt": input,
          "i18n/es.txt": targetInput,
        });

        const textFileLoader = createTextFileLoader("i18n/[locale].txt");
        textFileLoader.setDefaultLocale("en");
        await textFileLoader.pull("en");

        await textFileLoader.push("es", "Hola (translated)");

        expect(fs.writeFile).toHaveBeenCalledWith(
          "i18n/es.txt",
          expectedOutput,
          { encoding: "utf-8", flag: "w" },
        );
      });

      it("should not add trailing new line based on the target locale", async () => {
        setupFileMocks();

        const input = "Hello\n";
        const targetInput = "Hola";
        const expectedOutput = "Hola (translated)";

        mockFileOperationsForPaths({
          "i18n/en.txt": input,
          "i18n/es.txt": targetInput,
        });

        const textFileLoader = createTextFileLoader("i18n/[locale].txt");
        textFileLoader.setDefaultLocale("en");
        await textFileLoader.pull("en");

        await textFileLoader.push("es", "Hola (translated)");

        expect(fs.writeFile).toHaveBeenCalledWith(
          "i18n/es.txt",
          expectedOutput,
          { encoding: "utf-8", flag: "w" },
        );
      });
    });
  });

  describe("php bucket loader", () => {
    it("should load php array", async () => {
      setupFileMocks();

      const input = `<?php return ['button.title' => 'Submit'];`;
      const expectedOutput = { "button.title": "Submit" };

      mockFileOperations(input);

      const phpLoader = createBucketLoader("php", "i18n/[locale].php", {
        defaultLocale: "en",
      });
      phpLoader.setDefaultLocale("en");
      const data = await phpLoader.pull("en");

      expect(data).toEqual(expectedOutput);
    });

    it("should save php array", async () => {
      setupFileMocks();

      const input = `<?php 
// this is locale

return array(
  'button.title' => 'Submit',
  'button.description' => ['Hello', 'Goodbye'],
  'button.index' => 1,
  'button.class' => null,
);`;
      const expectedOutput = `<?php 
// this is locale

return array(
  'button.title' => 'Enviar',
  'button.description' => array(
    'Hola',
    'Adiós'
  ),
  'button.index' => 1,
  'button.class' => null
);`;

      mockFileOperations(input);

      const phpLoader = createBucketLoader("php", "i18n/[locale].php", {
        defaultLocale: "en",
      });
      phpLoader.setDefaultLocale("en");
      await phpLoader.pull("en");

      await phpLoader.push("es", {
        "button.title": "Enviar",
        "button.description/0": "Hola",
        "button.description/1": "Adiós",
      });

      expect(fs.writeFile).toHaveBeenCalledWith("i18n/es.php", expectedOutput, {
        encoding: "utf-8",
        flag: "w",
      });
    });

    it("should respect locked keys (pull)", async () => {
      setupFileMocks();

      const input = `<?php\n\nreturn [\n  'locked' => 'Original',\n  'hello' => 'Hello'\n];`;

      mockFileOperations(input);

      const phpLoader = createBucketLoader(
        "php",
        "i18n/[locale].php",
        {
          defaultLocale: "en",
        },
        ["locked"],
      );
      phpLoader.setDefaultLocale("en");
      const data = await phpLoader.pull("en");

      expect(data).toEqual({ hello: "Hello" });
    });
  });

  describe("po bucket loader", () => {
    it("should load po file", async () => {
      setupFileMocks();

      const input = `msgid "Hello"\nmsgstr "Hello"`;
      const expectedOutput = { "Hello/singular": "Hello" };

      mockFileOperations(input);

      const poLoader = createBucketLoader("po", "i18n/[locale].po", {
        defaultLocale: "en",
      });
      poLoader.setDefaultLocale("en");
      const data = await poLoader.pull("en");

      expect(data).toEqual(expectedOutput);
    });

    it("should save po file", async () => {
      setupFileMocks();

      const input = `msgid "Hello"\nmsgstr "Hello"`;
      const expectedOutput = `msgid "Hello"\nmsgstr "Hola"`;

      mockFileOperations(input);

      const poLoader = createBucketLoader("po", "i18n/[locale].po", {
        defaultLocale: "en",
      });
      poLoader.setDefaultLocale("en");
      await poLoader.pull("en");

      await poLoader.push("es", {
        "Hello/singular": "Hola",
      });

      expect(fs.writeFile).toHaveBeenCalledWith("i18n/es.po", expectedOutput, {
        encoding: "utf-8",
        flag: "w",
      });
    });

    it("should extract and restore variables", async () => {
      setupFileMocks();

      const input = `msgid "You have %(count)d items"\nmsgstr "You have %(count)d items"\n\n#~ msgid "I am obsolete"\n#~ msgstr "I am obsolete"`;

      const expectedPullOutput = {
        "You%20have%20%25(count)d%20items/singular":
          "You have {variable:0} items",
      };

      mockFileOperations(input);

      const poLoader = createBucketLoader("po", "i18n/[locale].po", {
        defaultLocale: "en",
      });
      poLoader.setDefaultLocale("en");

      const data = await poLoader.pull("en");

      expect(data).toEqual(expectedPullOutput);

      const payload = {
        "You%20have%20%25(count)d%20items/singular":
          "Sie haben {variable:0} Elemente",
      };

      await poLoader.push("de", payload);

      expect(fs.writeFile).toHaveBeenCalledWith(
        "i18n/de.po",
        `msgid "You have %(count)d items"\nmsgstr "Sie haben %(count)d Elemente"`,
        { encoding: "utf-8", flag: "w" },
      );
    });

    it("should respect locked keys (pull)", async () => {
      setupFileMocks();
      const input = `# Comment\n\nmsgid "greeting"\nmsgstr "Hello"\n\nmsgid "farewell"\nmsgstr "Bye"`;
      const payload = input; // same for mocking

      mockFileOperations(payload);

      const poLoader = createBucketLoader(
        "po",
        "i18n/[locale].po",
        {
          defaultLocale: "en",
        },
        ["greeting/singular"],
      );
      poLoader.setDefaultLocale("en");
      const data = await poLoader.pull("en");

      // Only farewell remains (po loader returns structured values, flattened to keys)
      expect(Object.keys(data)).toContain("farewell/singular");
      expect(Object.keys(data)).not.toContain("greeting/singular");
    });
  });

  describe("vue-json bucket loader", () => {
    const template = `<template>
  <div id="app">
    <label for="locale">locale</label>
    <select v-model="locale">
      <option>en</option>
      <option>ja</option>
    </select>
    <p>message: {{ $t('hello') }}</p>
  </div>
</template>`;
    const script = `<script>
export default {
  name: 'app',
  data () {
    this.$i18n.locale = 'en';
    return { locale: 'en' }
  },
  watch: {
    locale (val) {
      this.$i18n.locale = val
    }
  }
}
</script>`;

    it("should load vue-json file", async () => {
      setupFileMocks();

      const input = `${template}

<i18n>
{
  "en": {
    "hello": "hello world!"
  }
}
</i18n>

${script}`;
      const expectedOutput = { hello: "hello world!" };

      mockFileOperations(input);

      const vueLoader = createBucketLoader("vue-json", "i18n/[locale].vue", {
        defaultLocale: "en",
      });
      vueLoader.setDefaultLocale("en");
      const data = await vueLoader.pull("en");

      expect(data).toEqual(expectedOutput);
    });

    it("should save vue-json file", async () => {
      setupFileMocks();

      const input = `${template}

<i18n>
{
  "en": {
    "hello": "hello world!"
  }
}
</i18n>

${script}`;
      const expectedOutput = `${template}

<i18n>
{
  "en": {
    "hello": "hello world!"
  },
  "es": {
    "hello": "hola mundo!"
  }
}
</i18n>

${script}`;

      mockFileOperations(input);

      const vueLoader = createBucketLoader("vue-json", "i18n/App.vue", {
        defaultLocale: "en",
      });
      vueLoader.setDefaultLocale("en");
      await vueLoader.pull("en");

      await vueLoader.push("es", {
        hello: "hola mundo!",
      });

      expect(fs.writeFile).toHaveBeenCalledWith(
        "i18n/App.vue",
        expectedOutput,
        { encoding: "utf-8", flag: "w" },
      );
    });

    it("should ignore vue file without i18n tag", async () => {
      setupFileMocks();

      const input = `${template}

${script}`;
      const expectedOutput = `${template}

${script}`;

      mockFileOperations(input);

      const vueLoader = createBucketLoader("vue-json", "i18n/App.vue", {
        defaultLocale: "en",
      });
      vueLoader.setDefaultLocale("en");
      await vueLoader.pull("en");

      await vueLoader.push("es", {
        hello: "hola mundo!",
      });

      expect(fs.writeFile).toHaveBeenCalledWith(
        "i18n/App.vue",
        expectedOutput,
        { encoding: "utf-8", flag: "w" },
      );
    });

    it("should respect locked keys (pull)", async () => {
      setupFileMocks();

      const input = `${template}

<i18n>
{
  "en": {
    "locked": "Original",
    "hello": "Hello!"
  }
}
</i18n>

${script}`;

      mockFileOperations(input);

      const vueLoader = createBucketLoader(
        "vue-json",
        "i18n/[locale].vue",
        {
          defaultLocale: "en",
        },
        ["locked"],
      );
      vueLoader.setDefaultLocale("en");
      const data = await vueLoader.pull("en");

      expect(data).toEqual({ hello: "Hello!" });
    });
  });
  describe("ejs bucket loader", () => {
    it("should load ejs data", async () => {
      setupFileMocks();

      const input = `<!DOCTYPE html>
<html>
<head>
  <title>Welcome Page</title>
</head>
<body>
  <h1>Hello <%= user.name %>!</h1>
  <% if (user.isLoggedIn) { %>
    <p>Welcome back to our application.</p>
    <p>You have <%= notifications.length %> new notifications.</p>
  <% } else { %>
    <p>Please log in to continue.</p>
  <% } %>
  <ul>
    <% items.forEach(function(item, index) { %>
      <li>Item <%= index + 1 %>: <%= item.title %></li>
    <% }); %>
  </ul>
  <footer>© 2024 My Company. All rights reserved.</footer>
</body>
</html>`;

      const expectedOutput = {
        text_0: "Welcome Page",
        text_1: "Hello",
        text_2: "!",
        text_3: "Welcome back to our application.",
        text_4: "You have",
        text_5: "new notifications.",
        text_6: "Please log in to continue.",
        text_7: "Item",
        text_8: ":",
        text_9: "© 2024 My Company. All rights reserved.",
      };

      mockFileOperations(input);

      const ejsLoader = createBucketLoader("ejs", "templates/[locale].ejs", {
        defaultLocale: "en",
      });
      ejsLoader.setDefaultLocale("en");
      const data = await ejsLoader.pull("en");

      expect(data).toEqual(expectedOutput);
    });

    it("should save ejs data", async () => {
      setupFileMocks();

      const input = `<!DOCTYPE html>
<html>
<head>
  <title>Welcome Page</title>
</head>
<body>
  <h1>Hello <%= user.name %>!</h1>
  <p>Welcome to our application.</p>
  <footer>© 2024 My Company. All rights reserved.</footer>
</body>
</html>`;

      const payload = {
        text_0: "Página de Bienvenida",
        text_1: "Hola",
        text_2: "!",
        text_3: "Bienvenido a nuestra aplicación.",
        text_4: "© 2024 Mi Empresa. Todos los derechos reservados.",
      };

      const expectedOutput = `<!DOCTYPE html>
<html>
<head>
  <title>Página de Bienvenida</title>
</head>
<body>
  <h1>Hola <%= user.name %>!</h1>
  <p>Bienvenido a nuestra aplicación.</p>
  <footer>© 2024 Mi Empresa. Todos los derechos reservados.</footer>
</body>
</html>`;

      mockFileOperations(input);

      const ejsLoader = createBucketLoader("ejs", "templates/[locale].ejs", {
        defaultLocale: "en",
      });
      ejsLoader.setDefaultLocale("en");
      await ejsLoader.pull("en");

      await ejsLoader.push("es", payload);

      expect(fs.writeFile).toHaveBeenCalledWith(
        "templates/es.ejs",
        expectedOutput,
        { encoding: "utf-8", flag: "w" },
      );
    });

    it("should respect locked keys (pull)", async () => {
      setupFileMocks();

      const input = `<!DOCTYPE html>
<html>
<head>
  <title>Welcome Page</title>
</head>
<body>
  <h1>Hello <%= user.name %>!</h1>
  <p>Welcome to our application.</p>
</body>
</html>`;

      mockFileOperations(input);

      const ejsLoader = createBucketLoader(
        "ejs",
        "templates/[locale].ejs",
        {
          defaultLocale: "en",
        },
        ["text_0"],
      );
      ejsLoader.setDefaultLocale("en");
      const data = await ejsLoader.pull("en");

      // text_0 (title) is locked; remaining translatables present
      expect(Object.keys(data)).not.toContain("text_0");
      expect(Object.keys(data)).toContain("text_1");
    });
  });

  describe("txt bucket loader", () => {
    it("should load txt", async () => {
      setupFileMocks();

      const input = `Welcome to our application!
This is a sample text file for fastlane metadata.
It contains app description that needs to be translated.`;

      const expectedOutput = {
        "1": "Welcome to our application!",
        "2": "This is a sample text file for fastlane metadata.",
        "3": "It contains app description that needs to be translated.",
      };

      mockFileOperations(input);

      const txtLoader = createBucketLoader(
        "txt",
        "fastlane/metadata/[locale]/description.txt",
        {
          defaultLocale: "en",
        },
      );
      txtLoader.setDefaultLocale("en");
      const data = await txtLoader.pull("en");

      expect(data).toEqual(expectedOutput);
    });

    it("should save txt", async () => {
      setupFileMocks();

      const input = `Welcome to our application!
This is a sample text file for fastlane metadata.
It contains app description that needs to be translated.`;

      const payload = {
        "1": "¡Bienvenido a nuestra aplicación!",
        "2": "Este es un archivo de texto de muestra para metadatos de fastlane.",
        "3": "Contiene la descripción de la aplicación que necesita ser traducida.",
      };

      const expectedOutput = `¡Bienvenido a nuestra aplicación!
Este es un archivo de texto de muestra para metadatos de fastlane.
Contiene la descripción de la aplicación que necesita ser traducida.`;

      mockFileOperations(input);

      const txtLoader = createBucketLoader(
        "txt",
        "fastlane/metadata/[locale]/description.txt",
        {
          defaultLocale: "en",
        },
      );
      txtLoader.setDefaultLocale("en");
      await txtLoader.pull("en");

      await txtLoader.push("es", payload);

      expect(fs.writeFile).toHaveBeenCalledWith(
        "fastlane/metadata/es/description.txt",
        expectedOutput,
        { encoding: "utf-8", flag: "w" },
      );
    });

    it("should handle empty txt files", async () => {
      setupFileMocks();

      const input = "";
      const expectedOutput = {};

      mockFileOperations(input);

      const txtLoader = createBucketLoader(
        "txt",
        "fastlane/metadata/[locale]/description.txt",
        {
          defaultLocale: "en",
        },
      );
      txtLoader.setDefaultLocale("en");
      const data = await txtLoader.pull("en");

      expect(data).toEqual(expectedOutput);
    });

    it("should filter out empty lines during pull", async () => {
      setupFileMocks();

      const input = `Line 1

Line 3`;
      const expectedOutput = {
        "1": "Line 1",
        "3": "Line 3",
      };

      mockFileOperations(input);

      const txtLoader = createBucketLoader(
        "txt",
        "fastlane/metadata/[locale]/description.txt",
        {
          defaultLocale: "en",
        },
      );
      txtLoader.setDefaultLocale("en");
      const data = await txtLoader.pull("en");

      expect(data).toEqual(expectedOutput);
    });

    it("should reconstruct file with empty lines restored", async () => {
      setupFileMocks();

      const input = `Line 1

Line 3`;

      const payload = {
        "1": "Línea 1",
        "3": "Línea 3",
      };

      const expectedOutput = `Línea 1

Línea 3`;

      mockFileOperations(input);

      const txtLoader = createBucketLoader(
        "txt",
        "fastlane/metadata/[locale]/description.txt",
        {
          defaultLocale: "en",
        },
      );
      txtLoader.setDefaultLocale("en");
      await txtLoader.pull("en");

      await txtLoader.push("es", payload);

      expect(fs.writeFile).toHaveBeenCalledWith(
        "fastlane/metadata/es/description.txt",
        expectedOutput,
        { encoding: "utf-8", flag: "w" },
      );
    });

    it("should respect locked keys (pull)", async () => {
      setupFileMocks();

      const input = `Secret\nHello`;
      mockFileOperations(input);

      const txtLoader = createBucketLoader(
        "txt",
        "fastlane/metadata/[locale]/description.txt",
        { defaultLocale: "en" },
        ["1"],
      );
      txtLoader.setDefaultLocale("en");
      const data = await txtLoader.pull("en");

      expect(data).toEqual({ 2: "Hello" } as any);
    });
  });

  describe("json-dictionary bucket loader", () => {
    it("should add target locale keys only where source locale keys exist", async () => {
      setupFileMocks();
      const input = {
        title: { en: "I am a title" },
        logoPosition: "right",
        pages: [
          {
            name: "Welcome to my world",
            elements: [
              {
                title: { en: "I am an element title" },
                description: { en: "I am an element description" },
              },
            ],
          },
        ],
      };
      mockFileOperations(JSON.stringify(input));
      const loader = createBucketLoader(
        "json-dictionary",
        "i18n/[locale].json",
        {
          defaultLocale: "en",
        },
      );
      loader.setDefaultLocale("en");
      await loader.pull("en");
      await loader.push("es", {
        title: "Yo soy un titulo",
        "pages/0/elements/0/title": "Yo soy un elemento de titulo",
        "pages/0/elements/0/description": "Yo soy una descripcion de elemento",
      });
      const expectedOutput = `{
  "title": {
    "en": "I am a title",
    "es": "Yo soy un titulo"
  },
  "logoPosition": "right",
  "pages": [
    {
      "name": "Welcome to my world",
      "elements": [
        {
          "title": {
            "en": "I am an element title",
            "es": "Yo soy un elemento de titulo"
          },
          "description": {
            "en": "I am an element description",
            "es": "Yo soy una descripcion de elemento"
          }
        }
      ]
    }
  ]
}`;
      expect(fs.writeFile).toHaveBeenCalledWith(
        "i18n/es.json",
        expectedOutput,
        { encoding: "utf-8", flag: "w" },
      );
    });

    it("should respect locked keys (pull)", async () => {
      setupFileMocks();
      const input = {
        title: { en: "I am a title" },
        subtitle: { en: "Sub" },
      };
      mockFileOperations(JSON.stringify(input));
      const loader = createBucketLoader(
        "json-dictionary",
        "i18n/[locale].json",
        { defaultLocale: "en" },
        ["title"],
      );
      loader.setDefaultLocale("en");
      const data = await loader.pull("en");
      expect(data).toEqual({ subtitle: "Sub" });
    });
  });

  describe("yaml-root-key bucket loader", () => {
    it("should respect locked keys (pull)", async () => {
      setupFileMocks();
      const input = `en:\n  locked: Original\n  hello: Hello!`;
      mockFileOperations(input);
      const loader = createBucketLoader(
        "yaml-root-key",
        "i18n/[locale].yml",
        { defaultLocale: "en" },
        ["locked"],
      );
      loader.setDefaultLocale("en");
      const data = await loader.pull("en");
      expect(data).toEqual({ hello: "Hello!" });
    });
  });

  describe("xcode-xcstrings-v2 bucket loader", () => {
    it("should respect locked keys (pull)", async () => {
      setupFileMocks();
      const input = JSON.stringify({
        sourceLanguage: "en",
        strings: {
          locked: {
            extractionState: "manual",
            localizations: {
              en: { stringUnit: { state: "translated", value: "Original" } },
            },
          },
          hello: {
            extractionState: "manual",
            localizations: {
              en: { stringUnit: { state: "translated", value: "Hello" } },
            },
          },
        },
      });
      mockFileOperations(input);

      const loader = createBucketLoader(
        "xcode-xcstrings-v2",
        "i18n/[locale].xcstrings",
        { defaultLocale: "en" },
        ["locked"],
      );
      loader.setDefaultLocale("en");
      const data = await loader.pull("en");
      expect(data).toEqual({ hello: "Hello" });
    });
  });

  describe("typescript bucket loader", () => {
    it("should respect locked keys (pull)", async () => {
      setupFileMocks();
      const input = `export default { locked: "Original", hello: "Hello" };`;
      mockFileOperations(input);
      const loader = createBucketLoader(
        "typescript",
        "i18n/[locale].ts",
        { defaultLocale: "en" },
        ["locked"],
      );
      loader.setDefaultLocale("en");
      const data = await loader.pull("en");
      expect(data).toEqual({ hello: "Hello" });
    });
  });
});

function setupFileMocks() {
  vi.mock("fs/promises", () => ({
    default: {
      readFile: vi.fn(),
      writeFile: vi.fn(),
      mkdir: vi.fn(),
      access: vi.fn(),
    },
  }));

  vi.mock("path", () => ({
    default: {
      resolve: vi.fn((path) => path),
      dirname: vi.fn((path) => path.split("/").slice(0, -1).join("/")),
    },
  }));
}

function mockFileOperations(input: string) {
  (fs.access as any).mockImplementation(() => Promise.resolve());
  (fs.readFile as any).mockImplementation(() => Promise.resolve(input));
  (fs.writeFile as any).mockImplementation(() => Promise.resolve());
}

function mockFileOperationsForPaths(input: Record<string, string>) {
  (fs.access as any).mockImplementation((path) =>
    input.hasOwnProperty(path)
      ? Promise.resolve()
      : Promise.reject(`fs.access: ${path} not mocked`),
  );
  (fs.readFile as any).mockImplementation((path) =>
    input.hasOwnProperty(path)
      ? Promise.resolve(input[path])
      : Promise.reject(`fs.readFile: ${path} not mocked`),
  );
  (fs.writeFile as any).mockImplementation((path) =>
    input.hasOwnProperty(path)
      ? Promise.resolve()
      : Promise.reject(`fs:writeFile: ${path} not mocked`),
  );
}

```
Page 15/15FirstPrevNextLast