{"id":31952357,"url":"https://github.com/bryce-marshall/firebase-bridge","last_synced_at":"2026-01-20T17:03:04.909Z","repository":{"id":317150882,"uuid":"1061569306","full_name":"bryce-marshall/firebase-bridge","owner":"bryce-marshall","description":"High-fidelity Firestore Admin SDK mock and trigger binder for in-memory testing","archived":false,"fork":false,"pushed_at":"2025-11-28T01:08:32.000Z","size":1640,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-11-30T13:42:40.746Z","etag":null,"topics":["firebase","firebase-admin","firestore","firestore-emulator","firestore-functions","jest","mock","testing","vitest"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bryce-marshall.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-22T05:18:20.000Z","updated_at":"2025-11-28T01:06:25.000Z","dependencies_parsed_at":null,"dependency_job_id":"998d101e-8409-4773-b3aa-9cb82b1546ff","html_url":"https://github.com/bryce-marshall/firebase-bridge","commit_stats":null,"previous_names":["bryce-marshall/firebase-bridge"],"tags_count":24,"template":false,"template_full_name":null,"purl":"pkg:github/bryce-marshall/firebase-bridge","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bryce-marshall%2Ffirebase-bridge","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bryce-marshall%2Ffirebase-bridge/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bryce-marshall%2Ffirebase-bridge/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bryce-marshall%2Ffirebase-bridge/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bryce-marshall","download_url":"https://codeload.github.com/bryce-marshall/firebase-bridge/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bryce-marshall%2Ffirebase-bridge/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28607624,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-20T16:10:39.856Z","status":"ssl_error","status_checked_at":"2026-01-20T16:10:39.493Z","response_time":117,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["firebase","firebase-admin","firestore","firestore-emulator","firestore-functions","jest","mock","testing","vitest"],"created_at":"2025-10-14T13:13:42.542Z","updated_at":"2026-01-20T17:03:04.903Z","avatar_url":"https://github.com/bryce-marshall.png","language":"TypeScript","readme":"# Firebase‑Bridge Workspace\n\n[![license: Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](#license) ![node \u003e=18](https://img.shields.io/badge/node-%E2%89%A518-brightgreen.svg) ![TypeScript](https://img.shields.io/badge/TypeScript-5.x-blue.svg)\n\nDeveloper‑focused overview of the **Firebase‑Bridge** monorepo. This workspace provides an **in‑memory Firestore Admin SDK mock** and **Cloud Functions trigger binding** utilities to enable fast, deterministic testing of backend code, plus a shared test‑suite to verify parity against the Firebase Emulator.\n\n---\n\n## Support\n\nThis project is made freely available under the [Apache 2.0 License](#license).  \nIf you find it useful and would like to support ongoing development, you can [buy me a coffee](https://buymeacoffee.com/brycemarshall). ☕\n\n---\n\n## Intent\n\n- **Move fast**: iterate on triggers and backend logic without the emulator boot/deploy loop.\n- **High fidelity**: mirror Firestore Admin SDK semantics (writes, transforms, queries, listeners, vector values, etc.).\n- **Trust but verify**: run the same suites against the **mock** and the **emulator** to catch divergences early.\n\n---\n\n## Output npm packages \u0026 licensing\n\n| Package                                  | Project (this repo)            | Purpose                                                                        | License        |\n| ---------------------------------------- | ------------------------------ | ------------------------------------------------------------------------------ | -------------- |\n| **@firebase-bridge/firestore-admin**     | `packages/firestore-admin`     | High‑fidelity **in‑memory Firestore Admin SDK** mock for unit tests            | **Apache‑2.0** |\n| **@firebase-bridge/firestore-functions** | `packages/firestore-functions` | Binds **`firebase-functions` v1 \u0026 v2** Firestore triggers to the in‑memory DB  | **Apache‑2.0** |\n| **@firebase-bridge/auth-context**        | `packages/auth-context`        | High-fidelity **mock invocation layer** for **Firebase HTTPS Cloud Functions** | **Apache‑2.0** |\n\n\u003e Licensing: The workspace uses **Apache‑2.0**. Some files adapt Google code (e.g., `googleapis/nodejs-firestore`); those files carry upstream headers and a modification notice. See each package’s `LICENSE` and (where applicable) `NOTICE`.\n\n---\n\n## Projects (at repo root)\n\n- **`packages/firestore-admin`** — implementation of `@firebase-bridge/firestore-admin` (the in‑memory Firestore Admin SDK mock). Tests run **in‑process** (no emulator).\n- **`packages/firestore-functions`** — implementation of `@firebase-bridge/firestore-functions` (trigger binding for `firebase-functions` v1/v2). Tests run **in‑process** (no emulator). Binding is **explicit** in tests.\n- **`packages/auth-context`** — implementation of `@firebase-bridge/auth-context` (mock invocation layer for Firebase HTTPS Cloud Functions (v1 \u0026 v2) integrating a lightweight in-memory mock of the firebase-admin/auth API). Tests run **in‑process** (no emulator). Binding is **explicit** in tests.\n- **`firestore-bridge-test-suites`** — shared, black‑box test suites that exercise Firestore behavior via public APIs. Consumed by both the mock and emulator runners.\n- **`firestore-bridge-production`** — test runner that targets the **Firebase Emulator** and forwards to `firestore-bridge-test-suites` to validate parity.\n- **`smoke/smoke-consumer`** — a tiny app that consumes the locally built packages, verifying installability, published shape, and dual CJS/ESM execution.\n\n\u003e **Workspaces:** The root `package.json` declares workspaces:\n\u003e\n\u003e - `packages/*`\n\u003e - `firestore-bridge-production`\n\u003e - `firestore-bridge-test-suites`\n\u003e - `smoke/*`\n\n### Repository structure\n\n```txt\n.\n├─ packages/\n│  ├─ firestore-admin/             # @firebase-bridge/firestore-admin (in-memory Admin SDK)\n│  │  ├─ src/\n│  │  ├─ jest.config.ts\n│  │  └─ package.json\n│  ├─ firestore-functions/         # @firebase-bridge/firestore-functions (v1/v2 trigger binding)\n│  │  ├─ src/\n│  │  ├─ jest.config.ts\n│  │  └─ package.json\n│  └─ auth-context/                 # @firebase-bridge/auth-context (v1/v2 cloud function invocation)\n│     ├─ src/\n│     ├─ jest.config.ts\n│     └─ package.json\n├─ firestore-bridge-production/    # emulator-backed test runner\n│  ├─ src/\n│  ├─ jest.config.ts\n│  └─ package.json\n├─ firestore-bridge-test-suites/   # shared suites used by both runners\n│  ├─ src/\n│  ├─ jest.config.ts\n│  └─ package.json\n├─ smoke/\n│  └─ smoke-consumer/              # consumer app for smoke-testing built packages\n│     ├─ src/\n│     ├─ dist/\n│     └─ package.json\n├─ .scripts/\n│  └─ start-emulators.js\n├─ nx.json\n├─ package.json                    # workspaces root (private)\n├─ tsconfig.base.json\n└─ README.md\n```\n\n---\n\n## Prerequisites\n\n- **Node.js ≥ 18** (repo uses `@types/node@18.16.9`)\n- Local install of **Nx** (invoked via `npx nx`) and **Jest** via devDependencies\n- Firebase Emulator (only needed for `firestore-bridge-production` tests)\n\nInstall dependencies at the repo root:\n\n```bash\nnpm i\n```\n\n---\n\n## Root workspace metadata\n\nFrom `package.json` (root):\n\n- **Name:** `@firebase-bridge/source` (**private**)\n- **License (root):** **Apache‑2.0**\n- **Scripts:**\n\n  - `npm test` → `jest --detectOpenHandles`\n  - `npm run firebase-emulators:start` → runs `./.scripts/start-emulators.js`\n\n- **Dependencies (runtime):**\n\n  - `firebase-admin@^13.4.0`\n  - `firebase-functions@^6.4.0`\n  - `google-gax@\u003e=5 \u003c6`\n\n- **Dev dependencies (tooling excerpt):**\n\n  - `nx@21.2.3`, `typescript@~5.8.2`, `jest@^29.7.0`\n  - ESLint 9 + `typescript-eslint@^8.40.0`, Prettier 2\n  - Both **@swc/jest** and **ts-jest** are available; use per-project Jest config\n\n---\n\n## Build \u0026 project info (Nx + TypeScript)\n\nUse TypeScript project references or Nx to build/inspect:\n\n```bash\n# TypeScript build (shared test suites)\nnpx tsc -b firestore-bridge-test-suites\n\n# Nx builds (per project)\nnpx nx run firestore-admin:build\nnpx nx run firestore-functions:build\n\n# Show Nx project info\nnpx nx show project firestore-admin\n```\n\n---\n\n## Testing\n\n### In‑process (mock) tests\n\nFor **`firestore-admin`** and **`firestore-functions`** the unit tests run entirely **in process** — no emulator, no special init.\n\n```bash\n# Run tests per project\nnpx jest firestore-admin\nnpx jest firestore-functions\n```\n\n### Emulator tests\n\nFor **`firestore-bridge-production`**, start the emulator first, then run tests:\n\n```bash\nnpm run firebase-emulators:start\nnpx jest firestore-bridge-production\n```\n\n\u003e The production runner imports the same `firestore-bridge-test-suites` to verify behavioral consistency with the mock.\n\n### Run all tests\n\n```bash\nnpm run firebase-emulators:start\nnpx jest\n```\n\n---\n\n## Trigger binding (tests)\n\nIn production, Cloud Functions are wired at deploy time. In tests, **binding is explicit** so you decide which triggers to exercise.\n\n```ts\nimport { FirestoreMock } from '@firebase-bridge/firestore-admin';\nimport * as v1 from 'firebase-functions/v1';\nimport * as v2 from 'firebase-functions/v2';\nimport * as bridgeV1 from '@firebase-bridge/firestore-functions/v1';\nimport * as bridgeV2 from '@firebase-bridge/firestore-functions/v2';\n\nconst onUserCreateV1 = v1.firestore\n  .document('users/{uid}')\n  .onCreate(async (snap, ctx) =\u003e {\n    /* ... */\n  });\n\nconst onUserWrittenV2 = v2.firestore.onDocumentWritten(\n  'users/{uid}',\n  async (event) =\u003e {\n    /* ... */\n  }\n);\n\nconst env = new FirestoreMock();\nconst ctl = env.createDatabase('proj', '(default)');\nconst db = ctl.firestore();\n\nbridgeV1.registerTrigger(ctl, onUserCreateV1);\nbridgeV2.registerTrigger(ctl, onUserWrittenV2);\n\nawait db.collection('users').doc('u1').set({ name: 'Ada' });\n```\n\n---\n\n## Deterministic time in tests\n\nThe mock exposes a controllable clock (`SystemTime`) to make **commit/write/update times** deterministic. Internal timestamps and `FieldValue.serverTimestamp()` respect this clock.\n\n- If your code calls `Timestamp.now()`, note that it uses the **real clock** by default. You can align global time with your test runner’s fake timers or patch `Timestamp.now()` in a scoped way.\n\n---\n\n## Known limits (mock layer)\n\n- **Partitioned queries** (`CollectionGroup.getPartitions()` / `Query.getPartitions()` → GAPIC `partitionQuery`) are currently **stubbed** and return an **empty stream**.\n\n---\n\n## Publishing\n\nFollow this checklist when publishing any Firebase‑Bridge package.\n\n### 1. Prepare package metadata\n\nEach package must define:\n\n- `name`, `version`, and `license: \"Apache‑2.0\"`\n- `files` whitelist (e.g., `cjs/`, `esm/`, `LICENSE`, `NOTICE`, `README.md`, `package.json`)\n- `publishConfig.access: \"public\"`\n- Correct `exports` and `types` entries for both ESM and CJS\n- `sideEffects: false` unless the module performs work on import\n\nInclude **LICENSE** in every package. Add a **NOTICE** file where Google‑derived code exists.\n\n### 2. Build artifacts\n\nRun the Nx build targets or package scripts to generate both ESM and CJS outputs:\n\n```bash\nnpx nx run firestore-admin:build\nnpx nx run firestore-functions:build\nnpx nx run auth-context:build\n```\n\n### 3. Sanity check before publishing\n\nRefer to `smoke/smoke-consumer/README.md` for pre‑publish validation steps. This confirms installability, import behavior, and type resolution in both CJS and ESM environments.\n\n### 4. Verify publish output\n\nFrom each package directory:\n\n```bash\nnpm publish --dry-run\n```\n\nConfirm the tarball contents include only built files, licenses, and docs (no TypeScript sources).\n\n### 5. Authenticate with npm\n\nLogin once via:\n\n```bash\nnpm login\n```\n\nEnsure your account has publish rights under the `@firebase-bridge` scope.\n\n### 6. Publish\n\nFrom each package root:\n\n```bash\nnpm publish --access public\n```\n\nUse `--tag next` for prereleases if desired.\n\n### 7. Tag the release in Git\n\nTag each package individually:\n\n```bash\ngit tag -a firestore-admin-v0.0.1 -m \"firestore-admin v0.0.1\"\ngit tag -a firestore-functions-v0.0.1 -m \"firestore-functions v0.0.1\"\ngit tag -a auth-context-v0.0.1 -m \"auth-context v0.0.1\"\ngit push --tags\n```\n\n### 8. Post‑publish\n\n- Confirm packages appear on npm and can be installed directly.\n- Update GitHub releases and changelog as needed.\n\n---\n\n## Contributing\n\n- Keep behavior parity with the Admin SDK and the Emulator as a priority.\n- Add/extend test cases in `firestore-bridge-test-suites` and run against both runners.\n- If behavior diverges, prefer matching the **real** Firestore semantics.\n\n---\n\n## License\n\n**Apache‑2.0** © 2025 Bryce Marshall — applies to the entire workspace and all published packages.\n\n- Each package ships a `LICENSE` (Apache‑2.0).\n- Packages containing adapted Google files also ship a `NOTICE` and preserve upstream headers with a modification notice.\n","funding_links":["https://buymeacoffee.com/brycemarshall"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbryce-marshall%2Ffirebase-bridge","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbryce-marshall%2Ffirebase-bridge","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbryce-marshall%2Ffirebase-bridge/lists"}