# @smithers-orchestrator/electric-proxy — src

The auth/scope/rate-limit/observability proxy that fronts an ElectricSQL shape
API (`/v1/shape`) for Smithers cloud and self-hosted deployments. Everything
re-exported from `index.js` is public npm surface, and the package's `./*`
export map makes every file here a public deep-import path — do not rename
files. Runtime modules are JSDoc-typed `.js`; type-only declarations live in
`.ts` files with non-colliding basenames; `index.d.ts` is generated by
`pnpm build` (`tsup --dts-only`) and committed.

How the pieces fit:

- `createSmithersElectricProxy.js` — the core fetch handler: duplicate-param
  guard → authenticate → shape lookup in the catalog → gateway-scope check →
  where-clause micro-parser validated against granted run/workspace/user ids →
  open + active rate limits with TTL slot reclaim → frame-bounded upstream
  forwarding. Also serves `/healthz` and `/metrics`. Its public types
  (`SmithersElectricProxyOptions`, `SmithersElectricAuthContext`, …) live in
  `SmithersElectricProxyOptions.ts`.
- `smithersElectricShapeCatalog.js` — the explicit shape allowlist: base
  `_smithers_*` tables plus an opt-in output-table allowlist, never a regex
  catch-all. Shape entry type in `SmithersElectricShapeDefinition.ts`.
- `createSmithersElectricProxyMetrics.js` — the Prometheus counters/gauges
  rendered at `/metrics`. Types in `SmithersElectricProxyMetrics.ts`.
- `createSmithersElectricProxyObserver.js` — zero-dependency telemetry seam:
  per-proxy observer plus the `__smithersElectricTelemetry` global sink; never
  throws on the hot path. Types in `SmithersElectricProxyObserver.ts`.
- `serveSmithersElectricProxy.js` — wraps the fetch handler in a real Node HTTP
  server (used by `bin/smithers-electric-proxy.js`). Types in
  `ServeSmithersElectricProxyOptions.ts`.

Key entry points: `createSmithersElectricProxy(options).fetch(request)` and
`serveSmithersElectricProxy({ proxy })`.

Gotchas: the proxy FAILS CLOSED — a scoped principal with no concrete grant
arrays is rejected unless `auth.unscoped` is explicitly set (single-user
local-cloud only). The where parser rejects OR/UNION/SELECT/NOT, comments, and
backslash escapes by design. Output tables are reachable only via the explicit
`outputTables` allowlist.
