[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-prisma-prisma-composer":3,"mdc--gggi1j-key":33,"related-org-prisma-prisma-composer":9099,"related-repo-prisma-prisma-composer":9274},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":11,"stars":23,"repoUrl":24,"updatedAt":25,"license":26,"forks":27,"topics":28,"repo":29,"sourceUrl":31,"mdContent":32},"prisma-composer","build applications with Prisma Composer","How to write, test, and deploy an app with Prisma Composer (`@prisma\u002Fcomposer`): declare services with `compute()` and typed dependencies, define RPC contracts, compose Modules, declare the service input (config and secrets as one schema, read back with `input()`), compose the ready-made cron\u002Fstorage\u002Fstreams Modules, provision a raw S3-compatible object-store bucket with `bucket()`, find extensions (npm packages named `prisma-composer-*`), test with `mockService`\u002F`bootstrapService`, run the whole app locally with `prisma-composer dev` and tail its logs with `prisma-composer log`, and deploy with `prisma-composer deploy` (stages, destroy). Use when building a Prisma App, wiring a service dependency, adding a Postgres database, adding scheduled jobs \u002F blob storage \u002F event streams \u002F a raw bucket, writing tests for composed services, running an app locally, reading its logs, or deploying\u002Ftearing down an environment. Triggers on \"prisma composer\", \"@prisma\u002Fcomposer\", \"prisma app\", \"compute()\", \"service.load()\", \"module()\", \"contract()\", \"mockService\", \"bootstrapService\", \"prisma-composer dev\", \"prisma-composer log\", \"prisma-composer deploy\", \"--stage\", \"--fresh\", \"--tail\", \"prisma-composer destroy\", \"prisma-composer-\", \"bucket()\".",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},"prisma","Prisma","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Fprisma.png",[12,16,19,20],{"name":13,"slug":14,"type":15},"Architecture","architecture","tag",{"name":17,"slug":18,"type":15},"Engineering","engineering",{"name":9,"slug":8,"type":15},{"name":21,"slug":22,"type":15},"API Development","api-development",3,"https:\u002F\u002Fgithub.com\u002Fprisma\u002Fcomposer","2026-07-27T06:07:21.695273",null,0,[],{"repoUrl":24,"stars":23,"forks":27,"topics":30,"description":26},[],"https:\u002F\u002Fgithub.com\u002Fprisma\u002Fcomposer\u002Ftree\u002FHEAD\u002Fskills\u002Fprisma-composer","---\nname: prisma-composer\ndescription: >-\n  How to write, test, and deploy an app with Prisma Composer\n  (`@prisma\u002Fcomposer`): declare services with `compute()` and typed\n  dependencies, define RPC contracts, compose Modules, declare the service\n  input (config and secrets as one schema, read back with `input()`),\n  compose the ready-made cron\u002Fstorage\u002Fstreams Modules, provision a\n  raw S3-compatible object-store bucket with `bucket()`, find extensions (npm\n  packages named `prisma-composer-*`), test with `mockService`\u002F`bootstrapService`,\n  run the whole app locally with `prisma-composer dev` and tail its logs with\n  `prisma-composer log`, and deploy with `prisma-composer deploy` (stages,\n  destroy). Use when building a Prisma App, wiring a service dependency, adding\n  a Postgres database, adding scheduled jobs \u002F blob storage \u002F event streams \u002F a\n  raw bucket, writing tests for composed services, running an app locally,\n  reading its logs, or deploying\u002Ftearing down an environment. Triggers on\n  \"prisma composer\", \"@prisma\u002Fcomposer\", \"prisma app\", \"compute()\",\n  \"service.load()\", \"module()\", \"contract()\", \"mockService\",\n  \"bootstrapService\", \"prisma-composer dev\", \"prisma-composer log\",\n  \"prisma-composer deploy\", \"--stage\", \"--fresh\", \"--tail\",\n  \"prisma-composer destroy\", \"prisma-composer-\", \"bucket()\".\n---\n\n# Writing apps with Prisma Composer\n\nA **Prisma App** is a tree of **Modules** composed in TypeScript. The leaves\nare **services** (`compute()`) and **resources** (`postgres()`); the root\nmodule wires them together by their typed ports. Your code receives everything\nfrom exactly one place — the service node:\n\n- `service.load()` — dependencies (typed RPC clients, database bindings)\n- `service.input()` — the service's whole input, one schema-validated typed\n  object; credentials in it are redacting `SecretString` boxes\n- `service.port()` — the reserved port to bind (default 3000), typed; never\n  `process.env`\n\nThe framework never bundles or transforms your code. You build your app with\nwhatever bundler you like (`bun build`, `next build`); `prisma-composer deploy`\nassembles the built output and provisions it on Prisma Cloud (Compute + Prisma\nPostgres).\n\nTwo things make building here fast and hard to get wrong — lean on both:\n\n- **Compose before you write.** Reach for an existing Module (below) before\n  implementing a capability yourself; wiring one in is a couple of lines.\n- **The compiler checks the wiring.** A dependency wired to the wrong\n  producer, a missing RPC handler, a config value of the wrong shape — all of\n  it fails `tsc`, not the deploy. Typecheck, then build, then deploy; don't\n  reach for the cloud to find out whether the app is correct.\n\nTwo packages, and only two, appear in your `package.json`:\n\n| Package | Provides |\n| --- | --- |\n| `@prisma\u002Fcomposer` | Core authoring: `module`, `secret`, `isSecretString`, `\u002Farktype` (the `secretString()` schema leaf), `\u002Frpc`, `\u002Fnode`, `\u002Fnextjs`, `\u002Fconfig`, `\u002Ftesting`, the `prisma-composer` CLI |\n| `@prisma\u002Fcomposer-prisma-cloud` | The Prisma Cloud target: `compute`, `postgres`, `envSecret`, `envParam`, `\u002Fcontrol`, `\u002Ftesting`, and the shared `\u002Fcron`, `\u002Fstorage`, `\u002Fstreams`, `\u002Fprisma-next` modules |\n\n## Anatomy of a service\n\nA service is four small files. Worked example: an `auth` service that owns a\nPostgres database and serves an RPC contract, consumed by a `storefront`\nNext.js app.\n\n**The contract** lives with the service that owns it. Any Standard Schema\nvalidator types the messages; arktype is the house choice:\n\n```ts\n\u002F\u002F auth\u002Fsrc\u002Fcontract.ts\nimport { contract, rpc } from '@prisma\u002Fcomposer\u002Fservice-rpc';\nimport { type } from 'arktype';\n\nexport const authContract = contract({\n  verify: rpc({ input: type({ token: 'string' }), output: type({ ok: 'boolean' }) }),\n});\n```\n\n**The service declaration** is pure data — name, dependencies, build, exposed\nports. No behavior, no platform keys:\n\n```ts\n\u002F\u002F auth\u002Fsrc\u002Fservice.ts\nimport node from '@prisma\u002Fcomposer\u002Fnode';\nimport { compute, postgres } from '@prisma\u002Fcomposer-prisma-cloud';\nimport { authContract } from '.\u002Fcontract.ts';\n\nexport default compute({\n  name: 'auth',\n  deps: { db: postgres() },\n  build: node({ module: import.meta.url, entry: '..\u002Fdist\u002Fserver.mjs' }),\n  expose: { rpc: authContract },\n});\n```\n\n**The server entry** is what your build produces and the platform boots. It\nreads its dependencies through `load()` and serves the contract with\n`serve()` — the handler map is keyed by the expose port's name and is\nexhaustive at compile time:\n\n```ts\n\u002F\u002F auth\u002Fsrc\u002Fserver.ts\nimport { serve } from '@prisma\u002Fcomposer\u002Fservice-rpc';\nimport { SQL } from 'bun';\nimport service from '.\u002Fservice.ts';\n\nconst { db } = service.load(); \u002F\u002F { url } — you build your own client\nconst port = service.port();   \u002F\u002F the reserved port, resolved (default 3000)\n\nconst sql = new SQL({ url: db.url, max: 1, idleTimeout: 10 });\n\nconst handler = serve(service, {\n  rpc: {\n    verify: async ({ token }) => ({ ok: token.length > 0 }),\n  },\n});\nexport default handler;\n\n\u002F\u002F Bind all interfaces — Compute routes external HTTP to the VM; a\n\u002F\u002F loopback-only listener is unreachable.\nBun.serve({ port, hostname: '0.0.0.0', fetch: handler });\n```\n\n**The consumer** declares the dependency as `rpc(contract)` and gets a typed\nclient back from `load()`:\n\n```ts\n\u002F\u002F storefront\u002Fsrc\u002Fservice.ts\nimport nextjs from '@prisma\u002Fcomposer\u002Fnextjs';\nimport { rpc } from '@prisma\u002Fcomposer\u002Fservice-rpc';\nimport { compute } from '@prisma\u002Fcomposer-prisma-cloud';\nimport { authContract } from '@my-app\u002Fauth\u002Fcontract';\n\nexport default compute({\n  name: 'storefront',\n  deps: { auth: rpc(authContract) },\n  build: nextjs({ module: import.meta.url, appDir: '..' }),\n});\n```\n\n```tsx\n\u002F\u002F storefront\u002Fapp\u002Fpage.tsx\nimport service from '..\u002Fsrc\u002Fservice.ts';\n\n\u002F\u002F load() reads the runtime environment, which doesn't exist at build time —\n\u002F\u002F render per request instead of prerendering.\nexport const dynamic = 'force-dynamic';\n\nexport default async function Home() {\n  const { auth } = service.load();\n  const { ok } = await auth.verify({ token: 'demo-token' });\n  return \u003Cp>Signed in: {String(ok)}\u003C\u002Fp>;\n}\n```\n\n**Service-to-service calls are authenticated for you.** At deploy the\nframework mints a distinct, unguessable **service key** per consumer→provider\nbinding: the consumer's client sends it on every call, and `serve()` returns\n`401` to anything else *before* the handler runs. Nothing declares it — no key\nin the contract, the service, the module, or the app's code.\n\nTwo rules follow for you specifically: **don't build your own\nservice-to-service auth** on top of this, and **don't tell a user to `curl` a\ndeployed `\u002Frpc\u002F\u003Cmethod>` to check it works** — an unwired caller always gets\n`401`, which looks like a broken deploy and isn't. Debug through a consumer,\nor locally.\n\n**Calls carry an idempotency key and retry safely for you.** Every call the\ngenerated client makes carries an `Idempotency-Key`; a call dropped while the\ntarget cold-starts is retried with a backoff, and `serve()` runs one call per\nkey — a retry that arrives after the first completed replays that answer\ninstead of re-running the handler. So every method is safely retryable and no\ncontract declares anything about it (do not add an \"is this idempotent\" flag —\nthe framework does not have one). Two consequences for you: a handler may take\nan **optional third argument** `(input, deps, ctx)` and read `ctx.idempotencyKey`\n(`string | undefined` — it's absent for a keyless caller) if it needs exactly-once\nbeyond one instance's memory (most don't); and a request without the header is\nserved once without deduplication rather than rejected, so a hand-rolled probe\nworks but gets no retry safety.\n\n| | |\n| --- | --- |\n| Locally \u002F in tests | nothing is provisioned, so `serve()` passes every call through — never supply a key in `inputs` |\n| Per binding | two consumers of one provider hold different keys, so one leaking can't impersonate the other |\n| Scope | service-level — any valid key reaches every method that service exposes; split into two services to gate separately |\n| Rotation | remove the binding (or destroy the stack) and redeploy — a plain redeploy is a no-op, not a rotation |\n| Storage | `COMPOSER_*` variables the deploy owns and rewrites; never hand-edit one |\n\nIt's a capability token (\"I'm a service this app wired to you\"), not a secret,\nand its value lives in deploy state — deliberately unlike `secret()`, whose\nvalue the framework never holds. `docs\u002Fdesign\u002F90-decisions\u002FADR-0030…` in the\nprisma\u002Fcomposer repo carries the reasoning.\n\n## The root module\n\nThe root module provisions the pieces and wires exposed ports into dependency\nslots. It is the app — `prisma-composer deploy` loads its default export:\n\n```ts\n\u002F\u002F module.ts\nimport { module } from '@prisma\u002Fcomposer';\nimport authModule from '@my-app\u002Fauth';\nimport storefrontService from '@my-app\u002Fstorefront';\n\nexport default module('my-app', ({ provision }) => {\n  const auth = provision(authModule);\n  provision(storefrontService, { deps: { auth: auth.rpc } });\n});\n```\n\n`provision(node, opts?)` accepts `id` (defaults to the node's own name),\n`deps` (wire each declared dependency to a provisioned ref or exposed port),\n`input` (the service's input binding — required exactly when it declares an\ninput schema, see § Service input), and `secrets` (bind a module boundary's\nforwarded secret needs).\n\n## Builds are yours\n\nThe framework assembles only what you built — users build, the framework\nassembles. For a plain server process, `entry` must point at a single\nself-contained ESM file: everything inlined except runtime built-ins (`bun`,\n`bun:*`, `node:*`), which the deploy VM provides. Deploy copies that one file\nand never ships `node_modules`, so anything left un-inlined fails at boot. Any\nbundler that produces such a file works. With bun:\n\n```sh\nbun build src\u002Fserver.ts --target=bun --outfile dist\u002Fserver.mjs\n```\n\nTwo services in one package means two separate builds, one per entry — not one\nmulti-entry build, which would split shared code into a chunk neither output\ncontains.\n\nIf the build emits a directory rather than one file — a server plus the client\nbundle, CSS and images it serves, as Bun's HTML import produces — name the\ndirectory with `dir` and the booting file inside it with `entry`:\n\n```ts\nbuild: node({ module: import.meta.url, dir: '..\u002Fdist\u002Fserver', entry: 'server.js' })\n```\n\n`dir` resolves relative to the service module; `entry` resolves inside `dir`\nand may be nested. Deploy copies the tree verbatim and boots the named file,\nso the server must resolve its siblings against `import.meta.url`, not the\nworking directory. Nothing is inferred, and two rules bite: the tree must\ncontain no symlinks (the packager rejects them — assembly fails and names the\nlink), and `entry` must be a file inside `dir` (`..\u002F` is an error, not an\nescape). Omit `dir` for the single-file form.\n\nFor Next.js, `next build` with `output: 'standalone'` is the whole build;\n`nextjs({ module, appDir })` tells the deploy where the app root is.\n\nAlways build before deploying — `prisma-composer deploy` does not build for\nyou.\n\n## Deploy config\n\n`prisma-composer.config.ts` sits next to `module.ts`. It is read only by\n`prisma-composer deploy`\u002F`destroy`, never imported by app code:\n\n```ts\n\u002F\u002F prisma-composer.config.ts\nimport { defineConfig } from '@prisma\u002Fcomposer\u002Fconfig';\nimport { nodeBuild } from '@prisma\u002Fcomposer\u002Fnode\u002Fcontrol';\nimport { prismaCloud, prismaState } from '@prisma\u002Fcomposer-prisma-cloud\u002Fcontrol';\n\nexport default defineConfig({\n  extensions: [prismaCloud(), nodeBuild()],\n  state: () => prismaState(), \u002F\u002F deploy state, in its own database on the stage's branch\n});\n```\n\nAdd `nextjsBuild()` from `@prisma\u002Fcomposer\u002Fnextjs\u002Fcontrol` to `extensions`\nwhen the app contains a Next.js service.\n\n## Databases\n\nTwo kinds of Postgres dependency:\n\n**`postgres()`** — the binding is `{ url }` and the app owns its client.\nConstruct it in your server entry, as in the auth example above.\n\n**`pnPostgres(...)`** — a Prisma Next-typed database: `load()`\nreturns the typed client the framework constructs from your data contract, so\nqueries like `db.orm.public.Product.all()` are compile-time checked. The\ncontract is emitted from `contract.prisma` by `prisma-next contract emit` and\nwrapped once, referenced by both ends:\n\n```ts\n\u002F\u002F src\u002Fdata.ts — the ONE value both ends reference\nimport { pnContract } from '@prisma\u002Fcomposer-prisma-cloud\u002Fprisma-next';\nimport type { Contract } from '..\u002Fcontract.d.ts';\nimport contractJson from '..\u002Fcontract.json' with { type: 'json' };\n\nexport const catalogData = pnContract\u003CContract>(contractJson);\n```\n\nThe dependency end is `deps: { db: pnPostgres(catalogData) }`. The resource\nend (inside the module that owns the database) also names the\n`prisma-next.config.ts` path, which the deploy's migration step loads to find\n`migrations\u002F` — migrations are applied at deploy, before the service starts:\n\n```ts\nconst db = provision(\n  pnPostgres({ name: 'database', contract: catalogData, config: '.\u002Fprisma-next.config.ts' }),\n);\n```\n\n(`pnPostgres` is both ends: the contract alone is the dependency end; the\noptions object is the resource end.)\n\nSee `examples\u002Fstore\u002Fmodules\u002Fcatalog` in the prisma\u002Fcomposer repo for the\ncomplete pattern.\n\n## Object Storage\n\n`bucket` is a raw S3-compatible object-store bucket, imported alongside `postgres`:\n\n```ts\nimport { bucket, compute } from '@prisma\u002Fcomposer-prisma-cloud';\n\n\u002F\u002F service.ts — dependency end: receives { url, bucket, accessKeyId, secretAccessKey }\nexport default compute({ name: 'uploads', deps: { store: bucket() } });\n\n\u002F\u002F module.ts — resource end: provisions the bucket and mints a keypair\nconst store = provision(bucket({ name: 'uploads' }));\nprovision(uploadsService, { deps: { store } });\n```\n\nUse any S3-compatible client with the binding: the shape matches the standard S3\nconfig and is also compatible with the `s3()` dependency from `\u002Fstorage`, so any\nservice wired to `s3()` can be rewired to a `bucket` resource without changing\nthe service declaration.\n\n## Reusable Modules\n\nA Module is the unit of reuse: it owns its internals (its database, its\nservices) and exposes only typed ports. Declare the boundary in the second\nargument; wire internals in the builder; return the exposed ports:\n\n```ts\n\u002F\u002F auth\u002Fsrc\u002Fmodule.ts — a Module that owns its own Postgres\nimport { module, secret } from '@prisma\u002Fcomposer';\nimport { postgres } from '@prisma\u002Fcomposer-prisma-cloud';\nimport { authContract } from '.\u002Fcontract.ts';\nimport authService from '.\u002Fservice.ts';\n\nexport default module(\n  'auth',\n  { secrets: { signingKey: secret() }, expose: { rpc: authContract } },\n  ({ secrets, provision }) => {\n    const db = provision(postgres({ name: 'database' }));\n    const service = provision(authService, {\n      id: 'service',\n      deps: { db },\n      input: { signingKey: secrets.signingKey }, \u002F\u002F forwarded ref as a binding leaf\n    });\n    return { rpc: service.rpc };\n  },\n);\n```\n\nNaming rules that bite: a provision id shorter than 3 characters is rejected\nby the platform (name the database `'database'`, not `'db'`), and a service\nwhose name equals its enclosing module's reads as `auth.auth` unless you give\nit an explicit `id`.\n\nA module can also declare boundary `deps` — inputs the parent wires exactly as\nit would wire a service's. The consumer never sees the module's internals.\n\n### The building blocks you can compose\n\nModules are the building blocks: provision one, wire its exposed port, and\nyou're done — you never reimplement what a Module already owns. The\nfirst-party set ships inside `@prisma\u002Fcomposer-prisma-cloud`. It's small, and\ngrowing:\n\n| Import | What it provisions | Exposes |\n| --- | --- | --- |\n| `cron` from `\u002Fcron` | An always-on scheduler firing your schedule at your runner service | nothing |\n| `storage` from `\u002Fstorage` | An S3-backed blob store (own Postgres + minted credentials) | `store` |\n| `streams` from `\u002Fstreams` | Durable append-only event streams over a `store` | `streams` |\n\n**Finding more.** A Composer extension — a package that brings its own\nModules, resources, or deploy target — is published on npm under the name\n`prisma-composer-*`. That name is the convention, so it's how you look for\none. The ecosystem is new: today the blocks above plus the app Modules you\nwrite are the whole set, so don't reach for a `prisma-composer-*` package\nwithout checking that it actually exists on npm first.\n\nCron end to end — the schedule is one source of truth; `serveSchedule` is\nexhaustive over its job ids at compile time:\n\n```ts\n\u002F\u002F service.ts\nimport { defineSchedule, triggerContract } from '@prisma\u002Fcomposer-prisma-cloud\u002Fcron';\nexport const schedule = defineSchedule({ tick: '60s' });\n\u002F\u002F the runner service exposes { trigger: triggerContract }\n\n\u002F\u002F server.ts\nimport { serveSchedule } from '@prisma\u002Fcomposer-prisma-cloud\u002Fcron';\nconst handler = serveSchedule(service, schedule, {\n  tick: (deps) => deps.worker.tick({}),\n});\n\n\u002F\u002F module.ts — the cron module's boundary deps mirror the runner's own\nprovision(cron({ schedule, runner: runnerService }), { deps: { worker: worker.rpc } });\n```\n\n## Service input\n\nChoosing the channel is most of the decision:\n\n| The value is… | Declare | Provide | Read |\n| --- | --- | --- | --- |\n| produced by another node | `deps: { db: postgres() }` | wire at `provision()` | `load()` |\n| anything else — config or credential | one field of the `input` schema | bind at `provision()`: literal, `envParam()`, or `envSecret()` | `input()` |\n\nThe service declares its whole incoming configuration — plain values and\ncredentials together — as **one\n[Standard Schema](https:\u002F\u002Fstandardschema.dev)** (arktype is the house\nchoice). A credential is a field typed as the redacting `SecretString` box;\nconditional legality (\"no stripe key unless billing is on\") is an ordinary\nschema union:\n\n```ts\n\u002F\u002F service.ts — the shapes that are legal\nimport { secretString } from '@prisma\u002Fcomposer\u002Farktype';\nimport { type } from 'arktype';\n\ncompute({\n  name: 'scheduler',\n  input: type({\n    jobs: type({ jobId: 'string', every: 'string' }).array(),\n    'region?': 'string',\n    apiKey: secretString(),\n  }),\n  \u002F\u002F ...\n});\n\n\u002F\u002F module.ts — where each value comes from; the binding mirrors the schema's shape\nimport { envParam, envSecret } from '@prisma\u002Fcomposer-prisma-cloud';\nprovision(scheduler, {\n  input: {\n    jobs: [{ jobId: 'tick', every: '60s' }],   \u002F\u002F a literal\n    region: envParam('REGION'),                 \u002F\u002F a per-stage platform variable\n    apiKey: envSecret('SCHEDULER_API_KEY'),     \u002F\u002F a credential — name only, never the value\n  },\n});\n\n\u002F\u002F server.ts — one call, one validated typed object\nconst input = service.input();\ninput.apiKey.expose(); \u002F\u002F the only way to a secret's value; the box redacts everywhere else\n```\n\nRules that bite:\n\n- **Secretness is enforced by validation**: a literal bound where the schema\n  expects `SecretString` fails the deploy, and `envSecret` bound to a plain\n  string field fails the same way. Don't put credentials in plain fields.\n- **`envParam` values arrive as raw strings** — bind them to string fields.\n  The stage's platform variable is the store; the deploying shell only seeds\n  it (preflight copies a missing name up from the shell, and fails early,\n  naming the variable, when both lack it). Changing the platform value needs\n  a redeploy.\n- **Absence is the schema's call**: an env-bound field whose variable is\n  unset (or empty) resolves to *key omitted* — legal only if the schema says\n  so (optional field, union arm). The deploy report prints the serialized\n  input document (secret-free: secrets ride as `{\"$secret\":\"VAR\"}` pointers)\n  and every key that resolved absent.\n- **The reserved `port` (default 3000) is outside the schema** — read it\n  through `service.port()` (a sibling of `service.origin()`), never\n  `process.env`. The framework also exports `PORT` for Next.js standalone,\n  which binds it itself.\n- A module forwards a secret need without learning the platform name\n  (the auth Module above); the forwarded ref is a binding leaf.\n\n`examples\u002Fenv-param` and `examples\u002Fstorefront-auth` in the prisma\u002Fcomposer\nrepo are the working versions.\n\n## Testing\n\nYou test by deciding what `load()` gives the code, never by editing the code\nunder test:\n\n| You want to… | Use | From |\n| --- | --- | --- |\n| Test a page \u002F action \u002F handler in isolation | `mockService` | `@prisma\u002Fcomposer\u002Ftesting` |\n| Run the real boot + request path against a fake dependency | `bootstrapService` | `@prisma\u002Fcomposer-prisma-cloud\u002Ftesting` |\n\n**Unit — `mockService`.** Returns a copy of the service whose `load()` yields\nyour doubles (type-checked against the declared deps) and whose `input()`\nyields the object you pass under the reserved `input` key, in one flat\nobject (required exactly when the service declares an input schema; handed\nover as-is, not validated). Wiring the module substitution is your runner's\njob (`vi.mock` in Vitest, `mock.module` in bun test):\n\n```tsx\n\u002F\u002F page.test.tsx\nimport { mockService } from '@prisma\u002Fcomposer\u002Ftesting';\nimport realService from '..\u002Fsrc\u002Fservice.ts';\n\nvi.mock('..\u002Fsrc\u002Fservice.ts', () => ({\n  default: mockService(realService, {\n    auth: { verify: async () => ({ ok: true }) }, \u002F\u002F wrong shape = compile error\n  }),\n}));\n\nimport Page from '.\u002Fpage.tsx';\nexpect(renderToString(await Page())).toContain('Signed in: true');\n```\n\n**Integration — `bootstrapService`.** Boots the service's real built entry\nin-process against a config you choose, exactly as a deployed boot would;\ndrive it over real HTTP. Run under `bun test`:\n\n```ts\nimport { bootstrapService } from '@prisma\u002Fcomposer-prisma-cloud\u002Ftesting';\nimport fakeAuth from '@my-app\u002Fauth\u002Ffake'; \u002F\u002F in-memory handler, no db\nimport storefront from '..\u002Fsrc\u002Fservice.ts';\n\nconst fake = Bun.serve({ port: 0, fetch: fakeAuth });\n\nconst app = await bootstrapService(storefront, {\n  service: { port: 4310 },\n  inputs: { auth: { url: fake.url.href } },\n});\n\nconst res = await app.fetch(new Request(app.url));\n```\n\n- **`service.port` must be concrete** — the entry self-listens; no OS-assigned\n  port is reported back.\n- **No `close()`** — run each integration-test file in its own process (bun\n  test does).\n- **Next.js services take a third argument**, a boot thunk, because the built\n  entry lives in Next's standalone output — resolve it with\n  `standaloneServerPath` from `@prisma\u002Fcomposer\u002Fnextjs\u002Fcontrol`.\n  `bootstrapService` exports the resolved port as `process.env.PORT` before\n  booting, which is what Next's standalone server binds.\n- **A service with an input schema takes `input`** in the config — a binding\n  exactly like `provision()`'s, run through the real serialize\u002Fread path, so\n  `input()` in the booted entry sees what a deploy would produce.\n\n**The fake you pass.** A dependency's type is its contract, so any value of\nthat shape is a valid double: a bare object (fastest), the real client over an\nin-memory handler, or a real local server (what `bootstrapService` drives).\nShip a dependency's fake from its own package as a `\u002Ffake` entry point,\noutside `src\u002F`, so the fake and the real service always share one contract.\n\n## Running locally\n\n`prisma-composer dev module.ts` runs the whole app on this machine — every\nservice, its Postgres and buckets, wired as they deploy — with **no cloud\ncredentials** (no `PRISMA_*`). It runs the same pipeline as deploy against\nlocal emulators, so build first, exactly like deploy:\n\n```sh\nturbo run build && prisma-composer dev module.ts\n```\n\nIt prints each service's local URL (the \"front door\"), watches built output\nand restarts a service when its build changes, and runs until Ctrl-C. Ctrl-C\nstops the app's processes but leaves the local databases, buckets, and their\ndata up, so the next `dev` is a warm start; `--fresh` wipes this app's local\ninstances and data first.\n\n`dev` does **not** print service logs — that would bury the front door once\nseveral services run. Logs are their own command:\n\n| You want to… | Run |\n| --- | --- |\n| Run the app locally | `prisma-composer dev module.ts` |\n| Start clean (wipe local data) | `prisma-composer dev module.ts --fresh` |\n| Tail every service's logs | `prisma-composer log module.ts` |\n| Tail one service | `prisma-composer log module.ts \u003Caddress>` |\n| Show more history first | `prisma-composer log module.ts --tail \u003Cn>` |\n\n`prisma-composer log` follows the merged logs of the already-running app, each\nline prefixed with its service (`[catalog.service] …`); pass a dotted address\nto narrow to one. It only reads — it never builds, provisions, starts, or\nstops anything. `--tail \u003Cn>` sets how much recent history to show before live\noutput (default 20; `0` for live-only). An unset secret doesn't block a local\nrun: it becomes a placeholder plus a warning, and only the code path that\nspends it fails, at the real external service it calls. Windows isn't\nsupported yet.\n\n## Deploying\n\nRequires exactly two environment variables: `PRISMA_SERVICE_TOKEN` and\n`PRISMA_WORKSPACE_ID`. The target environment — a **stage** — is chosen on the\ncommand line, never in code:\n\n| You want to… | Run |\n| --- | --- |\n| Deploy to production | `prisma-composer deploy module.ts` |\n| Deploy an isolated environment | `prisma-composer deploy module.ts --stage \u003Cname>` |\n| Override the app name for one run | `prisma-composer deploy module.ts --name demo-42` |\n| Tear down an isolated environment | `prisma-composer destroy module.ts --stage \u003Cname>` |\n| Tear down production's resources | `prisma-composer destroy module.ts --production` |\n\nA Prisma App is one Project; a stage is a Branch of it — its\nown compute, its own empty database, its own configuration. Deploys are\nidempotent: re-deploying a stage updates the resources inside it. A stage name\nmust be a valid git ref name; an invalid name is a hard error.\n\nDestroy always requires an explicit target — a bare `prisma-composer destroy`\nis an error, and `--stage` with `--production` is too. Destroying a stage\ndeletes its Branch after removing its resources; the production Branch itself\nis never deleted, only the resources inside it. Destroying production also\ndeletes the Project itself once it's empty, so hand-run stacks don't leave\nbehind empty Projects — but a Project still holding another stage's resources\nis kept. Destroy never creates anything: destroying a never-deployed stage\nfails rather than standing one up.\n\n```sh\nturbo run build && prisma-composer deploy module.ts --stage pr-42\n```\n\n### What a deploy prints\n\nA deploy ends by printing the app's own topology — authored names, the\nplatform resource each became, and public URLs. The tree is the module\nstructure (`auth.api` is the `api` service inside the `auth` module):\n\n```\nstorefront-auth\n├─ auth\n│  └─ api   compute-service cps_abc123\n│           https:\u002F\u002Fxyz.ewr.prisma.build\n├─ db       postgres-database db_def456\n└─ web      compute-service cps_ghi789\n            https:\u002F\u002Fuvw.ewr.prisma.build\n```\n\nRead ids out of this rather than telling the user to go hunting in the\nConsole. A URL appears only where the address is genuinely public — a compute\nservice prints one, a database never does (it has a connection string, not a\npublic endpoint), and a node whose product is secret material (an\n`s3-credentials` keypair) reports no resource line at all. A node that\npublished nothing reportable still appears, marked `(no entities reported)`.\n\nOlder deploys ended with a raw `{ outputs: {} }` blob from the deploy engine —\nalways empty, never about the app. It is gone; nothing configured it and\nnothing consumed it.\n\n### The connection contract is checked at deploy\n\nA connection declares the values it needs by name, and the producer on the\nother end must supply them. A producer that omits one fails the deploy, naming\nthe edge, the param, and what the producer did supply:\n\n```\nConnection input \"auth.db\" declares param \"url\", but its producer \"db\" did not\nsupply it — the producer's outputs carry [host].\n```\n\nFix it at whichever end is wrong: add the name to the outputs the producer\nreturns from its lowering, or mark the param `optional` on the connection if absent is\ngenuinely legal (the consumer then reads `undefined`).\n\nThis is a deploy-time refusal, not a broken deploy — and it can appear on an\napp whose code didn't change. The gap used to pass silently: the value reached\nthe consumer as `undefined`, went into its environment, and crashed *that*\nservice at boot, blaming the reader instead of the supplier. Don't route around\nit by making the param optional unless absent really is valid; that reinstates\nthe silent `undefined`.\n\nOnly reachable if you authored the connection or the extension on one side —\nevery shipped block supplies what it declares.\n\n## Production pitfalls\n\n- **Scale-to-zero closes idle database connections.** A persistent client\n  crashes into a 502 restart loop unless you keep the pool small and\n  reconnect-friendly (`new SQL({ url, max: 1, idleTimeout: 10 })` for Bun) and\n  log `uncaughtException`\u002F`unhandledRejection` instead of dying.\n- **Bind `0.0.0.0`**, not loopback — Compute routes external HTTP to the VM.\n- **Next.js pages that call `load()` need `export const dynamic =\n  'force-dynamic'`** — the runtime environment doesn't exist at build time,\n  and Next ignores runtime env for prerendered routes.\n- **A deployed `\u002Frpc\u002F\u003Cmethod>` returns `401` to anything but a wired peer.**\n  Every RPC binding carries an auto-provisioned service key, so a hand-rolled\n  `curl` is never authorized, and a provider with no wired consumers rejects\n  everything. Not a broken deploy — reach it through a consumer, or run it\n  locally where nothing is enforced.\n- **Cold starts reset service-to-service connections.** A call into a\n  scaled-to-zero service can get `ECONNRESET`; retry it.\n- **The ingress buffers streaming responses.** An open SSE tail delivers\n  nothing and times out at 60s — don't build on streamed HTTP responses.\n\n## What Composer doesn't do yet\n\nName the gap instead of inventing an API:\n\n- **No interactive auth.** Deploys authenticate only via a static\n  `PRISMA_SERVICE_TOKEN`; there is no `login` flow.\n- **No in-memory contract bindings.** A dependency can't yet be wired to a\n  co-located handler without HTTP; use `bootstrapService` with a loopback\n  fake.\n- **RPC over HTTP is the only contract kind.** No gRPC, WebSocket, or\n  streaming contracts.\n\nFor anything else missing, check the examples and design docs in the\nprisma\u002Fcomposer repo (`examples\u002F`, `docs\u002Fdesign\u002F10-domains\u002F`,\n`docs\u002Fdesign\u002F90-decisions\u002F`), then file an issue there rather than guessing.\n",{"data":34,"body":35},{"name":4,"description":6},{"type":36,"children":37},"root",[38,47,98,150,179,184,215,228,441,448,469,479,821,831,1215,1241,1889,1913,2278,2615,2655,2697,2753,2855,2876,2882,2894,3204,3247,3253,3295,3337,3342,3361,3480,3540,3568,3580,3586,3620,3893,3922,3928,3933,3954,3999,4218,4247,4382,4394,4407,4413,4430,4730,4764,4770,4775,5377,5412,5424,5431,5443,5566,5591,5604,6046,6052,6057,6180,6208,6961,6966,7085,7104,7110,7122,7201,7254,7646,7669,8101,8204,8237,8243,8269,8313,8334,8351,8456,8491,8497,8525,8630,8635,8663,8713,8719,8747,8757,8777,8790,8796,8801,8810,8831,8856,8861,8867,9000,9006,9011,9066,9093],{"type":39,"tag":40,"props":41,"children":43},"element","h1",{"id":42},"writing-apps-with-prisma-composer",[44],{"type":45,"value":46},"text","Writing apps with Prisma Composer",{"type":39,"tag":48,"props":49,"children":50},"p",{},[51,53,59,61,66,68,73,75,82,84,89,90,96],{"type":45,"value":52},"A ",{"type":39,"tag":54,"props":55,"children":56},"strong",{},[57],{"type":45,"value":58},"Prisma App",{"type":45,"value":60}," is a tree of ",{"type":39,"tag":54,"props":62,"children":63},{},[64],{"type":45,"value":65},"Modules",{"type":45,"value":67}," composed in TypeScript. The leaves\nare ",{"type":39,"tag":54,"props":69,"children":70},{},[71],{"type":45,"value":72},"services",{"type":45,"value":74}," (",{"type":39,"tag":76,"props":77,"children":79},"code",{"className":78},[],[80],{"type":45,"value":81},"compute()",{"type":45,"value":83},") and ",{"type":39,"tag":54,"props":85,"children":86},{},[87],{"type":45,"value":88},"resources",{"type":45,"value":74},{"type":39,"tag":76,"props":91,"children":93},{"className":92},[],[94],{"type":45,"value":95},"postgres()",{"type":45,"value":97},"); the root\nmodule wires them together by their typed ports. Your code receives everything\nfrom exactly one place — the service node:",{"type":39,"tag":99,"props":100,"children":101},"ul",{},[102,114,133],{"type":39,"tag":103,"props":104,"children":105},"li",{},[106,112],{"type":39,"tag":76,"props":107,"children":109},{"className":108},[],[110],{"type":45,"value":111},"service.load()",{"type":45,"value":113}," — dependencies (typed RPC clients, database bindings)",{"type":39,"tag":103,"props":115,"children":116},{},[117,123,125,131],{"type":39,"tag":76,"props":118,"children":120},{"className":119},[],[121],{"type":45,"value":122},"service.input()",{"type":45,"value":124}," — the service's whole input, one schema-validated typed\nobject; credentials in it are redacting ",{"type":39,"tag":76,"props":126,"children":128},{"className":127},[],[129],{"type":45,"value":130},"SecretString",{"type":45,"value":132}," boxes",{"type":39,"tag":103,"props":134,"children":135},{},[136,142,144],{"type":39,"tag":76,"props":137,"children":139},{"className":138},[],[140],{"type":45,"value":141},"service.port()",{"type":45,"value":143}," — the reserved port to bind (default 3000), typed; never\n",{"type":39,"tag":76,"props":145,"children":147},{"className":146},[],[148],{"type":45,"value":149},"process.env",{"type":39,"tag":48,"props":151,"children":152},{},[153,155,161,163,169,171,177],{"type":45,"value":154},"The framework never bundles or transforms your code. You build your app with\nwhatever bundler you like (",{"type":39,"tag":76,"props":156,"children":158},{"className":157},[],[159],{"type":45,"value":160},"bun build",{"type":45,"value":162},", ",{"type":39,"tag":76,"props":164,"children":166},{"className":165},[],[167],{"type":45,"value":168},"next build",{"type":45,"value":170},"); ",{"type":39,"tag":76,"props":172,"children":174},{"className":173},[],[175],{"type":45,"value":176},"prisma-composer deploy",{"type":45,"value":178},"\nassembles the built output and provisions it on Prisma Cloud (Compute + Prisma\nPostgres).",{"type":39,"tag":48,"props":180,"children":181},{},[182],{"type":45,"value":183},"Two things make building here fast and hard to get wrong — lean on both:",{"type":39,"tag":99,"props":185,"children":186},{},[187,197],{"type":39,"tag":103,"props":188,"children":189},{},[190,195],{"type":39,"tag":54,"props":191,"children":192},{},[193],{"type":45,"value":194},"Compose before you write.",{"type":45,"value":196}," Reach for an existing Module (below) before\nimplementing a capability yourself; wiring one in is a couple of lines.",{"type":39,"tag":103,"props":198,"children":199},{},[200,205,207,213],{"type":39,"tag":54,"props":201,"children":202},{},[203],{"type":45,"value":204},"The compiler checks the wiring.",{"type":45,"value":206}," A dependency wired to the wrong\nproducer, a missing RPC handler, a config value of the wrong shape — all of\nit fails ",{"type":39,"tag":76,"props":208,"children":210},{"className":209},[],[211],{"type":45,"value":212},"tsc",{"type":45,"value":214},", not the deploy. Typecheck, then build, then deploy; don't\nreach for the cloud to find out whether the app is correct.",{"type":39,"tag":48,"props":216,"children":217},{},[218,220,226],{"type":45,"value":219},"Two packages, and only two, appear in your ",{"type":39,"tag":76,"props":221,"children":223},{"className":222},[],[224],{"type":45,"value":225},"package.json",{"type":45,"value":227},":",{"type":39,"tag":229,"props":230,"children":231},"table",{},[232,251],{"type":39,"tag":233,"props":234,"children":235},"thead",{},[236],{"type":39,"tag":237,"props":238,"children":239},"tr",{},[240,246],{"type":39,"tag":241,"props":242,"children":243},"th",{},[244],{"type":45,"value":245},"Package",{"type":39,"tag":241,"props":247,"children":248},{},[249],{"type":45,"value":250},"Provides",{"type":39,"tag":252,"props":253,"children":254},"tbody",{},[255,353],{"type":39,"tag":237,"props":256,"children":257},{},[258,268],{"type":39,"tag":259,"props":260,"children":261},"td",{},[262],{"type":39,"tag":76,"props":263,"children":265},{"className":264},[],[266],{"type":45,"value":267},"@prisma\u002Fcomposer",{"type":39,"tag":259,"props":269,"children":270},{},[271,273,279,280,286,287,293,294,300,302,308,310,316,317,323,324,330,331,337,338,344,346,351],{"type":45,"value":272},"Core authoring: ",{"type":39,"tag":76,"props":274,"children":276},{"className":275},[],[277],{"type":45,"value":278},"module",{"type":45,"value":162},{"type":39,"tag":76,"props":281,"children":283},{"className":282},[],[284],{"type":45,"value":285},"secret",{"type":45,"value":162},{"type":39,"tag":76,"props":288,"children":290},{"className":289},[],[291],{"type":45,"value":292},"isSecretString",{"type":45,"value":162},{"type":39,"tag":76,"props":295,"children":297},{"className":296},[],[298],{"type":45,"value":299},"\u002Farktype",{"type":45,"value":301}," (the ",{"type":39,"tag":76,"props":303,"children":305},{"className":304},[],[306],{"type":45,"value":307},"secretString()",{"type":45,"value":309}," schema leaf), ",{"type":39,"tag":76,"props":311,"children":313},{"className":312},[],[314],{"type":45,"value":315},"\u002Frpc",{"type":45,"value":162},{"type":39,"tag":76,"props":318,"children":320},{"className":319},[],[321],{"type":45,"value":322},"\u002Fnode",{"type":45,"value":162},{"type":39,"tag":76,"props":325,"children":327},{"className":326},[],[328],{"type":45,"value":329},"\u002Fnextjs",{"type":45,"value":162},{"type":39,"tag":76,"props":332,"children":334},{"className":333},[],[335],{"type":45,"value":336},"\u002Fconfig",{"type":45,"value":162},{"type":39,"tag":76,"props":339,"children":341},{"className":340},[],[342],{"type":45,"value":343},"\u002Ftesting",{"type":45,"value":345},", the ",{"type":39,"tag":76,"props":347,"children":349},{"className":348},[],[350],{"type":45,"value":4},{"type":45,"value":352}," CLI",{"type":39,"tag":237,"props":354,"children":355},{},[356,365],{"type":39,"tag":259,"props":357,"children":358},{},[359],{"type":39,"tag":76,"props":360,"children":362},{"className":361},[],[363],{"type":45,"value":364},"@prisma\u002Fcomposer-prisma-cloud",{"type":39,"tag":259,"props":366,"children":367},{},[368,370,376,377,383,384,390,391,397,398,404,405,410,412,418,419,425,426,432,433,439],{"type":45,"value":369},"The Prisma Cloud target: ",{"type":39,"tag":76,"props":371,"children":373},{"className":372},[],[374],{"type":45,"value":375},"compute",{"type":45,"value":162},{"type":39,"tag":76,"props":378,"children":380},{"className":379},[],[381],{"type":45,"value":382},"postgres",{"type":45,"value":162},{"type":39,"tag":76,"props":385,"children":387},{"className":386},[],[388],{"type":45,"value":389},"envSecret",{"type":45,"value":162},{"type":39,"tag":76,"props":392,"children":394},{"className":393},[],[395],{"type":45,"value":396},"envParam",{"type":45,"value":162},{"type":39,"tag":76,"props":399,"children":401},{"className":400},[],[402],{"type":45,"value":403},"\u002Fcontrol",{"type":45,"value":162},{"type":39,"tag":76,"props":406,"children":408},{"className":407},[],[409],{"type":45,"value":343},{"type":45,"value":411},", and the shared ",{"type":39,"tag":76,"props":413,"children":415},{"className":414},[],[416],{"type":45,"value":417},"\u002Fcron",{"type":45,"value":162},{"type":39,"tag":76,"props":420,"children":422},{"className":421},[],[423],{"type":45,"value":424},"\u002Fstorage",{"type":45,"value":162},{"type":39,"tag":76,"props":427,"children":429},{"className":428},[],[430],{"type":45,"value":431},"\u002Fstreams",{"type":45,"value":162},{"type":39,"tag":76,"props":434,"children":436},{"className":435},[],[437],{"type":45,"value":438},"\u002Fprisma-next",{"type":45,"value":440}," modules",{"type":39,"tag":442,"props":443,"children":445},"h2",{"id":444},"anatomy-of-a-service",[446],{"type":45,"value":447},"Anatomy of a service",{"type":39,"tag":48,"props":449,"children":450},{},[451,453,459,461,467],{"type":45,"value":452},"A service is four small files. Worked example: an ",{"type":39,"tag":76,"props":454,"children":456},{"className":455},[],[457],{"type":45,"value":458},"auth",{"type":45,"value":460}," service that owns a\nPostgres database and serves an RPC contract, consumed by a ",{"type":39,"tag":76,"props":462,"children":464},{"className":463},[],[465],{"type":45,"value":466},"storefront",{"type":45,"value":468},"\nNext.js app.",{"type":39,"tag":48,"props":470,"children":471},{},[472,477],{"type":39,"tag":54,"props":473,"children":474},{},[475],{"type":45,"value":476},"The contract",{"type":45,"value":478}," lives with the service that owns it. Any Standard Schema\nvalidator types the messages; arktype is the house choice:",{"type":39,"tag":480,"props":481,"children":486},"pre",{"className":482,"code":483,"language":484,"meta":485,"style":485},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u002F\u002F auth\u002Fsrc\u002Fcontract.ts\nimport { contract, rpc } from '@prisma\u002Fcomposer\u002Fservice-rpc';\nimport { type } from 'arktype';\n\nexport const authContract = contract({\n  verify: rpc({ input: type({ token: 'string' }), output: type({ ok: 'boolean' }) }),\n});\n","ts","",[487],{"type":39,"tag":76,"props":488,"children":489},{"__ignoreMap":485},[490,502,565,606,616,656,805],{"type":39,"tag":491,"props":492,"children":495},"span",{"class":493,"line":494},"line",1,[496],{"type":39,"tag":491,"props":497,"children":499},{"style":498},"--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic",[500],{"type":45,"value":501},"\u002F\u002F auth\u002Fsrc\u002Fcontract.ts\n",{"type":39,"tag":491,"props":503,"children":505},{"class":493,"line":504},2,[506,512,518,524,529,534,539,544,549,555,560],{"type":39,"tag":491,"props":507,"children":509},{"style":508},"--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic",[510],{"type":45,"value":511},"import",{"type":39,"tag":491,"props":513,"children":515},{"style":514},"--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF",[516],{"type":45,"value":517}," {",{"type":39,"tag":491,"props":519,"children":521},{"style":520},"--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8",[522],{"type":45,"value":523}," contract",{"type":39,"tag":491,"props":525,"children":526},{"style":514},[527],{"type":45,"value":528},",",{"type":39,"tag":491,"props":530,"children":531},{"style":520},[532],{"type":45,"value":533}," rpc",{"type":39,"tag":491,"props":535,"children":536},{"style":514},[537],{"type":45,"value":538}," }",{"type":39,"tag":491,"props":540,"children":541},{"style":508},[542],{"type":45,"value":543}," from",{"type":39,"tag":491,"props":545,"children":546},{"style":514},[547],{"type":45,"value":548}," '",{"type":39,"tag":491,"props":550,"children":552},{"style":551},"--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D",[553],{"type":45,"value":554},"@prisma\u002Fcomposer\u002Fservice-rpc",{"type":39,"tag":491,"props":556,"children":557},{"style":514},[558],{"type":45,"value":559},"'",{"type":39,"tag":491,"props":561,"children":562},{"style":514},[563],{"type":45,"value":564},";\n",{"type":39,"tag":491,"props":566,"children":567},{"class":493,"line":23},[568,572,576,581,585,589,593,598,602],{"type":39,"tag":491,"props":569,"children":570},{"style":508},[571],{"type":45,"value":511},{"type":39,"tag":491,"props":573,"children":574},{"style":514},[575],{"type":45,"value":517},{"type":39,"tag":491,"props":577,"children":578},{"style":520},[579],{"type":45,"value":580}," type",{"type":39,"tag":491,"props":582,"children":583},{"style":514},[584],{"type":45,"value":538},{"type":39,"tag":491,"props":586,"children":587},{"style":508},[588],{"type":45,"value":543},{"type":39,"tag":491,"props":590,"children":591},{"style":514},[592],{"type":45,"value":548},{"type":39,"tag":491,"props":594,"children":595},{"style":551},[596],{"type":45,"value":597},"arktype",{"type":39,"tag":491,"props":599,"children":600},{"style":514},[601],{"type":45,"value":559},{"type":39,"tag":491,"props":603,"children":604},{"style":514},[605],{"type":45,"value":564},{"type":39,"tag":491,"props":607,"children":609},{"class":493,"line":608},4,[610],{"type":39,"tag":491,"props":611,"children":613},{"emptyLinePlaceholder":612},true,[614],{"type":45,"value":615},"\n",{"type":39,"tag":491,"props":617,"children":619},{"class":493,"line":618},5,[620,625,631,636,641,646,651],{"type":39,"tag":491,"props":621,"children":622},{"style":508},[623],{"type":45,"value":624},"export",{"type":39,"tag":491,"props":626,"children":628},{"style":627},"--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA",[629],{"type":45,"value":630}," const",{"type":39,"tag":491,"props":632,"children":633},{"style":520},[634],{"type":45,"value":635}," authContract ",{"type":39,"tag":491,"props":637,"children":638},{"style":514},[639],{"type":45,"value":640},"=",{"type":39,"tag":491,"props":642,"children":644},{"style":643},"--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF",[645],{"type":45,"value":523},{"type":39,"tag":491,"props":647,"children":648},{"style":520},[649],{"type":45,"value":650},"(",{"type":39,"tag":491,"props":652,"children":653},{"style":514},[654],{"type":45,"value":655},"{\n",{"type":39,"tag":491,"props":657,"children":659},{"class":493,"line":658},6,[660,666,670,674,678,683,688,692,696,700,704,709,713,717,722,726,730,735,739,744,748,752,756,760,765,769,773,778,782,786,791,796,800],{"type":39,"tag":491,"props":661,"children":663},{"style":662},"--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178",[664],{"type":45,"value":665},"  verify",{"type":39,"tag":491,"props":667,"children":668},{"style":514},[669],{"type":45,"value":227},{"type":39,"tag":491,"props":671,"children":672},{"style":643},[673],{"type":45,"value":533},{"type":39,"tag":491,"props":675,"children":676},{"style":520},[677],{"type":45,"value":650},{"type":39,"tag":491,"props":679,"children":680},{"style":514},[681],{"type":45,"value":682},"{",{"type":39,"tag":491,"props":684,"children":685},{"style":662},[686],{"type":45,"value":687}," input",{"type":39,"tag":491,"props":689,"children":690},{"style":514},[691],{"type":45,"value":227},{"type":39,"tag":491,"props":693,"children":694},{"style":643},[695],{"type":45,"value":580},{"type":39,"tag":491,"props":697,"children":698},{"style":520},[699],{"type":45,"value":650},{"type":39,"tag":491,"props":701,"children":702},{"style":514},[703],{"type":45,"value":682},{"type":39,"tag":491,"props":705,"children":706},{"style":662},[707],{"type":45,"value":708}," token",{"type":39,"tag":491,"props":710,"children":711},{"style":514},[712],{"type":45,"value":227},{"type":39,"tag":491,"props":714,"children":715},{"style":514},[716],{"type":45,"value":548},{"type":39,"tag":491,"props":718,"children":719},{"style":551},[720],{"type":45,"value":721},"string",{"type":39,"tag":491,"props":723,"children":724},{"style":514},[725],{"type":45,"value":559},{"type":39,"tag":491,"props":727,"children":728},{"style":514},[729],{"type":45,"value":538},{"type":39,"tag":491,"props":731,"children":732},{"style":520},[733],{"type":45,"value":734},")",{"type":39,"tag":491,"props":736,"children":737},{"style":514},[738],{"type":45,"value":528},{"type":39,"tag":491,"props":740,"children":741},{"style":662},[742],{"type":45,"value":743}," output",{"type":39,"tag":491,"props":745,"children":746},{"style":514},[747],{"type":45,"value":227},{"type":39,"tag":491,"props":749,"children":750},{"style":643},[751],{"type":45,"value":580},{"type":39,"tag":491,"props":753,"children":754},{"style":520},[755],{"type":45,"value":650},{"type":39,"tag":491,"props":757,"children":758},{"style":514},[759],{"type":45,"value":682},{"type":39,"tag":491,"props":761,"children":762},{"style":662},[763],{"type":45,"value":764}," ok",{"type":39,"tag":491,"props":766,"children":767},{"style":514},[768],{"type":45,"value":227},{"type":39,"tag":491,"props":770,"children":771},{"style":514},[772],{"type":45,"value":548},{"type":39,"tag":491,"props":774,"children":775},{"style":551},[776],{"type":45,"value":777},"boolean",{"type":39,"tag":491,"props":779,"children":780},{"style":514},[781],{"type":45,"value":559},{"type":39,"tag":491,"props":783,"children":784},{"style":514},[785],{"type":45,"value":538},{"type":39,"tag":491,"props":787,"children":788},{"style":520},[789],{"type":45,"value":790},") ",{"type":39,"tag":491,"props":792,"children":793},{"style":514},[794],{"type":45,"value":795},"}",{"type":39,"tag":491,"props":797,"children":798},{"style":520},[799],{"type":45,"value":734},{"type":39,"tag":491,"props":801,"children":802},{"style":514},[803],{"type":45,"value":804},",\n",{"type":39,"tag":491,"props":806,"children":808},{"class":493,"line":807},7,[809,813,817],{"type":39,"tag":491,"props":810,"children":811},{"style":514},[812],{"type":45,"value":795},{"type":39,"tag":491,"props":814,"children":815},{"style":520},[816],{"type":45,"value":734},{"type":39,"tag":491,"props":818,"children":819},{"style":514},[820],{"type":45,"value":564},{"type":39,"tag":48,"props":822,"children":823},{},[824,829],{"type":39,"tag":54,"props":825,"children":826},{},[827],{"type":45,"value":828},"The service declaration",{"type":45,"value":830}," is pure data — name, dependencies, build, exposed\nports. No behavior, no platform keys:",{"type":39,"tag":480,"props":832,"children":834},{"className":482,"code":833,"language":484,"meta":485,"style":485},"\u002F\u002F auth\u002Fsrc\u002Fservice.ts\nimport node from '@prisma\u002Fcomposer\u002Fnode';\nimport { compute, postgres } from '@prisma\u002Fcomposer-prisma-cloud';\nimport { authContract } from '.\u002Fcontract.ts';\n\nexport default compute({\n  name: 'auth',\n  deps: { db: postgres() },\n  build: node({ module: import.meta.url, entry: '..\u002Fdist\u002Fserver.mjs' }),\n  expose: { rpc: authContract },\n});\n",[835],{"type":39,"tag":76,"props":836,"children":837},{"__ignoreMap":485},[838,846,880,929,970,977,1001,1029,1069,1166,1199],{"type":39,"tag":491,"props":839,"children":840},{"class":493,"line":494},[841],{"type":39,"tag":491,"props":842,"children":843},{"style":498},[844],{"type":45,"value":845},"\u002F\u002F auth\u002Fsrc\u002Fservice.ts\n",{"type":39,"tag":491,"props":847,"children":848},{"class":493,"line":504},[849,853,858,863,867,872,876],{"type":39,"tag":491,"props":850,"children":851},{"style":508},[852],{"type":45,"value":511},{"type":39,"tag":491,"props":854,"children":855},{"style":520},[856],{"type":45,"value":857}," node ",{"type":39,"tag":491,"props":859,"children":860},{"style":508},[861],{"type":45,"value":862},"from",{"type":39,"tag":491,"props":864,"children":865},{"style":514},[866],{"type":45,"value":548},{"type":39,"tag":491,"props":868,"children":869},{"style":551},[870],{"type":45,"value":871},"@prisma\u002Fcomposer\u002Fnode",{"type":39,"tag":491,"props":873,"children":874},{"style":514},[875],{"type":45,"value":559},{"type":39,"tag":491,"props":877,"children":878},{"style":514},[879],{"type":45,"value":564},{"type":39,"tag":491,"props":881,"children":882},{"class":493,"line":23},[883,887,891,896,900,905,909,913,917,921,925],{"type":39,"tag":491,"props":884,"children":885},{"style":508},[886],{"type":45,"value":511},{"type":39,"tag":491,"props":888,"children":889},{"style":514},[890],{"type":45,"value":517},{"type":39,"tag":491,"props":892,"children":893},{"style":520},[894],{"type":45,"value":895}," compute",{"type":39,"tag":491,"props":897,"children":898},{"style":514},[899],{"type":45,"value":528},{"type":39,"tag":491,"props":901,"children":902},{"style":520},[903],{"type":45,"value":904}," postgres",{"type":39,"tag":491,"props":906,"children":907},{"style":514},[908],{"type":45,"value":538},{"type":39,"tag":491,"props":910,"children":911},{"style":508},[912],{"type":45,"value":543},{"type":39,"tag":491,"props":914,"children":915},{"style":514},[916],{"type":45,"value":548},{"type":39,"tag":491,"props":918,"children":919},{"style":551},[920],{"type":45,"value":364},{"type":39,"tag":491,"props":922,"children":923},{"style":514},[924],{"type":45,"value":559},{"type":39,"tag":491,"props":926,"children":927},{"style":514},[928],{"type":45,"value":564},{"type":39,"tag":491,"props":930,"children":931},{"class":493,"line":608},[932,936,940,945,949,953,957,962,966],{"type":39,"tag":491,"props":933,"children":934},{"style":508},[935],{"type":45,"value":511},{"type":39,"tag":491,"props":937,"children":938},{"style":514},[939],{"type":45,"value":517},{"type":39,"tag":491,"props":941,"children":942},{"style":520},[943],{"type":45,"value":944}," authContract",{"type":39,"tag":491,"props":946,"children":947},{"style":514},[948],{"type":45,"value":538},{"type":39,"tag":491,"props":950,"children":951},{"style":508},[952],{"type":45,"value":543},{"type":39,"tag":491,"props":954,"children":955},{"style":514},[956],{"type":45,"value":548},{"type":39,"tag":491,"props":958,"children":959},{"style":551},[960],{"type":45,"value":961},".\u002Fcontract.ts",{"type":39,"tag":491,"props":963,"children":964},{"style":514},[965],{"type":45,"value":559},{"type":39,"tag":491,"props":967,"children":968},{"style":514},[969],{"type":45,"value":564},{"type":39,"tag":491,"props":971,"children":972},{"class":493,"line":618},[973],{"type":39,"tag":491,"props":974,"children":975},{"emptyLinePlaceholder":612},[976],{"type":45,"value":615},{"type":39,"tag":491,"props":978,"children":979},{"class":493,"line":658},[980,984,989,993,997],{"type":39,"tag":491,"props":981,"children":982},{"style":508},[983],{"type":45,"value":624},{"type":39,"tag":491,"props":985,"children":986},{"style":508},[987],{"type":45,"value":988}," default",{"type":39,"tag":491,"props":990,"children":991},{"style":643},[992],{"type":45,"value":895},{"type":39,"tag":491,"props":994,"children":995},{"style":520},[996],{"type":45,"value":650},{"type":39,"tag":491,"props":998,"children":999},{"style":514},[1000],{"type":45,"value":655},{"type":39,"tag":491,"props":1002,"children":1003},{"class":493,"line":807},[1004,1009,1013,1017,1021,1025],{"type":39,"tag":491,"props":1005,"children":1006},{"style":662},[1007],{"type":45,"value":1008},"  name",{"type":39,"tag":491,"props":1010,"children":1011},{"style":514},[1012],{"type":45,"value":227},{"type":39,"tag":491,"props":1014,"children":1015},{"style":514},[1016],{"type":45,"value":548},{"type":39,"tag":491,"props":1018,"children":1019},{"style":551},[1020],{"type":45,"value":458},{"type":39,"tag":491,"props":1022,"children":1023},{"style":514},[1024],{"type":45,"value":559},{"type":39,"tag":491,"props":1026,"children":1027},{"style":514},[1028],{"type":45,"value":804},{"type":39,"tag":491,"props":1030,"children":1032},{"class":493,"line":1031},8,[1033,1038,1042,1046,1051,1055,1059,1064],{"type":39,"tag":491,"props":1034,"children":1035},{"style":662},[1036],{"type":45,"value":1037},"  deps",{"type":39,"tag":491,"props":1039,"children":1040},{"style":514},[1041],{"type":45,"value":227},{"type":39,"tag":491,"props":1043,"children":1044},{"style":514},[1045],{"type":45,"value":517},{"type":39,"tag":491,"props":1047,"children":1048},{"style":662},[1049],{"type":45,"value":1050}," db",{"type":39,"tag":491,"props":1052,"children":1053},{"style":514},[1054],{"type":45,"value":227},{"type":39,"tag":491,"props":1056,"children":1057},{"style":643},[1058],{"type":45,"value":904},{"type":39,"tag":491,"props":1060,"children":1061},{"style":520},[1062],{"type":45,"value":1063},"() ",{"type":39,"tag":491,"props":1065,"children":1066},{"style":514},[1067],{"type":45,"value":1068},"},\n",{"type":39,"tag":491,"props":1070,"children":1072},{"class":493,"line":1071},9,[1073,1078,1082,1087,1091,1095,1100,1104,1109,1114,1119,1123,1128,1132,1137,1141,1145,1150,1154,1158,1162],{"type":39,"tag":491,"props":1074,"children":1075},{"style":662},[1076],{"type":45,"value":1077},"  build",{"type":39,"tag":491,"props":1079,"children":1080},{"style":514},[1081],{"type":45,"value":227},{"type":39,"tag":491,"props":1083,"children":1084},{"style":643},[1085],{"type":45,"value":1086}," node",{"type":39,"tag":491,"props":1088,"children":1089},{"style":520},[1090],{"type":45,"value":650},{"type":39,"tag":491,"props":1092,"children":1093},{"style":514},[1094],{"type":45,"value":682},{"type":39,"tag":491,"props":1096,"children":1097},{"style":662},[1098],{"type":45,"value":1099}," module",{"type":39,"tag":491,"props":1101,"children":1102},{"style":514},[1103],{"type":45,"value":227},{"type":39,"tag":491,"props":1105,"children":1106},{"style":508},[1107],{"type":45,"value":1108}," import",{"type":39,"tag":491,"props":1110,"children":1111},{"style":514},[1112],{"type":45,"value":1113},".",{"type":39,"tag":491,"props":1115,"children":1116},{"style":520},[1117],{"type":45,"value":1118},"meta",{"type":39,"tag":491,"props":1120,"children":1121},{"style":514},[1122],{"type":45,"value":1113},{"type":39,"tag":491,"props":1124,"children":1125},{"style":520},[1126],{"type":45,"value":1127},"url",{"type":39,"tag":491,"props":1129,"children":1130},{"style":514},[1131],{"type":45,"value":528},{"type":39,"tag":491,"props":1133,"children":1134},{"style":662},[1135],{"type":45,"value":1136}," entry",{"type":39,"tag":491,"props":1138,"children":1139},{"style":514},[1140],{"type":45,"value":227},{"type":39,"tag":491,"props":1142,"children":1143},{"style":514},[1144],{"type":45,"value":548},{"type":39,"tag":491,"props":1146,"children":1147},{"style":551},[1148],{"type":45,"value":1149},"..\u002Fdist\u002Fserver.mjs",{"type":39,"tag":491,"props":1151,"children":1152},{"style":514},[1153],{"type":45,"value":559},{"type":39,"tag":491,"props":1155,"children":1156},{"style":514},[1157],{"type":45,"value":538},{"type":39,"tag":491,"props":1159,"children":1160},{"style":520},[1161],{"type":45,"value":734},{"type":39,"tag":491,"props":1163,"children":1164},{"style":514},[1165],{"type":45,"value":804},{"type":39,"tag":491,"props":1167,"children":1169},{"class":493,"line":1168},10,[1170,1175,1179,1183,1187,1191,1195],{"type":39,"tag":491,"props":1171,"children":1172},{"style":662},[1173],{"type":45,"value":1174},"  expose",{"type":39,"tag":491,"props":1176,"children":1177},{"style":514},[1178],{"type":45,"value":227},{"type":39,"tag":491,"props":1180,"children":1181},{"style":514},[1182],{"type":45,"value":517},{"type":39,"tag":491,"props":1184,"children":1185},{"style":662},[1186],{"type":45,"value":533},{"type":39,"tag":491,"props":1188,"children":1189},{"style":514},[1190],{"type":45,"value":227},{"type":39,"tag":491,"props":1192,"children":1193},{"style":520},[1194],{"type":45,"value":635},{"type":39,"tag":491,"props":1196,"children":1197},{"style":514},[1198],{"type":45,"value":1068},{"type":39,"tag":491,"props":1200,"children":1202},{"class":493,"line":1201},11,[1203,1207,1211],{"type":39,"tag":491,"props":1204,"children":1205},{"style":514},[1206],{"type":45,"value":795},{"type":39,"tag":491,"props":1208,"children":1209},{"style":520},[1210],{"type":45,"value":734},{"type":39,"tag":491,"props":1212,"children":1213},{"style":514},[1214],{"type":45,"value":564},{"type":39,"tag":48,"props":1216,"children":1217},{},[1218,1223,1225,1231,1233,1239],{"type":39,"tag":54,"props":1219,"children":1220},{},[1221],{"type":45,"value":1222},"The server entry",{"type":45,"value":1224}," is what your build produces and the platform boots. It\nreads its dependencies through ",{"type":39,"tag":76,"props":1226,"children":1228},{"className":1227},[],[1229],{"type":45,"value":1230},"load()",{"type":45,"value":1232}," and serves the contract with\n",{"type":39,"tag":76,"props":1234,"children":1236},{"className":1235},[],[1237],{"type":45,"value":1238},"serve()",{"type":45,"value":1240}," — the handler map is keyed by the expose port's name and is\nexhaustive at compile time:",{"type":39,"tag":480,"props":1242,"children":1244},{"className":482,"code":1243,"language":484,"meta":485,"style":485},"\u002F\u002F auth\u002Fsrc\u002Fserver.ts\nimport { serve } from '@prisma\u002Fcomposer\u002Fservice-rpc';\nimport { SQL } from 'bun';\nimport service from '.\u002Fservice.ts';\n\nconst { db } = service.load(); \u002F\u002F { url } — you build your own client\nconst port = service.port();   \u002F\u002F the reserved port, resolved (default 3000)\n\nconst sql = new SQL({ url: db.url, max: 1, idleTimeout: 10 });\n\nconst handler = serve(service, {\n  rpc: {\n    verify: async ({ token }) => ({ ok: token.length > 0 }),\n  },\n});\nexport default handler;\n\n\u002F\u002F Bind all interfaces — Compute routes external HTTP to the VM; a\n\u002F\u002F loopback-only listener is unreachable.\nBun.serve({ port, hostname: '0.0.0.0', fetch: handler });\n",[1245],{"type":39,"tag":76,"props":1246,"children":1247},{"__ignoreMap":485},[1248,1256,1296,1337,1370,1377,1432,1474,1481,1584,1591,1625,1642,1731,1740,1756,1777,1785,1794,1803],{"type":39,"tag":491,"props":1249,"children":1250},{"class":493,"line":494},[1251],{"type":39,"tag":491,"props":1252,"children":1253},{"style":498},[1254],{"type":45,"value":1255},"\u002F\u002F auth\u002Fsrc\u002Fserver.ts\n",{"type":39,"tag":491,"props":1257,"children":1258},{"class":493,"line":504},[1259,1263,1267,1272,1276,1280,1284,1288,1292],{"type":39,"tag":491,"props":1260,"children":1261},{"style":508},[1262],{"type":45,"value":511},{"type":39,"tag":491,"props":1264,"children":1265},{"style":514},[1266],{"type":45,"value":517},{"type":39,"tag":491,"props":1268,"children":1269},{"style":520},[1270],{"type":45,"value":1271}," serve",{"type":39,"tag":491,"props":1273,"children":1274},{"style":514},[1275],{"type":45,"value":538},{"type":39,"tag":491,"props":1277,"children":1278},{"style":508},[1279],{"type":45,"value":543},{"type":39,"tag":491,"props":1281,"children":1282},{"style":514},[1283],{"type":45,"value":548},{"type":39,"tag":491,"props":1285,"children":1286},{"style":551},[1287],{"type":45,"value":554},{"type":39,"tag":491,"props":1289,"children":1290},{"style":514},[1291],{"type":45,"value":559},{"type":39,"tag":491,"props":1293,"children":1294},{"style":514},[1295],{"type":45,"value":564},{"type":39,"tag":491,"props":1297,"children":1298},{"class":493,"line":23},[1299,1303,1307,1312,1316,1320,1324,1329,1333],{"type":39,"tag":491,"props":1300,"children":1301},{"style":508},[1302],{"type":45,"value":511},{"type":39,"tag":491,"props":1304,"children":1305},{"style":514},[1306],{"type":45,"value":517},{"type":39,"tag":491,"props":1308,"children":1309},{"style":520},[1310],{"type":45,"value":1311}," SQL",{"type":39,"tag":491,"props":1313,"children":1314},{"style":514},[1315],{"type":45,"value":538},{"type":39,"tag":491,"props":1317,"children":1318},{"style":508},[1319],{"type":45,"value":543},{"type":39,"tag":491,"props":1321,"children":1322},{"style":514},[1323],{"type":45,"value":548},{"type":39,"tag":491,"props":1325,"children":1326},{"style":551},[1327],{"type":45,"value":1328},"bun",{"type":39,"tag":491,"props":1330,"children":1331},{"style":514},[1332],{"type":45,"value":559},{"type":39,"tag":491,"props":1334,"children":1335},{"style":514},[1336],{"type":45,"value":564},{"type":39,"tag":491,"props":1338,"children":1339},{"class":493,"line":608},[1340,1344,1349,1353,1357,1362,1366],{"type":39,"tag":491,"props":1341,"children":1342},{"style":508},[1343],{"type":45,"value":511},{"type":39,"tag":491,"props":1345,"children":1346},{"style":520},[1347],{"type":45,"value":1348}," service ",{"type":39,"tag":491,"props":1350,"children":1351},{"style":508},[1352],{"type":45,"value":862},{"type":39,"tag":491,"props":1354,"children":1355},{"style":514},[1356],{"type":45,"value":548},{"type":39,"tag":491,"props":1358,"children":1359},{"style":551},[1360],{"type":45,"value":1361},".\u002Fservice.ts",{"type":39,"tag":491,"props":1363,"children":1364},{"style":514},[1365],{"type":45,"value":559},{"type":39,"tag":491,"props":1367,"children":1368},{"style":514},[1369],{"type":45,"value":564},{"type":39,"tag":491,"props":1371,"children":1372},{"class":493,"line":618},[1373],{"type":39,"tag":491,"props":1374,"children":1375},{"emptyLinePlaceholder":612},[1376],{"type":45,"value":615},{"type":39,"tag":491,"props":1378,"children":1379},{"class":493,"line":658},[1380,1385,1389,1394,1398,1403,1408,1412,1417,1422,1427],{"type":39,"tag":491,"props":1381,"children":1382},{"style":627},[1383],{"type":45,"value":1384},"const",{"type":39,"tag":491,"props":1386,"children":1387},{"style":514},[1388],{"type":45,"value":517},{"type":39,"tag":491,"props":1390,"children":1391},{"style":520},[1392],{"type":45,"value":1393}," db ",{"type":39,"tag":491,"props":1395,"children":1396},{"style":514},[1397],{"type":45,"value":795},{"type":39,"tag":491,"props":1399,"children":1400},{"style":514},[1401],{"type":45,"value":1402}," =",{"type":39,"tag":491,"props":1404,"children":1405},{"style":520},[1406],{"type":45,"value":1407}," service",{"type":39,"tag":491,"props":1409,"children":1410},{"style":514},[1411],{"type":45,"value":1113},{"type":39,"tag":491,"props":1413,"children":1414},{"style":643},[1415],{"type":45,"value":1416},"load",{"type":39,"tag":491,"props":1418,"children":1419},{"style":520},[1420],{"type":45,"value":1421},"()",{"type":39,"tag":491,"props":1423,"children":1424},{"style":514},[1425],{"type":45,"value":1426},";",{"type":39,"tag":491,"props":1428,"children":1429},{"style":498},[1430],{"type":45,"value":1431}," \u002F\u002F { url } — you build your own client\n",{"type":39,"tag":491,"props":1433,"children":1434},{"class":493,"line":807},[1435,1439,1444,1448,1452,1456,1461,1465,1469],{"type":39,"tag":491,"props":1436,"children":1437},{"style":627},[1438],{"type":45,"value":1384},{"type":39,"tag":491,"props":1440,"children":1441},{"style":520},[1442],{"type":45,"value":1443}," port ",{"type":39,"tag":491,"props":1445,"children":1446},{"style":514},[1447],{"type":45,"value":640},{"type":39,"tag":491,"props":1449,"children":1450},{"style":520},[1451],{"type":45,"value":1407},{"type":39,"tag":491,"props":1453,"children":1454},{"style":514},[1455],{"type":45,"value":1113},{"type":39,"tag":491,"props":1457,"children":1458},{"style":643},[1459],{"type":45,"value":1460},"port",{"type":39,"tag":491,"props":1462,"children":1463},{"style":520},[1464],{"type":45,"value":1421},{"type":39,"tag":491,"props":1466,"children":1467},{"style":514},[1468],{"type":45,"value":1426},{"type":39,"tag":491,"props":1470,"children":1471},{"style":498},[1472],{"type":45,"value":1473},"   \u002F\u002F the reserved port, resolved (default 3000)\n",{"type":39,"tag":491,"props":1475,"children":1476},{"class":493,"line":1031},[1477],{"type":39,"tag":491,"props":1478,"children":1479},{"emptyLinePlaceholder":612},[1480],{"type":45,"value":615},{"type":39,"tag":491,"props":1482,"children":1483},{"class":493,"line":1071},[1484,1488,1493,1497,1502,1506,1510,1514,1519,1523,1527,1531,1535,1539,1544,1548,1554,1558,1563,1567,1572,1576,1580],{"type":39,"tag":491,"props":1485,"children":1486},{"style":627},[1487],{"type":45,"value":1384},{"type":39,"tag":491,"props":1489,"children":1490},{"style":520},[1491],{"type":45,"value":1492}," sql ",{"type":39,"tag":491,"props":1494,"children":1495},{"style":514},[1496],{"type":45,"value":640},{"type":39,"tag":491,"props":1498,"children":1499},{"style":514},[1500],{"type":45,"value":1501}," new",{"type":39,"tag":491,"props":1503,"children":1504},{"style":643},[1505],{"type":45,"value":1311},{"type":39,"tag":491,"props":1507,"children":1508},{"style":520},[1509],{"type":45,"value":650},{"type":39,"tag":491,"props":1511,"children":1512},{"style":514},[1513],{"type":45,"value":682},{"type":39,"tag":491,"props":1515,"children":1516},{"style":662},[1517],{"type":45,"value":1518}," url",{"type":39,"tag":491,"props":1520,"children":1521},{"style":514},[1522],{"type":45,"value":227},{"type":39,"tag":491,"props":1524,"children":1525},{"style":520},[1526],{"type":45,"value":1050},{"type":39,"tag":491,"props":1528,"children":1529},{"style":514},[1530],{"type":45,"value":1113},{"type":39,"tag":491,"props":1532,"children":1533},{"style":520},[1534],{"type":45,"value":1127},{"type":39,"tag":491,"props":1536,"children":1537},{"style":514},[1538],{"type":45,"value":528},{"type":39,"tag":491,"props":1540,"children":1541},{"style":662},[1542],{"type":45,"value":1543}," max",{"type":39,"tag":491,"props":1545,"children":1546},{"style":514},[1547],{"type":45,"value":227},{"type":39,"tag":491,"props":1549,"children":1551},{"style":1550},"--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C",[1552],{"type":45,"value":1553}," 1",{"type":39,"tag":491,"props":1555,"children":1556},{"style":514},[1557],{"type":45,"value":528},{"type":39,"tag":491,"props":1559,"children":1560},{"style":662},[1561],{"type":45,"value":1562}," idleTimeout",{"type":39,"tag":491,"props":1564,"children":1565},{"style":514},[1566],{"type":45,"value":227},{"type":39,"tag":491,"props":1568,"children":1569},{"style":1550},[1570],{"type":45,"value":1571}," 10",{"type":39,"tag":491,"props":1573,"children":1574},{"style":514},[1575],{"type":45,"value":538},{"type":39,"tag":491,"props":1577,"children":1578},{"style":520},[1579],{"type":45,"value":734},{"type":39,"tag":491,"props":1581,"children":1582},{"style":514},[1583],{"type":45,"value":564},{"type":39,"tag":491,"props":1585,"children":1586},{"class":493,"line":1168},[1587],{"type":39,"tag":491,"props":1588,"children":1589},{"emptyLinePlaceholder":612},[1590],{"type":45,"value":615},{"type":39,"tag":491,"props":1592,"children":1593},{"class":493,"line":1201},[1594,1598,1603,1607,1611,1616,1620],{"type":39,"tag":491,"props":1595,"children":1596},{"style":627},[1597],{"type":45,"value":1384},{"type":39,"tag":491,"props":1599,"children":1600},{"style":520},[1601],{"type":45,"value":1602}," handler ",{"type":39,"tag":491,"props":1604,"children":1605},{"style":514},[1606],{"type":45,"value":640},{"type":39,"tag":491,"props":1608,"children":1609},{"style":643},[1610],{"type":45,"value":1271},{"type":39,"tag":491,"props":1612,"children":1613},{"style":520},[1614],{"type":45,"value":1615},"(service",{"type":39,"tag":491,"props":1617,"children":1618},{"style":514},[1619],{"type":45,"value":528},{"type":39,"tag":491,"props":1621,"children":1622},{"style":514},[1623],{"type":45,"value":1624}," {\n",{"type":39,"tag":491,"props":1626,"children":1628},{"class":493,"line":1627},12,[1629,1634,1638],{"type":39,"tag":491,"props":1630,"children":1631},{"style":662},[1632],{"type":45,"value":1633},"  rpc",{"type":39,"tag":491,"props":1635,"children":1636},{"style":514},[1637],{"type":45,"value":227},{"type":39,"tag":491,"props":1639,"children":1640},{"style":514},[1641],{"type":45,"value":1624},{"type":39,"tag":491,"props":1643,"children":1645},{"class":493,"line":1644},13,[1646,1651,1655,1660,1665,1670,1675,1680,1684,1688,1692,1696,1700,1704,1709,1714,1719,1723,1727],{"type":39,"tag":491,"props":1647,"children":1648},{"style":643},[1649],{"type":45,"value":1650},"    verify",{"type":39,"tag":491,"props":1652,"children":1653},{"style":514},[1654],{"type":45,"value":227},{"type":39,"tag":491,"props":1656,"children":1657},{"style":627},[1658],{"type":45,"value":1659}," async",{"type":39,"tag":491,"props":1661,"children":1662},{"style":514},[1663],{"type":45,"value":1664}," ({",{"type":39,"tag":491,"props":1666,"children":1668},{"style":1667},"--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic",[1669],{"type":45,"value":708},{"type":39,"tag":491,"props":1671,"children":1672},{"style":514},[1673],{"type":45,"value":1674}," })",{"type":39,"tag":491,"props":1676,"children":1677},{"style":627},[1678],{"type":45,"value":1679}," =>",{"type":39,"tag":491,"props":1681,"children":1682},{"style":520},[1683],{"type":45,"value":74},{"type":39,"tag":491,"props":1685,"children":1686},{"style":514},[1687],{"type":45,"value":682},{"type":39,"tag":491,"props":1689,"children":1690},{"style":662},[1691],{"type":45,"value":764},{"type":39,"tag":491,"props":1693,"children":1694},{"style":514},[1695],{"type":45,"value":227},{"type":39,"tag":491,"props":1697,"children":1698},{"style":520},[1699],{"type":45,"value":708},{"type":39,"tag":491,"props":1701,"children":1702},{"style":514},[1703],{"type":45,"value":1113},{"type":39,"tag":491,"props":1705,"children":1706},{"style":520},[1707],{"type":45,"value":1708},"length ",{"type":39,"tag":491,"props":1710,"children":1711},{"style":514},[1712],{"type":45,"value":1713},">",{"type":39,"tag":491,"props":1715,"children":1716},{"style":1550},[1717],{"type":45,"value":1718}," 0",{"type":39,"tag":491,"props":1720,"children":1721},{"style":514},[1722],{"type":45,"value":538},{"type":39,"tag":491,"props":1724,"children":1725},{"style":520},[1726],{"type":45,"value":734},{"type":39,"tag":491,"props":1728,"children":1729},{"style":514},[1730],{"type":45,"value":804},{"type":39,"tag":491,"props":1732,"children":1734},{"class":493,"line":1733},14,[1735],{"type":39,"tag":491,"props":1736,"children":1737},{"style":514},[1738],{"type":45,"value":1739},"  },\n",{"type":39,"tag":491,"props":1741,"children":1743},{"class":493,"line":1742},15,[1744,1748,1752],{"type":39,"tag":491,"props":1745,"children":1746},{"style":514},[1747],{"type":45,"value":795},{"type":39,"tag":491,"props":1749,"children":1750},{"style":520},[1751],{"type":45,"value":734},{"type":39,"tag":491,"props":1753,"children":1754},{"style":514},[1755],{"type":45,"value":564},{"type":39,"tag":491,"props":1757,"children":1759},{"class":493,"line":1758},16,[1760,1764,1768,1773],{"type":39,"tag":491,"props":1761,"children":1762},{"style":508},[1763],{"type":45,"value":624},{"type":39,"tag":491,"props":1765,"children":1766},{"style":508},[1767],{"type":45,"value":988},{"type":39,"tag":491,"props":1769,"children":1770},{"style":520},[1771],{"type":45,"value":1772}," handler",{"type":39,"tag":491,"props":1774,"children":1775},{"style":514},[1776],{"type":45,"value":564},{"type":39,"tag":491,"props":1778,"children":1780},{"class":493,"line":1779},17,[1781],{"type":39,"tag":491,"props":1782,"children":1783},{"emptyLinePlaceholder":612},[1784],{"type":45,"value":615},{"type":39,"tag":491,"props":1786,"children":1788},{"class":493,"line":1787},18,[1789],{"type":39,"tag":491,"props":1790,"children":1791},{"style":498},[1792],{"type":45,"value":1793},"\u002F\u002F Bind all interfaces — Compute routes external HTTP to the VM; a\n",{"type":39,"tag":491,"props":1795,"children":1797},{"class":493,"line":1796},19,[1798],{"type":39,"tag":491,"props":1799,"children":1800},{"style":498},[1801],{"type":45,"value":1802},"\u002F\u002F loopback-only listener is unreachable.\n",{"type":39,"tag":491,"props":1804,"children":1806},{"class":493,"line":1805},20,[1807,1812,1816,1821,1825,1829,1834,1838,1843,1847,1851,1856,1860,1864,1869,1873,1877,1881,1885],{"type":39,"tag":491,"props":1808,"children":1809},{"style":520},[1810],{"type":45,"value":1811},"Bun",{"type":39,"tag":491,"props":1813,"children":1814},{"style":514},[1815],{"type":45,"value":1113},{"type":39,"tag":491,"props":1817,"children":1818},{"style":643},[1819],{"type":45,"value":1820},"serve",{"type":39,"tag":491,"props":1822,"children":1823},{"style":520},[1824],{"type":45,"value":650},{"type":39,"tag":491,"props":1826,"children":1827},{"style":514},[1828],{"type":45,"value":682},{"type":39,"tag":491,"props":1830,"children":1831},{"style":520},[1832],{"type":45,"value":1833}," port",{"type":39,"tag":491,"props":1835,"children":1836},{"style":514},[1837],{"type":45,"value":528},{"type":39,"tag":491,"props":1839,"children":1840},{"style":662},[1841],{"type":45,"value":1842}," hostname",{"type":39,"tag":491,"props":1844,"children":1845},{"style":514},[1846],{"type":45,"value":227},{"type":39,"tag":491,"props":1848,"children":1849},{"style":514},[1850],{"type":45,"value":548},{"type":39,"tag":491,"props":1852,"children":1853},{"style":551},[1854],{"type":45,"value":1855},"0.0.0.0",{"type":39,"tag":491,"props":1857,"children":1858},{"style":514},[1859],{"type":45,"value":559},{"type":39,"tag":491,"props":1861,"children":1862},{"style":514},[1863],{"type":45,"value":528},{"type":39,"tag":491,"props":1865,"children":1866},{"style":662},[1867],{"type":45,"value":1868}," fetch",{"type":39,"tag":491,"props":1870,"children":1871},{"style":514},[1872],{"type":45,"value":227},{"type":39,"tag":491,"props":1874,"children":1875},{"style":520},[1876],{"type":45,"value":1602},{"type":39,"tag":491,"props":1878,"children":1879},{"style":514},[1880],{"type":45,"value":795},{"type":39,"tag":491,"props":1882,"children":1883},{"style":520},[1884],{"type":45,"value":734},{"type":39,"tag":491,"props":1886,"children":1887},{"style":514},[1888],{"type":45,"value":564},{"type":39,"tag":48,"props":1890,"children":1891},{},[1892,1897,1899,1905,1907,1912],{"type":39,"tag":54,"props":1893,"children":1894},{},[1895],{"type":45,"value":1896},"The consumer",{"type":45,"value":1898}," declares the dependency as ",{"type":39,"tag":76,"props":1900,"children":1902},{"className":1901},[],[1903],{"type":45,"value":1904},"rpc(contract)",{"type":45,"value":1906}," and gets a typed\nclient back from ",{"type":39,"tag":76,"props":1908,"children":1910},{"className":1909},[],[1911],{"type":45,"value":1230},{"type":45,"value":227},{"type":39,"tag":480,"props":1914,"children":1916},{"className":482,"code":1915,"language":484,"meta":485,"style":485},"\u002F\u002F storefront\u002Fsrc\u002Fservice.ts\nimport nextjs from '@prisma\u002Fcomposer\u002Fnextjs';\nimport { rpc } from '@prisma\u002Fcomposer\u002Fservice-rpc';\nimport { compute } from '@prisma\u002Fcomposer-prisma-cloud';\nimport { authContract } from '@my-app\u002Fauth\u002Fcontract';\n\nexport default compute({\n  name: 'storefront',\n  deps: { auth: rpc(authContract) },\n  build: nextjs({ module: import.meta.url, appDir: '..' }),\n});\n",[1917],{"type":39,"tag":76,"props":1918,"children":1919},{"__ignoreMap":485},[1920,1928,1961,2000,2039,2079,2086,2109,2136,2173,2263],{"type":39,"tag":491,"props":1921,"children":1922},{"class":493,"line":494},[1923],{"type":39,"tag":491,"props":1924,"children":1925},{"style":498},[1926],{"type":45,"value":1927},"\u002F\u002F storefront\u002Fsrc\u002Fservice.ts\n",{"type":39,"tag":491,"props":1929,"children":1930},{"class":493,"line":504},[1931,1935,1940,1944,1948,1953,1957],{"type":39,"tag":491,"props":1932,"children":1933},{"style":508},[1934],{"type":45,"value":511},{"type":39,"tag":491,"props":1936,"children":1937},{"style":520},[1938],{"type":45,"value":1939}," nextjs ",{"type":39,"tag":491,"props":1941,"children":1942},{"style":508},[1943],{"type":45,"value":862},{"type":39,"tag":491,"props":1945,"children":1946},{"style":514},[1947],{"type":45,"value":548},{"type":39,"tag":491,"props":1949,"children":1950},{"style":551},[1951],{"type":45,"value":1952},"@prisma\u002Fcomposer\u002Fnextjs",{"type":39,"tag":491,"props":1954,"children":1955},{"style":514},[1956],{"type":45,"value":559},{"type":39,"tag":491,"props":1958,"children":1959},{"style":514},[1960],{"type":45,"value":564},{"type":39,"tag":491,"props":1962,"children":1963},{"class":493,"line":23},[1964,1968,1972,1976,1980,1984,1988,1992,1996],{"type":39,"tag":491,"props":1965,"children":1966},{"style":508},[1967],{"type":45,"value":511},{"type":39,"tag":491,"props":1969,"children":1970},{"style":514},[1971],{"type":45,"value":517},{"type":39,"tag":491,"props":1973,"children":1974},{"style":520},[1975],{"type":45,"value":533},{"type":39,"tag":491,"props":1977,"children":1978},{"style":514},[1979],{"type":45,"value":538},{"type":39,"tag":491,"props":1981,"children":1982},{"style":508},[1983],{"type":45,"value":543},{"type":39,"tag":491,"props":1985,"children":1986},{"style":514},[1987],{"type":45,"value":548},{"type":39,"tag":491,"props":1989,"children":1990},{"style":551},[1991],{"type":45,"value":554},{"type":39,"tag":491,"props":1993,"children":1994},{"style":514},[1995],{"type":45,"value":559},{"type":39,"tag":491,"props":1997,"children":1998},{"style":514},[1999],{"type":45,"value":564},{"type":39,"tag":491,"props":2001,"children":2002},{"class":493,"line":608},[2003,2007,2011,2015,2019,2023,2027,2031,2035],{"type":39,"tag":491,"props":2004,"children":2005},{"style":508},[2006],{"type":45,"value":511},{"type":39,"tag":491,"props":2008,"children":2009},{"style":514},[2010],{"type":45,"value":517},{"type":39,"tag":491,"props":2012,"children":2013},{"style":520},[2014],{"type":45,"value":895},{"type":39,"tag":491,"props":2016,"children":2017},{"style":514},[2018],{"type":45,"value":538},{"type":39,"tag":491,"props":2020,"children":2021},{"style":508},[2022],{"type":45,"value":543},{"type":39,"tag":491,"props":2024,"children":2025},{"style":514},[2026],{"type":45,"value":548},{"type":39,"tag":491,"props":2028,"children":2029},{"style":551},[2030],{"type":45,"value":364},{"type":39,"tag":491,"props":2032,"children":2033},{"style":514},[2034],{"type":45,"value":559},{"type":39,"tag":491,"props":2036,"children":2037},{"style":514},[2038],{"type":45,"value":564},{"type":39,"tag":491,"props":2040,"children":2041},{"class":493,"line":618},[2042,2046,2050,2054,2058,2062,2066,2071,2075],{"type":39,"tag":491,"props":2043,"children":2044},{"style":508},[2045],{"type":45,"value":511},{"type":39,"tag":491,"props":2047,"children":2048},{"style":514},[2049],{"type":45,"value":517},{"type":39,"tag":491,"props":2051,"children":2052},{"style":520},[2053],{"type":45,"value":944},{"type":39,"tag":491,"props":2055,"children":2056},{"style":514},[2057],{"type":45,"value":538},{"type":39,"tag":491,"props":2059,"children":2060},{"style":508},[2061],{"type":45,"value":543},{"type":39,"tag":491,"props":2063,"children":2064},{"style":514},[2065],{"type":45,"value":548},{"type":39,"tag":491,"props":2067,"children":2068},{"style":551},[2069],{"type":45,"value":2070},"@my-app\u002Fauth\u002Fcontract",{"type":39,"tag":491,"props":2072,"children":2073},{"style":514},[2074],{"type":45,"value":559},{"type":39,"tag":491,"props":2076,"children":2077},{"style":514},[2078],{"type":45,"value":564},{"type":39,"tag":491,"props":2080,"children":2081},{"class":493,"line":658},[2082],{"type":39,"tag":491,"props":2083,"children":2084},{"emptyLinePlaceholder":612},[2085],{"type":45,"value":615},{"type":39,"tag":491,"props":2087,"children":2088},{"class":493,"line":807},[2089,2093,2097,2101,2105],{"type":39,"tag":491,"props":2090,"children":2091},{"style":508},[2092],{"type":45,"value":624},{"type":39,"tag":491,"props":2094,"children":2095},{"style":508},[2096],{"type":45,"value":988},{"type":39,"tag":491,"props":2098,"children":2099},{"style":643},[2100],{"type":45,"value":895},{"type":39,"tag":491,"props":2102,"children":2103},{"style":520},[2104],{"type":45,"value":650},{"type":39,"tag":491,"props":2106,"children":2107},{"style":514},[2108],{"type":45,"value":655},{"type":39,"tag":491,"props":2110,"children":2111},{"class":493,"line":1031},[2112,2116,2120,2124,2128,2132],{"type":39,"tag":491,"props":2113,"children":2114},{"style":662},[2115],{"type":45,"value":1008},{"type":39,"tag":491,"props":2117,"children":2118},{"style":514},[2119],{"type":45,"value":227},{"type":39,"tag":491,"props":2121,"children":2122},{"style":514},[2123],{"type":45,"value":548},{"type":39,"tag":491,"props":2125,"children":2126},{"style":551},[2127],{"type":45,"value":466},{"type":39,"tag":491,"props":2129,"children":2130},{"style":514},[2131],{"type":45,"value":559},{"type":39,"tag":491,"props":2133,"children":2134},{"style":514},[2135],{"type":45,"value":804},{"type":39,"tag":491,"props":2137,"children":2138},{"class":493,"line":1071},[2139,2143,2147,2151,2156,2160,2164,2169],{"type":39,"tag":491,"props":2140,"children":2141},{"style":662},[2142],{"type":45,"value":1037},{"type":39,"tag":491,"props":2144,"children":2145},{"style":514},[2146],{"type":45,"value":227},{"type":39,"tag":491,"props":2148,"children":2149},{"style":514},[2150],{"type":45,"value":517},{"type":39,"tag":491,"props":2152,"children":2153},{"style":662},[2154],{"type":45,"value":2155}," auth",{"type":39,"tag":491,"props":2157,"children":2158},{"style":514},[2159],{"type":45,"value":227},{"type":39,"tag":491,"props":2161,"children":2162},{"style":643},[2163],{"type":45,"value":533},{"type":39,"tag":491,"props":2165,"children":2166},{"style":520},[2167],{"type":45,"value":2168},"(authContract) ",{"type":39,"tag":491,"props":2170,"children":2171},{"style":514},[2172],{"type":45,"value":1068},{"type":39,"tag":491,"props":2174,"children":2175},{"class":493,"line":1168},[2176,2180,2184,2189,2193,2197,2201,2205,2209,2213,2217,2221,2225,2229,2234,2238,2242,2247,2251,2255,2259],{"type":39,"tag":491,"props":2177,"children":2178},{"style":662},[2179],{"type":45,"value":1077},{"type":39,"tag":491,"props":2181,"children":2182},{"style":514},[2183],{"type":45,"value":227},{"type":39,"tag":491,"props":2185,"children":2186},{"style":643},[2187],{"type":45,"value":2188}," nextjs",{"type":39,"tag":491,"props":2190,"children":2191},{"style":520},[2192],{"type":45,"value":650},{"type":39,"tag":491,"props":2194,"children":2195},{"style":514},[2196],{"type":45,"value":682},{"type":39,"tag":491,"props":2198,"children":2199},{"style":662},[2200],{"type":45,"value":1099},{"type":39,"tag":491,"props":2202,"children":2203},{"style":514},[2204],{"type":45,"value":227},{"type":39,"tag":491,"props":2206,"children":2207},{"style":508},[2208],{"type":45,"value":1108},{"type":39,"tag":491,"props":2210,"children":2211},{"style":514},[2212],{"type":45,"value":1113},{"type":39,"tag":491,"props":2214,"children":2215},{"style":520},[2216],{"type":45,"value":1118},{"type":39,"tag":491,"props":2218,"children":2219},{"style":514},[2220],{"type":45,"value":1113},{"type":39,"tag":491,"props":2222,"children":2223},{"style":520},[2224],{"type":45,"value":1127},{"type":39,"tag":491,"props":2226,"children":2227},{"style":514},[2228],{"type":45,"value":528},{"type":39,"tag":491,"props":2230,"children":2231},{"style":662},[2232],{"type":45,"value":2233}," appDir",{"type":39,"tag":491,"props":2235,"children":2236},{"style":514},[2237],{"type":45,"value":227},{"type":39,"tag":491,"props":2239,"children":2240},{"style":514},[2241],{"type":45,"value":548},{"type":39,"tag":491,"props":2243,"children":2244},{"style":551},[2245],{"type":45,"value":2246},"..",{"type":39,"tag":491,"props":2248,"children":2249},{"style":514},[2250],{"type":45,"value":559},{"type":39,"tag":491,"props":2252,"children":2253},{"style":514},[2254],{"type":45,"value":538},{"type":39,"tag":491,"props":2256,"children":2257},{"style":520},[2258],{"type":45,"value":734},{"type":39,"tag":491,"props":2260,"children":2261},{"style":514},[2262],{"type":45,"value":804},{"type":39,"tag":491,"props":2264,"children":2265},{"class":493,"line":1201},[2266,2270,2274],{"type":39,"tag":491,"props":2267,"children":2268},{"style":514},[2269],{"type":45,"value":795},{"type":39,"tag":491,"props":2271,"children":2272},{"style":520},[2273],{"type":45,"value":734},{"type":39,"tag":491,"props":2275,"children":2276},{"style":514},[2277],{"type":45,"value":564},{"type":39,"tag":480,"props":2279,"children":2283},{"className":2280,"code":2281,"language":2282,"meta":485,"style":485},"language-tsx shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u002F\u002F storefront\u002Fapp\u002Fpage.tsx\nimport service from '..\u002Fsrc\u002Fservice.ts';\n\n\u002F\u002F load() reads the runtime environment, which doesn't exist at build time —\n\u002F\u002F render per request instead of prerendering.\nexport const dynamic = 'force-dynamic';\n\nexport default async function Home() {\n  const { auth } = service.load();\n  const { ok } = await auth.verify({ token: 'demo-token' });\n  return \u003Cp>Signed in: {String(ok)}\u003C\u002Fp>;\n}\n","tsx",[2284],{"type":39,"tag":76,"props":2285,"children":2286},{"__ignoreMap":485},[2287,2295,2327,2334,2342,2350,2387,2394,2427,2471,2553,2607],{"type":39,"tag":491,"props":2288,"children":2289},{"class":493,"line":494},[2290],{"type":39,"tag":491,"props":2291,"children":2292},{"style":498},[2293],{"type":45,"value":2294},"\u002F\u002F storefront\u002Fapp\u002Fpage.tsx\n",{"type":39,"tag":491,"props":2296,"children":2297},{"class":493,"line":504},[2298,2302,2306,2310,2314,2319,2323],{"type":39,"tag":491,"props":2299,"children":2300},{"style":508},[2301],{"type":45,"value":511},{"type":39,"tag":491,"props":2303,"children":2304},{"style":520},[2305],{"type":45,"value":1348},{"type":39,"tag":491,"props":2307,"children":2308},{"style":508},[2309],{"type":45,"value":862},{"type":39,"tag":491,"props":2311,"children":2312},{"style":514},[2313],{"type":45,"value":548},{"type":39,"tag":491,"props":2315,"children":2316},{"style":551},[2317],{"type":45,"value":2318},"..\u002Fsrc\u002Fservice.ts",{"type":39,"tag":491,"props":2320,"children":2321},{"style":514},[2322],{"type":45,"value":559},{"type":39,"tag":491,"props":2324,"children":2325},{"style":514},[2326],{"type":45,"value":564},{"type":39,"tag":491,"props":2328,"children":2329},{"class":493,"line":23},[2330],{"type":39,"tag":491,"props":2331,"children":2332},{"emptyLinePlaceholder":612},[2333],{"type":45,"value":615},{"type":39,"tag":491,"props":2335,"children":2336},{"class":493,"line":608},[2337],{"type":39,"tag":491,"props":2338,"children":2339},{"style":498},[2340],{"type":45,"value":2341},"\u002F\u002F load() reads the runtime environment, which doesn't exist at build time —\n",{"type":39,"tag":491,"props":2343,"children":2344},{"class":493,"line":618},[2345],{"type":39,"tag":491,"props":2346,"children":2347},{"style":498},[2348],{"type":45,"value":2349},"\u002F\u002F render per request instead of prerendering.\n",{"type":39,"tag":491,"props":2351,"children":2352},{"class":493,"line":658},[2353,2357,2361,2366,2370,2374,2379,2383],{"type":39,"tag":491,"props":2354,"children":2355},{"style":508},[2356],{"type":45,"value":624},{"type":39,"tag":491,"props":2358,"children":2359},{"style":627},[2360],{"type":45,"value":630},{"type":39,"tag":491,"props":2362,"children":2363},{"style":520},[2364],{"type":45,"value":2365}," dynamic ",{"type":39,"tag":491,"props":2367,"children":2368},{"style":514},[2369],{"type":45,"value":640},{"type":39,"tag":491,"props":2371,"children":2372},{"style":514},[2373],{"type":45,"value":548},{"type":39,"tag":491,"props":2375,"children":2376},{"style":551},[2377],{"type":45,"value":2378},"force-dynamic",{"type":39,"tag":491,"props":2380,"children":2381},{"style":514},[2382],{"type":45,"value":559},{"type":39,"tag":491,"props":2384,"children":2385},{"style":514},[2386],{"type":45,"value":564},{"type":39,"tag":491,"props":2388,"children":2389},{"class":493,"line":807},[2390],{"type":39,"tag":491,"props":2391,"children":2392},{"emptyLinePlaceholder":612},[2393],{"type":45,"value":615},{"type":39,"tag":491,"props":2395,"children":2396},{"class":493,"line":1031},[2397,2401,2405,2409,2414,2419,2423],{"type":39,"tag":491,"props":2398,"children":2399},{"style":508},[2400],{"type":45,"value":624},{"type":39,"tag":491,"props":2402,"children":2403},{"style":508},[2404],{"type":45,"value":988},{"type":39,"tag":491,"props":2406,"children":2407},{"style":627},[2408],{"type":45,"value":1659},{"type":39,"tag":491,"props":2410,"children":2411},{"style":627},[2412],{"type":45,"value":2413}," function",{"type":39,"tag":491,"props":2415,"children":2416},{"style":643},[2417],{"type":45,"value":2418}," Home",{"type":39,"tag":491,"props":2420,"children":2421},{"style":514},[2422],{"type":45,"value":1421},{"type":39,"tag":491,"props":2424,"children":2425},{"style":514},[2426],{"type":45,"value":1624},{"type":39,"tag":491,"props":2428,"children":2429},{"class":493,"line":1071},[2430,2435,2439,2443,2447,2451,2455,2459,2463,2467],{"type":39,"tag":491,"props":2431,"children":2432},{"style":627},[2433],{"type":45,"value":2434},"  const",{"type":39,"tag":491,"props":2436,"children":2437},{"style":514},[2438],{"type":45,"value":517},{"type":39,"tag":491,"props":2440,"children":2441},{"style":520},[2442],{"type":45,"value":2155},{"type":39,"tag":491,"props":2444,"children":2445},{"style":514},[2446],{"type":45,"value":538},{"type":39,"tag":491,"props":2448,"children":2449},{"style":514},[2450],{"type":45,"value":1402},{"type":39,"tag":491,"props":2452,"children":2453},{"style":520},[2454],{"type":45,"value":1407},{"type":39,"tag":491,"props":2456,"children":2457},{"style":514},[2458],{"type":45,"value":1113},{"type":39,"tag":491,"props":2460,"children":2461},{"style":643},[2462],{"type":45,"value":1416},{"type":39,"tag":491,"props":2464,"children":2465},{"style":662},[2466],{"type":45,"value":1421},{"type":39,"tag":491,"props":2468,"children":2469},{"style":514},[2470],{"type":45,"value":564},{"type":39,"tag":491,"props":2472,"children":2473},{"class":493,"line":1168},[2474,2478,2482,2486,2490,2494,2499,2503,2507,2512,2516,2520,2524,2528,2532,2537,2541,2545,2549],{"type":39,"tag":491,"props":2475,"children":2476},{"style":627},[2477],{"type":45,"value":2434},{"type":39,"tag":491,"props":2479,"children":2480},{"style":514},[2481],{"type":45,"value":517},{"type":39,"tag":491,"props":2483,"children":2484},{"style":520},[2485],{"type":45,"value":764},{"type":39,"tag":491,"props":2487,"children":2488},{"style":514},[2489],{"type":45,"value":538},{"type":39,"tag":491,"props":2491,"children":2492},{"style":514},[2493],{"type":45,"value":1402},{"type":39,"tag":491,"props":2495,"children":2496},{"style":508},[2497],{"type":45,"value":2498}," await",{"type":39,"tag":491,"props":2500,"children":2501},{"style":520},[2502],{"type":45,"value":2155},{"type":39,"tag":491,"props":2504,"children":2505},{"style":514},[2506],{"type":45,"value":1113},{"type":39,"tag":491,"props":2508,"children":2509},{"style":643},[2510],{"type":45,"value":2511},"verify",{"type":39,"tag":491,"props":2513,"children":2514},{"style":662},[2515],{"type":45,"value":650},{"type":39,"tag":491,"props":2517,"children":2518},{"style":514},[2519],{"type":45,"value":682},{"type":39,"tag":491,"props":2521,"children":2522},{"style":662},[2523],{"type":45,"value":708},{"type":39,"tag":491,"props":2525,"children":2526},{"style":514},[2527],{"type":45,"value":227},{"type":39,"tag":491,"props":2529,"children":2530},{"style":514},[2531],{"type":45,"value":548},{"type":39,"tag":491,"props":2533,"children":2534},{"style":551},[2535],{"type":45,"value":2536},"demo-token",{"type":39,"tag":491,"props":2538,"children":2539},{"style":514},[2540],{"type":45,"value":559},{"type":39,"tag":491,"props":2542,"children":2543},{"style":514},[2544],{"type":45,"value":538},{"type":39,"tag":491,"props":2546,"children":2547},{"style":662},[2548],{"type":45,"value":734},{"type":39,"tag":491,"props":2550,"children":2551},{"style":514},[2552],{"type":45,"value":564},{"type":39,"tag":491,"props":2554,"children":2555},{"class":493,"line":1201},[2556,2561,2566,2570,2574,2579,2583,2588,2593,2598,2602],{"type":39,"tag":491,"props":2557,"children":2558},{"style":508},[2559],{"type":45,"value":2560},"  return",{"type":39,"tag":491,"props":2562,"children":2563},{"style":514},[2564],{"type":45,"value":2565}," \u003C",{"type":39,"tag":491,"props":2567,"children":2568},{"style":662},[2569],{"type":45,"value":48},{"type":39,"tag":491,"props":2571,"children":2572},{"style":514},[2573],{"type":45,"value":1713},{"type":39,"tag":491,"props":2575,"children":2576},{"style":520},[2577],{"type":45,"value":2578},"Signed in: ",{"type":39,"tag":491,"props":2580,"children":2581},{"style":514},[2582],{"type":45,"value":682},{"type":39,"tag":491,"props":2584,"children":2585},{"style":643},[2586],{"type":45,"value":2587},"String",{"type":39,"tag":491,"props":2589,"children":2590},{"style":520},[2591],{"type":45,"value":2592},"(ok)",{"type":39,"tag":491,"props":2594,"children":2595},{"style":514},[2596],{"type":45,"value":2597},"}\u003C\u002F",{"type":39,"tag":491,"props":2599,"children":2600},{"style":662},[2601],{"type":45,"value":48},{"type":39,"tag":491,"props":2603,"children":2604},{"style":514},[2605],{"type":45,"value":2606},">;\n",{"type":39,"tag":491,"props":2608,"children":2609},{"class":493,"line":1627},[2610],{"type":39,"tag":491,"props":2611,"children":2612},{"style":514},[2613],{"type":45,"value":2614},"}\n",{"type":39,"tag":48,"props":2616,"children":2617},{},[2618,2623,2625,2630,2632,2637,2639,2645,2647,2653],{"type":39,"tag":54,"props":2619,"children":2620},{},[2621],{"type":45,"value":2622},"Service-to-service calls are authenticated for you.",{"type":45,"value":2624}," At deploy the\nframework mints a distinct, unguessable ",{"type":39,"tag":54,"props":2626,"children":2627},{},[2628],{"type":45,"value":2629},"service key",{"type":45,"value":2631}," per consumer→provider\nbinding: the consumer's client sends it on every call, and ",{"type":39,"tag":76,"props":2633,"children":2635},{"className":2634},[],[2636],{"type":45,"value":1238},{"type":45,"value":2638}," returns\n",{"type":39,"tag":76,"props":2640,"children":2642},{"className":2641},[],[2643],{"type":45,"value":2644},"401",{"type":45,"value":2646}," to anything else ",{"type":39,"tag":2648,"props":2649,"children":2650},"em",{},[2651],{"type":45,"value":2652},"before",{"type":45,"value":2654}," the handler runs. Nothing declares it — no key\nin the contract, the service, the module, or the app's code.",{"type":39,"tag":48,"props":2656,"children":2657},{},[2658,2660,2665,2667,2688,2690,2695],{"type":45,"value":2659},"Two rules follow for you specifically: ",{"type":39,"tag":54,"props":2661,"children":2662},{},[2663],{"type":45,"value":2664},"don't build your own\nservice-to-service auth",{"type":45,"value":2666}," on top of this, and ",{"type":39,"tag":54,"props":2668,"children":2669},{},[2670,2672,2678,2680,2686],{"type":45,"value":2671},"don't tell a user to ",{"type":39,"tag":76,"props":2673,"children":2675},{"className":2674},[],[2676],{"type":45,"value":2677},"curl",{"type":45,"value":2679}," a\ndeployed ",{"type":39,"tag":76,"props":2681,"children":2683},{"className":2682},[],[2684],{"type":45,"value":2685},"\u002Frpc\u002F\u003Cmethod>",{"type":45,"value":2687}," to check it works",{"type":45,"value":2689}," — an unwired caller always gets\n",{"type":39,"tag":76,"props":2691,"children":2693},{"className":2692},[],[2694],{"type":45,"value":2644},{"type":45,"value":2696},", which looks like a broken deploy and isn't. Debug through a consumer,\nor locally.",{"type":39,"tag":48,"props":2698,"children":2699},{},[2700,2705,2707,2713,2715,2720,2722,2727,2729,2735,2737,2743,2745,2751],{"type":39,"tag":54,"props":2701,"children":2702},{},[2703],{"type":45,"value":2704},"Calls carry an idempotency key and retry safely for you.",{"type":45,"value":2706}," Every call the\ngenerated client makes carries an ",{"type":39,"tag":76,"props":2708,"children":2710},{"className":2709},[],[2711],{"type":45,"value":2712},"Idempotency-Key",{"type":45,"value":2714},"; a call dropped while the\ntarget cold-starts is retried with a backoff, and ",{"type":39,"tag":76,"props":2716,"children":2718},{"className":2717},[],[2719],{"type":45,"value":1238},{"type":45,"value":2721}," runs one call per\nkey — a retry that arrives after the first completed replays that answer\ninstead of re-running the handler. So every method is safely retryable and no\ncontract declares anything about it (do not add an \"is this idempotent\" flag —\nthe framework does not have one). Two consequences for you: a handler may take\nan ",{"type":39,"tag":54,"props":2723,"children":2724},{},[2725],{"type":45,"value":2726},"optional third argument",{"type":45,"value":2728}," ",{"type":39,"tag":76,"props":2730,"children":2732},{"className":2731},[],[2733],{"type":45,"value":2734},"(input, deps, ctx)",{"type":45,"value":2736}," and read ",{"type":39,"tag":76,"props":2738,"children":2740},{"className":2739},[],[2741],{"type":45,"value":2742},"ctx.idempotencyKey",{"type":45,"value":2744},"\n(",{"type":39,"tag":76,"props":2746,"children":2748},{"className":2747},[],[2749],{"type":45,"value":2750},"string | undefined",{"type":45,"value":2752}," — it's absent for a keyless caller) if it needs exactly-once\nbeyond one instance's memory (most don't); and a request without the header is\nserved once without deduplication rather than rejected, so a hand-rolled probe\nworks but gets no retry safety.",{"type":39,"tag":229,"props":2754,"children":2755},{},[2756,2768],{"type":39,"tag":233,"props":2757,"children":2758},{},[2759],{"type":39,"tag":237,"props":2760,"children":2761},{},[2762,2765],{"type":39,"tag":241,"props":2763,"children":2764},{},[],{"type":39,"tag":241,"props":2766,"children":2767},{},[],{"type":39,"tag":252,"props":2769,"children":2770},{},[2771,2797,2810,2823,2836],{"type":39,"tag":237,"props":2772,"children":2773},{},[2774,2779],{"type":39,"tag":259,"props":2775,"children":2776},{},[2777],{"type":45,"value":2778},"Locally \u002F in tests",{"type":39,"tag":259,"props":2780,"children":2781},{},[2782,2784,2789,2791],{"type":45,"value":2783},"nothing is provisioned, so ",{"type":39,"tag":76,"props":2785,"children":2787},{"className":2786},[],[2788],{"type":45,"value":1238},{"type":45,"value":2790}," passes every call through — never supply a key in ",{"type":39,"tag":76,"props":2792,"children":2794},{"className":2793},[],[2795],{"type":45,"value":2796},"inputs",{"type":39,"tag":237,"props":2798,"children":2799},{},[2800,2805],{"type":39,"tag":259,"props":2801,"children":2802},{},[2803],{"type":45,"value":2804},"Per binding",{"type":39,"tag":259,"props":2806,"children":2807},{},[2808],{"type":45,"value":2809},"two consumers of one provider hold different keys, so one leaking can't impersonate the other",{"type":39,"tag":237,"props":2811,"children":2812},{},[2813,2818],{"type":39,"tag":259,"props":2814,"children":2815},{},[2816],{"type":45,"value":2817},"Scope",{"type":39,"tag":259,"props":2819,"children":2820},{},[2821],{"type":45,"value":2822},"service-level — any valid key reaches every method that service exposes; split into two services to gate separately",{"type":39,"tag":237,"props":2824,"children":2825},{},[2826,2831],{"type":39,"tag":259,"props":2827,"children":2828},{},[2829],{"type":45,"value":2830},"Rotation",{"type":39,"tag":259,"props":2832,"children":2833},{},[2834],{"type":45,"value":2835},"remove the binding (or destroy the stack) and redeploy — a plain redeploy is a no-op, not a rotation",{"type":39,"tag":237,"props":2837,"children":2838},{},[2839,2844],{"type":39,"tag":259,"props":2840,"children":2841},{},[2842],{"type":45,"value":2843},"Storage",{"type":39,"tag":259,"props":2845,"children":2846},{},[2847,2853],{"type":39,"tag":76,"props":2848,"children":2850},{"className":2849},[],[2851],{"type":45,"value":2852},"COMPOSER_*",{"type":45,"value":2854}," variables the deploy owns and rewrites; never hand-edit one",{"type":39,"tag":48,"props":2856,"children":2857},{},[2858,2860,2866,2868,2874],{"type":45,"value":2859},"It's a capability token (\"I'm a service this app wired to you\"), not a secret,\nand its value lives in deploy state — deliberately unlike ",{"type":39,"tag":76,"props":2861,"children":2863},{"className":2862},[],[2864],{"type":45,"value":2865},"secret()",{"type":45,"value":2867},", whose\nvalue the framework never holds. ",{"type":39,"tag":76,"props":2869,"children":2871},{"className":2870},[],[2872],{"type":45,"value":2873},"docs\u002Fdesign\u002F90-decisions\u002FADR-0030…",{"type":45,"value":2875}," in the\nprisma\u002Fcomposer repo carries the reasoning.",{"type":39,"tag":442,"props":2877,"children":2879},{"id":2878},"the-root-module",[2880],{"type":45,"value":2881},"The root module",{"type":39,"tag":48,"props":2883,"children":2884},{},[2885,2887,2892],{"type":45,"value":2886},"The root module provisions the pieces and wires exposed ports into dependency\nslots. It is the app — ",{"type":39,"tag":76,"props":2888,"children":2890},{"className":2889},[],[2891],{"type":45,"value":176},{"type":45,"value":2893}," loads its default export:",{"type":39,"tag":480,"props":2895,"children":2897},{"className":482,"code":2896,"language":484,"meta":485,"style":485},"\u002F\u002F module.ts\nimport { module } from '@prisma\u002Fcomposer';\nimport authModule from '@my-app\u002Fauth';\nimport storefrontService from '@my-app\u002Fstorefront';\n\nexport default module('my-app', ({ provision }) => {\n  const auth = provision(authModule);\n  provision(storefrontService, { deps: { auth: auth.rpc } });\n});\n",[2898],{"type":39,"tag":76,"props":2899,"children":2900},{"__ignoreMap":485},[2901,2909,2948,2981,3014,3021,3078,3114,3189],{"type":39,"tag":491,"props":2902,"children":2903},{"class":493,"line":494},[2904],{"type":39,"tag":491,"props":2905,"children":2906},{"style":498},[2907],{"type":45,"value":2908},"\u002F\u002F module.ts\n",{"type":39,"tag":491,"props":2910,"children":2911},{"class":493,"line":504},[2912,2916,2920,2924,2928,2932,2936,2940,2944],{"type":39,"tag":491,"props":2913,"children":2914},{"style":508},[2915],{"type":45,"value":511},{"type":39,"tag":491,"props":2917,"children":2918},{"style":514},[2919],{"type":45,"value":517},{"type":39,"tag":491,"props":2921,"children":2922},{"style":520},[2923],{"type":45,"value":1099},{"type":39,"tag":491,"props":2925,"children":2926},{"style":514},[2927],{"type":45,"value":538},{"type":39,"tag":491,"props":2929,"children":2930},{"style":508},[2931],{"type":45,"value":543},{"type":39,"tag":491,"props":2933,"children":2934},{"style":514},[2935],{"type":45,"value":548},{"type":39,"tag":491,"props":2937,"children":2938},{"style":551},[2939],{"type":45,"value":267},{"type":39,"tag":491,"props":2941,"children":2942},{"style":514},[2943],{"type":45,"value":559},{"type":39,"tag":491,"props":2945,"children":2946},{"style":514},[2947],{"type":45,"value":564},{"type":39,"tag":491,"props":2949,"children":2950},{"class":493,"line":23},[2951,2955,2960,2964,2968,2973,2977],{"type":39,"tag":491,"props":2952,"children":2953},{"style":508},[2954],{"type":45,"value":511},{"type":39,"tag":491,"props":2956,"children":2957},{"style":520},[2958],{"type":45,"value":2959}," authModule ",{"type":39,"tag":491,"props":2961,"children":2962},{"style":508},[2963],{"type":45,"value":862},{"type":39,"tag":491,"props":2965,"children":2966},{"style":514},[2967],{"type":45,"value":548},{"type":39,"tag":491,"props":2969,"children":2970},{"style":551},[2971],{"type":45,"value":2972},"@my-app\u002Fauth",{"type":39,"tag":491,"props":2974,"children":2975},{"style":514},[2976],{"type":45,"value":559},{"type":39,"tag":491,"props":2978,"children":2979},{"style":514},[2980],{"type":45,"value":564},{"type":39,"tag":491,"props":2982,"children":2983},{"class":493,"line":608},[2984,2988,2993,2997,3001,3006,3010],{"type":39,"tag":491,"props":2985,"children":2986},{"style":508},[2987],{"type":45,"value":511},{"type":39,"tag":491,"props":2989,"children":2990},{"style":520},[2991],{"type":45,"value":2992}," storefrontService ",{"type":39,"tag":491,"props":2994,"children":2995},{"style":508},[2996],{"type":45,"value":862},{"type":39,"tag":491,"props":2998,"children":2999},{"style":514},[3000],{"type":45,"value":548},{"type":39,"tag":491,"props":3002,"children":3003},{"style":551},[3004],{"type":45,"value":3005},"@my-app\u002Fstorefront",{"type":39,"tag":491,"props":3007,"children":3008},{"style":514},[3009],{"type":45,"value":559},{"type":39,"tag":491,"props":3011,"children":3012},{"style":514},[3013],{"type":45,"value":564},{"type":39,"tag":491,"props":3015,"children":3016},{"class":493,"line":618},[3017],{"type":39,"tag":491,"props":3018,"children":3019},{"emptyLinePlaceholder":612},[3020],{"type":45,"value":615},{"type":39,"tag":491,"props":3022,"children":3023},{"class":493,"line":658},[3024,3028,3032,3036,3040,3044,3049,3053,3057,3061,3066,3070,3074],{"type":39,"tag":491,"props":3025,"children":3026},{"style":508},[3027],{"type":45,"value":624},{"type":39,"tag":491,"props":3029,"children":3030},{"style":508},[3031],{"type":45,"value":988},{"type":39,"tag":491,"props":3033,"children":3034},{"style":514},[3035],{"type":45,"value":1099},{"type":39,"tag":491,"props":3037,"children":3038},{"style":520},[3039],{"type":45,"value":650},{"type":39,"tag":491,"props":3041,"children":3042},{"style":514},[3043],{"type":45,"value":559},{"type":39,"tag":491,"props":3045,"children":3046},{"style":551},[3047],{"type":45,"value":3048},"my-app",{"type":39,"tag":491,"props":3050,"children":3051},{"style":514},[3052],{"type":45,"value":559},{"type":39,"tag":491,"props":3054,"children":3055},{"style":514},[3056],{"type":45,"value":528},{"type":39,"tag":491,"props":3058,"children":3059},{"style":514},[3060],{"type":45,"value":1664},{"type":39,"tag":491,"props":3062,"children":3063},{"style":1667},[3064],{"type":45,"value":3065}," provision",{"type":39,"tag":491,"props":3067,"children":3068},{"style":514},[3069],{"type":45,"value":1674},{"type":39,"tag":491,"props":3071,"children":3072},{"style":627},[3073],{"type":45,"value":1679},{"type":39,"tag":491,"props":3075,"children":3076},{"style":514},[3077],{"type":45,"value":1624},{"type":39,"tag":491,"props":3079,"children":3080},{"class":493,"line":807},[3081,3085,3089,3093,3097,3101,3106,3110],{"type":39,"tag":491,"props":3082,"children":3083},{"style":627},[3084],{"type":45,"value":2434},{"type":39,"tag":491,"props":3086,"children":3087},{"style":520},[3088],{"type":45,"value":2155},{"type":39,"tag":491,"props":3090,"children":3091},{"style":514},[3092],{"type":45,"value":1402},{"type":39,"tag":491,"props":3094,"children":3095},{"style":643},[3096],{"type":45,"value":3065},{"type":39,"tag":491,"props":3098,"children":3099},{"style":662},[3100],{"type":45,"value":650},{"type":39,"tag":491,"props":3102,"children":3103},{"style":520},[3104],{"type":45,"value":3105},"authModule",{"type":39,"tag":491,"props":3107,"children":3108},{"style":662},[3109],{"type":45,"value":734},{"type":39,"tag":491,"props":3111,"children":3112},{"style":514},[3113],{"type":45,"value":564},{"type":39,"tag":491,"props":3115,"children":3116},{"class":493,"line":1031},[3117,3122,3126,3131,3135,3139,3144,3148,3152,3156,3160,3164,3168,3173,3177,3181,3185],{"type":39,"tag":491,"props":3118,"children":3119},{"style":643},[3120],{"type":45,"value":3121},"  provision",{"type":39,"tag":491,"props":3123,"children":3124},{"style":662},[3125],{"type":45,"value":650},{"type":39,"tag":491,"props":3127,"children":3128},{"style":520},[3129],{"type":45,"value":3130},"storefrontService",{"type":39,"tag":491,"props":3132,"children":3133},{"style":514},[3134],{"type":45,"value":528},{"type":39,"tag":491,"props":3136,"children":3137},{"style":514},[3138],{"type":45,"value":517},{"type":39,"tag":491,"props":3140,"children":3141},{"style":662},[3142],{"type":45,"value":3143}," deps",{"type":39,"tag":491,"props":3145,"children":3146},{"style":514},[3147],{"type":45,"value":227},{"type":39,"tag":491,"props":3149,"children":3150},{"style":514},[3151],{"type":45,"value":517},{"type":39,"tag":491,"props":3153,"children":3154},{"style":662},[3155],{"type":45,"value":2155},{"type":39,"tag":491,"props":3157,"children":3158},{"style":514},[3159],{"type":45,"value":227},{"type":39,"tag":491,"props":3161,"children":3162},{"style":520},[3163],{"type":45,"value":2155},{"type":39,"tag":491,"props":3165,"children":3166},{"style":514},[3167],{"type":45,"value":1113},{"type":39,"tag":491,"props":3169,"children":3170},{"style":520},[3171],{"type":45,"value":3172},"rpc",{"type":39,"tag":491,"props":3174,"children":3175},{"style":514},[3176],{"type":45,"value":538},{"type":39,"tag":491,"props":3178,"children":3179},{"style":514},[3180],{"type":45,"value":538},{"type":39,"tag":491,"props":3182,"children":3183},{"style":662},[3184],{"type":45,"value":734},{"type":39,"tag":491,"props":3186,"children":3187},{"style":514},[3188],{"type":45,"value":564},{"type":39,"tag":491,"props":3190,"children":3191},{"class":493,"line":1071},[3192,3196,3200],{"type":39,"tag":491,"props":3193,"children":3194},{"style":514},[3195],{"type":45,"value":795},{"type":39,"tag":491,"props":3197,"children":3198},{"style":520},[3199],{"type":45,"value":734},{"type":39,"tag":491,"props":3201,"children":3202},{"style":514},[3203],{"type":45,"value":564},{"type":39,"tag":48,"props":3205,"children":3206},{},[3207,3213,3215,3221,3223,3229,3231,3237,3239,3245],{"type":39,"tag":76,"props":3208,"children":3210},{"className":3209},[],[3211],{"type":45,"value":3212},"provision(node, opts?)",{"type":45,"value":3214}," accepts ",{"type":39,"tag":76,"props":3216,"children":3218},{"className":3217},[],[3219],{"type":45,"value":3220},"id",{"type":45,"value":3222}," (defaults to the node's own name),\n",{"type":39,"tag":76,"props":3224,"children":3226},{"className":3225},[],[3227],{"type":45,"value":3228},"deps",{"type":45,"value":3230}," (wire each declared dependency to a provisioned ref or exposed port),\n",{"type":39,"tag":76,"props":3232,"children":3234},{"className":3233},[],[3235],{"type":45,"value":3236},"input",{"type":45,"value":3238}," (the service's input binding — required exactly when it declares an\ninput schema, see § Service input), and ",{"type":39,"tag":76,"props":3240,"children":3242},{"className":3241},[],[3243],{"type":45,"value":3244},"secrets",{"type":45,"value":3246}," (bind a module boundary's\nforwarded secret needs).",{"type":39,"tag":442,"props":3248,"children":3250},{"id":3249},"builds-are-yours",[3251],{"type":45,"value":3252},"Builds are yours",{"type":39,"tag":48,"props":3254,"children":3255},{},[3256,3258,3264,3266,3271,3272,3278,3279,3285,3287,3293],{"type":45,"value":3257},"The framework assembles only what you built — users build, the framework\nassembles. For a plain server process, ",{"type":39,"tag":76,"props":3259,"children":3261},{"className":3260},[],[3262],{"type":45,"value":3263},"entry",{"type":45,"value":3265}," must point at a single\nself-contained ESM file: everything inlined except runtime built-ins (",{"type":39,"tag":76,"props":3267,"children":3269},{"className":3268},[],[3270],{"type":45,"value":1328},{"type":45,"value":804},{"type":39,"tag":76,"props":3273,"children":3275},{"className":3274},[],[3276],{"type":45,"value":3277},"bun:*",{"type":45,"value":162},{"type":39,"tag":76,"props":3280,"children":3282},{"className":3281},[],[3283],{"type":45,"value":3284},"node:*",{"type":45,"value":3286},"), which the deploy VM provides. Deploy copies that one file\nand never ships ",{"type":39,"tag":76,"props":3288,"children":3290},{"className":3289},[],[3291],{"type":45,"value":3292},"node_modules",{"type":45,"value":3294},", so anything left un-inlined fails at boot. Any\nbundler that produces such a file works. With bun:",{"type":39,"tag":480,"props":3296,"children":3300},{"className":3297,"code":3298,"language":3299,"meta":485,"style":485},"language-sh shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","bun build src\u002Fserver.ts --target=bun --outfile dist\u002Fserver.mjs\n","sh",[3301],{"type":39,"tag":76,"props":3302,"children":3303},{"__ignoreMap":485},[3304],{"type":39,"tag":491,"props":3305,"children":3306},{"class":493,"line":494},[3307,3312,3317,3322,3327,3332],{"type":39,"tag":491,"props":3308,"children":3310},{"style":3309},"--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B",[3311],{"type":45,"value":1328},{"type":39,"tag":491,"props":3313,"children":3314},{"style":551},[3315],{"type":45,"value":3316}," build",{"type":39,"tag":491,"props":3318,"children":3319},{"style":551},[3320],{"type":45,"value":3321}," src\u002Fserver.ts",{"type":39,"tag":491,"props":3323,"children":3324},{"style":551},[3325],{"type":45,"value":3326}," --target=bun",{"type":39,"tag":491,"props":3328,"children":3329},{"style":551},[3330],{"type":45,"value":3331}," --outfile",{"type":39,"tag":491,"props":3333,"children":3334},{"style":551},[3335],{"type":45,"value":3336}," dist\u002Fserver.mjs\n",{"type":39,"tag":48,"props":3338,"children":3339},{},[3340],{"type":45,"value":3341},"Two services in one package means two separate builds, one per entry — not one\nmulti-entry build, which would split shared code into a chunk neither output\ncontains.",{"type":39,"tag":48,"props":3343,"children":3344},{},[3345,3347,3353,3355,3360],{"type":45,"value":3346},"If the build emits a directory rather than one file — a server plus the client\nbundle, CSS and images it serves, as Bun's HTML import produces — name the\ndirectory with ",{"type":39,"tag":76,"props":3348,"children":3350},{"className":3349},[],[3351],{"type":45,"value":3352},"dir",{"type":45,"value":3354}," and the booting file inside it with ",{"type":39,"tag":76,"props":3356,"children":3358},{"className":3357},[],[3359],{"type":45,"value":3263},{"type":45,"value":227},{"type":39,"tag":480,"props":3362,"children":3364},{"className":482,"code":3363,"language":484,"meta":485,"style":485},"build: node({ module: import.meta.url, dir: '..\u002Fdist\u002Fserver', entry: 'server.js' })\n",[3365],{"type":39,"tag":76,"props":3366,"children":3367},{"__ignoreMap":485},[3368],{"type":39,"tag":491,"props":3369,"children":3370},{"class":493,"line":494},[3371,3376,3380,3384,3388,3392,3396,3400,3404,3408,3412,3416,3420,3424,3429,3433,3437,3442,3446,3450,3454,3458,3462,3467,3471,3475],{"type":39,"tag":491,"props":3372,"children":3373},{"style":3309},[3374],{"type":45,"value":3375},"build",{"type":39,"tag":491,"props":3377,"children":3378},{"style":514},[3379],{"type":45,"value":227},{"type":39,"tag":491,"props":3381,"children":3382},{"style":643},[3383],{"type":45,"value":1086},{"type":39,"tag":491,"props":3385,"children":3386},{"style":520},[3387],{"type":45,"value":650},{"type":39,"tag":491,"props":3389,"children":3390},{"style":514},[3391],{"type":45,"value":682},{"type":39,"tag":491,"props":3393,"children":3394},{"style":662},[3395],{"type":45,"value":1099},{"type":39,"tag":491,"props":3397,"children":3398},{"style":514},[3399],{"type":45,"value":227},{"type":39,"tag":491,"props":3401,"children":3402},{"style":508},[3403],{"type":45,"value":1108},{"type":39,"tag":491,"props":3405,"children":3406},{"style":514},[3407],{"type":45,"value":1113},{"type":39,"tag":491,"props":3409,"children":3410},{"style":520},[3411],{"type":45,"value":1118},{"type":39,"tag":491,"props":3413,"children":3414},{"style":514},[3415],{"type":45,"value":1113},{"type":39,"tag":491,"props":3417,"children":3418},{"style":520},[3419],{"type":45,"value":1127},{"type":39,"tag":491,"props":3421,"children":3422},{"style":514},[3423],{"type":45,"value":528},{"type":39,"tag":491,"props":3425,"children":3426},{"style":662},[3427],{"type":45,"value":3428}," dir",{"type":39,"tag":491,"props":3430,"children":3431},{"style":514},[3432],{"type":45,"value":227},{"type":39,"tag":491,"props":3434,"children":3435},{"style":514},[3436],{"type":45,"value":548},{"type":39,"tag":491,"props":3438,"children":3439},{"style":551},[3440],{"type":45,"value":3441},"..\u002Fdist\u002Fserver",{"type":39,"tag":491,"props":3443,"children":3444},{"style":514},[3445],{"type":45,"value":559},{"type":39,"tag":491,"props":3447,"children":3448},{"style":514},[3449],{"type":45,"value":528},{"type":39,"tag":491,"props":3451,"children":3452},{"style":662},[3453],{"type":45,"value":1136},{"type":39,"tag":491,"props":3455,"children":3456},{"style":514},[3457],{"type":45,"value":227},{"type":39,"tag":491,"props":3459,"children":3460},{"style":514},[3461],{"type":45,"value":548},{"type":39,"tag":491,"props":3463,"children":3464},{"style":551},[3465],{"type":45,"value":3466},"server.js",{"type":39,"tag":491,"props":3468,"children":3469},{"style":514},[3470],{"type":45,"value":559},{"type":39,"tag":491,"props":3472,"children":3473},{"style":514},[3474],{"type":45,"value":538},{"type":39,"tag":491,"props":3476,"children":3477},{"style":520},[3478],{"type":45,"value":3479},")\n",{"type":39,"tag":48,"props":3481,"children":3482},{},[3483,3488,3490,3495,3497,3502,3504,3510,3512,3517,3519,3524,3525,3531,3533,3538],{"type":39,"tag":76,"props":3484,"children":3486},{"className":3485},[],[3487],{"type":45,"value":3352},{"type":45,"value":3489}," resolves relative to the service module; ",{"type":39,"tag":76,"props":3491,"children":3493},{"className":3492},[],[3494],{"type":45,"value":3263},{"type":45,"value":3496}," resolves inside ",{"type":39,"tag":76,"props":3498,"children":3500},{"className":3499},[],[3501],{"type":45,"value":3352},{"type":45,"value":3503},"\nand may be nested. Deploy copies the tree verbatim and boots the named file,\nso the server must resolve its siblings against ",{"type":39,"tag":76,"props":3505,"children":3507},{"className":3506},[],[3508],{"type":45,"value":3509},"import.meta.url",{"type":45,"value":3511},", not the\nworking directory. Nothing is inferred, and two rules bite: the tree must\ncontain no symlinks (the packager rejects them — assembly fails and names the\nlink), and ",{"type":39,"tag":76,"props":3513,"children":3515},{"className":3514},[],[3516],{"type":45,"value":3263},{"type":45,"value":3518}," must be a file inside ",{"type":39,"tag":76,"props":3520,"children":3522},{"className":3521},[],[3523],{"type":45,"value":3352},{"type":45,"value":74},{"type":39,"tag":76,"props":3526,"children":3528},{"className":3527},[],[3529],{"type":45,"value":3530},"..\u002F",{"type":45,"value":3532}," is an error, not an\nescape). Omit ",{"type":39,"tag":76,"props":3534,"children":3536},{"className":3535},[],[3537],{"type":45,"value":3352},{"type":45,"value":3539}," for the single-file form.",{"type":39,"tag":48,"props":3541,"children":3542},{},[3543,3545,3550,3552,3558,3560,3566],{"type":45,"value":3544},"For Next.js, ",{"type":39,"tag":76,"props":3546,"children":3548},{"className":3547},[],[3549],{"type":45,"value":168},{"type":45,"value":3551}," with ",{"type":39,"tag":76,"props":3553,"children":3555},{"className":3554},[],[3556],{"type":45,"value":3557},"output: 'standalone'",{"type":45,"value":3559}," is the whole build;\n",{"type":39,"tag":76,"props":3561,"children":3563},{"className":3562},[],[3564],{"type":45,"value":3565},"nextjs({ module, appDir })",{"type":45,"value":3567}," tells the deploy where the app root is.",{"type":39,"tag":48,"props":3569,"children":3570},{},[3571,3573,3578],{"type":45,"value":3572},"Always build before deploying — ",{"type":39,"tag":76,"props":3574,"children":3576},{"className":3575},[],[3577],{"type":45,"value":176},{"type":45,"value":3579}," does not build for\nyou.",{"type":39,"tag":442,"props":3581,"children":3583},{"id":3582},"deploy-config",[3584],{"type":45,"value":3585},"Deploy config",{"type":39,"tag":48,"props":3587,"children":3588},{},[3589,3595,3597,3603,3605,3610,3612,3618],{"type":39,"tag":76,"props":3590,"children":3592},{"className":3591},[],[3593],{"type":45,"value":3594},"prisma-composer.config.ts",{"type":45,"value":3596}," sits next to ",{"type":39,"tag":76,"props":3598,"children":3600},{"className":3599},[],[3601],{"type":45,"value":3602},"module.ts",{"type":45,"value":3604},". It is read only by\n",{"type":39,"tag":76,"props":3606,"children":3608},{"className":3607},[],[3609],{"type":45,"value":176},{"type":45,"value":3611},"\u002F",{"type":39,"tag":76,"props":3613,"children":3615},{"className":3614},[],[3616],{"type":45,"value":3617},"destroy",{"type":45,"value":3619},", never imported by app code:",{"type":39,"tag":480,"props":3621,"children":3623},{"className":482,"code":3622,"language":484,"meta":485,"style":485},"\u002F\u002F prisma-composer.config.ts\nimport { defineConfig } from '@prisma\u002Fcomposer\u002Fconfig';\nimport { nodeBuild } from '@prisma\u002Fcomposer\u002Fnode\u002Fcontrol';\nimport { prismaCloud, prismaState } from '@prisma\u002Fcomposer-prisma-cloud\u002Fcontrol';\n\nexport default defineConfig({\n  extensions: [prismaCloud(), nodeBuild()],\n  state: () => prismaState(), \u002F\u002F deploy state, in its own database on the stage's branch\n});\n",[3624],{"type":39,"tag":76,"props":3625,"children":3626},{"__ignoreMap":485},[3627,3635,3676,3717,3767,3774,3797,3840,3878],{"type":39,"tag":491,"props":3628,"children":3629},{"class":493,"line":494},[3630],{"type":39,"tag":491,"props":3631,"children":3632},{"style":498},[3633],{"type":45,"value":3634},"\u002F\u002F prisma-composer.config.ts\n",{"type":39,"tag":491,"props":3636,"children":3637},{"class":493,"line":504},[3638,3642,3646,3651,3655,3659,3663,3668,3672],{"type":39,"tag":491,"props":3639,"children":3640},{"style":508},[3641],{"type":45,"value":511},{"type":39,"tag":491,"props":3643,"children":3644},{"style":514},[3645],{"type":45,"value":517},{"type":39,"tag":491,"props":3647,"children":3648},{"style":520},[3649],{"type":45,"value":3650}," defineConfig",{"type":39,"tag":491,"props":3652,"children":3653},{"style":514},[3654],{"type":45,"value":538},{"type":39,"tag":491,"props":3656,"children":3657},{"style":508},[3658],{"type":45,"value":543},{"type":39,"tag":491,"props":3660,"children":3661},{"style":514},[3662],{"type":45,"value":548},{"type":39,"tag":491,"props":3664,"children":3665},{"style":551},[3666],{"type":45,"value":3667},"@prisma\u002Fcomposer\u002Fconfig",{"type":39,"tag":491,"props":3669,"children":3670},{"style":514},[3671],{"type":45,"value":559},{"type":39,"tag":491,"props":3673,"children":3674},{"style":514},[3675],{"type":45,"value":564},{"type":39,"tag":491,"props":3677,"children":3678},{"class":493,"line":23},[3679,3683,3687,3692,3696,3700,3704,3709,3713],{"type":39,"tag":491,"props":3680,"children":3681},{"style":508},[3682],{"type":45,"value":511},{"type":39,"tag":491,"props":3684,"children":3685},{"style":514},[3686],{"type":45,"value":517},{"type":39,"tag":491,"props":3688,"children":3689},{"style":520},[3690],{"type":45,"value":3691}," nodeBuild",{"type":39,"tag":491,"props":3693,"children":3694},{"style":514},[3695],{"type":45,"value":538},{"type":39,"tag":491,"props":3697,"children":3698},{"style":508},[3699],{"type":45,"value":543},{"type":39,"tag":491,"props":3701,"children":3702},{"style":514},[3703],{"type":45,"value":548},{"type":39,"tag":491,"props":3705,"children":3706},{"style":551},[3707],{"type":45,"value":3708},"@prisma\u002Fcomposer\u002Fnode\u002Fcontrol",{"type":39,"tag":491,"props":3710,"children":3711},{"style":514},[3712],{"type":45,"value":559},{"type":39,"tag":491,"props":3714,"children":3715},{"style":514},[3716],{"type":45,"value":564},{"type":39,"tag":491,"props":3718,"children":3719},{"class":493,"line":608},[3720,3724,3728,3733,3737,3742,3746,3750,3754,3759,3763],{"type":39,"tag":491,"props":3721,"children":3722},{"style":508},[3723],{"type":45,"value":511},{"type":39,"tag":491,"props":3725,"children":3726},{"style":514},[3727],{"type":45,"value":517},{"type":39,"tag":491,"props":3729,"children":3730},{"style":520},[3731],{"type":45,"value":3732}," prismaCloud",{"type":39,"tag":491,"props":3734,"children":3735},{"style":514},[3736],{"type":45,"value":528},{"type":39,"tag":491,"props":3738,"children":3739},{"style":520},[3740],{"type":45,"value":3741}," prismaState",{"type":39,"tag":491,"props":3743,"children":3744},{"style":514},[3745],{"type":45,"value":538},{"type":39,"tag":491,"props":3747,"children":3748},{"style":508},[3749],{"type":45,"value":543},{"type":39,"tag":491,"props":3751,"children":3752},{"style":514},[3753],{"type":45,"value":548},{"type":39,"tag":491,"props":3755,"children":3756},{"style":551},[3757],{"type":45,"value":3758},"@prisma\u002Fcomposer-prisma-cloud\u002Fcontrol",{"type":39,"tag":491,"props":3760,"children":3761},{"style":514},[3762],{"type":45,"value":559},{"type":39,"tag":491,"props":3764,"children":3765},{"style":514},[3766],{"type":45,"value":564},{"type":39,"tag":491,"props":3768,"children":3769},{"class":493,"line":618},[3770],{"type":39,"tag":491,"props":3771,"children":3772},{"emptyLinePlaceholder":612},[3773],{"type":45,"value":615},{"type":39,"tag":491,"props":3775,"children":3776},{"class":493,"line":658},[3777,3781,3785,3789,3793],{"type":39,"tag":491,"props":3778,"children":3779},{"style":508},[3780],{"type":45,"value":624},{"type":39,"tag":491,"props":3782,"children":3783},{"style":508},[3784],{"type":45,"value":988},{"type":39,"tag":491,"props":3786,"children":3787},{"style":643},[3788],{"type":45,"value":3650},{"type":39,"tag":491,"props":3790,"children":3791},{"style":520},[3792],{"type":45,"value":650},{"type":39,"tag":491,"props":3794,"children":3795},{"style":514},[3796],{"type":45,"value":655},{"type":39,"tag":491,"props":3798,"children":3799},{"class":493,"line":807},[3800,3805,3809,3814,3819,3823,3827,3831,3836],{"type":39,"tag":491,"props":3801,"children":3802},{"style":662},[3803],{"type":45,"value":3804},"  extensions",{"type":39,"tag":491,"props":3806,"children":3807},{"style":514},[3808],{"type":45,"value":227},{"type":39,"tag":491,"props":3810,"children":3811},{"style":520},[3812],{"type":45,"value":3813}," [",{"type":39,"tag":491,"props":3815,"children":3816},{"style":643},[3817],{"type":45,"value":3818},"prismaCloud",{"type":39,"tag":491,"props":3820,"children":3821},{"style":520},[3822],{"type":45,"value":1421},{"type":39,"tag":491,"props":3824,"children":3825},{"style":514},[3826],{"type":45,"value":528},{"type":39,"tag":491,"props":3828,"children":3829},{"style":643},[3830],{"type":45,"value":3691},{"type":39,"tag":491,"props":3832,"children":3833},{"style":520},[3834],{"type":45,"value":3835},"()]",{"type":39,"tag":491,"props":3837,"children":3838},{"style":514},[3839],{"type":45,"value":804},{"type":39,"tag":491,"props":3841,"children":3842},{"class":493,"line":1031},[3843,3848,3852,3857,3861,3865,3869,3873],{"type":39,"tag":491,"props":3844,"children":3845},{"style":643},[3846],{"type":45,"value":3847},"  state",{"type":39,"tag":491,"props":3849,"children":3850},{"style":514},[3851],{"type":45,"value":227},{"type":39,"tag":491,"props":3853,"children":3854},{"style":514},[3855],{"type":45,"value":3856}," ()",{"type":39,"tag":491,"props":3858,"children":3859},{"style":627},[3860],{"type":45,"value":1679},{"type":39,"tag":491,"props":3862,"children":3863},{"style":643},[3864],{"type":45,"value":3741},{"type":39,"tag":491,"props":3866,"children":3867},{"style":520},[3868],{"type":45,"value":1421},{"type":39,"tag":491,"props":3870,"children":3871},{"style":514},[3872],{"type":45,"value":528},{"type":39,"tag":491,"props":3874,"children":3875},{"style":498},[3876],{"type":45,"value":3877}," \u002F\u002F deploy state, in its own database on the stage's branch\n",{"type":39,"tag":491,"props":3879,"children":3880},{"class":493,"line":1071},[3881,3885,3889],{"type":39,"tag":491,"props":3882,"children":3883},{"style":514},[3884],{"type":45,"value":795},{"type":39,"tag":491,"props":3886,"children":3887},{"style":520},[3888],{"type":45,"value":734},{"type":39,"tag":491,"props":3890,"children":3891},{"style":514},[3892],{"type":45,"value":564},{"type":39,"tag":48,"props":3894,"children":3895},{},[3896,3898,3904,3906,3912,3914,3920],{"type":45,"value":3897},"Add ",{"type":39,"tag":76,"props":3899,"children":3901},{"className":3900},[],[3902],{"type":45,"value":3903},"nextjsBuild()",{"type":45,"value":3905}," from ",{"type":39,"tag":76,"props":3907,"children":3909},{"className":3908},[],[3910],{"type":45,"value":3911},"@prisma\u002Fcomposer\u002Fnextjs\u002Fcontrol",{"type":45,"value":3913}," to ",{"type":39,"tag":76,"props":3915,"children":3917},{"className":3916},[],[3918],{"type":45,"value":3919},"extensions",{"type":45,"value":3921},"\nwhen the app contains a Next.js service.",{"type":39,"tag":442,"props":3923,"children":3925},{"id":3924},"databases",[3926],{"type":45,"value":3927},"Databases",{"type":39,"tag":48,"props":3929,"children":3930},{},[3931],{"type":45,"value":3932},"Two kinds of Postgres dependency:",{"type":39,"tag":48,"props":3934,"children":3935},{},[3936,3944,3946,3952],{"type":39,"tag":54,"props":3937,"children":3938},{},[3939],{"type":39,"tag":76,"props":3940,"children":3942},{"className":3941},[],[3943],{"type":45,"value":95},{"type":45,"value":3945}," — the binding is ",{"type":39,"tag":76,"props":3947,"children":3949},{"className":3948},[],[3950],{"type":45,"value":3951},"{ url }",{"type":45,"value":3953}," and the app owns its client.\nConstruct it in your server entry, as in the auth example above.",{"type":39,"tag":48,"props":3955,"children":3956},{},[3957,3966,3968,3973,3975,3981,3983,3989,3991,3997],{"type":39,"tag":54,"props":3958,"children":3959},{},[3960],{"type":39,"tag":76,"props":3961,"children":3963},{"className":3962},[],[3964],{"type":45,"value":3965},"pnPostgres(...)",{"type":45,"value":3967}," — a Prisma Next-typed database: ",{"type":39,"tag":76,"props":3969,"children":3971},{"className":3970},[],[3972],{"type":45,"value":1230},{"type":45,"value":3974},"\nreturns the typed client the framework constructs from your data contract, so\nqueries like ",{"type":39,"tag":76,"props":3976,"children":3978},{"className":3977},[],[3979],{"type":45,"value":3980},"db.orm.public.Product.all()",{"type":45,"value":3982}," are compile-time checked. The\ncontract is emitted from ",{"type":39,"tag":76,"props":3984,"children":3986},{"className":3985},[],[3987],{"type":45,"value":3988},"contract.prisma",{"type":45,"value":3990}," by ",{"type":39,"tag":76,"props":3992,"children":3994},{"className":3993},[],[3995],{"type":45,"value":3996},"prisma-next contract emit",{"type":45,"value":3998}," and\nwrapped once, referenced by both ends:",{"type":39,"tag":480,"props":4000,"children":4002},{"className":482,"code":4001,"language":484,"meta":485,"style":485},"\u002F\u002F src\u002Fdata.ts — the ONE value both ends reference\nimport { pnContract } from '@prisma\u002Fcomposer-prisma-cloud\u002Fprisma-next';\nimport type { Contract } from '..\u002Fcontract.d.ts';\nimport contractJson from '..\u002Fcontract.json' with { type: 'json' };\n\nexport const catalogData = pnContract\u003CContract>(contractJson);\n",[4003],{"type":39,"tag":76,"props":4004,"children":4005},{"__ignoreMap":485},[4006,4014,4055,4100,4164,4171],{"type":39,"tag":491,"props":4007,"children":4008},{"class":493,"line":494},[4009],{"type":39,"tag":491,"props":4010,"children":4011},{"style":498},[4012],{"type":45,"value":4013},"\u002F\u002F src\u002Fdata.ts — the ONE value both ends reference\n",{"type":39,"tag":491,"props":4015,"children":4016},{"class":493,"line":504},[4017,4021,4025,4030,4034,4038,4042,4047,4051],{"type":39,"tag":491,"props":4018,"children":4019},{"style":508},[4020],{"type":45,"value":511},{"type":39,"tag":491,"props":4022,"children":4023},{"style":514},[4024],{"type":45,"value":517},{"type":39,"tag":491,"props":4026,"children":4027},{"style":520},[4028],{"type":45,"value":4029}," pnContract",{"type":39,"tag":491,"props":4031,"children":4032},{"style":514},[4033],{"type":45,"value":538},{"type":39,"tag":491,"props":4035,"children":4036},{"style":508},[4037],{"type":45,"value":543},{"type":39,"tag":491,"props":4039,"children":4040},{"style":514},[4041],{"type":45,"value":548},{"type":39,"tag":491,"props":4043,"children":4044},{"style":551},[4045],{"type":45,"value":4046},"@prisma\u002Fcomposer-prisma-cloud\u002Fprisma-next",{"type":39,"tag":491,"props":4048,"children":4049},{"style":514},[4050],{"type":45,"value":559},{"type":39,"tag":491,"props":4052,"children":4053},{"style":514},[4054],{"type":45,"value":564},{"type":39,"tag":491,"props":4056,"children":4057},{"class":493,"line":23},[4058,4062,4066,4070,4075,4079,4083,4087,4092,4096],{"type":39,"tag":491,"props":4059,"children":4060},{"style":508},[4061],{"type":45,"value":511},{"type":39,"tag":491,"props":4063,"children":4064},{"style":508},[4065],{"type":45,"value":580},{"type":39,"tag":491,"props":4067,"children":4068},{"style":514},[4069],{"type":45,"value":517},{"type":39,"tag":491,"props":4071,"children":4072},{"style":520},[4073],{"type":45,"value":4074}," Contract",{"type":39,"tag":491,"props":4076,"children":4077},{"style":514},[4078],{"type":45,"value":538},{"type":39,"tag":491,"props":4080,"children":4081},{"style":508},[4082],{"type":45,"value":543},{"type":39,"tag":491,"props":4084,"children":4085},{"style":514},[4086],{"type":45,"value":548},{"type":39,"tag":491,"props":4088,"children":4089},{"style":551},[4090],{"type":45,"value":4091},"..\u002Fcontract.d.ts",{"type":39,"tag":491,"props":4093,"children":4094},{"style":514},[4095],{"type":45,"value":559},{"type":39,"tag":491,"props":4097,"children":4098},{"style":514},[4099],{"type":45,"value":564},{"type":39,"tag":491,"props":4101,"children":4102},{"class":493,"line":608},[4103,4107,4112,4116,4120,4125,4129,4134,4138,4142,4146,4150,4155,4159],{"type":39,"tag":491,"props":4104,"children":4105},{"style":508},[4106],{"type":45,"value":511},{"type":39,"tag":491,"props":4108,"children":4109},{"style":520},[4110],{"type":45,"value":4111}," contractJson ",{"type":39,"tag":491,"props":4113,"children":4114},{"style":508},[4115],{"type":45,"value":862},{"type":39,"tag":491,"props":4117,"children":4118},{"style":514},[4119],{"type":45,"value":548},{"type":39,"tag":491,"props":4121,"children":4122},{"style":551},[4123],{"type":45,"value":4124},"..\u002Fcontract.json",{"type":39,"tag":491,"props":4126,"children":4127},{"style":514},[4128],{"type":45,"value":559},{"type":39,"tag":491,"props":4130,"children":4131},{"style":508},[4132],{"type":45,"value":4133}," with",{"type":39,"tag":491,"props":4135,"children":4136},{"style":514},[4137],{"type":45,"value":517},{"type":39,"tag":491,"props":4139,"children":4140},{"style":662},[4141],{"type":45,"value":580},{"type":39,"tag":491,"props":4143,"children":4144},{"style":514},[4145],{"type":45,"value":227},{"type":39,"tag":491,"props":4147,"children":4148},{"style":514},[4149],{"type":45,"value":548},{"type":39,"tag":491,"props":4151,"children":4152},{"style":551},[4153],{"type":45,"value":4154},"json",{"type":39,"tag":491,"props":4156,"children":4157},{"style":514},[4158],{"type":45,"value":559},{"type":39,"tag":491,"props":4160,"children":4161},{"style":514},[4162],{"type":45,"value":4163}," };\n",{"type":39,"tag":491,"props":4165,"children":4166},{"class":493,"line":618},[4167],{"type":39,"tag":491,"props":4168,"children":4169},{"emptyLinePlaceholder":612},[4170],{"type":45,"value":615},{"type":39,"tag":491,"props":4172,"children":4173},{"class":493,"line":658},[4174,4178,4182,4187,4191,4195,4200,4205,4209,4214],{"type":39,"tag":491,"props":4175,"children":4176},{"style":508},[4177],{"type":45,"value":624},{"type":39,"tag":491,"props":4179,"children":4180},{"style":627},[4181],{"type":45,"value":630},{"type":39,"tag":491,"props":4183,"children":4184},{"style":520},[4185],{"type":45,"value":4186}," catalogData ",{"type":39,"tag":491,"props":4188,"children":4189},{"style":514},[4190],{"type":45,"value":640},{"type":39,"tag":491,"props":4192,"children":4193},{"style":643},[4194],{"type":45,"value":4029},{"type":39,"tag":491,"props":4196,"children":4197},{"style":514},[4198],{"type":45,"value":4199},"\u003C",{"type":39,"tag":491,"props":4201,"children":4202},{"style":3309},[4203],{"type":45,"value":4204},"Contract",{"type":39,"tag":491,"props":4206,"children":4207},{"style":514},[4208],{"type":45,"value":1713},{"type":39,"tag":491,"props":4210,"children":4211},{"style":520},[4212],{"type":45,"value":4213},"(contractJson)",{"type":39,"tag":491,"props":4215,"children":4216},{"style":514},[4217],{"type":45,"value":564},{"type":39,"tag":48,"props":4219,"children":4220},{},[4221,4223,4229,4231,4237,4239,4245],{"type":45,"value":4222},"The dependency end is ",{"type":39,"tag":76,"props":4224,"children":4226},{"className":4225},[],[4227],{"type":45,"value":4228},"deps: { db: pnPostgres(catalogData) }",{"type":45,"value":4230},". The resource\nend (inside the module that owns the database) also names the\n",{"type":39,"tag":76,"props":4232,"children":4234},{"className":4233},[],[4235],{"type":45,"value":4236},"prisma-next.config.ts",{"type":45,"value":4238}," path, which the deploy's migration step loads to find\n",{"type":39,"tag":76,"props":4240,"children":4242},{"className":4241},[],[4243],{"type":45,"value":4244},"migrations\u002F",{"type":45,"value":4246}," — migrations are applied at deploy, before the service starts:",{"type":39,"tag":480,"props":4248,"children":4250},{"className":482,"code":4249,"language":484,"meta":485,"style":485},"const db = provision(\n  pnPostgres({ name: 'database', contract: catalogData, config: '.\u002Fprisma-next.config.ts' }),\n);\n",[4251],{"type":39,"tag":76,"props":4252,"children":4253},{"__ignoreMap":485},[4254,4278,4371],{"type":39,"tag":491,"props":4255,"children":4256},{"class":493,"line":494},[4257,4261,4265,4269,4273],{"type":39,"tag":491,"props":4258,"children":4259},{"style":627},[4260],{"type":45,"value":1384},{"type":39,"tag":491,"props":4262,"children":4263},{"style":520},[4264],{"type":45,"value":1393},{"type":39,"tag":491,"props":4266,"children":4267},{"style":514},[4268],{"type":45,"value":640},{"type":39,"tag":491,"props":4270,"children":4271},{"style":643},[4272],{"type":45,"value":3065},{"type":39,"tag":491,"props":4274,"children":4275},{"style":520},[4276],{"type":45,"value":4277},"(\n",{"type":39,"tag":491,"props":4279,"children":4280},{"class":493,"line":504},[4281,4286,4290,4294,4299,4303,4307,4312,4316,4320,4324,4328,4333,4337,4342,4346,4350,4355,4359,4363,4367],{"type":39,"tag":491,"props":4282,"children":4283},{"style":643},[4284],{"type":45,"value":4285},"  pnPostgres",{"type":39,"tag":491,"props":4287,"children":4288},{"style":520},[4289],{"type":45,"value":650},{"type":39,"tag":491,"props":4291,"children":4292},{"style":514},[4293],{"type":45,"value":682},{"type":39,"tag":491,"props":4295,"children":4296},{"style":662},[4297],{"type":45,"value":4298}," name",{"type":39,"tag":491,"props":4300,"children":4301},{"style":514},[4302],{"type":45,"value":227},{"type":39,"tag":491,"props":4304,"children":4305},{"style":514},[4306],{"type":45,"value":548},{"type":39,"tag":491,"props":4308,"children":4309},{"style":551},[4310],{"type":45,"value":4311},"database",{"type":39,"tag":491,"props":4313,"children":4314},{"style":514},[4315],{"type":45,"value":559},{"type":39,"tag":491,"props":4317,"children":4318},{"style":514},[4319],{"type":45,"value":528},{"type":39,"tag":491,"props":4321,"children":4322},{"style":662},[4323],{"type":45,"value":523},{"type":39,"tag":491,"props":4325,"children":4326},{"style":514},[4327],{"type":45,"value":227},{"type":39,"tag":491,"props":4329,"children":4330},{"style":520},[4331],{"type":45,"value":4332}," catalogData",{"type":39,"tag":491,"props":4334,"children":4335},{"style":514},[4336],{"type":45,"value":528},{"type":39,"tag":491,"props":4338,"children":4339},{"style":662},[4340],{"type":45,"value":4341}," config",{"type":39,"tag":491,"props":4343,"children":4344},{"style":514},[4345],{"type":45,"value":227},{"type":39,"tag":491,"props":4347,"children":4348},{"style":514},[4349],{"type":45,"value":548},{"type":39,"tag":491,"props":4351,"children":4352},{"style":551},[4353],{"type":45,"value":4354},".\u002Fprisma-next.config.ts",{"type":39,"tag":491,"props":4356,"children":4357},{"style":514},[4358],{"type":45,"value":559},{"type":39,"tag":491,"props":4360,"children":4361},{"style":514},[4362],{"type":45,"value":538},{"type":39,"tag":491,"props":4364,"children":4365},{"style":520},[4366],{"type":45,"value":734},{"type":39,"tag":491,"props":4368,"children":4369},{"style":514},[4370],{"type":45,"value":804},{"type":39,"tag":491,"props":4372,"children":4373},{"class":493,"line":23},[4374,4378],{"type":39,"tag":491,"props":4375,"children":4376},{"style":520},[4377],{"type":45,"value":734},{"type":39,"tag":491,"props":4379,"children":4380},{"style":514},[4381],{"type":45,"value":564},{"type":39,"tag":48,"props":4383,"children":4384},{},[4385,4386,4392],{"type":45,"value":650},{"type":39,"tag":76,"props":4387,"children":4389},{"className":4388},[],[4390],{"type":45,"value":4391},"pnPostgres",{"type":45,"value":4393}," is both ends: the contract alone is the dependency end; the\noptions object is the resource end.)",{"type":39,"tag":48,"props":4395,"children":4396},{},[4397,4399,4405],{"type":45,"value":4398},"See ",{"type":39,"tag":76,"props":4400,"children":4402},{"className":4401},[],[4403],{"type":45,"value":4404},"examples\u002Fstore\u002Fmodules\u002Fcatalog",{"type":45,"value":4406}," in the prisma\u002Fcomposer repo for the\ncomplete pattern.",{"type":39,"tag":442,"props":4408,"children":4410},{"id":4409},"object-storage",[4411],{"type":45,"value":4412},"Object Storage",{"type":39,"tag":48,"props":4414,"children":4415},{},[4416,4422,4424,4429],{"type":39,"tag":76,"props":4417,"children":4419},{"className":4418},[],[4420],{"type":45,"value":4421},"bucket",{"type":45,"value":4423}," is a raw S3-compatible object-store bucket, imported alongside ",{"type":39,"tag":76,"props":4425,"children":4427},{"className":4426},[],[4428],{"type":45,"value":382},{"type":45,"value":227},{"type":39,"tag":480,"props":4431,"children":4433},{"className":482,"code":4432,"language":484,"meta":485,"style":485},"import { bucket, compute } from '@prisma\u002Fcomposer-prisma-cloud';\n\n\u002F\u002F service.ts — dependency end: receives { url, bucket, accessKeyId, secretAccessKey }\nexport default compute({ name: 'uploads', deps: { store: bucket() } });\n\n\u002F\u002F module.ts — resource end: provisions the bucket and mints a keypair\nconst store = provision(bucket({ name: 'uploads' }));\nprovision(uploadsService, { deps: { store } });\n",[4434],{"type":39,"tag":76,"props":4435,"children":4436},{"__ignoreMap":485},[4437,4485,4492,4500,4593,4600,4608,4677],{"type":39,"tag":491,"props":4438,"children":4439},{"class":493,"line":494},[4440,4444,4448,4453,4457,4461,4465,4469,4473,4477,4481],{"type":39,"tag":491,"props":4441,"children":4442},{"style":508},[4443],{"type":45,"value":511},{"type":39,"tag":491,"props":4445,"children":4446},{"style":514},[4447],{"type":45,"value":517},{"type":39,"tag":491,"props":4449,"children":4450},{"style":520},[4451],{"type":45,"value":4452}," bucket",{"type":39,"tag":491,"props":4454,"children":4455},{"style":514},[4456],{"type":45,"value":528},{"type":39,"tag":491,"props":4458,"children":4459},{"style":520},[4460],{"type":45,"value":895},{"type":39,"tag":491,"props":4462,"children":4463},{"style":514},[4464],{"type":45,"value":538},{"type":39,"tag":491,"props":4466,"children":4467},{"style":508},[4468],{"type":45,"value":543},{"type":39,"tag":491,"props":4470,"children":4471},{"style":514},[4472],{"type":45,"value":548},{"type":39,"tag":491,"props":4474,"children":4475},{"style":551},[4476],{"type":45,"value":364},{"type":39,"tag":491,"props":4478,"children":4479},{"style":514},[4480],{"type":45,"value":559},{"type":39,"tag":491,"props":4482,"children":4483},{"style":514},[4484],{"type":45,"value":564},{"type":39,"tag":491,"props":4486,"children":4487},{"class":493,"line":504},[4488],{"type":39,"tag":491,"props":4489,"children":4490},{"emptyLinePlaceholder":612},[4491],{"type":45,"value":615},{"type":39,"tag":491,"props":4493,"children":4494},{"class":493,"line":23},[4495],{"type":39,"tag":491,"props":4496,"children":4497},{"style":498},[4498],{"type":45,"value":4499},"\u002F\u002F service.ts — dependency end: receives { url, bucket, accessKeyId, secretAccessKey }\n",{"type":39,"tag":491,"props":4501,"children":4502},{"class":493,"line":608},[4503,4507,4511,4515,4519,4523,4527,4531,4535,4540,4544,4548,4552,4556,4560,4565,4569,4573,4577,4581,4585,4589],{"type":39,"tag":491,"props":4504,"children":4505},{"style":508},[4506],{"type":45,"value":624},{"type":39,"tag":491,"props":4508,"children":4509},{"style":508},[4510],{"type":45,"value":988},{"type":39,"tag":491,"props":4512,"children":4513},{"style":643},[4514],{"type":45,"value":895},{"type":39,"tag":491,"props":4516,"children":4517},{"style":520},[4518],{"type":45,"value":650},{"type":39,"tag":491,"props":4520,"children":4521},{"style":514},[4522],{"type":45,"value":682},{"type":39,"tag":491,"props":4524,"children":4525},{"style":662},[4526],{"type":45,"value":4298},{"type":39,"tag":491,"props":4528,"children":4529},{"style":514},[4530],{"type":45,"value":227},{"type":39,"tag":491,"props":4532,"children":4533},{"style":514},[4534],{"type":45,"value":548},{"type":39,"tag":491,"props":4536,"children":4537},{"style":551},[4538],{"type":45,"value":4539},"uploads",{"type":39,"tag":491,"props":4541,"children":4542},{"style":514},[4543],{"type":45,"value":559},{"type":39,"tag":491,"props":4545,"children":4546},{"style":514},[4547],{"type":45,"value":528},{"type":39,"tag":491,"props":4549,"children":4550},{"style":662},[4551],{"type":45,"value":3143},{"type":39,"tag":491,"props":4553,"children":4554},{"style":514},[4555],{"type":45,"value":227},{"type":39,"tag":491,"props":4557,"children":4558},{"style":514},[4559],{"type":45,"value":517},{"type":39,"tag":491,"props":4561,"children":4562},{"style":662},[4563],{"type":45,"value":4564}," store",{"type":39,"tag":491,"props":4566,"children":4567},{"style":514},[4568],{"type":45,"value":227},{"type":39,"tag":491,"props":4570,"children":4571},{"style":643},[4572],{"type":45,"value":4452},{"type":39,"tag":491,"props":4574,"children":4575},{"style":520},[4576],{"type":45,"value":1063},{"type":39,"tag":491,"props":4578,"children":4579},{"style":514},[4580],{"type":45,"value":795},{"type":39,"tag":491,"props":4582,"children":4583},{"style":514},[4584],{"type":45,"value":538},{"type":39,"tag":491,"props":4586,"children":4587},{"style":520},[4588],{"type":45,"value":734},{"type":39,"tag":491,"props":4590,"children":4591},{"style":514},[4592],{"type":45,"value":564},{"type":39,"tag":491,"props":4594,"children":4595},{"class":493,"line":618},[4596],{"type":39,"tag":491,"props":4597,"children":4598},{"emptyLinePlaceholder":612},[4599],{"type":45,"value":615},{"type":39,"tag":491,"props":4601,"children":4602},{"class":493,"line":658},[4603],{"type":39,"tag":491,"props":4604,"children":4605},{"style":498},[4606],{"type":45,"value":4607},"\u002F\u002F module.ts — resource end: provisions the bucket and mints a keypair\n",{"type":39,"tag":491,"props":4609,"children":4610},{"class":493,"line":807},[4611,4615,4620,4624,4628,4632,4636,4640,4644,4648,4652,4656,4660,4664,4668,4673],{"type":39,"tag":491,"props":4612,"children":4613},{"style":627},[4614],{"type":45,"value":1384},{"type":39,"tag":491,"props":4616,"children":4617},{"style":520},[4618],{"type":45,"value":4619}," store ",{"type":39,"tag":491,"props":4621,"children":4622},{"style":514},[4623],{"type":45,"value":640},{"type":39,"tag":491,"props":4625,"children":4626},{"style":643},[4627],{"type":45,"value":3065},{"type":39,"tag":491,"props":4629,"children":4630},{"style":520},[4631],{"type":45,"value":650},{"type":39,"tag":491,"props":4633,"children":4634},{"style":643},[4635],{"type":45,"value":4421},{"type":39,"tag":491,"props":4637,"children":4638},{"style":520},[4639],{"type":45,"value":650},{"type":39,"tag":491,"props":4641,"children":4642},{"style":514},[4643],{"type":45,"value":682},{"type":39,"tag":491,"props":4645,"children":4646},{"style":662},[4647],{"type":45,"value":4298},{"type":39,"tag":491,"props":4649,"children":4650},{"style":514},[4651],{"type":45,"value":227},{"type":39,"tag":491,"props":4653,"children":4654},{"style":514},[4655],{"type":45,"value":548},{"type":39,"tag":491,"props":4657,"children":4658},{"style":551},[4659],{"type":45,"value":4539},{"type":39,"tag":491,"props":4661,"children":4662},{"style":514},[4663],{"type":45,"value":559},{"type":39,"tag":491,"props":4665,"children":4666},{"style":514},[4667],{"type":45,"value":538},{"type":39,"tag":491,"props":4669,"children":4670},{"style":520},[4671],{"type":45,"value":4672},"))",{"type":39,"tag":491,"props":4674,"children":4675},{"style":514},[4676],{"type":45,"value":564},{"type":39,"tag":491,"props":4678,"children":4679},{"class":493,"line":1031},[4680,4685,4690,4694,4698,4702,4706,4710,4714,4718,4722,4726],{"type":39,"tag":491,"props":4681,"children":4682},{"style":643},[4683],{"type":45,"value":4684},"provision",{"type":39,"tag":491,"props":4686,"children":4687},{"style":520},[4688],{"type":45,"value":4689},"(uploadsService",{"type":39,"tag":491,"props":4691,"children":4692},{"style":514},[4693],{"type":45,"value":528},{"type":39,"tag":491,"props":4695,"children":4696},{"style":514},[4697],{"type":45,"value":517},{"type":39,"tag":491,"props":4699,"children":4700},{"style":662},[4701],{"type":45,"value":3143},{"type":39,"tag":491,"props":4703,"children":4704},{"style":514},[4705],{"type":45,"value":227},{"type":39,"tag":491,"props":4707,"children":4708},{"style":514},[4709],{"type":45,"value":517},{"type":39,"tag":491,"props":4711,"children":4712},{"style":520},[4713],{"type":45,"value":4619},{"type":39,"tag":491,"props":4715,"children":4716},{"style":514},[4717],{"type":45,"value":795},{"type":39,"tag":491,"props":4719,"children":4720},{"style":514},[4721],{"type":45,"value":538},{"type":39,"tag":491,"props":4723,"children":4724},{"style":520},[4725],{"type":45,"value":734},{"type":39,"tag":491,"props":4727,"children":4728},{"style":514},[4729],{"type":45,"value":564},{"type":39,"tag":48,"props":4731,"children":4732},{},[4733,4735,4741,4743,4748,4750,4755,4757,4762],{"type":45,"value":4734},"Use any S3-compatible client with the binding: the shape matches the standard S3\nconfig and is also compatible with the ",{"type":39,"tag":76,"props":4736,"children":4738},{"className":4737},[],[4739],{"type":45,"value":4740},"s3()",{"type":45,"value":4742}," dependency from ",{"type":39,"tag":76,"props":4744,"children":4746},{"className":4745},[],[4747],{"type":45,"value":424},{"type":45,"value":4749},", so any\nservice wired to ",{"type":39,"tag":76,"props":4751,"children":4753},{"className":4752},[],[4754],{"type":45,"value":4740},{"type":45,"value":4756}," can be rewired to a ",{"type":39,"tag":76,"props":4758,"children":4760},{"className":4759},[],[4761],{"type":45,"value":4421},{"type":45,"value":4763}," resource without changing\nthe service declaration.",{"type":39,"tag":442,"props":4765,"children":4767},{"id":4766},"reusable-modules",[4768],{"type":45,"value":4769},"Reusable Modules",{"type":39,"tag":48,"props":4771,"children":4772},{},[4773],{"type":45,"value":4774},"A Module is the unit of reuse: it owns its internals (its database, its\nservices) and exposes only typed ports. Declare the boundary in the second\nargument; wire internals in the builder; return the exposed ports:",{"type":39,"tag":480,"props":4776,"children":4778},{"className":482,"code":4777,"language":484,"meta":485,"style":485},"\u002F\u002F auth\u002Fsrc\u002Fmodule.ts — a Module that owns its own Postgres\nimport { module, secret } from '@prisma\u002Fcomposer';\nimport { postgres } from '@prisma\u002Fcomposer-prisma-cloud';\nimport { authContract } from '.\u002Fcontract.ts';\nimport authService from '.\u002Fservice.ts';\n\nexport default module(\n  'auth',\n  { secrets: { signingKey: secret() }, expose: { rpc: authContract } },\n  ({ secrets, provision }) => {\n    const db = provision(postgres({ name: 'database' }));\n    const service = provision(authService, {\n      id: 'service',\n      deps: { db },\n      input: { signingKey: secrets.signingKey }, \u002F\u002F forwarded ref as a binding leaf\n    });\n    return { rpc: service.rpc };\n  },\n);\n",[4779],{"type":39,"tag":76,"props":4780,"children":4781},{"__ignoreMap":485},[4782,4790,4838,4877,4916,4948,4955,4974,4994,5071,5103,5171,5207,5236,5260,5307,5323,5359,5366],{"type":39,"tag":491,"props":4783,"children":4784},{"class":493,"line":494},[4785],{"type":39,"tag":491,"props":4786,"children":4787},{"style":498},[4788],{"type":45,"value":4789},"\u002F\u002F auth\u002Fsrc\u002Fmodule.ts — a Module that owns its own Postgres\n",{"type":39,"tag":491,"props":4791,"children":4792},{"class":493,"line":504},[4793,4797,4801,4805,4809,4814,4818,4822,4826,4830,4834],{"type":39,"tag":491,"props":4794,"children":4795},{"style":508},[4796],{"type":45,"value":511},{"type":39,"tag":491,"props":4798,"children":4799},{"style":514},[4800],{"type":45,"value":517},{"type":39,"tag":491,"props":4802,"children":4803},{"style":520},[4804],{"type":45,"value":1099},{"type":39,"tag":491,"props":4806,"children":4807},{"style":514},[4808],{"type":45,"value":528},{"type":39,"tag":491,"props":4810,"children":4811},{"style":520},[4812],{"type":45,"value":4813}," secret",{"type":39,"tag":491,"props":4815,"children":4816},{"style":514},[4817],{"type":45,"value":538},{"type":39,"tag":491,"props":4819,"children":4820},{"style":508},[4821],{"type":45,"value":543},{"type":39,"tag":491,"props":4823,"children":4824},{"style":514},[4825],{"type":45,"value":548},{"type":39,"tag":491,"props":4827,"children":4828},{"style":551},[4829],{"type":45,"value":267},{"type":39,"tag":491,"props":4831,"children":4832},{"style":514},[4833],{"type":45,"value":559},{"type":39,"tag":491,"props":4835,"children":4836},{"style":514},[4837],{"type":45,"value":564},{"type":39,"tag":491,"props":4839,"children":4840},{"class":493,"line":23},[4841,4845,4849,4853,4857,4861,4865,4869,4873],{"type":39,"tag":491,"props":4842,"children":4843},{"style":508},[4844],{"type":45,"value":511},{"type":39,"tag":491,"props":4846,"children":4847},{"style":514},[4848],{"type":45,"value":517},{"type":39,"tag":491,"props":4850,"children":4851},{"style":520},[4852],{"type":45,"value":904},{"type":39,"tag":491,"props":4854,"children":4855},{"style":514},[4856],{"type":45,"value":538},{"type":39,"tag":491,"props":4858,"children":4859},{"style":508},[4860],{"type":45,"value":543},{"type":39,"tag":491,"props":4862,"children":4863},{"style":514},[4864],{"type":45,"value":548},{"type":39,"tag":491,"props":4866,"children":4867},{"style":551},[4868],{"type":45,"value":364},{"type":39,"tag":491,"props":4870,"children":4871},{"style":514},[4872],{"type":45,"value":559},{"type":39,"tag":491,"props":4874,"children":4875},{"style":514},[4876],{"type":45,"value":564},{"type":39,"tag":491,"props":4878,"children":4879},{"class":493,"line":608},[4880,4884,4888,4892,4896,4900,4904,4908,4912],{"type":39,"tag":491,"props":4881,"children":4882},{"style":508},[4883],{"type":45,"value":511},{"type":39,"tag":491,"props":4885,"children":4886},{"style":514},[4887],{"type":45,"value":517},{"type":39,"tag":491,"props":4889,"children":4890},{"style":520},[4891],{"type":45,"value":944},{"type":39,"tag":491,"props":4893,"children":4894},{"style":514},[4895],{"type":45,"value":538},{"type":39,"tag":491,"props":4897,"children":4898},{"style":508},[4899],{"type":45,"value":543},{"type":39,"tag":491,"props":4901,"children":4902},{"style":514},[4903],{"type":45,"value":548},{"type":39,"tag":491,"props":4905,"children":4906},{"style":551},[4907],{"type":45,"value":961},{"type":39,"tag":491,"props":4909,"children":4910},{"style":514},[4911],{"type":45,"value":559},{"type":39,"tag":491,"props":4913,"children":4914},{"style":514},[4915],{"type":45,"value":564},{"type":39,"tag":491,"props":4917,"children":4918},{"class":493,"line":618},[4919,4923,4928,4932,4936,4940,4944],{"type":39,"tag":491,"props":4920,"children":4921},{"style":508},[4922],{"type":45,"value":511},{"type":39,"tag":491,"props":4924,"children":4925},{"style":520},[4926],{"type":45,"value":4927}," authService ",{"type":39,"tag":491,"props":4929,"children":4930},{"style":508},[4931],{"type":45,"value":862},{"type":39,"tag":491,"props":4933,"children":4934},{"style":514},[4935],{"type":45,"value":548},{"type":39,"tag":491,"props":4937,"children":4938},{"style":551},[4939],{"type":45,"value":1361},{"type":39,"tag":491,"props":4941,"children":4942},{"style":514},[4943],{"type":45,"value":559},{"type":39,"tag":491,"props":4945,"children":4946},{"style":514},[4947],{"type":45,"value":564},{"type":39,"tag":491,"props":4949,"children":4950},{"class":493,"line":658},[4951],{"type":39,"tag":491,"props":4952,"children":4953},{"emptyLinePlaceholder":612},[4954],{"type":45,"value":615},{"type":39,"tag":491,"props":4956,"children":4957},{"class":493,"line":807},[4958,4962,4966,4970],{"type":39,"tag":491,"props":4959,"children":4960},{"style":508},[4961],{"type":45,"value":624},{"type":39,"tag":491,"props":4963,"children":4964},{"style":508},[4965],{"type":45,"value":988},{"type":39,"tag":491,"props":4967,"children":4968},{"style":514},[4969],{"type":45,"value":1099},{"type":39,"tag":491,"props":4971,"children":4972},{"style":520},[4973],{"type":45,"value":4277},{"type":39,"tag":491,"props":4975,"children":4976},{"class":493,"line":1031},[4977,4982,4986,4990],{"type":39,"tag":491,"props":4978,"children":4979},{"style":514},[4980],{"type":45,"value":4981},"  '",{"type":39,"tag":491,"props":4983,"children":4984},{"style":551},[4985],{"type":45,"value":458},{"type":39,"tag":491,"props":4987,"children":4988},{"style":514},[4989],{"type":45,"value":559},{"type":39,"tag":491,"props":4991,"children":4992},{"style":514},[4993],{"type":45,"value":804},{"type":39,"tag":491,"props":4995,"children":4996},{"class":493,"line":1071},[4997,5002,5007,5011,5015,5020,5024,5028,5032,5037,5042,5046,5050,5054,5058,5062,5066],{"type":39,"tag":491,"props":4998,"children":4999},{"style":514},[5000],{"type":45,"value":5001},"  {",{"type":39,"tag":491,"props":5003,"children":5004},{"style":662},[5005],{"type":45,"value":5006}," secrets",{"type":39,"tag":491,"props":5008,"children":5009},{"style":514},[5010],{"type":45,"value":227},{"type":39,"tag":491,"props":5012,"children":5013},{"style":514},[5014],{"type":45,"value":517},{"type":39,"tag":491,"props":5016,"children":5017},{"style":662},[5018],{"type":45,"value":5019}," signingKey",{"type":39,"tag":491,"props":5021,"children":5022},{"style":514},[5023],{"type":45,"value":227},{"type":39,"tag":491,"props":5025,"children":5026},{"style":643},[5027],{"type":45,"value":4813},{"type":39,"tag":491,"props":5029,"children":5030},{"style":520},[5031],{"type":45,"value":1063},{"type":39,"tag":491,"props":5033,"children":5034},{"style":514},[5035],{"type":45,"value":5036},"},",{"type":39,"tag":491,"props":5038,"children":5039},{"style":662},[5040],{"type":45,"value":5041}," expose",{"type":39,"tag":491,"props":5043,"children":5044},{"style":514},[5045],{"type":45,"value":227},{"type":39,"tag":491,"props":5047,"children":5048},{"style":514},[5049],{"type":45,"value":517},{"type":39,"tag":491,"props":5051,"children":5052},{"style":662},[5053],{"type":45,"value":533},{"type":39,"tag":491,"props":5055,"children":5056},{"style":514},[5057],{"type":45,"value":227},{"type":39,"tag":491,"props":5059,"children":5060},{"style":520},[5061],{"type":45,"value":635},{"type":39,"tag":491,"props":5063,"children":5064},{"style":514},[5065],{"type":45,"value":795},{"type":39,"tag":491,"props":5067,"children":5068},{"style":514},[5069],{"type":45,"value":5070}," },\n",{"type":39,"tag":491,"props":5072,"children":5073},{"class":493,"line":1168},[5074,5079,5083,5087,5091,5095,5099],{"type":39,"tag":491,"props":5075,"children":5076},{"style":514},[5077],{"type":45,"value":5078},"  ({",{"type":39,"tag":491,"props":5080,"children":5081},{"style":1667},[5082],{"type":45,"value":5006},{"type":39,"tag":491,"props":5084,"children":5085},{"style":514},[5086],{"type":45,"value":528},{"type":39,"tag":491,"props":5088,"children":5089},{"style":1667},[5090],{"type":45,"value":3065},{"type":39,"tag":491,"props":5092,"children":5093},{"style":514},[5094],{"type":45,"value":1674},{"type":39,"tag":491,"props":5096,"children":5097},{"style":627},[5098],{"type":45,"value":1679},{"type":39,"tag":491,"props":5100,"children":5101},{"style":514},[5102],{"type":45,"value":1624},{"type":39,"tag":491,"props":5104,"children":5105},{"class":493,"line":1201},[5106,5111,5115,5119,5123,5127,5131,5135,5139,5143,5147,5151,5155,5159,5163,5167],{"type":39,"tag":491,"props":5107,"children":5108},{"style":627},[5109],{"type":45,"value":5110},"    const",{"type":39,"tag":491,"props":5112,"children":5113},{"style":520},[5114],{"type":45,"value":1050},{"type":39,"tag":491,"props":5116,"children":5117},{"style":514},[5118],{"type":45,"value":1402},{"type":39,"tag":491,"props":5120,"children":5121},{"style":643},[5122],{"type":45,"value":3065},{"type":39,"tag":491,"props":5124,"children":5125},{"style":662},[5126],{"type":45,"value":650},{"type":39,"tag":491,"props":5128,"children":5129},{"style":643},[5130],{"type":45,"value":382},{"type":39,"tag":491,"props":5132,"children":5133},{"style":662},[5134],{"type":45,"value":650},{"type":39,"tag":491,"props":5136,"children":5137},{"style":514},[5138],{"type":45,"value":682},{"type":39,"tag":491,"props":5140,"children":5141},{"style":662},[5142],{"type":45,"value":4298},{"type":39,"tag":491,"props":5144,"children":5145},{"style":514},[5146],{"type":45,"value":227},{"type":39,"tag":491,"props":5148,"children":5149},{"style":514},[5150],{"type":45,"value":548},{"type":39,"tag":491,"props":5152,"children":5153},{"style":551},[5154],{"type":45,"value":4311},{"type":39,"tag":491,"props":5156,"children":5157},{"style":514},[5158],{"type":45,"value":559},{"type":39,"tag":491,"props":5160,"children":5161},{"style":514},[5162],{"type":45,"value":538},{"type":39,"tag":491,"props":5164,"children":5165},{"style":662},[5166],{"type":45,"value":4672},{"type":39,"tag":491,"props":5168,"children":5169},{"style":514},[5170],{"type":45,"value":564},{"type":39,"tag":491,"props":5172,"children":5173},{"class":493,"line":1627},[5174,5178,5182,5186,5190,5194,5199,5203],{"type":39,"tag":491,"props":5175,"children":5176},{"style":627},[5177],{"type":45,"value":5110},{"type":39,"tag":491,"props":5179,"children":5180},{"style":520},[5181],{"type":45,"value":1407},{"type":39,"tag":491,"props":5183,"children":5184},{"style":514},[5185],{"type":45,"value":1402},{"type":39,"tag":491,"props":5187,"children":5188},{"style":643},[5189],{"type":45,"value":3065},{"type":39,"tag":491,"props":5191,"children":5192},{"style":662},[5193],{"type":45,"value":650},{"type":39,"tag":491,"props":5195,"children":5196},{"style":520},[5197],{"type":45,"value":5198},"authService",{"type":39,"tag":491,"props":5200,"children":5201},{"style":514},[5202],{"type":45,"value":528},{"type":39,"tag":491,"props":5204,"children":5205},{"style":514},[5206],{"type":45,"value":1624},{"type":39,"tag":491,"props":5208,"children":5209},{"class":493,"line":1644},[5210,5215,5219,5223,5228,5232],{"type":39,"tag":491,"props":5211,"children":5212},{"style":662},[5213],{"type":45,"value":5214},"      id",{"type":39,"tag":491,"props":5216,"children":5217},{"style":514},[5218],{"type":45,"value":227},{"type":39,"tag":491,"props":5220,"children":5221},{"style":514},[5222],{"type":45,"value":548},{"type":39,"tag":491,"props":5224,"children":5225},{"style":551},[5226],{"type":45,"value":5227},"service",{"type":39,"tag":491,"props":5229,"children":5230},{"style":514},[5231],{"type":45,"value":559},{"type":39,"tag":491,"props":5233,"children":5234},{"style":514},[5235],{"type":45,"value":804},{"type":39,"tag":491,"props":5237,"children":5238},{"class":493,"line":1733},[5239,5244,5248,5252,5256],{"type":39,"tag":491,"props":5240,"children":5241},{"style":662},[5242],{"type":45,"value":5243},"      deps",{"type":39,"tag":491,"props":5245,"children":5246},{"style":514},[5247],{"type":45,"value":227},{"type":39,"tag":491,"props":5249,"children":5250},{"style":514},[5251],{"type":45,"value":517},{"type":39,"tag":491,"props":5253,"children":5254},{"style":520},[5255],{"type":45,"value":1050},{"type":39,"tag":491,"props":5257,"children":5258},{"style":514},[5259],{"type":45,"value":5070},{"type":39,"tag":491,"props":5261,"children":5262},{"class":493,"line":1742},[5263,5268,5272,5276,5280,5284,5288,5292,5297,5302],{"type":39,"tag":491,"props":5264,"children":5265},{"style":662},[5266],{"type":45,"value":5267},"      input",{"type":39,"tag":491,"props":5269,"children":5270},{"style":514},[5271],{"type":45,"value":227},{"type":39,"tag":491,"props":5273,"children":5274},{"style":514},[5275],{"type":45,"value":517},{"type":39,"tag":491,"props":5277,"children":5278},{"style":662},[5279],{"type":45,"value":5019},{"type":39,"tag":491,"props":5281,"children":5282},{"style":514},[5283],{"type":45,"value":227},{"type":39,"tag":491,"props":5285,"children":5286},{"style":520},[5287],{"type":45,"value":5006},{"type":39,"tag":491,"props":5289,"children":5290},{"style":514},[5291],{"type":45,"value":1113},{"type":39,"tag":491,"props":5293,"children":5294},{"style":520},[5295],{"type":45,"value":5296},"signingKey",{"type":39,"tag":491,"props":5298,"children":5299},{"style":514},[5300],{"type":45,"value":5301}," },",{"type":39,"tag":491,"props":5303,"children":5304},{"style":498},[5305],{"type":45,"value":5306}," \u002F\u002F forwarded ref as a binding leaf\n",{"type":39,"tag":491,"props":5308,"children":5309},{"class":493,"line":1758},[5310,5315,5319],{"type":39,"tag":491,"props":5311,"children":5312},{"style":514},[5313],{"type":45,"value":5314},"    }",{"type":39,"tag":491,"props":5316,"children":5317},{"style":662},[5318],{"type":45,"value":734},{"type":39,"tag":491,"props":5320,"children":5321},{"style":514},[5322],{"type":45,"value":564},{"type":39,"tag":491,"props":5324,"children":5325},{"class":493,"line":1779},[5326,5331,5335,5339,5343,5347,5351,5355],{"type":39,"tag":491,"props":5327,"children":5328},{"style":508},[5329],{"type":45,"value":5330},"    return",{"type":39,"tag":491,"props":5332,"children":5333},{"style":514},[5334],{"type":45,"value":517},{"type":39,"tag":491,"props":5336,"children":5337},{"style":662},[5338],{"type":45,"value":533},{"type":39,"tag":491,"props":5340,"children":5341},{"style":514},[5342],{"type":45,"value":227},{"type":39,"tag":491,"props":5344,"children":5345},{"style":520},[5346],{"type":45,"value":1407},{"type":39,"tag":491,"props":5348,"children":5349},{"style":514},[5350],{"type":45,"value":1113},{"type":39,"tag":491,"props":5352,"children":5353},{"style":520},[5354],{"type":45,"value":3172},{"type":39,"tag":491,"props":5356,"children":5357},{"style":514},[5358],{"type":45,"value":4163},{"type":39,"tag":491,"props":5360,"children":5361},{"class":493,"line":1787},[5362],{"type":39,"tag":491,"props":5363,"children":5364},{"style":514},[5365],{"type":45,"value":1739},{"type":39,"tag":491,"props":5367,"children":5368},{"class":493,"line":1796},[5369,5373],{"type":39,"tag":491,"props":5370,"children":5371},{"style":520},[5372],{"type":45,"value":734},{"type":39,"tag":491,"props":5374,"children":5375},{"style":514},[5376],{"type":45,"value":564},{"type":39,"tag":48,"props":5378,"children":5379},{},[5380,5382,5388,5390,5396,5398,5404,5406,5411],{"type":45,"value":5381},"Naming rules that bite: a provision id shorter than 3 characters is rejected\nby the platform (name the database ",{"type":39,"tag":76,"props":5383,"children":5385},{"className":5384},[],[5386],{"type":45,"value":5387},"'database'",{"type":45,"value":5389},", not ",{"type":39,"tag":76,"props":5391,"children":5393},{"className":5392},[],[5394],{"type":45,"value":5395},"'db'",{"type":45,"value":5397},"), and a service\nwhose name equals its enclosing module's reads as ",{"type":39,"tag":76,"props":5399,"children":5401},{"className":5400},[],[5402],{"type":45,"value":5403},"auth.auth",{"type":45,"value":5405}," unless you give\nit an explicit ",{"type":39,"tag":76,"props":5407,"children":5409},{"className":5408},[],[5410],{"type":45,"value":3220},{"type":45,"value":1113},{"type":39,"tag":48,"props":5413,"children":5414},{},[5415,5417,5422],{"type":45,"value":5416},"A module can also declare boundary ",{"type":39,"tag":76,"props":5418,"children":5420},{"className":5419},[],[5421],{"type":45,"value":3228},{"type":45,"value":5423}," — inputs the parent wires exactly as\nit would wire a service's. The consumer never sees the module's internals.",{"type":39,"tag":5425,"props":5426,"children":5428},"h3",{"id":5427},"the-building-blocks-you-can-compose",[5429],{"type":45,"value":5430},"The building blocks you can compose",{"type":39,"tag":48,"props":5432,"children":5433},{},[5434,5436,5441],{"type":45,"value":5435},"Modules are the building blocks: provision one, wire its exposed port, and\nyou're done — you never reimplement what a Module already owns. The\nfirst-party set ships inside ",{"type":39,"tag":76,"props":5437,"children":5439},{"className":5438},[],[5440],{"type":45,"value":364},{"type":45,"value":5442},". It's small, and\ngrowing:",{"type":39,"tag":229,"props":5444,"children":5445},{},[5446,5467],{"type":39,"tag":233,"props":5447,"children":5448},{},[5449],{"type":39,"tag":237,"props":5450,"children":5451},{},[5452,5457,5462],{"type":39,"tag":241,"props":5453,"children":5454},{},[5455],{"type":45,"value":5456},"Import",{"type":39,"tag":241,"props":5458,"children":5459},{},[5460],{"type":45,"value":5461},"What it provisions",{"type":39,"tag":241,"props":5463,"children":5464},{},[5465],{"type":45,"value":5466},"Exposes",{"type":39,"tag":252,"props":5468,"children":5469},{},[5470,5498,5530],{"type":39,"tag":237,"props":5471,"children":5472},{},[5473,5488,5493],{"type":39,"tag":259,"props":5474,"children":5475},{},[5476,5482,5483],{"type":39,"tag":76,"props":5477,"children":5479},{"className":5478},[],[5480],{"type":45,"value":5481},"cron",{"type":45,"value":3905},{"type":39,"tag":76,"props":5484,"children":5486},{"className":5485},[],[5487],{"type":45,"value":417},{"type":39,"tag":259,"props":5489,"children":5490},{},[5491],{"type":45,"value":5492},"An always-on scheduler firing your schedule at your runner service",{"type":39,"tag":259,"props":5494,"children":5495},{},[5496],{"type":45,"value":5497},"nothing",{"type":39,"tag":237,"props":5499,"children":5500},{},[5501,5516,5521],{"type":39,"tag":259,"props":5502,"children":5503},{},[5504,5510,5511],{"type":39,"tag":76,"props":5505,"children":5507},{"className":5506},[],[5508],{"type":45,"value":5509},"storage",{"type":45,"value":3905},{"type":39,"tag":76,"props":5512,"children":5514},{"className":5513},[],[5515],{"type":45,"value":424},{"type":39,"tag":259,"props":5517,"children":5518},{},[5519],{"type":45,"value":5520},"An S3-backed blob store (own Postgres + minted credentials)",{"type":39,"tag":259,"props":5522,"children":5523},{},[5524],{"type":39,"tag":76,"props":5525,"children":5527},{"className":5526},[],[5528],{"type":45,"value":5529},"store",{"type":39,"tag":237,"props":5531,"children":5532},{},[5533,5548,5558],{"type":39,"tag":259,"props":5534,"children":5535},{},[5536,5542,5543],{"type":39,"tag":76,"props":5537,"children":5539},{"className":5538},[],[5540],{"type":45,"value":5541},"streams",{"type":45,"value":3905},{"type":39,"tag":76,"props":5544,"children":5546},{"className":5545},[],[5547],{"type":45,"value":431},{"type":39,"tag":259,"props":5549,"children":5550},{},[5551,5553],{"type":45,"value":5552},"Durable append-only event streams over a ",{"type":39,"tag":76,"props":5554,"children":5556},{"className":5555},[],[5557],{"type":45,"value":5529},{"type":39,"tag":259,"props":5559,"children":5560},{},[5561],{"type":39,"tag":76,"props":5562,"children":5564},{"className":5563},[],[5565],{"type":45,"value":5541},{"type":39,"tag":48,"props":5567,"children":5568},{},[5569,5574,5576,5582,5584,5589],{"type":39,"tag":54,"props":5570,"children":5571},{},[5572],{"type":45,"value":5573},"Finding more.",{"type":45,"value":5575}," A Composer extension — a package that brings its own\nModules, resources, or deploy target — is published on npm under the name\n",{"type":39,"tag":76,"props":5577,"children":5579},{"className":5578},[],[5580],{"type":45,"value":5581},"prisma-composer-*",{"type":45,"value":5583},". That name is the convention, so it's how you look for\none. The ecosystem is new: today the blocks above plus the app Modules you\nwrite are the whole set, so don't reach for a ",{"type":39,"tag":76,"props":5585,"children":5587},{"className":5586},[],[5588],{"type":45,"value":5581},{"type":45,"value":5590}," package\nwithout checking that it actually exists on npm first.",{"type":39,"tag":48,"props":5592,"children":5593},{},[5594,5596,5602],{"type":45,"value":5595},"Cron end to end — the schedule is one source of truth; ",{"type":39,"tag":76,"props":5597,"children":5599},{"className":5598},[],[5600],{"type":45,"value":5601},"serveSchedule",{"type":45,"value":5603}," is\nexhaustive over its job ids at compile time:",{"type":39,"tag":480,"props":5605,"children":5607},{"className":482,"code":5606,"language":484,"meta":485,"style":485},"\u002F\u002F service.ts\nimport { defineSchedule, triggerContract } from '@prisma\u002Fcomposer-prisma-cloud\u002Fcron';\nexport const schedule = defineSchedule({ tick: '60s' });\n\u002F\u002F the runner service exposes { trigger: triggerContract }\n\n\u002F\u002F server.ts\nimport { serveSchedule } from '@prisma\u002Fcomposer-prisma-cloud\u002Fcron';\nconst handler = serveSchedule(service, schedule, {\n  tick: (deps) => deps.worker.tick({}),\n});\n\n\u002F\u002F module.ts — the cron module's boundary deps mirror the runner's own\nprovision(cron({ schedule, runner: runnerService }), { deps: { worker: worker.rpc } });\n",[5608],{"type":39,"tag":76,"props":5609,"children":5610},{"__ignoreMap":485},[5611,5619,5669,5735,5743,5750,5758,5798,5838,5905,5920,5927,5935],{"type":39,"tag":491,"props":5612,"children":5613},{"class":493,"line":494},[5614],{"type":39,"tag":491,"props":5615,"children":5616},{"style":498},[5617],{"type":45,"value":5618},"\u002F\u002F service.ts\n",{"type":39,"tag":491,"props":5620,"children":5621},{"class":493,"line":504},[5622,5626,5630,5635,5639,5644,5648,5652,5656,5661,5665],{"type":39,"tag":491,"props":5623,"children":5624},{"style":508},[5625],{"type":45,"value":511},{"type":39,"tag":491,"props":5627,"children":5628},{"style":514},[5629],{"type":45,"value":517},{"type":39,"tag":491,"props":5631,"children":5632},{"style":520},[5633],{"type":45,"value":5634}," defineSchedule",{"type":39,"tag":491,"props":5636,"children":5637},{"style":514},[5638],{"type":45,"value":528},{"type":39,"tag":491,"props":5640,"children":5641},{"style":520},[5642],{"type":45,"value":5643}," triggerContract",{"type":39,"tag":491,"props":5645,"children":5646},{"style":514},[5647],{"type":45,"value":538},{"type":39,"tag":491,"props":5649,"children":5650},{"style":508},[5651],{"type":45,"value":543},{"type":39,"tag":491,"props":5653,"children":5654},{"style":514},[5655],{"type":45,"value":548},{"type":39,"tag":491,"props":5657,"children":5658},{"style":551},[5659],{"type":45,"value":5660},"@prisma\u002Fcomposer-prisma-cloud\u002Fcron",{"type":39,"tag":491,"props":5662,"children":5663},{"style":514},[5664],{"type":45,"value":559},{"type":39,"tag":491,"props":5666,"children":5667},{"style":514},[5668],{"type":45,"value":564},{"type":39,"tag":491,"props":5670,"children":5671},{"class":493,"line":23},[5672,5676,5680,5685,5689,5693,5697,5701,5706,5710,5714,5719,5723,5727,5731],{"type":39,"tag":491,"props":5673,"children":5674},{"style":508},[5675],{"type":45,"value":624},{"type":39,"tag":491,"props":5677,"children":5678},{"style":627},[5679],{"type":45,"value":630},{"type":39,"tag":491,"props":5681,"children":5682},{"style":520},[5683],{"type":45,"value":5684}," schedule ",{"type":39,"tag":491,"props":5686,"children":5687},{"style":514},[5688],{"type":45,"value":640},{"type":39,"tag":491,"props":5690,"children":5691},{"style":643},[5692],{"type":45,"value":5634},{"type":39,"tag":491,"props":5694,"children":5695},{"style":520},[5696],{"type":45,"value":650},{"type":39,"tag":491,"props":5698,"children":5699},{"style":514},[5700],{"type":45,"value":682},{"type":39,"tag":491,"props":5702,"children":5703},{"style":662},[5704],{"type":45,"value":5705}," tick",{"type":39,"tag":491,"props":5707,"children":5708},{"style":514},[5709],{"type":45,"value":227},{"type":39,"tag":491,"props":5711,"children":5712},{"style":514},[5713],{"type":45,"value":548},{"type":39,"tag":491,"props":5715,"children":5716},{"style":551},[5717],{"type":45,"value":5718},"60s",{"type":39,"tag":491,"props":5720,"children":5721},{"style":514},[5722],{"type":45,"value":559},{"type":39,"tag":491,"props":5724,"children":5725},{"style":514},[5726],{"type":45,"value":538},{"type":39,"tag":491,"props":5728,"children":5729},{"style":520},[5730],{"type":45,"value":734},{"type":39,"tag":491,"props":5732,"children":5733},{"style":514},[5734],{"type":45,"value":564},{"type":39,"tag":491,"props":5736,"children":5737},{"class":493,"line":608},[5738],{"type":39,"tag":491,"props":5739,"children":5740},{"style":498},[5741],{"type":45,"value":5742},"\u002F\u002F the runner service exposes { trigger: triggerContract }\n",{"type":39,"tag":491,"props":5744,"children":5745},{"class":493,"line":618},[5746],{"type":39,"tag":491,"props":5747,"children":5748},{"emptyLinePlaceholder":612},[5749],{"type":45,"value":615},{"type":39,"tag":491,"props":5751,"children":5752},{"class":493,"line":658},[5753],{"type":39,"tag":491,"props":5754,"children":5755},{"style":498},[5756],{"type":45,"value":5757},"\u002F\u002F server.ts\n",{"type":39,"tag":491,"props":5759,"children":5760},{"class":493,"line":807},[5761,5765,5769,5774,5778,5782,5786,5790,5794],{"type":39,"tag":491,"props":5762,"children":5763},{"style":508},[5764],{"type":45,"value":511},{"type":39,"tag":491,"props":5766,"children":5767},{"style":514},[5768],{"type":45,"value":517},{"type":39,"tag":491,"props":5770,"children":5771},{"style":520},[5772],{"type":45,"value":5773}," serveSchedule",{"type":39,"tag":491,"props":5775,"children":5776},{"style":514},[5777],{"type":45,"value":538},{"type":39,"tag":491,"props":5779,"children":5780},{"style":508},[5781],{"type":45,"value":543},{"type":39,"tag":491,"props":5783,"children":5784},{"style":514},[5785],{"type":45,"value":548},{"type":39,"tag":491,"props":5787,"children":5788},{"style":551},[5789],{"type":45,"value":5660},{"type":39,"tag":491,"props":5791,"children":5792},{"style":514},[5793],{"type":45,"value":559},{"type":39,"tag":491,"props":5795,"children":5796},{"style":514},[5797],{"type":45,"value":564},{"type":39,"tag":491,"props":5799,"children":5800},{"class":493,"line":1031},[5801,5805,5809,5813,5817,5821,5825,5830,5834],{"type":39,"tag":491,"props":5802,"children":5803},{"style":627},[5804],{"type":45,"value":1384},{"type":39,"tag":491,"props":5806,"children":5807},{"style":520},[5808],{"type":45,"value":1602},{"type":39,"tag":491,"props":5810,"children":5811},{"style":514},[5812],{"type":45,"value":640},{"type":39,"tag":491,"props":5814,"children":5815},{"style":643},[5816],{"type":45,"value":5773},{"type":39,"tag":491,"props":5818,"children":5819},{"style":520},[5820],{"type":45,"value":1615},{"type":39,"tag":491,"props":5822,"children":5823},{"style":514},[5824],{"type":45,"value":528},{"type":39,"tag":491,"props":5826,"children":5827},{"style":520},[5828],{"type":45,"value":5829}," schedule",{"type":39,"tag":491,"props":5831,"children":5832},{"style":514},[5833],{"type":45,"value":528},{"type":39,"tag":491,"props":5835,"children":5836},{"style":514},[5837],{"type":45,"value":1624},{"type":39,"tag":491,"props":5839,"children":5840},{"class":493,"line":1071},[5841,5846,5850,5854,5858,5862,5866,5870,5874,5879,5883,5888,5892,5897,5901],{"type":39,"tag":491,"props":5842,"children":5843},{"style":643},[5844],{"type":45,"value":5845},"  tick",{"type":39,"tag":491,"props":5847,"children":5848},{"style":514},[5849],{"type":45,"value":227},{"type":39,"tag":491,"props":5851,"children":5852},{"style":514},[5853],{"type":45,"value":74},{"type":39,"tag":491,"props":5855,"children":5856},{"style":1667},[5857],{"type":45,"value":3228},{"type":39,"tag":491,"props":5859,"children":5860},{"style":514},[5861],{"type":45,"value":734},{"type":39,"tag":491,"props":5863,"children":5864},{"style":627},[5865],{"type":45,"value":1679},{"type":39,"tag":491,"props":5867,"children":5868},{"style":520},[5869],{"type":45,"value":3143},{"type":39,"tag":491,"props":5871,"children":5872},{"style":514},[5873],{"type":45,"value":1113},{"type":39,"tag":491,"props":5875,"children":5876},{"style":520},[5877],{"type":45,"value":5878},"worker",{"type":39,"tag":491,"props":5880,"children":5881},{"style":514},[5882],{"type":45,"value":1113},{"type":39,"tag":491,"props":5884,"children":5885},{"style":643},[5886],{"type":45,"value":5887},"tick",{"type":39,"tag":491,"props":5889,"children":5890},{"style":520},[5891],{"type":45,"value":650},{"type":39,"tag":491,"props":5893,"children":5894},{"style":514},[5895],{"type":45,"value":5896},"{}",{"type":39,"tag":491,"props":5898,"children":5899},{"style":520},[5900],{"type":45,"value":734},{"type":39,"tag":491,"props":5902,"children":5903},{"style":514},[5904],{"type":45,"value":804},{"type":39,"tag":491,"props":5906,"children":5907},{"class":493,"line":1168},[5908,5912,5916],{"type":39,"tag":491,"props":5909,"children":5910},{"style":514},[5911],{"type":45,"value":795},{"type":39,"tag":491,"props":5913,"children":5914},{"style":520},[5915],{"type":45,"value":734},{"type":39,"tag":491,"props":5917,"children":5918},{"style":514},[5919],{"type":45,"value":564},{"type":39,"tag":491,"props":5921,"children":5922},{"class":493,"line":1201},[5923],{"type":39,"tag":491,"props":5924,"children":5925},{"emptyLinePlaceholder":612},[5926],{"type":45,"value":615},{"type":39,"tag":491,"props":5928,"children":5929},{"class":493,"line":1627},[5930],{"type":39,"tag":491,"props":5931,"children":5932},{"style":498},[5933],{"type":45,"value":5934},"\u002F\u002F module.ts — the cron module's boundary deps mirror the runner's own\n",{"type":39,"tag":491,"props":5936,"children":5937},{"class":493,"line":1644},[5938,5942,5946,5950,5954,5958,5962,5966,5971,5975,5980,5984,5988,5992,5996,6000,6004,6008,6013,6017,6021,6025,6030,6034,6038,6042],{"type":39,"tag":491,"props":5939,"children":5940},{"style":643},[5941],{"type":45,"value":4684},{"type":39,"tag":491,"props":5943,"children":5944},{"style":520},[5945],{"type":45,"value":650},{"type":39,"tag":491,"props":5947,"children":5948},{"style":643},[5949],{"type":45,"value":5481},{"type":39,"tag":491,"props":5951,"children":5952},{"style":520},[5953],{"type":45,"value":650},{"type":39,"tag":491,"props":5955,"children":5956},{"style":514},[5957],{"type":45,"value":682},{"type":39,"tag":491,"props":5959,"children":5960},{"style":520},[5961],{"type":45,"value":5829},{"type":39,"tag":491,"props":5963,"children":5964},{"style":514},[5965],{"type":45,"value":528},{"type":39,"tag":491,"props":5967,"children":5968},{"style":662},[5969],{"type":45,"value":5970}," runner",{"type":39,"tag":491,"props":5972,"children":5973},{"style":514},[5974],{"type":45,"value":227},{"type":39,"tag":491,"props":5976,"children":5977},{"style":520},[5978],{"type":45,"value":5979}," runnerService ",{"type":39,"tag":491,"props":5981,"children":5982},{"style":514},[5983],{"type":45,"value":795},{"type":39,"tag":491,"props":5985,"children":5986},{"style":520},[5987],{"type":45,"value":734},{"type":39,"tag":491,"props":5989,"children":5990},{"style":514},[5991],{"type":45,"value":528},{"type":39,"tag":491,"props":5993,"children":5994},{"style":514},[5995],{"type":45,"value":517},{"type":39,"tag":491,"props":5997,"children":5998},{"style":662},[5999],{"type":45,"value":3143},{"type":39,"tag":491,"props":6001,"children":6002},{"style":514},[6003],{"type":45,"value":227},{"type":39,"tag":491,"props":6005,"children":6006},{"style":514},[6007],{"type":45,"value":517},{"type":39,"tag":491,"props":6009,"children":6010},{"style":662},[6011],{"type":45,"value":6012}," worker",{"type":39,"tag":491,"props":6014,"children":6015},{"style":514},[6016],{"type":45,"value":227},{"type":39,"tag":491,"props":6018,"children":6019},{"style":520},[6020],{"type":45,"value":6012},{"type":39,"tag":491,"props":6022,"children":6023},{"style":514},[6024],{"type":45,"value":1113},{"type":39,"tag":491,"props":6026,"children":6027},{"style":520},[6028],{"type":45,"value":6029},"rpc ",{"type":39,"tag":491,"props":6031,"children":6032},{"style":514},[6033],{"type":45,"value":795},{"type":39,"tag":491,"props":6035,"children":6036},{"style":514},[6037],{"type":45,"value":538},{"type":39,"tag":491,"props":6039,"children":6040},{"style":520},[6041],{"type":45,"value":734},{"type":39,"tag":491,"props":6043,"children":6044},{"style":514},[6045],{"type":45,"value":564},{"type":39,"tag":442,"props":6047,"children":6049},{"id":6048},"service-input",[6050],{"type":45,"value":6051},"Service input",{"type":39,"tag":48,"props":6053,"children":6054},{},[6055],{"type":45,"value":6056},"Choosing the channel is most of the decision:",{"type":39,"tag":229,"props":6058,"children":6059},{},[6060,6086],{"type":39,"tag":233,"props":6061,"children":6062},{},[6063],{"type":39,"tag":237,"props":6064,"children":6065},{},[6066,6071,6076,6081],{"type":39,"tag":241,"props":6067,"children":6068},{},[6069],{"type":45,"value":6070},"The value is…",{"type":39,"tag":241,"props":6072,"children":6073},{},[6074],{"type":45,"value":6075},"Declare",{"type":39,"tag":241,"props":6077,"children":6078},{},[6079],{"type":45,"value":6080},"Provide",{"type":39,"tag":241,"props":6082,"children":6083},{},[6084],{"type":45,"value":6085},"Read",{"type":39,"tag":252,"props":6087,"children":6088},{},[6089,6125],{"type":39,"tag":237,"props":6090,"children":6091},{},[6092,6097,6106,6117],{"type":39,"tag":259,"props":6093,"children":6094},{},[6095],{"type":45,"value":6096},"produced by another node",{"type":39,"tag":259,"props":6098,"children":6099},{},[6100],{"type":39,"tag":76,"props":6101,"children":6103},{"className":6102},[],[6104],{"type":45,"value":6105},"deps: { db: postgres() }",{"type":39,"tag":259,"props":6107,"children":6108},{},[6109,6111],{"type":45,"value":6110},"wire at ",{"type":39,"tag":76,"props":6112,"children":6114},{"className":6113},[],[6115],{"type":45,"value":6116},"provision()",{"type":39,"tag":259,"props":6118,"children":6119},{},[6120],{"type":39,"tag":76,"props":6121,"children":6123},{"className":6122},[],[6124],{"type":45,"value":1230},{"type":39,"tag":237,"props":6126,"children":6127},{},[6128,6133,6145,6171],{"type":39,"tag":259,"props":6129,"children":6130},{},[6131],{"type":45,"value":6132},"anything else — config or credential",{"type":39,"tag":259,"props":6134,"children":6135},{},[6136,6138,6143],{"type":45,"value":6137},"one field of the ",{"type":39,"tag":76,"props":6139,"children":6141},{"className":6140},[],[6142],{"type":45,"value":3236},{"type":45,"value":6144}," schema",{"type":39,"tag":259,"props":6146,"children":6147},{},[6148,6150,6155,6157,6163,6165],{"type":45,"value":6149},"bind at ",{"type":39,"tag":76,"props":6151,"children":6153},{"className":6152},[],[6154],{"type":45,"value":6116},{"type":45,"value":6156},": literal, ",{"type":39,"tag":76,"props":6158,"children":6160},{"className":6159},[],[6161],{"type":45,"value":6162},"envParam()",{"type":45,"value":6164},", or ",{"type":39,"tag":76,"props":6166,"children":6168},{"className":6167},[],[6169],{"type":45,"value":6170},"envSecret()",{"type":39,"tag":259,"props":6172,"children":6173},{},[6174],{"type":39,"tag":76,"props":6175,"children":6177},{"className":6176},[],[6178],{"type":45,"value":6179},"input()",{"type":39,"tag":48,"props":6181,"children":6182},{},[6183,6185,6199,6201,6206],{"type":45,"value":6184},"The service declares its whole incoming configuration — plain values and\ncredentials together — as ",{"type":39,"tag":54,"props":6186,"children":6187},{},[6188,6190],{"type":45,"value":6189},"one\n",{"type":39,"tag":6191,"props":6192,"children":6196},"a",{"href":6193,"rel":6194},"https:\u002F\u002Fstandardschema.dev",[6195],"nofollow",[6197],{"type":45,"value":6198},"Standard Schema",{"type":45,"value":6200}," (arktype is the house\nchoice). A credential is a field typed as the redacting ",{"type":39,"tag":76,"props":6202,"children":6204},{"className":6203},[],[6205],{"type":45,"value":130},{"type":45,"value":6207}," box;\nconditional legality (\"no stripe key unless billing is on\") is an ordinary\nschema union:",{"type":39,"tag":480,"props":6209,"children":6211},{"className":482,"code":6210,"language":484,"meta":485,"style":485},"\u002F\u002F service.ts — the shapes that are legal\nimport { secretString } from '@prisma\u002Fcomposer\u002Farktype';\nimport { type } from 'arktype';\n\ncompute({\n  name: 'scheduler',\n  input: type({\n    jobs: type({ jobId: 'string', every: 'string' }).array(),\n    'region?': 'string',\n    apiKey: secretString(),\n  }),\n  \u002F\u002F ...\n});\n\n\u002F\u002F module.ts — where each value comes from; the binding mirrors the schema's shape\nimport { envParam, envSecret } from '@prisma\u002Fcomposer-prisma-cloud';\nprovision(scheduler, {\n  input: {\n    jobs: [{ jobId: 'tick', every: '60s' }],   \u002F\u002F a literal\n    region: envParam('REGION'),                 \u002F\u002F a per-stage platform variable\n    apiKey: envSecret('SCHEDULER_API_KEY'),     \u002F\u002F a credential — name only, never the value\n  },\n});\n\n\u002F\u002F server.ts — one call, one validated typed object\nconst input = service.input();\ninput.apiKey.expose(); \u002F\u002F the only way to a secret's value; the box redacts everywhere else\n",[6212],{"type":39,"tag":76,"props":6213,"children":6214},{"__ignoreMap":485},[6215,6223,6264,6303,6310,6325,6353,6377,6472,6509,6533,6549,6557,6572,6579,6587,6636,6656,6671,6752,6798,6844,6852,6868,6876,6885,6922],{"type":39,"tag":491,"props":6216,"children":6217},{"class":493,"line":494},[6218],{"type":39,"tag":491,"props":6219,"children":6220},{"style":498},[6221],{"type":45,"value":6222},"\u002F\u002F service.ts — the shapes that are legal\n",{"type":39,"tag":491,"props":6224,"children":6225},{"class":493,"line":504},[6226,6230,6234,6239,6243,6247,6251,6256,6260],{"type":39,"tag":491,"props":6227,"children":6228},{"style":508},[6229],{"type":45,"value":511},{"type":39,"tag":491,"props":6231,"children":6232},{"style":514},[6233],{"type":45,"value":517},{"type":39,"tag":491,"props":6235,"children":6236},{"style":520},[6237],{"type":45,"value":6238}," secretString",{"type":39,"tag":491,"props":6240,"children":6241},{"style":514},[6242],{"type":45,"value":538},{"type":39,"tag":491,"props":6244,"children":6245},{"style":508},[6246],{"type":45,"value":543},{"type":39,"tag":491,"props":6248,"children":6249},{"style":514},[6250],{"type":45,"value":548},{"type":39,"tag":491,"props":6252,"children":6253},{"style":551},[6254],{"type":45,"value":6255},"@prisma\u002Fcomposer\u002Farktype",{"type":39,"tag":491,"props":6257,"children":6258},{"style":514},[6259],{"type":45,"value":559},{"type":39,"tag":491,"props":6261,"children":6262},{"style":514},[6263],{"type":45,"value":564},{"type":39,"tag":491,"props":6265,"children":6266},{"class":493,"line":23},[6267,6271,6275,6279,6283,6287,6291,6295,6299],{"type":39,"tag":491,"props":6268,"children":6269},{"style":508},[6270],{"type":45,"value":511},{"type":39,"tag":491,"props":6272,"children":6273},{"style":514},[6274],{"type":45,"value":517},{"type":39,"tag":491,"props":6276,"children":6277},{"style":520},[6278],{"type":45,"value":580},{"type":39,"tag":491,"props":6280,"children":6281},{"style":514},[6282],{"type":45,"value":538},{"type":39,"tag":491,"props":6284,"children":6285},{"style":508},[6286],{"type":45,"value":543},{"type":39,"tag":491,"props":6288,"children":6289},{"style":514},[6290],{"type":45,"value":548},{"type":39,"tag":491,"props":6292,"children":6293},{"style":551},[6294],{"type":45,"value":597},{"type":39,"tag":491,"props":6296,"children":6297},{"style":514},[6298],{"type":45,"value":559},{"type":39,"tag":491,"props":6300,"children":6301},{"style":514},[6302],{"type":45,"value":564},{"type":39,"tag":491,"props":6304,"children":6305},{"class":493,"line":608},[6306],{"type":39,"tag":491,"props":6307,"children":6308},{"emptyLinePlaceholder":612},[6309],{"type":45,"value":615},{"type":39,"tag":491,"props":6311,"children":6312},{"class":493,"line":618},[6313,6317,6321],{"type":39,"tag":491,"props":6314,"children":6315},{"style":643},[6316],{"type":45,"value":375},{"type":39,"tag":491,"props":6318,"children":6319},{"style":520},[6320],{"type":45,"value":650},{"type":39,"tag":491,"props":6322,"children":6323},{"style":514},[6324],{"type":45,"value":655},{"type":39,"tag":491,"props":6326,"children":6327},{"class":493,"line":658},[6328,6332,6336,6340,6345,6349],{"type":39,"tag":491,"props":6329,"children":6330},{"style":662},[6331],{"type":45,"value":1008},{"type":39,"tag":491,"props":6333,"children":6334},{"style":514},[6335],{"type":45,"value":227},{"type":39,"tag":491,"props":6337,"children":6338},{"style":514},[6339],{"type":45,"value":548},{"type":39,"tag":491,"props":6341,"children":6342},{"style":551},[6343],{"type":45,"value":6344},"scheduler",{"type":39,"tag":491,"props":6346,"children":6347},{"style":514},[6348],{"type":45,"value":559},{"type":39,"tag":491,"props":6350,"children":6351},{"style":514},[6352],{"type":45,"value":804},{"type":39,"tag":491,"props":6354,"children":6355},{"class":493,"line":807},[6356,6361,6365,6369,6373],{"type":39,"tag":491,"props":6357,"children":6358},{"style":662},[6359],{"type":45,"value":6360},"  input",{"type":39,"tag":491,"props":6362,"children":6363},{"style":514},[6364],{"type":45,"value":227},{"type":39,"tag":491,"props":6366,"children":6367},{"style":643},[6368],{"type":45,"value":580},{"type":39,"tag":491,"props":6370,"children":6371},{"style":520},[6372],{"type":45,"value":650},{"type":39,"tag":491,"props":6374,"children":6375},{"style":514},[6376],{"type":45,"value":655},{"type":39,"tag":491,"props":6378,"children":6379},{"class":493,"line":1031},[6380,6385,6389,6393,6397,6401,6406,6410,6414,6418,6422,6426,6431,6435,6439,6443,6447,6451,6455,6459,6464,6468],{"type":39,"tag":491,"props":6381,"children":6382},{"style":662},[6383],{"type":45,"value":6384},"    jobs",{"type":39,"tag":491,"props":6386,"children":6387},{"style":514},[6388],{"type":45,"value":227},{"type":39,"tag":491,"props":6390,"children":6391},{"style":643},[6392],{"type":45,"value":580},{"type":39,"tag":491,"props":6394,"children":6395},{"style":520},[6396],{"type":45,"value":650},{"type":39,"tag":491,"props":6398,"children":6399},{"style":514},[6400],{"type":45,"value":682},{"type":39,"tag":491,"props":6402,"children":6403},{"style":662},[6404],{"type":45,"value":6405}," jobId",{"type":39,"tag":491,"props":6407,"children":6408},{"style":514},[6409],{"type":45,"value":227},{"type":39,"tag":491,"props":6411,"children":6412},{"style":514},[6413],{"type":45,"value":548},{"type":39,"tag":491,"props":6415,"children":6416},{"style":551},[6417],{"type":45,"value":721},{"type":39,"tag":491,"props":6419,"children":6420},{"style":514},[6421],{"type":45,"value":559},{"type":39,"tag":491,"props":6423,"children":6424},{"style":514},[6425],{"type":45,"value":528},{"type":39,"tag":491,"props":6427,"children":6428},{"style":662},[6429],{"type":45,"value":6430}," every",{"type":39,"tag":491,"props":6432,"children":6433},{"style":514},[6434],{"type":45,"value":227},{"type":39,"tag":491,"props":6436,"children":6437},{"style":514},[6438],{"type":45,"value":548},{"type":39,"tag":491,"props":6440,"children":6441},{"style":551},[6442],{"type":45,"value":721},{"type":39,"tag":491,"props":6444,"children":6445},{"style":514},[6446],{"type":45,"value":559},{"type":39,"tag":491,"props":6448,"children":6449},{"style":514},[6450],{"type":45,"value":538},{"type":39,"tag":491,"props":6452,"children":6453},{"style":520},[6454],{"type":45,"value":734},{"type":39,"tag":491,"props":6456,"children":6457},{"style":514},[6458],{"type":45,"value":1113},{"type":39,"tag":491,"props":6460,"children":6461},{"style":643},[6462],{"type":45,"value":6463},"array",{"type":39,"tag":491,"props":6465,"children":6466},{"style":520},[6467],{"type":45,"value":1421},{"type":39,"tag":491,"props":6469,"children":6470},{"style":514},[6471],{"type":45,"value":804},{"type":39,"tag":491,"props":6473,"children":6474},{"class":493,"line":1071},[6475,6480,6485,6489,6493,6497,6501,6505],{"type":39,"tag":491,"props":6476,"children":6477},{"style":514},[6478],{"type":45,"value":6479},"    '",{"type":39,"tag":491,"props":6481,"children":6482},{"style":662},[6483],{"type":45,"value":6484},"region?",{"type":39,"tag":491,"props":6486,"children":6487},{"style":514},[6488],{"type":45,"value":559},{"type":39,"tag":491,"props":6490,"children":6491},{"style":514},[6492],{"type":45,"value":227},{"type":39,"tag":491,"props":6494,"children":6495},{"style":514},[6496],{"type":45,"value":548},{"type":39,"tag":491,"props":6498,"children":6499},{"style":551},[6500],{"type":45,"value":721},{"type":39,"tag":491,"props":6502,"children":6503},{"style":514},[6504],{"type":45,"value":559},{"type":39,"tag":491,"props":6506,"children":6507},{"style":514},[6508],{"type":45,"value":804},{"type":39,"tag":491,"props":6510,"children":6511},{"class":493,"line":1168},[6512,6517,6521,6525,6529],{"type":39,"tag":491,"props":6513,"children":6514},{"style":662},[6515],{"type":45,"value":6516},"    apiKey",{"type":39,"tag":491,"props":6518,"children":6519},{"style":514},[6520],{"type":45,"value":227},{"type":39,"tag":491,"props":6522,"children":6523},{"style":643},[6524],{"type":45,"value":6238},{"type":39,"tag":491,"props":6526,"children":6527},{"style":520},[6528],{"type":45,"value":1421},{"type":39,"tag":491,"props":6530,"children":6531},{"style":514},[6532],{"type":45,"value":804},{"type":39,"tag":491,"props":6534,"children":6535},{"class":493,"line":1201},[6536,6541,6545],{"type":39,"tag":491,"props":6537,"children":6538},{"style":514},[6539],{"type":45,"value":6540},"  }",{"type":39,"tag":491,"props":6542,"children":6543},{"style":520},[6544],{"type":45,"value":734},{"type":39,"tag":491,"props":6546,"children":6547},{"style":514},[6548],{"type":45,"value":804},{"type":39,"tag":491,"props":6550,"children":6551},{"class":493,"line":1627},[6552],{"type":39,"tag":491,"props":6553,"children":6554},{"style":498},[6555],{"type":45,"value":6556},"  \u002F\u002F ...\n",{"type":39,"tag":491,"props":6558,"children":6559},{"class":493,"line":1644},[6560,6564,6568],{"type":39,"tag":491,"props":6561,"children":6562},{"style":514},[6563],{"type":45,"value":795},{"type":39,"tag":491,"props":6565,"children":6566},{"style":520},[6567],{"type":45,"value":734},{"type":39,"tag":491,"props":6569,"children":6570},{"style":514},[6571],{"type":45,"value":564},{"type":39,"tag":491,"props":6573,"children":6574},{"class":493,"line":1733},[6575],{"type":39,"tag":491,"props":6576,"children":6577},{"emptyLinePlaceholder":612},[6578],{"type":45,"value":615},{"type":39,"tag":491,"props":6580,"children":6581},{"class":493,"line":1742},[6582],{"type":39,"tag":491,"props":6583,"children":6584},{"style":498},[6585],{"type":45,"value":6586},"\u002F\u002F module.ts — where each value comes from; the binding mirrors the schema's shape\n",{"type":39,"tag":491,"props":6588,"children":6589},{"class":493,"line":1758},[6590,6594,6598,6603,6607,6612,6616,6620,6624,6628,6632],{"type":39,"tag":491,"props":6591,"children":6592},{"style":508},[6593],{"type":45,"value":511},{"type":39,"tag":491,"props":6595,"children":6596},{"style":514},[6597],{"type":45,"value":517},{"type":39,"tag":491,"props":6599,"children":6600},{"style":520},[6601],{"type":45,"value":6602}," envParam",{"type":39,"tag":491,"props":6604,"children":6605},{"style":514},[6606],{"type":45,"value":528},{"type":39,"tag":491,"props":6608,"children":6609},{"style":520},[6610],{"type":45,"value":6611}," envSecret",{"type":39,"tag":491,"props":6613,"children":6614},{"style":514},[6615],{"type":45,"value":538},{"type":39,"tag":491,"props":6617,"children":6618},{"style":508},[6619],{"type":45,"value":543},{"type":39,"tag":491,"props":6621,"children":6622},{"style":514},[6623],{"type":45,"value":548},{"type":39,"tag":491,"props":6625,"children":6626},{"style":551},[6627],{"type":45,"value":364},{"type":39,"tag":491,"props":6629,"children":6630},{"style":514},[6631],{"type":45,"value":559},{"type":39,"tag":491,"props":6633,"children":6634},{"style":514},[6635],{"type":45,"value":564},{"type":39,"tag":491,"props":6637,"children":6638},{"class":493,"line":1779},[6639,6643,6648,6652],{"type":39,"tag":491,"props":6640,"children":6641},{"style":643},[6642],{"type":45,"value":4684},{"type":39,"tag":491,"props":6644,"children":6645},{"style":520},[6646],{"type":45,"value":6647},"(scheduler",{"type":39,"tag":491,"props":6649,"children":6650},{"style":514},[6651],{"type":45,"value":528},{"type":39,"tag":491,"props":6653,"children":6654},{"style":514},[6655],{"type":45,"value":1624},{"type":39,"tag":491,"props":6657,"children":6658},{"class":493,"line":1787},[6659,6663,6667],{"type":39,"tag":491,"props":6660,"children":6661},{"style":662},[6662],{"type":45,"value":6360},{"type":39,"tag":491,"props":6664,"children":6665},{"style":514},[6666],{"type":45,"value":227},{"type":39,"tag":491,"props":6668,"children":6669},{"style":514},[6670],{"type":45,"value":1624},{"type":39,"tag":491,"props":6672,"children":6673},{"class":493,"line":1796},[6674,6678,6682,6686,6690,6694,6698,6702,6706,6710,6714,6718,6722,6726,6730,6734,6738,6743,6747],{"type":39,"tag":491,"props":6675,"children":6676},{"style":662},[6677],{"type":45,"value":6384},{"type":39,"tag":491,"props":6679,"children":6680},{"style":514},[6681],{"type":45,"value":227},{"type":39,"tag":491,"props":6683,"children":6684},{"style":520},[6685],{"type":45,"value":3813},{"type":39,"tag":491,"props":6687,"children":6688},{"style":514},[6689],{"type":45,"value":682},{"type":39,"tag":491,"props":6691,"children":6692},{"style":662},[6693],{"type":45,"value":6405},{"type":39,"tag":491,"props":6695,"children":6696},{"style":514},[6697],{"type":45,"value":227},{"type":39,"tag":491,"props":6699,"children":6700},{"style":514},[6701],{"type":45,"value":548},{"type":39,"tag":491,"props":6703,"children":6704},{"style":551},[6705],{"type":45,"value":5887},{"type":39,"tag":491,"props":6707,"children":6708},{"style":514},[6709],{"type":45,"value":559},{"type":39,"tag":491,"props":6711,"children":6712},{"style":514},[6713],{"type":45,"value":528},{"type":39,"tag":491,"props":6715,"children":6716},{"style":662},[6717],{"type":45,"value":6430},{"type":39,"tag":491,"props":6719,"children":6720},{"style":514},[6721],{"type":45,"value":227},{"type":39,"tag":491,"props":6723,"children":6724},{"style":514},[6725],{"type":45,"value":548},{"type":39,"tag":491,"props":6727,"children":6728},{"style":551},[6729],{"type":45,"value":5718},{"type":39,"tag":491,"props":6731,"children":6732},{"style":514},[6733],{"type":45,"value":559},{"type":39,"tag":491,"props":6735,"children":6736},{"style":514},[6737],{"type":45,"value":538},{"type":39,"tag":491,"props":6739,"children":6740},{"style":520},[6741],{"type":45,"value":6742},"]",{"type":39,"tag":491,"props":6744,"children":6745},{"style":514},[6746],{"type":45,"value":528},{"type":39,"tag":491,"props":6748,"children":6749},{"style":498},[6750],{"type":45,"value":6751},"   \u002F\u002F a literal\n",{"type":39,"tag":491,"props":6753,"children":6754},{"class":493,"line":1805},[6755,6760,6764,6768,6772,6776,6781,6785,6789,6793],{"type":39,"tag":491,"props":6756,"children":6757},{"style":662},[6758],{"type":45,"value":6759},"    region",{"type":39,"tag":491,"props":6761,"children":6762},{"style":514},[6763],{"type":45,"value":227},{"type":39,"tag":491,"props":6765,"children":6766},{"style":643},[6767],{"type":45,"value":6602},{"type":39,"tag":491,"props":6769,"children":6770},{"style":520},[6771],{"type":45,"value":650},{"type":39,"tag":491,"props":6773,"children":6774},{"style":514},[6775],{"type":45,"value":559},{"type":39,"tag":491,"props":6777,"children":6778},{"style":551},[6779],{"type":45,"value":6780},"REGION",{"type":39,"tag":491,"props":6782,"children":6783},{"style":514},[6784],{"type":45,"value":559},{"type":39,"tag":491,"props":6786,"children":6787},{"style":520},[6788],{"type":45,"value":734},{"type":39,"tag":491,"props":6790,"children":6791},{"style":514},[6792],{"type":45,"value":528},{"type":39,"tag":491,"props":6794,"children":6795},{"style":498},[6796],{"type":45,"value":6797},"                 \u002F\u002F a per-stage platform variable\n",{"type":39,"tag":491,"props":6799,"children":6801},{"class":493,"line":6800},21,[6802,6806,6810,6814,6818,6822,6827,6831,6835,6839],{"type":39,"tag":491,"props":6803,"children":6804},{"style":662},[6805],{"type":45,"value":6516},{"type":39,"tag":491,"props":6807,"children":6808},{"style":514},[6809],{"type":45,"value":227},{"type":39,"tag":491,"props":6811,"children":6812},{"style":643},[6813],{"type":45,"value":6611},{"type":39,"tag":491,"props":6815,"children":6816},{"style":520},[6817],{"type":45,"value":650},{"type":39,"tag":491,"props":6819,"children":6820},{"style":514},[6821],{"type":45,"value":559},{"type":39,"tag":491,"props":6823,"children":6824},{"style":551},[6825],{"type":45,"value":6826},"SCHEDULER_API_KEY",{"type":39,"tag":491,"props":6828,"children":6829},{"style":514},[6830],{"type":45,"value":559},{"type":39,"tag":491,"props":6832,"children":6833},{"style":520},[6834],{"type":45,"value":734},{"type":39,"tag":491,"props":6836,"children":6837},{"style":514},[6838],{"type":45,"value":528},{"type":39,"tag":491,"props":6840,"children":6841},{"style":498},[6842],{"type":45,"value":6843},"     \u002F\u002F a credential — name only, never the value\n",{"type":39,"tag":491,"props":6845,"children":6847},{"class":493,"line":6846},22,[6848],{"type":39,"tag":491,"props":6849,"children":6850},{"style":514},[6851],{"type":45,"value":1739},{"type":39,"tag":491,"props":6853,"children":6855},{"class":493,"line":6854},23,[6856,6860,6864],{"type":39,"tag":491,"props":6857,"children":6858},{"style":514},[6859],{"type":45,"value":795},{"type":39,"tag":491,"props":6861,"children":6862},{"style":520},[6863],{"type":45,"value":734},{"type":39,"tag":491,"props":6865,"children":6866},{"style":514},[6867],{"type":45,"value":564},{"type":39,"tag":491,"props":6869,"children":6871},{"class":493,"line":6870},24,[6872],{"type":39,"tag":491,"props":6873,"children":6874},{"emptyLinePlaceholder":612},[6875],{"type":45,"value":615},{"type":39,"tag":491,"props":6877,"children":6879},{"class":493,"line":6878},25,[6880],{"type":39,"tag":491,"props":6881,"children":6882},{"style":498},[6883],{"type":45,"value":6884},"\u002F\u002F server.ts — one call, one validated typed object\n",{"type":39,"tag":491,"props":6886,"children":6888},{"class":493,"line":6887},26,[6889,6893,6898,6902,6906,6910,6914,6918],{"type":39,"tag":491,"props":6890,"children":6891},{"style":627},[6892],{"type":45,"value":1384},{"type":39,"tag":491,"props":6894,"children":6895},{"style":520},[6896],{"type":45,"value":6897}," input ",{"type":39,"tag":491,"props":6899,"children":6900},{"style":514},[6901],{"type":45,"value":640},{"type":39,"tag":491,"props":6903,"children":6904},{"style":520},[6905],{"type":45,"value":1407},{"type":39,"tag":491,"props":6907,"children":6908},{"style":514},[6909],{"type":45,"value":1113},{"type":39,"tag":491,"props":6911,"children":6912},{"style":643},[6913],{"type":45,"value":3236},{"type":39,"tag":491,"props":6915,"children":6916},{"style":520},[6917],{"type":45,"value":1421},{"type":39,"tag":491,"props":6919,"children":6920},{"style":514},[6921],{"type":45,"value":564},{"type":39,"tag":491,"props":6923,"children":6925},{"class":493,"line":6924},27,[6926,6930,6934,6939,6943,6948,6952,6956],{"type":39,"tag":491,"props":6927,"children":6928},{"style":520},[6929],{"type":45,"value":3236},{"type":39,"tag":491,"props":6931,"children":6932},{"style":514},[6933],{"type":45,"value":1113},{"type":39,"tag":491,"props":6935,"children":6936},{"style":520},[6937],{"type":45,"value":6938},"apiKey",{"type":39,"tag":491,"props":6940,"children":6941},{"style":514},[6942],{"type":45,"value":1113},{"type":39,"tag":491,"props":6944,"children":6945},{"style":643},[6946],{"type":45,"value":6947},"expose",{"type":39,"tag":491,"props":6949,"children":6950},{"style":520},[6951],{"type":45,"value":1421},{"type":39,"tag":491,"props":6953,"children":6954},{"style":514},[6955],{"type":45,"value":1426},{"type":39,"tag":491,"props":6957,"children":6958},{"style":498},[6959],{"type":45,"value":6960}," \u002F\u002F the only way to a secret's value; the box redacts everywhere else\n",{"type":39,"tag":48,"props":6962,"children":6963},{},[6964],{"type":45,"value":6965},"Rules that bite:",{"type":39,"tag":99,"props":6967,"children":6968},{},[6969,6993,7008,7033,7080],{"type":39,"tag":103,"props":6970,"children":6971},{},[6972,6977,6979,6984,6986,6991],{"type":39,"tag":54,"props":6973,"children":6974},{},[6975],{"type":45,"value":6976},"Secretness is enforced by validation",{"type":45,"value":6978},": a literal bound where the schema\nexpects ",{"type":39,"tag":76,"props":6980,"children":6982},{"className":6981},[],[6983],{"type":45,"value":130},{"type":45,"value":6985}," fails the deploy, and ",{"type":39,"tag":76,"props":6987,"children":6989},{"className":6988},[],[6990],{"type":45,"value":389},{"type":45,"value":6992}," bound to a plain\nstring field fails the same way. Don't put credentials in plain fields.",{"type":39,"tag":103,"props":6994,"children":6995},{},[6996,7006],{"type":39,"tag":54,"props":6997,"children":6998},{},[6999,7004],{"type":39,"tag":76,"props":7000,"children":7002},{"className":7001},[],[7003],{"type":45,"value":396},{"type":45,"value":7005}," values arrive as raw strings",{"type":45,"value":7007}," — bind them to string fields.\nThe stage's platform variable is the store; the deploying shell only seeds\nit (preflight copies a missing name up from the shell, and fails early,\nnaming the variable, when both lack it). Changing the platform value needs\na redeploy.",{"type":39,"tag":103,"props":7009,"children":7010},{},[7011,7016,7018,7023,7025,7031],{"type":39,"tag":54,"props":7012,"children":7013},{},[7014],{"type":45,"value":7015},"Absence is the schema's call",{"type":45,"value":7017},": an env-bound field whose variable is\nunset (or empty) resolves to ",{"type":39,"tag":2648,"props":7019,"children":7020},{},[7021],{"type":45,"value":7022},"key omitted",{"type":45,"value":7024}," — legal only if the schema says\nso (optional field, union arm). The deploy report prints the serialized\ninput document (secret-free: secrets ride as ",{"type":39,"tag":76,"props":7026,"children":7028},{"className":7027},[],[7029],{"type":45,"value":7030},"{\"$secret\":\"VAR\"}",{"type":45,"value":7032}," pointers)\nand every key that resolved absent.",{"type":39,"tag":103,"props":7034,"children":7035},{},[7036,7048,7050,7055,7057,7063,7065,7070,7072,7078],{"type":39,"tag":54,"props":7037,"children":7038},{},[7039,7041,7046],{"type":45,"value":7040},"The reserved ",{"type":39,"tag":76,"props":7042,"children":7044},{"className":7043},[],[7045],{"type":45,"value":1460},{"type":45,"value":7047}," (default 3000) is outside the schema",{"type":45,"value":7049}," — read it\nthrough ",{"type":39,"tag":76,"props":7051,"children":7053},{"className":7052},[],[7054],{"type":45,"value":141},{"type":45,"value":7056}," (a sibling of ",{"type":39,"tag":76,"props":7058,"children":7060},{"className":7059},[],[7061],{"type":45,"value":7062},"service.origin()",{"type":45,"value":7064},"), never\n",{"type":39,"tag":76,"props":7066,"children":7068},{"className":7067},[],[7069],{"type":45,"value":149},{"type":45,"value":7071},". The framework also exports ",{"type":39,"tag":76,"props":7073,"children":7075},{"className":7074},[],[7076],{"type":45,"value":7077},"PORT",{"type":45,"value":7079}," for Next.js standalone,\nwhich binds it itself.",{"type":39,"tag":103,"props":7081,"children":7082},{},[7083],{"type":45,"value":7084},"A module forwards a secret need without learning the platform name\n(the auth Module above); the forwarded ref is a binding leaf.",{"type":39,"tag":48,"props":7086,"children":7087},{},[7088,7094,7096,7102],{"type":39,"tag":76,"props":7089,"children":7091},{"className":7090},[],[7092],{"type":45,"value":7093},"examples\u002Fenv-param",{"type":45,"value":7095}," and ",{"type":39,"tag":76,"props":7097,"children":7099},{"className":7098},[],[7100],{"type":45,"value":7101},"examples\u002Fstorefront-auth",{"type":45,"value":7103}," in the prisma\u002Fcomposer\nrepo are the working versions.",{"type":39,"tag":442,"props":7105,"children":7107},{"id":7106},"testing",[7108],{"type":45,"value":7109},"Testing",{"type":39,"tag":48,"props":7111,"children":7112},{},[7113,7115,7120],{"type":45,"value":7114},"You test by deciding what ",{"type":39,"tag":76,"props":7116,"children":7118},{"className":7117},[],[7119],{"type":45,"value":1230},{"type":45,"value":7121}," gives the code, never by editing the code\nunder test:",{"type":39,"tag":229,"props":7123,"children":7124},{},[7125,7146],{"type":39,"tag":233,"props":7126,"children":7127},{},[7128],{"type":39,"tag":237,"props":7129,"children":7130},{},[7131,7136,7141],{"type":39,"tag":241,"props":7132,"children":7133},{},[7134],{"type":45,"value":7135},"You want to…",{"type":39,"tag":241,"props":7137,"children":7138},{},[7139],{"type":45,"value":7140},"Use",{"type":39,"tag":241,"props":7142,"children":7143},{},[7144],{"type":45,"value":7145},"From",{"type":39,"tag":252,"props":7147,"children":7148},{},[7149,7175],{"type":39,"tag":237,"props":7150,"children":7151},{},[7152,7157,7166],{"type":39,"tag":259,"props":7153,"children":7154},{},[7155],{"type":45,"value":7156},"Test a page \u002F action \u002F handler in isolation",{"type":39,"tag":259,"props":7158,"children":7159},{},[7160],{"type":39,"tag":76,"props":7161,"children":7163},{"className":7162},[],[7164],{"type":45,"value":7165},"mockService",{"type":39,"tag":259,"props":7167,"children":7168},{},[7169],{"type":39,"tag":76,"props":7170,"children":7172},{"className":7171},[],[7173],{"type":45,"value":7174},"@prisma\u002Fcomposer\u002Ftesting",{"type":39,"tag":237,"props":7176,"children":7177},{},[7178,7183,7192],{"type":39,"tag":259,"props":7179,"children":7180},{},[7181],{"type":45,"value":7182},"Run the real boot + request path against a fake dependency",{"type":39,"tag":259,"props":7184,"children":7185},{},[7186],{"type":39,"tag":76,"props":7187,"children":7189},{"className":7188},[],[7190],{"type":45,"value":7191},"bootstrapService",{"type":39,"tag":259,"props":7193,"children":7194},{},[7195],{"type":39,"tag":76,"props":7196,"children":7198},{"className":7197},[],[7199],{"type":45,"value":7200},"@prisma\u002Fcomposer-prisma-cloud\u002Ftesting",{"type":39,"tag":48,"props":7202,"children":7203},{},[7204,7215,7217,7222,7224,7229,7231,7236,7238,7244,7246,7252],{"type":39,"tag":54,"props":7205,"children":7206},{},[7207,7209,7214],{"type":45,"value":7208},"Unit — ",{"type":39,"tag":76,"props":7210,"children":7212},{"className":7211},[],[7213],{"type":45,"value":7165},{"type":45,"value":1113},{"type":45,"value":7216}," Returns a copy of the service whose ",{"type":39,"tag":76,"props":7218,"children":7220},{"className":7219},[],[7221],{"type":45,"value":1230},{"type":45,"value":7223}," yields\nyour doubles (type-checked against the declared deps) and whose ",{"type":39,"tag":76,"props":7225,"children":7227},{"className":7226},[],[7228],{"type":45,"value":6179},{"type":45,"value":7230},"\nyields the object you pass under the reserved ",{"type":39,"tag":76,"props":7232,"children":7234},{"className":7233},[],[7235],{"type":45,"value":3236},{"type":45,"value":7237}," key, in one flat\nobject (required exactly when the service declares an input schema; handed\nover as-is, not validated). Wiring the module substitution is your runner's\njob (",{"type":39,"tag":76,"props":7239,"children":7241},{"className":7240},[],[7242],{"type":45,"value":7243},"vi.mock",{"type":45,"value":7245}," in Vitest, ",{"type":39,"tag":76,"props":7247,"children":7249},{"className":7248},[],[7250],{"type":45,"value":7251},"mock.module",{"type":45,"value":7253}," in bun test):",{"type":39,"tag":480,"props":7255,"children":7257},{"className":2280,"code":7256,"language":2282,"meta":485,"style":485},"\u002F\u002F page.test.tsx\nimport { mockService } from '@prisma\u002Fcomposer\u002Ftesting';\nimport realService from '..\u002Fsrc\u002Fservice.ts';\n\nvi.mock('..\u002Fsrc\u002Fservice.ts', () => ({\n  default: mockService(realService, {\n    auth: { verify: async () => ({ ok: true }) }, \u002F\u002F wrong shape = compile error\n  }),\n}));\n\nimport Page from '.\u002Fpage.tsx';\nexpect(renderToString(await Page())).toContain('Signed in: true');\n",[7258],{"type":39,"tag":76,"props":7259,"children":7260},{"__ignoreMap":485},[7261,7269,7309,7341,7348,7401,7430,7506,7521,7536,7543,7576],{"type":39,"tag":491,"props":7262,"children":7263},{"class":493,"line":494},[7264],{"type":39,"tag":491,"props":7265,"children":7266},{"style":498},[7267],{"type":45,"value":7268},"\u002F\u002F page.test.tsx\n",{"type":39,"tag":491,"props":7270,"children":7271},{"class":493,"line":504},[7272,7276,7280,7285,7289,7293,7297,7301,7305],{"type":39,"tag":491,"props":7273,"children":7274},{"style":508},[7275],{"type":45,"value":511},{"type":39,"tag":491,"props":7277,"children":7278},{"style":514},[7279],{"type":45,"value":517},{"type":39,"tag":491,"props":7281,"children":7282},{"style":520},[7283],{"type":45,"value":7284}," mockService",{"type":39,"tag":491,"props":7286,"children":7287},{"style":514},[7288],{"type":45,"value":538},{"type":39,"tag":491,"props":7290,"children":7291},{"style":508},[7292],{"type":45,"value":543},{"type":39,"tag":491,"props":7294,"children":7295},{"style":514},[7296],{"type":45,"value":548},{"type":39,"tag":491,"props":7298,"children":7299},{"style":551},[7300],{"type":45,"value":7174},{"type":39,"tag":491,"props":7302,"children":7303},{"style":514},[7304],{"type":45,"value":559},{"type":39,"tag":491,"props":7306,"children":7307},{"style":514},[7308],{"type":45,"value":564},{"type":39,"tag":491,"props":7310,"children":7311},{"class":493,"line":23},[7312,7316,7321,7325,7329,7333,7337],{"type":39,"tag":491,"props":7313,"children":7314},{"style":508},[7315],{"type":45,"value":511},{"type":39,"tag":491,"props":7317,"children":7318},{"style":520},[7319],{"type":45,"value":7320}," realService ",{"type":39,"tag":491,"props":7322,"children":7323},{"style":508},[7324],{"type":45,"value":862},{"type":39,"tag":491,"props":7326,"children":7327},{"style":514},[7328],{"type":45,"value":548},{"type":39,"tag":491,"props":7330,"children":7331},{"style":551},[7332],{"type":45,"value":2318},{"type":39,"tag":491,"props":7334,"children":7335},{"style":514},[7336],{"type":45,"value":559},{"type":39,"tag":491,"props":7338,"children":7339},{"style":514},[7340],{"type":45,"value":564},{"type":39,"tag":491,"props":7342,"children":7343},{"class":493,"line":608},[7344],{"type":39,"tag":491,"props":7345,"children":7346},{"emptyLinePlaceholder":612},[7347],{"type":45,"value":615},{"type":39,"tag":491,"props":7349,"children":7350},{"class":493,"line":618},[7351,7356,7360,7365,7369,7373,7377,7381,7385,7389,7393,7397],{"type":39,"tag":491,"props":7352,"children":7353},{"style":520},[7354],{"type":45,"value":7355},"vi",{"type":39,"tag":491,"props":7357,"children":7358},{"style":514},[7359],{"type":45,"value":1113},{"type":39,"tag":491,"props":7361,"children":7362},{"style":643},[7363],{"type":45,"value":7364},"mock",{"type":39,"tag":491,"props":7366,"children":7367},{"style":520},[7368],{"type":45,"value":650},{"type":39,"tag":491,"props":7370,"children":7371},{"style":514},[7372],{"type":45,"value":559},{"type":39,"tag":491,"props":7374,"children":7375},{"style":551},[7376],{"type":45,"value":2318},{"type":39,"tag":491,"props":7378,"children":7379},{"style":514},[7380],{"type":45,"value":559},{"type":39,"tag":491,"props":7382,"children":7383},{"style":514},[7384],{"type":45,"value":528},{"type":39,"tag":491,"props":7386,"children":7387},{"style":514},[7388],{"type":45,"value":3856},{"type":39,"tag":491,"props":7390,"children":7391},{"style":627},[7392],{"type":45,"value":1679},{"type":39,"tag":491,"props":7394,"children":7395},{"style":520},[7396],{"type":45,"value":74},{"type":39,"tag":491,"props":7398,"children":7399},{"style":514},[7400],{"type":45,"value":655},{"type":39,"tag":491,"props":7402,"children":7403},{"class":493,"line":658},[7404,7409,7413,7417,7422,7426],{"type":39,"tag":491,"props":7405,"children":7406},{"style":662},[7407],{"type":45,"value":7408},"  default",{"type":39,"tag":491,"props":7410,"children":7411},{"style":514},[7412],{"type":45,"value":227},{"type":39,"tag":491,"props":7414,"children":7415},{"style":643},[7416],{"type":45,"value":7284},{"type":39,"tag":491,"props":7418,"children":7419},{"style":520},[7420],{"type":45,"value":7421},"(realService",{"type":39,"tag":491,"props":7423,"children":7424},{"style":514},[7425],{"type":45,"value":528},{"type":39,"tag":491,"props":7427,"children":7428},{"style":514},[7429],{"type":45,"value":1624},{"type":39,"tag":491,"props":7431,"children":7432},{"class":493,"line":807},[7433,7438,7442,7446,7451,7455,7459,7463,7467,7471,7475,7479,7483,7489,7493,7497,7501],{"type":39,"tag":491,"props":7434,"children":7435},{"style":662},[7436],{"type":45,"value":7437},"    auth",{"type":39,"tag":491,"props":7439,"children":7440},{"style":514},[7441],{"type":45,"value":227},{"type":39,"tag":491,"props":7443,"children":7444},{"style":514},[7445],{"type":45,"value":517},{"type":39,"tag":491,"props":7447,"children":7448},{"style":643},[7449],{"type":45,"value":7450}," verify",{"type":39,"tag":491,"props":7452,"children":7453},{"style":514},[7454],{"type":45,"value":227},{"type":39,"tag":491,"props":7456,"children":7457},{"style":627},[7458],{"type":45,"value":1659},{"type":39,"tag":491,"props":7460,"children":7461},{"style":514},[7462],{"type":45,"value":3856},{"type":39,"tag":491,"props":7464,"children":7465},{"style":627},[7466],{"type":45,"value":1679},{"type":39,"tag":491,"props":7468,"children":7469},{"style":520},[7470],{"type":45,"value":74},{"type":39,"tag":491,"props":7472,"children":7473},{"style":514},[7474],{"type":45,"value":682},{"type":39,"tag":491,"props":7476,"children":7477},{"style":662},[7478],{"type":45,"value":764},{"type":39,"tag":491,"props":7480,"children":7481},{"style":514},[7482],{"type":45,"value":227},{"type":39,"tag":491,"props":7484,"children":7486},{"style":7485},"--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC",[7487],{"type":45,"value":7488}," true",{"type":39,"tag":491,"props":7490,"children":7491},{"style":514},[7492],{"type":45,"value":538},{"type":39,"tag":491,"props":7494,"children":7495},{"style":520},[7496],{"type":45,"value":790},{"type":39,"tag":491,"props":7498,"children":7499},{"style":514},[7500],{"type":45,"value":5036},{"type":39,"tag":491,"props":7502,"children":7503},{"style":498},[7504],{"type":45,"value":7505}," \u002F\u002F wrong shape = compile error\n",{"type":39,"tag":491,"props":7507,"children":7508},{"class":493,"line":1031},[7509,7513,7517],{"type":39,"tag":491,"props":7510,"children":7511},{"style":514},[7512],{"type":45,"value":6540},{"type":39,"tag":491,"props":7514,"children":7515},{"style":520},[7516],{"type":45,"value":734},{"type":39,"tag":491,"props":7518,"children":7519},{"style":514},[7520],{"type":45,"value":804},{"type":39,"tag":491,"props":7522,"children":7523},{"class":493,"line":1071},[7524,7528,7532],{"type":39,"tag":491,"props":7525,"children":7526},{"style":514},[7527],{"type":45,"value":795},{"type":39,"tag":491,"props":7529,"children":7530},{"style":520},[7531],{"type":45,"value":4672},{"type":39,"tag":491,"props":7533,"children":7534},{"style":514},[7535],{"type":45,"value":564},{"type":39,"tag":491,"props":7537,"children":7538},{"class":493,"line":1168},[7539],{"type":39,"tag":491,"props":7540,"children":7541},{"emptyLinePlaceholder":612},[7542],{"type":45,"value":615},{"type":39,"tag":491,"props":7544,"children":7545},{"class":493,"line":1201},[7546,7550,7555,7559,7563,7568,7572],{"type":39,"tag":491,"props":7547,"children":7548},{"style":508},[7549],{"type":45,"value":511},{"type":39,"tag":491,"props":7551,"children":7552},{"style":520},[7553],{"type":45,"value":7554}," Page ",{"type":39,"tag":491,"props":7556,"children":7557},{"style":508},[7558],{"type":45,"value":862},{"type":39,"tag":491,"props":7560,"children":7561},{"style":514},[7562],{"type":45,"value":548},{"type":39,"tag":491,"props":7564,"children":7565},{"style":551},[7566],{"type":45,"value":7567},".\u002Fpage.tsx",{"type":39,"tag":491,"props":7569,"children":7570},{"style":514},[7571],{"type":45,"value":559},{"type":39,"tag":491,"props":7573,"children":7574},{"style":514},[7575],{"type":45,"value":564},{"type":39,"tag":491,"props":7577,"children":7578},{"class":493,"line":1627},[7579,7584,7588,7593,7597,7602,7607,7612,7616,7621,7625,7629,7634,7638,7642],{"type":39,"tag":491,"props":7580,"children":7581},{"style":643},[7582],{"type":45,"value":7583},"expect",{"type":39,"tag":491,"props":7585,"children":7586},{"style":520},[7587],{"type":45,"value":650},{"type":39,"tag":491,"props":7589,"children":7590},{"style":643},[7591],{"type":45,"value":7592},"renderToString",{"type":39,"tag":491,"props":7594,"children":7595},{"style":520},[7596],{"type":45,"value":650},{"type":39,"tag":491,"props":7598,"children":7599},{"style":508},[7600],{"type":45,"value":7601},"await",{"type":39,"tag":491,"props":7603,"children":7604},{"style":643},[7605],{"type":45,"value":7606}," Page",{"type":39,"tag":491,"props":7608,"children":7609},{"style":520},[7610],{"type":45,"value":7611},"()))",{"type":39,"tag":491,"props":7613,"children":7614},{"style":514},[7615],{"type":45,"value":1113},{"type":39,"tag":491,"props":7617,"children":7618},{"style":643},[7619],{"type":45,"value":7620},"toContain",{"type":39,"tag":491,"props":7622,"children":7623},{"style":520},[7624],{"type":45,"value":650},{"type":39,"tag":491,"props":7626,"children":7627},{"style":514},[7628],{"type":45,"value":559},{"type":39,"tag":491,"props":7630,"children":7631},{"style":551},[7632],{"type":45,"value":7633},"Signed in: true",{"type":39,"tag":491,"props":7635,"children":7636},{"style":514},[7637],{"type":45,"value":559},{"type":39,"tag":491,"props":7639,"children":7640},{"style":520},[7641],{"type":45,"value":734},{"type":39,"tag":491,"props":7643,"children":7644},{"style":514},[7645],{"type":45,"value":564},{"type":39,"tag":48,"props":7647,"children":7648},{},[7649,7660,7662,7668],{"type":39,"tag":54,"props":7650,"children":7651},{},[7652,7654,7659],{"type":45,"value":7653},"Integration — ",{"type":39,"tag":76,"props":7655,"children":7657},{"className":7656},[],[7658],{"type":45,"value":7191},{"type":45,"value":1113},{"type":45,"value":7661}," Boots the service's real built entry\nin-process against a config you choose, exactly as a deployed boot would;\ndrive it over real HTTP. Run under ",{"type":39,"tag":76,"props":7663,"children":7665},{"className":7664},[],[7666],{"type":45,"value":7667},"bun test",{"type":45,"value":227},{"type":39,"tag":480,"props":7670,"children":7672},{"className":482,"code":7671,"language":484,"meta":485,"style":485},"import { bootstrapService } from '@prisma\u002Fcomposer-prisma-cloud\u002Ftesting';\nimport fakeAuth from '@my-app\u002Fauth\u002Ffake'; \u002F\u002F in-memory handler, no db\nimport storefront from '..\u002Fsrc\u002Fservice.ts';\n\nconst fake = Bun.serve({ port: 0, fetch: fakeAuth });\n\nconst app = await bootstrapService(storefront, {\n  service: { port: 4310 },\n  inputs: { auth: { url: fake.url.href } },\n});\n\nconst res = await app.fetch(new Request(app.url));\n",[7673],{"type":39,"tag":76,"props":7674,"children":7675},{"__ignoreMap":485},[7676,7716,7754,7786,7793,7870,7877,7914,7947,8013,8028,8035],{"type":39,"tag":491,"props":7677,"children":7678},{"class":493,"line":494},[7679,7683,7687,7692,7696,7700,7704,7708,7712],{"type":39,"tag":491,"props":7680,"children":7681},{"style":508},[7682],{"type":45,"value":511},{"type":39,"tag":491,"props":7684,"children":7685},{"style":514},[7686],{"type":45,"value":517},{"type":39,"tag":491,"props":7688,"children":7689},{"style":520},[7690],{"type":45,"value":7691}," bootstrapService",{"type":39,"tag":491,"props":7693,"children":7694},{"style":514},[7695],{"type":45,"value":538},{"type":39,"tag":491,"props":7697,"children":7698},{"style":508},[7699],{"type":45,"value":543},{"type":39,"tag":491,"props":7701,"children":7702},{"style":514},[7703],{"type":45,"value":548},{"type":39,"tag":491,"props":7705,"children":7706},{"style":551},[7707],{"type":45,"value":7200},{"type":39,"tag":491,"props":7709,"children":7710},{"style":514},[7711],{"type":45,"value":559},{"type":39,"tag":491,"props":7713,"children":7714},{"style":514},[7715],{"type":45,"value":564},{"type":39,"tag":491,"props":7717,"children":7718},{"class":493,"line":504},[7719,7723,7728,7732,7736,7741,7745,7749],{"type":39,"tag":491,"props":7720,"children":7721},{"style":508},[7722],{"type":45,"value":511},{"type":39,"tag":491,"props":7724,"children":7725},{"style":520},[7726],{"type":45,"value":7727}," fakeAuth ",{"type":39,"tag":491,"props":7729,"children":7730},{"style":508},[7731],{"type":45,"value":862},{"type":39,"tag":491,"props":7733,"children":7734},{"style":514},[7735],{"type":45,"value":548},{"type":39,"tag":491,"props":7737,"children":7738},{"style":551},[7739],{"type":45,"value":7740},"@my-app\u002Fauth\u002Ffake",{"type":39,"tag":491,"props":7742,"children":7743},{"style":514},[7744],{"type":45,"value":559},{"type":39,"tag":491,"props":7746,"children":7747},{"style":514},[7748],{"type":45,"value":1426},{"type":39,"tag":491,"props":7750,"children":7751},{"style":498},[7752],{"type":45,"value":7753}," \u002F\u002F in-memory handler, no db\n",{"type":39,"tag":491,"props":7755,"children":7756},{"class":493,"line":23},[7757,7761,7766,7770,7774,7778,7782],{"type":39,"tag":491,"props":7758,"children":7759},{"style":508},[7760],{"type":45,"value":511},{"type":39,"tag":491,"props":7762,"children":7763},{"style":520},[7764],{"type":45,"value":7765}," storefront ",{"type":39,"tag":491,"props":7767,"children":7768},{"style":508},[7769],{"type":45,"value":862},{"type":39,"tag":491,"props":7771,"children":7772},{"style":514},[7773],{"type":45,"value":548},{"type":39,"tag":491,"props":7775,"children":7776},{"style":551},[7777],{"type":45,"value":2318},{"type":39,"tag":491,"props":7779,"children":7780},{"style":514},[7781],{"type":45,"value":559},{"type":39,"tag":491,"props":7783,"children":7784},{"style":514},[7785],{"type":45,"value":564},{"type":39,"tag":491,"props":7787,"children":7788},{"class":493,"line":608},[7789],{"type":39,"tag":491,"props":7790,"children":7791},{"emptyLinePlaceholder":612},[7792],{"type":45,"value":615},{"type":39,"tag":491,"props":7794,"children":7795},{"class":493,"line":618},[7796,7800,7805,7809,7814,7818,7822,7826,7830,7834,7838,7842,7846,7850,7854,7858,7862,7866],{"type":39,"tag":491,"props":7797,"children":7798},{"style":627},[7799],{"type":45,"value":1384},{"type":39,"tag":491,"props":7801,"children":7802},{"style":520},[7803],{"type":45,"value":7804}," fake ",{"type":39,"tag":491,"props":7806,"children":7807},{"style":514},[7808],{"type":45,"value":640},{"type":39,"tag":491,"props":7810,"children":7811},{"style":520},[7812],{"type":45,"value":7813}," Bun",{"type":39,"tag":491,"props":7815,"children":7816},{"style":514},[7817],{"type":45,"value":1113},{"type":39,"tag":491,"props":7819,"children":7820},{"style":643},[7821],{"type":45,"value":1820},{"type":39,"tag":491,"props":7823,"children":7824},{"style":520},[7825],{"type":45,"value":650},{"type":39,"tag":491,"props":7827,"children":7828},{"style":514},[7829],{"type":45,"value":682},{"type":39,"tag":491,"props":7831,"children":7832},{"style":662},[7833],{"type":45,"value":1833},{"type":39,"tag":491,"props":7835,"children":7836},{"style":514},[7837],{"type":45,"value":227},{"type":39,"tag":491,"props":7839,"children":7840},{"style":1550},[7841],{"type":45,"value":1718},{"type":39,"tag":491,"props":7843,"children":7844},{"style":514},[7845],{"type":45,"value":528},{"type":39,"tag":491,"props":7847,"children":7848},{"style":662},[7849],{"type":45,"value":1868},{"type":39,"tag":491,"props":7851,"children":7852},{"style":514},[7853],{"type":45,"value":227},{"type":39,"tag":491,"props":7855,"children":7856},{"style":520},[7857],{"type":45,"value":7727},{"type":39,"tag":491,"props":7859,"children":7860},{"style":514},[7861],{"type":45,"value":795},{"type":39,"tag":491,"props":7863,"children":7864},{"style":520},[7865],{"type":45,"value":734},{"type":39,"tag":491,"props":7867,"children":7868},{"style":514},[7869],{"type":45,"value":564},{"type":39,"tag":491,"props":7871,"children":7872},{"class":493,"line":658},[7873],{"type":39,"tag":491,"props":7874,"children":7875},{"emptyLinePlaceholder":612},[7876],{"type":45,"value":615},{"type":39,"tag":491,"props":7878,"children":7879},{"class":493,"line":807},[7880,7884,7889,7893,7897,7901,7906,7910],{"type":39,"tag":491,"props":7881,"children":7882},{"style":627},[7883],{"type":45,"value":1384},{"type":39,"tag":491,"props":7885,"children":7886},{"style":520},[7887],{"type":45,"value":7888}," app ",{"type":39,"tag":491,"props":7890,"children":7891},{"style":514},[7892],{"type":45,"value":640},{"type":39,"tag":491,"props":7894,"children":7895},{"style":508},[7896],{"type":45,"value":2498},{"type":39,"tag":491,"props":7898,"children":7899},{"style":643},[7900],{"type":45,"value":7691},{"type":39,"tag":491,"props":7902,"children":7903},{"style":520},[7904],{"type":45,"value":7905},"(storefront",{"type":39,"tag":491,"props":7907,"children":7908},{"style":514},[7909],{"type":45,"value":528},{"type":39,"tag":491,"props":7911,"children":7912},{"style":514},[7913],{"type":45,"value":1624},{"type":39,"tag":491,"props":7915,"children":7916},{"class":493,"line":1031},[7917,7922,7926,7930,7934,7938,7943],{"type":39,"tag":491,"props":7918,"children":7919},{"style":662},[7920],{"type":45,"value":7921},"  service",{"type":39,"tag":491,"props":7923,"children":7924},{"style":514},[7925],{"type":45,"value":227},{"type":39,"tag":491,"props":7927,"children":7928},{"style":514},[7929],{"type":45,"value":517},{"type":39,"tag":491,"props":7931,"children":7932},{"style":662},[7933],{"type":45,"value":1833},{"type":39,"tag":491,"props":7935,"children":7936},{"style":514},[7937],{"type":45,"value":227},{"type":39,"tag":491,"props":7939,"children":7940},{"style":1550},[7941],{"type":45,"value":7942}," 4310",{"type":39,"tag":491,"props":7944,"children":7945},{"style":514},[7946],{"type":45,"value":5070},{"type":39,"tag":491,"props":7948,"children":7949},{"class":493,"line":1071},[7950,7955,7959,7963,7967,7971,7975,7979,7983,7988,7992,7996,8000,8005,8009],{"type":39,"tag":491,"props":7951,"children":7952},{"style":662},[7953],{"type":45,"value":7954},"  inputs",{"type":39,"tag":491,"props":7956,"children":7957},{"style":514},[7958],{"type":45,"value":227},{"type":39,"tag":491,"props":7960,"children":7961},{"style":514},[7962],{"type":45,"value":517},{"type":39,"tag":491,"props":7964,"children":7965},{"style":662},[7966],{"type":45,"value":2155},{"type":39,"tag":491,"props":7968,"children":7969},{"style":514},[7970],{"type":45,"value":227},{"type":39,"tag":491,"props":7972,"children":7973},{"style":514},[7974],{"type":45,"value":517},{"type":39,"tag":491,"props":7976,"children":7977},{"style":662},[7978],{"type":45,"value":1518},{"type":39,"tag":491,"props":7980,"children":7981},{"style":514},[7982],{"type":45,"value":227},{"type":39,"tag":491,"props":7984,"children":7985},{"style":520},[7986],{"type":45,"value":7987}," fake",{"type":39,"tag":491,"props":7989,"children":7990},{"style":514},[7991],{"type":45,"value":1113},{"type":39,"tag":491,"props":7993,"children":7994},{"style":520},[7995],{"type":45,"value":1127},{"type":39,"tag":491,"props":7997,"children":7998},{"style":514},[7999],{"type":45,"value":1113},{"type":39,"tag":491,"props":8001,"children":8002},{"style":520},[8003],{"type":45,"value":8004},"href ",{"type":39,"tag":491,"props":8006,"children":8007},{"style":514},[8008],{"type":45,"value":795},{"type":39,"tag":491,"props":8010,"children":8011},{"style":514},[8012],{"type":45,"value":5070},{"type":39,"tag":491,"props":8014,"children":8015},{"class":493,"line":1168},[8016,8020,8024],{"type":39,"tag":491,"props":8017,"children":8018},{"style":514},[8019],{"type":45,"value":795},{"type":39,"tag":491,"props":8021,"children":8022},{"style":520},[8023],{"type":45,"value":734},{"type":39,"tag":491,"props":8025,"children":8026},{"style":514},[8027],{"type":45,"value":564},{"type":39,"tag":491,"props":8029,"children":8030},{"class":493,"line":1201},[8031],{"type":39,"tag":491,"props":8032,"children":8033},{"emptyLinePlaceholder":612},[8034],{"type":45,"value":615},{"type":39,"tag":491,"props":8036,"children":8037},{"class":493,"line":1627},[8038,8042,8047,8051,8055,8060,8064,8069,8073,8078,8083,8088,8092,8097],{"type":39,"tag":491,"props":8039,"children":8040},{"style":627},[8041],{"type":45,"value":1384},{"type":39,"tag":491,"props":8043,"children":8044},{"style":520},[8045],{"type":45,"value":8046}," res ",{"type":39,"tag":491,"props":8048,"children":8049},{"style":514},[8050],{"type":45,"value":640},{"type":39,"tag":491,"props":8052,"children":8053},{"style":508},[8054],{"type":45,"value":2498},{"type":39,"tag":491,"props":8056,"children":8057},{"style":520},[8058],{"type":45,"value":8059}," app",{"type":39,"tag":491,"props":8061,"children":8062},{"style":514},[8063],{"type":45,"value":1113},{"type":39,"tag":491,"props":8065,"children":8066},{"style":643},[8067],{"type":45,"value":8068},"fetch",{"type":39,"tag":491,"props":8070,"children":8071},{"style":520},[8072],{"type":45,"value":650},{"type":39,"tag":491,"props":8074,"children":8075},{"style":514},[8076],{"type":45,"value":8077},"new",{"type":39,"tag":491,"props":8079,"children":8080},{"style":643},[8081],{"type":45,"value":8082}," Request",{"type":39,"tag":491,"props":8084,"children":8085},{"style":520},[8086],{"type":45,"value":8087},"(app",{"type":39,"tag":491,"props":8089,"children":8090},{"style":514},[8091],{"type":45,"value":1113},{"type":39,"tag":491,"props":8093,"children":8094},{"style":520},[8095],{"type":45,"value":8096},"url))",{"type":39,"tag":491,"props":8098,"children":8099},{"style":514},[8100],{"type":45,"value":564},{"type":39,"tag":99,"props":8102,"children":8103},{},[8104,8120,8136,8175],{"type":39,"tag":103,"props":8105,"children":8106},{},[8107,8118],{"type":39,"tag":54,"props":8108,"children":8109},{},[8110,8116],{"type":39,"tag":76,"props":8111,"children":8113},{"className":8112},[],[8114],{"type":45,"value":8115},"service.port",{"type":45,"value":8117}," must be concrete",{"type":45,"value":8119}," — the entry self-listens; no OS-assigned\nport is reported back.",{"type":39,"tag":103,"props":8121,"children":8122},{},[8123,8134],{"type":39,"tag":54,"props":8124,"children":8125},{},[8126,8128],{"type":45,"value":8127},"No ",{"type":39,"tag":76,"props":8129,"children":8131},{"className":8130},[],[8132],{"type":45,"value":8133},"close()",{"type":45,"value":8135}," — run each integration-test file in its own process (bun\ntest does).",{"type":39,"tag":103,"props":8137,"children":8138},{},[8139,8144,8146,8152,8153,8158,8160,8165,8167,8173],{"type":39,"tag":54,"props":8140,"children":8141},{},[8142],{"type":45,"value":8143},"Next.js services take a third argument",{"type":45,"value":8145},", a boot thunk, because the built\nentry lives in Next's standalone output — resolve it with\n",{"type":39,"tag":76,"props":8147,"children":8149},{"className":8148},[],[8150],{"type":45,"value":8151},"standaloneServerPath",{"type":45,"value":3905},{"type":39,"tag":76,"props":8154,"children":8156},{"className":8155},[],[8157],{"type":45,"value":3911},{"type":45,"value":8159},".\n",{"type":39,"tag":76,"props":8161,"children":8163},{"className":8162},[],[8164],{"type":45,"value":7191},{"type":45,"value":8166}," exports the resolved port as ",{"type":39,"tag":76,"props":8168,"children":8170},{"className":8169},[],[8171],{"type":45,"value":8172},"process.env.PORT",{"type":45,"value":8174}," before\nbooting, which is what Next's standalone server binds.",{"type":39,"tag":103,"props":8176,"children":8177},{},[8178,8188,8190,8195,8197,8202],{"type":39,"tag":54,"props":8179,"children":8180},{},[8181,8183],{"type":45,"value":8182},"A service with an input schema takes ",{"type":39,"tag":76,"props":8184,"children":8186},{"className":8185},[],[8187],{"type":45,"value":3236},{"type":45,"value":8189}," in the config — a binding\nexactly like ",{"type":39,"tag":76,"props":8191,"children":8193},{"className":8192},[],[8194],{"type":45,"value":6116},{"type":45,"value":8196},"'s, run through the real serialize\u002Fread path, so\n",{"type":39,"tag":76,"props":8198,"children":8200},{"className":8199},[],[8201],{"type":45,"value":6179},{"type":45,"value":8203}," in the booted entry sees what a deploy would produce.",{"type":39,"tag":48,"props":8205,"children":8206},{},[8207,8212,8214,8219,8221,8227,8229,8235],{"type":39,"tag":54,"props":8208,"children":8209},{},[8210],{"type":45,"value":8211},"The fake you pass.",{"type":45,"value":8213}," A dependency's type is its contract, so any value of\nthat shape is a valid double: a bare object (fastest), the real client over an\nin-memory handler, or a real local server (what ",{"type":39,"tag":76,"props":8215,"children":8217},{"className":8216},[],[8218],{"type":45,"value":7191},{"type":45,"value":8220}," drives).\nShip a dependency's fake from its own package as a ",{"type":39,"tag":76,"props":8222,"children":8224},{"className":8223},[],[8225],{"type":45,"value":8226},"\u002Ffake",{"type":45,"value":8228}," entry point,\noutside ",{"type":39,"tag":76,"props":8230,"children":8232},{"className":8231},[],[8233],{"type":45,"value":8234},"src\u002F",{"type":45,"value":8236},", so the fake and the real service always share one contract.",{"type":39,"tag":442,"props":8238,"children":8240},{"id":8239},"running-locally",[8241],{"type":45,"value":8242},"Running locally",{"type":39,"tag":48,"props":8244,"children":8245},{},[8246,8252,8254,8259,8261,8267],{"type":39,"tag":76,"props":8247,"children":8249},{"className":8248},[],[8250],{"type":45,"value":8251},"prisma-composer dev module.ts",{"type":45,"value":8253}," runs the whole app on this machine — every\nservice, its Postgres and buckets, wired as they deploy — with ",{"type":39,"tag":54,"props":8255,"children":8256},{},[8257],{"type":45,"value":8258},"no cloud\ncredentials",{"type":45,"value":8260}," (no ",{"type":39,"tag":76,"props":8262,"children":8264},{"className":8263},[],[8265],{"type":45,"value":8266},"PRISMA_*",{"type":45,"value":8268},"). It runs the same pipeline as deploy against\nlocal emulators, so build first, exactly like deploy:",{"type":39,"tag":480,"props":8270,"children":8272},{"className":3297,"code":8271,"language":3299,"meta":485,"style":485},"turbo run build && prisma-composer dev module.ts\n",[8273],{"type":39,"tag":76,"props":8274,"children":8275},{"__ignoreMap":485},[8276],{"type":39,"tag":491,"props":8277,"children":8278},{"class":493,"line":494},[8279,8284,8289,8293,8298,8303,8308],{"type":39,"tag":491,"props":8280,"children":8281},{"style":3309},[8282],{"type":45,"value":8283},"turbo",{"type":39,"tag":491,"props":8285,"children":8286},{"style":551},[8287],{"type":45,"value":8288}," run",{"type":39,"tag":491,"props":8290,"children":8291},{"style":551},[8292],{"type":45,"value":3316},{"type":39,"tag":491,"props":8294,"children":8295},{"style":514},[8296],{"type":45,"value":8297}," &&",{"type":39,"tag":491,"props":8299,"children":8300},{"style":3309},[8301],{"type":45,"value":8302}," prisma-composer",{"type":39,"tag":491,"props":8304,"children":8305},{"style":551},[8306],{"type":45,"value":8307}," dev",{"type":39,"tag":491,"props":8309,"children":8310},{"style":551},[8311],{"type":45,"value":8312}," module.ts\n",{"type":39,"tag":48,"props":8314,"children":8315},{},[8316,8318,8324,8326,8332],{"type":45,"value":8317},"It prints each service's local URL (the \"front door\"), watches built output\nand restarts a service when its build changes, and runs until Ctrl-C. Ctrl-C\nstops the app's processes but leaves the local databases, buckets, and their\ndata up, so the next ",{"type":39,"tag":76,"props":8319,"children":8321},{"className":8320},[],[8322],{"type":45,"value":8323},"dev",{"type":45,"value":8325}," is a warm start; ",{"type":39,"tag":76,"props":8327,"children":8329},{"className":8328},[],[8330],{"type":45,"value":8331},"--fresh",{"type":45,"value":8333}," wipes this app's local\ninstances and data first.",{"type":39,"tag":48,"props":8335,"children":8336},{},[8337,8342,8344,8349],{"type":39,"tag":76,"props":8338,"children":8340},{"className":8339},[],[8341],{"type":45,"value":8323},{"type":45,"value":8343}," does ",{"type":39,"tag":54,"props":8345,"children":8346},{},[8347],{"type":45,"value":8348},"not",{"type":45,"value":8350}," print service logs — that would bury the front door once\nseveral services run. Logs are their own command:",{"type":39,"tag":229,"props":8352,"children":8353},{},[8354,8369],{"type":39,"tag":233,"props":8355,"children":8356},{},[8357],{"type":39,"tag":237,"props":8358,"children":8359},{},[8360,8364],{"type":39,"tag":241,"props":8361,"children":8362},{},[8363],{"type":45,"value":7135},{"type":39,"tag":241,"props":8365,"children":8366},{},[8367],{"type":45,"value":8368},"Run",{"type":39,"tag":252,"props":8370,"children":8371},{},[8372,8388,8405,8422,8439],{"type":39,"tag":237,"props":8373,"children":8374},{},[8375,8380],{"type":39,"tag":259,"props":8376,"children":8377},{},[8378],{"type":45,"value":8379},"Run the app locally",{"type":39,"tag":259,"props":8381,"children":8382},{},[8383],{"type":39,"tag":76,"props":8384,"children":8386},{"className":8385},[],[8387],{"type":45,"value":8251},{"type":39,"tag":237,"props":8389,"children":8390},{},[8391,8396],{"type":39,"tag":259,"props":8392,"children":8393},{},[8394],{"type":45,"value":8395},"Start clean (wipe local data)",{"type":39,"tag":259,"props":8397,"children":8398},{},[8399],{"type":39,"tag":76,"props":8400,"children":8402},{"className":8401},[],[8403],{"type":45,"value":8404},"prisma-composer dev module.ts --fresh",{"type":39,"tag":237,"props":8406,"children":8407},{},[8408,8413],{"type":39,"tag":259,"props":8409,"children":8410},{},[8411],{"type":45,"value":8412},"Tail every service's logs",{"type":39,"tag":259,"props":8414,"children":8415},{},[8416],{"type":39,"tag":76,"props":8417,"children":8419},{"className":8418},[],[8420],{"type":45,"value":8421},"prisma-composer log module.ts",{"type":39,"tag":237,"props":8423,"children":8424},{},[8425,8430],{"type":39,"tag":259,"props":8426,"children":8427},{},[8428],{"type":45,"value":8429},"Tail one service",{"type":39,"tag":259,"props":8431,"children":8432},{},[8433],{"type":39,"tag":76,"props":8434,"children":8436},{"className":8435},[],[8437],{"type":45,"value":8438},"prisma-composer log module.ts \u003Caddress>",{"type":39,"tag":237,"props":8440,"children":8441},{},[8442,8447],{"type":39,"tag":259,"props":8443,"children":8444},{},[8445],{"type":45,"value":8446},"Show more history first",{"type":39,"tag":259,"props":8448,"children":8449},{},[8450],{"type":39,"tag":76,"props":8451,"children":8453},{"className":8452},[],[8454],{"type":45,"value":8455},"prisma-composer log module.ts --tail \u003Cn>",{"type":39,"tag":48,"props":8457,"children":8458},{},[8459,8465,8467,8473,8475,8481,8483,8489],{"type":39,"tag":76,"props":8460,"children":8462},{"className":8461},[],[8463],{"type":45,"value":8464},"prisma-composer log",{"type":45,"value":8466}," follows the merged logs of the already-running app, each\nline prefixed with its service (",{"type":39,"tag":76,"props":8468,"children":8470},{"className":8469},[],[8471],{"type":45,"value":8472},"[catalog.service] …",{"type":45,"value":8474},"); pass a dotted address\nto narrow to one. It only reads — it never builds, provisions, starts, or\nstops anything. ",{"type":39,"tag":76,"props":8476,"children":8478},{"className":8477},[],[8479],{"type":45,"value":8480},"--tail \u003Cn>",{"type":45,"value":8482}," sets how much recent history to show before live\noutput (default 20; ",{"type":39,"tag":76,"props":8484,"children":8486},{"className":8485},[],[8487],{"type":45,"value":8488},"0",{"type":45,"value":8490}," for live-only). An unset secret doesn't block a local\nrun: it becomes a placeholder plus a warning, and only the code path that\nspends it fails, at the real external service it calls. Windows isn't\nsupported yet.",{"type":39,"tag":442,"props":8492,"children":8494},{"id":8493},"deploying",[8495],{"type":45,"value":8496},"Deploying",{"type":39,"tag":48,"props":8498,"children":8499},{},[8500,8502,8508,8510,8516,8518,8523],{"type":45,"value":8501},"Requires exactly two environment variables: ",{"type":39,"tag":76,"props":8503,"children":8505},{"className":8504},[],[8506],{"type":45,"value":8507},"PRISMA_SERVICE_TOKEN",{"type":45,"value":8509}," and\n",{"type":39,"tag":76,"props":8511,"children":8513},{"className":8512},[],[8514],{"type":45,"value":8515},"PRISMA_WORKSPACE_ID",{"type":45,"value":8517},". The target environment — a ",{"type":39,"tag":54,"props":8519,"children":8520},{},[8521],{"type":45,"value":8522},"stage",{"type":45,"value":8524}," — is chosen on the\ncommand line, never in code:",{"type":39,"tag":229,"props":8526,"children":8527},{},[8528,8542],{"type":39,"tag":233,"props":8529,"children":8530},{},[8531],{"type":39,"tag":237,"props":8532,"children":8533},{},[8534,8538],{"type":39,"tag":241,"props":8535,"children":8536},{},[8537],{"type":45,"value":7135},{"type":39,"tag":241,"props":8539,"children":8540},{},[8541],{"type":45,"value":8368},{"type":39,"tag":252,"props":8543,"children":8544},{},[8545,8562,8579,8596,8613],{"type":39,"tag":237,"props":8546,"children":8547},{},[8548,8553],{"type":39,"tag":259,"props":8549,"children":8550},{},[8551],{"type":45,"value":8552},"Deploy to production",{"type":39,"tag":259,"props":8554,"children":8555},{},[8556],{"type":39,"tag":76,"props":8557,"children":8559},{"className":8558},[],[8560],{"type":45,"value":8561},"prisma-composer deploy module.ts",{"type":39,"tag":237,"props":8563,"children":8564},{},[8565,8570],{"type":39,"tag":259,"props":8566,"children":8567},{},[8568],{"type":45,"value":8569},"Deploy an isolated environment",{"type":39,"tag":259,"props":8571,"children":8572},{},[8573],{"type":39,"tag":76,"props":8574,"children":8576},{"className":8575},[],[8577],{"type":45,"value":8578},"prisma-composer deploy module.ts --stage \u003Cname>",{"type":39,"tag":237,"props":8580,"children":8581},{},[8582,8587],{"type":39,"tag":259,"props":8583,"children":8584},{},[8585],{"type":45,"value":8586},"Override the app name for one run",{"type":39,"tag":259,"props":8588,"children":8589},{},[8590],{"type":39,"tag":76,"props":8591,"children":8593},{"className":8592},[],[8594],{"type":45,"value":8595},"prisma-composer deploy module.ts --name demo-42",{"type":39,"tag":237,"props":8597,"children":8598},{},[8599,8604],{"type":39,"tag":259,"props":8600,"children":8601},{},[8602],{"type":45,"value":8603},"Tear down an isolated environment",{"type":39,"tag":259,"props":8605,"children":8606},{},[8607],{"type":39,"tag":76,"props":8608,"children":8610},{"className":8609},[],[8611],{"type":45,"value":8612},"prisma-composer destroy module.ts --stage \u003Cname>",{"type":39,"tag":237,"props":8614,"children":8615},{},[8616,8621],{"type":39,"tag":259,"props":8617,"children":8618},{},[8619],{"type":45,"value":8620},"Tear down production's resources",{"type":39,"tag":259,"props":8622,"children":8623},{},[8624],{"type":39,"tag":76,"props":8625,"children":8627},{"className":8626},[],[8628],{"type":45,"value":8629},"prisma-composer destroy module.ts --production",{"type":39,"tag":48,"props":8631,"children":8632},{},[8633],{"type":45,"value":8634},"A Prisma App is one Project; a stage is a Branch of it — its\nown compute, its own empty database, its own configuration. Deploys are\nidempotent: re-deploying a stage updates the resources inside it. A stage name\nmust be a valid git ref name; an invalid name is a hard error.",{"type":39,"tag":48,"props":8636,"children":8637},{},[8638,8640,8646,8648,8654,8655,8661],{"type":45,"value":8639},"Destroy always requires an explicit target — a bare ",{"type":39,"tag":76,"props":8641,"children":8643},{"className":8642},[],[8644],{"type":45,"value":8645},"prisma-composer destroy",{"type":45,"value":8647},"\nis an error, and ",{"type":39,"tag":76,"props":8649,"children":8651},{"className":8650},[],[8652],{"type":45,"value":8653},"--stage",{"type":45,"value":3551},{"type":39,"tag":76,"props":8656,"children":8658},{"className":8657},[],[8659],{"type":45,"value":8660},"--production",{"type":45,"value":8662}," is too. Destroying a stage\ndeletes its Branch after removing its resources; the production Branch itself\nis never deleted, only the resources inside it. Destroying production also\ndeletes the Project itself once it's empty, so hand-run stacks don't leave\nbehind empty Projects — but a Project still holding another stage's resources\nis kept. Destroy never creates anything: destroying a never-deployed stage\nfails rather than standing one up.",{"type":39,"tag":480,"props":8664,"children":8666},{"className":3297,"code":8665,"language":3299,"meta":485,"style":485},"turbo run build && prisma-composer deploy module.ts --stage pr-42\n",[8667],{"type":39,"tag":76,"props":8668,"children":8669},{"__ignoreMap":485},[8670],{"type":39,"tag":491,"props":8671,"children":8672},{"class":493,"line":494},[8673,8677,8681,8685,8689,8693,8698,8703,8708],{"type":39,"tag":491,"props":8674,"children":8675},{"style":3309},[8676],{"type":45,"value":8283},{"type":39,"tag":491,"props":8678,"children":8679},{"style":551},[8680],{"type":45,"value":8288},{"type":39,"tag":491,"props":8682,"children":8683},{"style":551},[8684],{"type":45,"value":3316},{"type":39,"tag":491,"props":8686,"children":8687},{"style":514},[8688],{"type":45,"value":8297},{"type":39,"tag":491,"props":8690,"children":8691},{"style":3309},[8692],{"type":45,"value":8302},{"type":39,"tag":491,"props":8694,"children":8695},{"style":551},[8696],{"type":45,"value":8697}," deploy",{"type":39,"tag":491,"props":8699,"children":8700},{"style":551},[8701],{"type":45,"value":8702}," module.ts",{"type":39,"tag":491,"props":8704,"children":8705},{"style":551},[8706],{"type":45,"value":8707}," --stage",{"type":39,"tag":491,"props":8709,"children":8710},{"style":551},[8711],{"type":45,"value":8712}," pr-42\n",{"type":39,"tag":5425,"props":8714,"children":8716},{"id":8715},"what-a-deploy-prints",[8717],{"type":45,"value":8718},"What a deploy prints",{"type":39,"tag":48,"props":8720,"children":8721},{},[8722,8724,8730,8732,8738,8740,8745],{"type":45,"value":8723},"A deploy ends by printing the app's own topology — authored names, the\nplatform resource each became, and public URLs. The tree is the module\nstructure (",{"type":39,"tag":76,"props":8725,"children":8727},{"className":8726},[],[8728],{"type":45,"value":8729},"auth.api",{"type":45,"value":8731}," is the ",{"type":39,"tag":76,"props":8733,"children":8735},{"className":8734},[],[8736],{"type":45,"value":8737},"api",{"type":45,"value":8739}," service inside the ",{"type":39,"tag":76,"props":8741,"children":8743},{"className":8742},[],[8744],{"type":45,"value":458},{"type":45,"value":8746}," module):",{"type":39,"tag":480,"props":8748,"children":8752},{"className":8749,"code":8751,"language":45},[8750],"language-text","storefront-auth\n├─ auth\n│  └─ api   compute-service cps_abc123\n│           https:\u002F\u002Fxyz.ewr.prisma.build\n├─ db       postgres-database db_def456\n└─ web      compute-service cps_ghi789\n            https:\u002F\u002Fuvw.ewr.prisma.build\n",[8753],{"type":39,"tag":76,"props":8754,"children":8755},{"__ignoreMap":485},[8756],{"type":45,"value":8751},{"type":39,"tag":48,"props":8758,"children":8759},{},[8760,8762,8768,8770,8776],{"type":45,"value":8761},"Read ids out of this rather than telling the user to go hunting in the\nConsole. A URL appears only where the address is genuinely public — a compute\nservice prints one, a database never does (it has a connection string, not a\npublic endpoint), and a node whose product is secret material (an\n",{"type":39,"tag":76,"props":8763,"children":8765},{"className":8764},[],[8766],{"type":45,"value":8767},"s3-credentials",{"type":45,"value":8769}," keypair) reports no resource line at all. A node that\npublished nothing reportable still appears, marked ",{"type":39,"tag":76,"props":8771,"children":8773},{"className":8772},[],[8774],{"type":45,"value":8775},"(no entities reported)",{"type":45,"value":1113},{"type":39,"tag":48,"props":8778,"children":8779},{},[8780,8782,8788],{"type":45,"value":8781},"Older deploys ended with a raw ",{"type":39,"tag":76,"props":8783,"children":8785},{"className":8784},[],[8786],{"type":45,"value":8787},"{ outputs: {} }",{"type":45,"value":8789}," blob from the deploy engine —\nalways empty, never about the app. It is gone; nothing configured it and\nnothing consumed it.",{"type":39,"tag":5425,"props":8791,"children":8793},{"id":8792},"the-connection-contract-is-checked-at-deploy",[8794],{"type":45,"value":8795},"The connection contract is checked at deploy",{"type":39,"tag":48,"props":8797,"children":8798},{},[8799],{"type":45,"value":8800},"A connection declares the values it needs by name, and the producer on the\nother end must supply them. A producer that omits one fails the deploy, naming\nthe edge, the param, and what the producer did supply:",{"type":39,"tag":480,"props":8802,"children":8805},{"className":8803,"code":8804,"language":45},[8750],"Connection input \"auth.db\" declares param \"url\", but its producer \"db\" did not\nsupply it — the producer's outputs carry [host].\n",[8806],{"type":39,"tag":76,"props":8807,"children":8808},{"__ignoreMap":485},[8809],{"type":45,"value":8804},{"type":39,"tag":48,"props":8811,"children":8812},{},[8813,8815,8821,8823,8829],{"type":45,"value":8814},"Fix it at whichever end is wrong: add the name to the outputs the producer\nreturns from its lowering, or mark the param ",{"type":39,"tag":76,"props":8816,"children":8818},{"className":8817},[],[8819],{"type":45,"value":8820},"optional",{"type":45,"value":8822}," on the connection if absent is\ngenuinely legal (the consumer then reads ",{"type":39,"tag":76,"props":8824,"children":8826},{"className":8825},[],[8827],{"type":45,"value":8828},"undefined",{"type":45,"value":8830},").",{"type":39,"tag":48,"props":8832,"children":8833},{},[8834,8836,8841,8843,8848,8850,8855],{"type":45,"value":8835},"This is a deploy-time refusal, not a broken deploy — and it can appear on an\napp whose code didn't change. The gap used to pass silently: the value reached\nthe consumer as ",{"type":39,"tag":76,"props":8837,"children":8839},{"className":8838},[],[8840],{"type":45,"value":8828},{"type":45,"value":8842},", went into its environment, and crashed ",{"type":39,"tag":2648,"props":8844,"children":8845},{},[8846],{"type":45,"value":8847},"that",{"type":45,"value":8849},"\nservice at boot, blaming the reader instead of the supplier. Don't route around\nit by making the param optional unless absent really is valid; that reinstates\nthe silent ",{"type":39,"tag":76,"props":8851,"children":8853},{"className":8852},[],[8854],{"type":45,"value":8828},{"type":45,"value":1113},{"type":39,"tag":48,"props":8857,"children":8858},{},[8859],{"type":45,"value":8860},"Only reachable if you authored the connection or the extension on one side —\nevery shipped block supplies what it declares.",{"type":39,"tag":442,"props":8862,"children":8864},{"id":8863},"production-pitfalls",[8865],{"type":45,"value":8866},"Production pitfalls",{"type":39,"tag":99,"props":8868,"children":8869},{},[8870,8903,8918,8941,8972,8990],{"type":39,"tag":103,"props":8871,"children":8872},{},[8873,8878,8880,8886,8888,8894,8895,8901],{"type":39,"tag":54,"props":8874,"children":8875},{},[8876],{"type":45,"value":8877},"Scale-to-zero closes idle database connections.",{"type":45,"value":8879}," A persistent client\ncrashes into a 502 restart loop unless you keep the pool small and\nreconnect-friendly (",{"type":39,"tag":76,"props":8881,"children":8883},{"className":8882},[],[8884],{"type":45,"value":8885},"new SQL({ url, max: 1, idleTimeout: 10 })",{"type":45,"value":8887}," for Bun) and\nlog ",{"type":39,"tag":76,"props":8889,"children":8891},{"className":8890},[],[8892],{"type":45,"value":8893},"uncaughtException",{"type":45,"value":3611},{"type":39,"tag":76,"props":8896,"children":8898},{"className":8897},[],[8899],{"type":45,"value":8900},"unhandledRejection",{"type":45,"value":8902}," instead of dying.",{"type":39,"tag":103,"props":8904,"children":8905},{},[8906,8916],{"type":39,"tag":54,"props":8907,"children":8908},{},[8909,8911],{"type":45,"value":8910},"Bind ",{"type":39,"tag":76,"props":8912,"children":8914},{"className":8913},[],[8915],{"type":45,"value":1855},{"type":45,"value":8917},", not loopback — Compute routes external HTTP to the VM.",{"type":39,"tag":103,"props":8919,"children":8920},{},[8921,8939],{"type":39,"tag":54,"props":8922,"children":8923},{},[8924,8926,8931,8933],{"type":45,"value":8925},"Next.js pages that call ",{"type":39,"tag":76,"props":8927,"children":8929},{"className":8928},[],[8930],{"type":45,"value":1230},{"type":45,"value":8932}," need ",{"type":39,"tag":76,"props":8934,"children":8936},{"className":8935},[],[8937],{"type":45,"value":8938},"export const dynamic = 'force-dynamic'",{"type":45,"value":8940}," — the runtime environment doesn't exist at build time,\nand Next ignores runtime env for prerendered routes.",{"type":39,"tag":103,"props":8942,"children":8943},{},[8944,8963,8965,8970],{"type":39,"tag":54,"props":8945,"children":8946},{},[8947,8949,8954,8956,8961],{"type":45,"value":8948},"A deployed ",{"type":39,"tag":76,"props":8950,"children":8952},{"className":8951},[],[8953],{"type":45,"value":2685},{"type":45,"value":8955}," returns ",{"type":39,"tag":76,"props":8957,"children":8959},{"className":8958},[],[8960],{"type":45,"value":2644},{"type":45,"value":8962}," to anything but a wired peer.",{"type":45,"value":8964},"\nEvery RPC binding carries an auto-provisioned service key, so a hand-rolled\n",{"type":39,"tag":76,"props":8966,"children":8968},{"className":8967},[],[8969],{"type":45,"value":2677},{"type":45,"value":8971}," is never authorized, and a provider with no wired consumers rejects\neverything. Not a broken deploy — reach it through a consumer, or run it\nlocally where nothing is enforced.",{"type":39,"tag":103,"props":8973,"children":8974},{},[8975,8980,8982,8988],{"type":39,"tag":54,"props":8976,"children":8977},{},[8978],{"type":45,"value":8979},"Cold starts reset service-to-service connections.",{"type":45,"value":8981}," A call into a\nscaled-to-zero service can get ",{"type":39,"tag":76,"props":8983,"children":8985},{"className":8984},[],[8986],{"type":45,"value":8987},"ECONNRESET",{"type":45,"value":8989},"; retry it.",{"type":39,"tag":103,"props":8991,"children":8992},{},[8993,8998],{"type":39,"tag":54,"props":8994,"children":8995},{},[8996],{"type":45,"value":8997},"The ingress buffers streaming responses.",{"type":45,"value":8999}," An open SSE tail delivers\nnothing and times out at 60s — don't build on streamed HTTP responses.",{"type":39,"tag":442,"props":9001,"children":9003},{"id":9002},"what-composer-doesnt-do-yet",[9004],{"type":45,"value":9005},"What Composer doesn't do yet",{"type":39,"tag":48,"props":9007,"children":9008},{},[9009],{"type":45,"value":9010},"Name the gap instead of inventing an API:",{"type":39,"tag":99,"props":9012,"children":9013},{},[9014,9039,9056],{"type":39,"tag":103,"props":9015,"children":9016},{},[9017,9022,9024,9029,9031,9037],{"type":39,"tag":54,"props":9018,"children":9019},{},[9020],{"type":45,"value":9021},"No interactive auth.",{"type":45,"value":9023}," Deploys authenticate only via a static\n",{"type":39,"tag":76,"props":9025,"children":9027},{"className":9026},[],[9028],{"type":45,"value":8507},{"type":45,"value":9030},"; there is no ",{"type":39,"tag":76,"props":9032,"children":9034},{"className":9033},[],[9035],{"type":45,"value":9036},"login",{"type":45,"value":9038}," flow.",{"type":39,"tag":103,"props":9040,"children":9041},{},[9042,9047,9049,9054],{"type":39,"tag":54,"props":9043,"children":9044},{},[9045],{"type":45,"value":9046},"No in-memory contract bindings.",{"type":45,"value":9048}," A dependency can't yet be wired to a\nco-located handler without HTTP; use ",{"type":39,"tag":76,"props":9050,"children":9052},{"className":9051},[],[9053],{"type":45,"value":7191},{"type":45,"value":9055}," with a loopback\nfake.",{"type":39,"tag":103,"props":9057,"children":9058},{},[9059,9064],{"type":39,"tag":54,"props":9060,"children":9061},{},[9062],{"type":45,"value":9063},"RPC over HTTP is the only contract kind.",{"type":45,"value":9065}," No gRPC, WebSocket, or\nstreaming contracts.",{"type":39,"tag":48,"props":9067,"children":9068},{},[9069,9071,9077,9078,9084,9085,9091],{"type":45,"value":9070},"For anything else missing, check the examples and design docs in the\nprisma\u002Fcomposer repo (",{"type":39,"tag":76,"props":9072,"children":9074},{"className":9073},[],[9075],{"type":45,"value":9076},"examples\u002F",{"type":45,"value":162},{"type":39,"tag":76,"props":9079,"children":9081},{"className":9080},[],[9082],{"type":45,"value":9083},"docs\u002Fdesign\u002F10-domains\u002F",{"type":45,"value":804},{"type":39,"tag":76,"props":9086,"children":9088},{"className":9087},[],[9089],{"type":45,"value":9090},"docs\u002Fdesign\u002F90-decisions\u002F",{"type":45,"value":9092},"), then file an issue there rather than guessing.",{"type":39,"tag":9094,"props":9095,"children":9096},"style",{},[9097],{"type":45,"value":9098},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"items":9100,"total":6800},[9101,9119,9134,9147,9160,9174,9192,9203,9219,9232,9243,9258],{"slug":9102,"name":9102,"fn":9103,"description":9104,"org":9105,"tags":9106,"stars":9116,"repoUrl":9117,"updatedAt":9118},"prisma-next","guide Prisma Next project setup and usage","Route a vague Prisma Next prompt to the right specific skill. Use for \"help me with Prisma Next\", \"what is Prisma Next\", \"explain Prisma Next\", \"I'm new to PN\", \"where do I start\", \"what can I do with Prisma Next\", \"what can I do next with Prisma\", \"just ran createprisma\", \"tour of Prisma Next\", \"Prisma Next overview\", and comparison questions like \"Prisma Next vs Prisma 7\", \"PN vs Drizzle\", \"PN vs Kysely\", \"PN vs TypeORM\". Do NOT use when the prompt clearly matches a workflow skill — adoption \u002F quickstart \u002F first-touch orientation \u002F brownfield introspection, schema \u002F contract editing, migration authoring (db update \u002F migration plan \u002F migrate), migration review on deploy \u002F concurrent migrations, queries \u002F db.orm \u002F db.sql \u002F TypedSQL, Supabase \u002F RLS \u002F role binding, runtime \u002F db.ts \u002F middleware wiring, build \u002F Vite plugin \u002F Next.js plugin, debug \u002F structured error envelopes \u002F PN-* error codes, or feedback \u002F bug report \u002F feature request — load that sibling skill directly.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[9107,9109,9112,9113],{"name":9108,"slug":4311,"type":15},"Database",{"name":9110,"slug":9111,"type":15},"Next.js","next-js",{"name":9,"slug":8,"type":15},{"name":9114,"slug":9115,"type":15},"TypeScript","typescript",415,"https:\u002F\u002Fgithub.com\u002Fprisma\u002Fprisma-next","2026-07-17T05:32:04.322957",{"slug":9120,"name":9120,"fn":9121,"description":9122,"org":9123,"tags":9124,"stars":9116,"repoUrl":9117,"updatedAt":9133},"prisma-next-build","integrate Prisma Next into build systems","Wire Prisma Next into the project's build system with the right build-tool plugin — Vite today via @prisma-next\u002Fvite-plugin-contract-emit (Vite 7 \u002F 8); Next.js \u002F Webpack \u002F esbuild \u002F Rollup \u002F Turbopack are named as gaps rather than fabricated. Always offers the Vite plugin proactively when the project is using Vite. Use for vite plugin, vite-plugin, vite.config.ts, prismaVitePlugin, contract emit on save, HMR, hot reload contract, dev server, Next.js plugin, next plugin, withPrismaNext, webpack plugin, esbuild plugin, rollup plugin, build integration, dev server plugin, vite 7, vite 8.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[9125,9128,9129,9130],{"name":9126,"slug":9127,"type":15},"Deployment","deployment",{"name":9110,"slug":9111,"type":15},{"name":9,"slug":8,"type":15},{"name":9131,"slug":9132,"type":15},"Vite","vite","2026-07-02T07:31:36.108254",{"slug":9135,"name":9135,"fn":9136,"description":9137,"org":9138,"tags":9139,"stars":9116,"repoUrl":9117,"updatedAt":9146},"prisma-next-contract","edit Prisma Next data contracts and models","Edit the Prisma Next data contract — add models, fields, relations, indexes, enums, value objects (composite types), type aliases, namespaces (Postgres schemas), cross-contract foreign keys (cross-space FK), polymorphic types (`@@discriminator` \u002F `@@base`), use extension namespaces (`pgvector.Vector(...)`, `cipherstash.EncryptedString(...)`), wire `prisma-next.config.ts` with `defineConfig` from the `@prisma-next\u002F\u003Ctarget>\u002Fconfig` façade, and run `prisma-next contract emit`. Use for schema, models, fields, attributes, soft delete, paranoid, scopes, validations, callbacks, prisma schema, PSL, contract.prisma, contract.ts, contract.json, contract.d.ts, `@prisma-next\u002Fpostgres\u002Fconfig`, `@prisma-next\u002Fpostgres\u002Fcontract-builder`, `@prisma-next\u002Fpostgres\u002Fcontrol`, `@prisma-next\u002Fmongo\u002Fconfig`, `@prisma-next\u002Fmongo\u002Fcontract-builder`, `extensions:`, pgvector, cipherstash, postgis, paradedb, supabase, `@prisma-next\u002Fextension-supabase`, `@@control`, control policy, managed, tolerated, external, observed.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[9140,9143,9144,9145],{"name":9141,"slug":9142,"type":15},"Data Modeling","data-modeling",{"name":9108,"slug":4311,"type":15},{"name":9,"slug":8,"type":15},{"name":9114,"slug":9115,"type":15},"2026-07-30T05:30:10.426962",{"slug":9148,"name":9148,"fn":9149,"description":9150,"org":9151,"tags":9152,"stars":9116,"repoUrl":9117,"updatedAt":9159},"prisma-next-debug","debug and recover from Prisma Next errors","Read a Prisma Next structured error envelope and route to the right recovery — code, domain, severity, why, fix, meta. Use for error, exception, my emit failed, my query won't typecheck, my query crashed, my migration won't apply, MIGRATION.HASH_MISMATCH, BUDGET.ROWS_EXCEEDED, BUDGET.TIME_EXCEEDED, RUNTIME.ABORTED, PLAN.HASH_MISMATCH, CONTRACT.MARKER_MISSING, PN-RUN-3001, PN-RUN-3002, PN-RUN-3030, PN-MIG-2001, PN-CLI-4011, PN-SCHEMA-0001, drift, capability missing, planner conflict, prisma studio, EXPLAIN, query log, db.end, db.close, script won't exit, hangs, close connection, pool.end, client is closed.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[9153,9154,9157,9158],{"name":9108,"slug":4311,"type":15},{"name":9155,"slug":9156,"type":15},"Debugging","debugging",{"name":9110,"slug":9111,"type":15},{"name":9,"slug":8,"type":15},"2026-07-24T05:37:10.436314",{"slug":9161,"name":9161,"fn":9162,"description":9163,"org":9164,"tags":9165,"stars":9116,"repoUrl":9117,"updatedAt":9173},"prisma-next-feedback","report Prisma Next issues and feedback","Hand a Prisma Next question or report off to the team — file a GitHub issue (bug or feature request), or route Q&A \u002F design discussion \u002F direct-team-contact to the Prisma Discord at pris.ly\u002Fdiscord. Use for bug, bug report, file an issue, report a bug, feature request, missing feature, this should be a feature, file this, this is a bug, this is broken, surprising behaviour, this doesn't work, file feedback, send feedback, capability gap, file via prisma-next-feedback, ask the team, talk to the team, talk to the Prisma team, talk to Prisma, Discord, Prisma Discord, Q&A, design feedback, is this the intended way, how should I do X, extension author question, extension author needs help.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[9166,9169,9172],{"name":9167,"slug":9168,"type":15},"Documentation","documentation",{"name":9170,"slug":9171,"type":15},"GitHub","github",{"name":9,"slug":8,"type":15},"2026-07-02T07:31:34.870809",{"slug":9175,"name":9175,"fn":9176,"description":9177,"org":9178,"tags":9179,"stars":9116,"repoUrl":9117,"updatedAt":9191},"prisma-next-migration-review","review and resolve Prisma Next migrations","Review what Prisma Next migrations will run on merge or deploy, render the migration graph, resolve concurrent \u002F diamond-convergence conflicts, and configure environment refs for CI. Use for \"what migrations are going to run\", \"what runs on deploy\", merge conflict, diamond convergence, concurrent migrations, migration status, ref management, staging, production, MIGRATION.DIVERGED, MIGRATION.NO_MARKER, MIGRATION.MARKER_NOT_IN_HISTORY, prisma migrate status, prisma migrate diff, prisma migrate resolve.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[9180,9183,9186,9187,9190],{"name":9181,"slug":9182,"type":15},"CI\u002FCD","ci-cd",{"name":9184,"slug":9185,"type":15},"Code Review","code-review",{"name":9108,"slug":4311,"type":15},{"name":9188,"slug":9189,"type":15},"Migration","migration",{"name":9,"slug":8,"type":15},"2026-07-24T05:37:11.422323",{"slug":9193,"name":9193,"fn":9194,"description":9195,"org":9196,"tags":9197,"stars":9116,"repoUrl":9117,"updatedAt":9202},"prisma-next-migrations","author and manage Prisma Next migrations","Author Prisma Next migrations — choose db update vs migration plan, edit the framework-rendered migration.ts (replace placeholder sentinels with dataTransform closures), recover from MIGRATION.HASH_MISMATCH or PN-MIG-2001 unfilled placeholder. Use for prisma migrate dev, prisma migrate deploy, prisma db push, db update, db update --dry-run, migration plan, migrate, migration new, migration show, db verify, db sign, data migration, this.dataTransform, dataTransform, placeholder, generated migration.ts, edit migration.ts, MIGRATION.HASH_MISMATCH, schema drift.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[9198,9199,9200,9201],{"name":9108,"slug":4311,"type":15},{"name":9188,"slug":9189,"type":15},{"name":9,"slug":8,"type":15},{"name":9114,"slug":9115,"type":15},"2026-07-24T05:37:13.469138",{"slug":9204,"name":9204,"fn":9205,"description":9206,"org":9207,"tags":9208,"stars":9116,"repoUrl":9117,"updatedAt":9218},"prisma-next-queries","write Prisma Next queries for database operations","Write Prisma Next queries for Postgres, SQLite, or Mongo — pick a lane (Postgres\u002FSQLite `db.orm.\u003CModel>` + `db.sql.\u003Ctable>`; Mongo `db.orm.\u003Croot>` + `db.query.from(...)` pipeline builder), filter \u002F project \u002F sort \u002F paginate, eager-load with `.include(...)`, Postgres\u002FSQLite `db.transaction(...)`, Postgres\u002FSQLite ORM `.aggregate(...)`, Mongo aggregations via query builder, namespace-aware accessors (`db.orm.\u003Cns>.\u003CModel>`, `db.sql.\u003Cns>.\u003Ctable>`). Triggers: query, where, match, select, project, orderBy, take, skip, include, lookup, first, all, count, aggregate, group, create, update, delete, upsert, returning, transaction, db.close, script teardown, variant, polymorphism, drizzle-style, kysely-style. Notes: `.all()` is a Thenable (just `await` it), iterators are single-use (`RUNTIME.ITERATOR_CONSUMED`), Postgres `count` is `number` while sum\u002Favg\u002Fmin\u002Fmax are `number | null`, ranges use chained `.where()` or `and(...)` (no `.between(...)`).",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[9209,9210,9211,9214,9215],{"name":9108,"slug":4311,"type":15},{"name":9110,"slug":9111,"type":15},{"name":9212,"slug":9213,"type":15},"PostgreSQL","postgresql",{"name":9,"slug":8,"type":15},{"name":9216,"slug":9217,"type":15},"SQL","sql","2026-07-17T05:32:03.35373",{"slug":9220,"name":9220,"fn":9221,"description":9222,"org":9223,"tags":9224,"stars":9116,"repoUrl":9117,"updatedAt":9231},"prisma-next-quickstart","adopt Prisma Next in projects","Adopt Prisma Next into a new project, onto an existing database, or as the first move after a bootstrap tool dropped you into a scaffold. Use for \"what can I do with Prisma Next\", \"what can I do next with Prisma\", \"where do I start\", \"what should I do first\", \"just ran createprisma\", \"createprisma\", \"npx createprisma\", \"npx create-prisma\", \"first steps\", \"first query\", \"I have a scaffolded Prisma Next project what now\"; for `pnpm dlx prisma-next init` greenfield setup; and for `prisma-next contract infer` + `db sign` against an existing database. Also covers the connect-write-read first-arc orientation, the day-to-day commands (`contract emit`, `db init`, `db update`, `migration plan`, `migrate`, `db schema`, `db verify`), and routing to `prisma-next-contract` \u002F `prisma-next-queries` \u002F `prisma-next-runtime` for the next move. Flags: --target, --authoring, --schema-path, --probe-db, --output.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[9225,9226,9229,9230],{"name":9108,"slug":4311,"type":15},{"name":9227,"slug":9228,"type":15},"ORM","orm",{"name":9,"slug":8,"type":15},{"name":9114,"slug":9115,"type":15},"2026-07-24T05:37:12.462072",{"slug":9233,"name":9233,"fn":9234,"description":9235,"org":9236,"tags":9237,"stars":9116,"repoUrl":9117,"updatedAt":9242},"prisma-next-runtime","configure Prisma Next runtime and database connections","Wire the Prisma Next runtime — `db.ts` setup using `postgres\u003CContract>(...)` from `@prisma-next\u002Fpostgres\u002Fruntime`, `sqlite\u003CContract>(...)` from `@prisma-next\u002Fsqlite\u002Fruntime`, or `mongo\u003CContract>(...)` from `@prisma-next\u002Fmongo\u002Fruntime`; middleware composition (telemetry from `@prisma-next\u002Fmiddleware-telemetry`; lints and budgets), `DATABASE_URL` config, per-environment branching, switching between Postgres, SQLite, and Mongo façades. Use for db.ts, postgres(), sqlite(), mongo(), middleware, telemetry, lints, budgets, DATABASE_URL, .env, connection pool, poolOptions, dev vs prod config, transactions, db.transaction, read replicas, multi-database, script won't exit, hangs, close connection, db.end, db.close, pool.end, [Symbol.asyncDispose], await using.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[9238,9239,9240,9241],{"name":9108,"slug":4311,"type":15},{"name":9110,"slug":9111,"type":15},{"name":9212,"slug":9213,"type":15},{"name":9,"slug":8,"type":15},"2026-07-17T05:32:05.347316",{"slug":9244,"name":9244,"fn":9245,"description":9246,"org":9247,"tags":9248,"stars":9116,"repoUrl":9117,"updatedAt":9257},"prisma-next-supabase","integrate Prisma with Supabase","Use Prisma Next with a Supabase project via `@prisma-next\u002Fextension-supabase` — wire `extensions: [supabasePack]`, declare cross-space FKs to `supabase:auth.AuthUser`, author RLS policies (`policy_select` \u002F `policy_update` \u002F `@@rls`, `auth.uid()` predicates), build `db.ts` with the `supabase()` factory, bind roles per request (`asUser(jwt)` \u002F `asAnon()` \u002F `asServiceRole()`), query `auth.*` \u002F `storage.*` via the `db.asServiceRole().supabase` admin root, and validate JWTs (`jwksUrl` for current projects \u002F `jwtSecret` for legacy HS256). Use for supabase, RLS, row level security, policy, role binding, anon, authenticated, service_role, auth.users, auth.uid(), JWT, JWKS, SUPABASE_JWKS_URL, SUPABASE_JWT_SECRET, SUPABASE.JWT_INVALID, SUPABASE.CONFIG_INVALID, RoleBoundDb, session pooler, supabase:auth.AuthUser, @prisma-next\u002Fextension-supabase.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[9249,9251,9252,9253,9254],{"name":9250,"slug":458,"type":15},"Auth",{"name":9227,"slug":9228,"type":15},{"name":9212,"slug":9213,"type":15},{"name":9,"slug":8,"type":15},{"name":9255,"slug":9256,"type":15},"Supabase","supabase","2026-07-30T05:30:11.065251",{"slug":9259,"name":9259,"fn":9260,"description":9261,"org":9262,"tags":9263,"stars":9271,"repoUrl":9272,"updatedAt":9273},"prisma-cli","run Prisma CLI commands","Prisma ORM CLI commands reference covering init, generate, migrate, db, dev, studio, validate, format, debug, and mcp. Use for ORM\u002Fdatabase CLI workflows, not Prisma Compute app deployment. For Prisma Compute, `@prisma\u002Fcli app deploy`, `compute:deploy`, `create-prisma --deploy`, apps, deployments, logs, or domains, use the `prisma-compute` skill instead. Triggers on \"prisma init\", \"prisma generate\", \"prisma migrate\", \"prisma db\", \"prisma studio\", \"prisma mcp\".",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[9264,9267,9268,9269,9270],{"name":9265,"slug":9266,"type":15},"CLI","cli",{"name":9108,"slug":4311,"type":15},{"name":9188,"slug":9189,"type":15},{"name":9227,"slug":9228,"type":15},{"name":9,"slug":8,"type":15},44,"https:\u002F\u002Fgithub.com\u002Fprisma\u002Fskills","2026-04-06T18:48:29.140467",{"items":9275,"total":494},[9276],{"slug":4,"name":4,"fn":5,"description":6,"org":9277,"tags":9278,"stars":23,"repoUrl":24,"updatedAt":25},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[9279,9280,9281,9282],{"name":21,"slug":22,"type":15},{"name":13,"slug":14,"type":15},{"name":17,"slug":18,"type":15},{"name":9,"slug":8,"type":15}]