@samebase/alchemy-convex 0.5.0 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["DeploymentRow","DeploymentRows"],"sources":["../src/Credentials.ts","../src/Adoption.ts","../src/ManagementApi.ts","../src/Push.ts","../src/Deployment.ts","../src/Project.ts","../src/Providers.ts","../src/State.ts"],"sourcesContent":["// Convex credentials for the provider, by scope.\n//\n// - The access token works on the Management API: a team access token, an\n// OAuth token, or the Convex CLI login. Convex.Project needs it. A\n// Convex.Deployment needs it only when the deploy key does not fit.\n// - The deploy key is optional. A deploy key of one deployment\n// (`prod:<name>|...`, `dev:<name>|...`) lets Convex.Deployment set\n// variables and push to that deployment with no access token. A preview\n// deploy key of a project (`preview:<team>:<project>|...`) lets it create,\n// push to, and delete preview deployments of that project with no access\n// token.\n//\n// Credentials are a layer, never props: they do not go into Alchemy state.\n// Both values are Effects, so that building the providers layer never touches\n// the environment or the filesystem. A value is read on the first call that\n// needs it, which keeps `alchemy plan` on an unrelated stack free of Convex\n// credential errors.\nimport { readFile } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport * as Config from \"effect/Config\";\nimport * as Context from \"effect/Context\";\nimport * as Effect from \"effect/Effect\";\nimport * as Layer from \"effect/Layer\";\nimport * as Option from \"effect/Option\";\nimport * as Redacted from \"effect/Redacted\";\nimport * as Result from \"effect/Result\";\nimport * as Schema from \"effect/Schema\";\n\nexport interface ResolvedCredentials {\n /** Bearer token accepted by https://api.convex.dev/v1: a team access token, an OAuth token, or the Convex CLI login. */\n readonly accessToken: Redacted.Redacted<string>;\n /** Where the token came from, for error messages only. */\n readonly source: \"env\" | \"explicit\" | \"convex-cli-login\";\n}\n\nexport interface CredentialsService {\n /** The Management API token. Dies when there is none. */\n readonly accessToken: Effect.Effect<ResolvedCredentials>;\n /** True when there is a Management API token. */\n readonly hasAccessToken: Effect.Effect<boolean>;\n /** A deploy key or a preview deploy key, or undefined. */\n readonly deployKey: Effect.Effect<Redacted.Redacted<string> | undefined>;\n}\n\nexport class Credentials extends Context.Service<Credentials, CredentialsService>()(\n \"@samebase/alchemy-convex/Credentials\",\n) {}\n\n/** Environment variable for the access token, read by {@link fromConfig}. */\nexport const ACCESS_TOKEN_ENV = \"CONVEX_ACCESS_TOKEN\";\n\n/** Environment variable for the deploy key, read by {@link fromConfig}. The Convex CLI reads the same name. */\nexport const DEPLOY_KEY_ENV = \"CONVEX_DEPLOY_KEY\";\n\n/** The Convex CLI stores its device login here after `npx convex login`. */\nexport const convexCliConfigPath = () => join(homedir(), \".convex\", \"config.json\");\n\nconst CliConfig = Schema.Struct({ accessToken: Schema.String });\n\nexport class CredentialsError extends Schema.TaggedError<CredentialsError>()(\"CredentialsError\", {\n reason: Schema.String,\n}) {}\n\n/**\n * Token the Convex CLI saved on this machine. It works on the Management API\n * for the teams the logged-in user belongs to. Fails when nobody is logged in.\n */\nexport const readConvexCliLogin: Effect.Effect<ResolvedCredentials, CredentialsError> = Effect.gen(\n function* () {\n const path = convexCliConfigPath();\n const text = yield* Effect.tryPromise({\n try: () => readFile(path, \"utf8\"),\n catch: () =>\n new CredentialsError({\n reason: `This step needs the Convex Management API. Set ${ACCESS_TOKEN_ENV} to a team access token, or run \\`npx convex login\\`. There is no Convex CLI login at ${path}.`,\n }),\n });\n const parsed = yield* Schema.decodeUnknownEffect(Schema.fromJsonString(CliConfig))(text).pipe(\n Effect.mapError(() => new CredentialsError({ reason: `${path} has no accessToken` })),\n );\n return { accessToken: Redacted.make(parsed.accessToken), source: \"convex-cli-login\" } as const;\n },\n);\n\n/**\n * Default resolution through the stack ConfigProvider (process env, `.env`,\n * stack secrets): `CONVEX_ACCESS_TOKEN`, then the Convex CLI login on this\n * machine, for the access token; `CONVEX_DEPLOY_KEY` for the deploy key. A\n * developer who ran `npx convex login` needs nothing. CI sets only the\n * deploy key when the stack pushes to deployments that exist, and the access\n * token when the stack also creates projects or deployments.\n */\nexport const fromConfig = (): Layer.Layer<Credentials> =>\n Layer.effect(\n Credentials,\n Effect.gen(function* () {\n const resolved = yield* Effect.cached(\n Config.Redacted(ACCESS_TOKEN_ENV).pipe(\n Effect.map((token): ResolvedCredentials => ({ accessToken: token, source: \"env\" })),\n Effect.catch(() => readConvexCliLogin),\n Effect.result,\n ),\n );\n const deployKey = yield* Effect.cached(\n Config.option(Config.Redacted(DEPLOY_KEY_ENV)).pipe(\n Effect.map(Option.getOrUndefined),\n Effect.orDie,\n ),\n );\n return {\n accessToken: resolved.pipe(Effect.flatMap(Effect.fromResult), Effect.orDie),\n hasAccessToken: resolved.pipe(Effect.map(Result.isSuccess)),\n deployKey,\n };\n }),\n );\n\n/** Explicit values, for tests or callers that already hold them. */\nexport const fromValues = (values: {\n readonly accessToken?: Redacted.Redacted<string>;\n readonly deployKey?: Redacted.Redacted<string>;\n}): Layer.Layer<Credentials> =>\n Layer.succeed(Credentials, {\n accessToken:\n values.accessToken === undefined\n ? Effect.die(\n new CredentialsError({\n reason:\n \"This step needs the Convex Management API, and fromValues got no accessToken.\",\n }),\n )\n : Effect.succeed({ accessToken: values.accessToken, source: \"explicit\" } as const),\n hasAccessToken: Effect.succeed(values.accessToken !== undefined),\n deployKey: Effect.succeed(values.deployKey),\n });\n","// Adoption check for reconcile.\n//\n// The engine checks ownership during plan: `read` returns `Unowned(...)` for\n// an object that is not in state, and the engine then needs `--adopt`. A\n// reconcile without state can still find an existing object, for example\n// after a replacement, after an interrupted create, or when another run\n// created it between plan and apply. Reconcile takes that object over only\n// when adoption is on. The order is the same as in the engine: the\n// resource's own `adopt(...)`, then the AdoptPolicy service, then the\n// `--adopt` flag in AlchemyContext.\n//\n// Pattern from Confect, `packages/alchemy/src/internal/Lifecycle.ts`\n// (https://github.com/rjdellecese/confect, ISC license).\nimport { AdoptPolicy } from \"alchemy/AdoptPolicy\";\nimport { AlchemyContext } from \"alchemy/AlchemyContext\";\nimport { Stack } from \"alchemy/Stack\";\nimport * as Effect from \"effect/Effect\";\nimport * as Option from \"effect/Option\";\n\n/** True when the resource `fqn` may take over an object that is not in state. */\nexport const shouldAdopt = (fqn: string): Effect.Effect<boolean> =>\n Effect.gen(function* () {\n const stack = yield* Effect.serviceOption(Stack);\n const own = Option.isSome(stack) ? stack.value.resources[fqn]?.Adopt : undefined;\n if (own !== undefined) return own;\n const policy = yield* Effect.serviceOption(AdoptPolicy);\n if (Option.isSome(policy)) return policy.value;\n const context = yield* Effect.serviceOption(AlchemyContext);\n return Option.isSome(context) && context.value.adopt;\n });\n","// Effect wrapper around the official Convex platform client.\n//\n// `@convex-dev/platform` is an openapi-fetch client: every call resolves to\n// `{ data, error, response }`. This service turns that into an Effect with one\n// typed error, resolves credentials lazily, and validates the fields the\n// provider relies on at runtime.\nimport { createDeploymentClient, createManagementClient } from \"@convex-dev/platform\";\nimport * as Context from \"effect/Context\";\nimport * as Effect from \"effect/Effect\";\nimport * as Layer from \"effect/Layer\";\nimport * as Redacted from \"effect/Redacted\";\nimport * as Schedule from \"effect/Schedule\";\nimport * as Schema from \"effect/Schema\";\nimport { Credentials, type ResolvedCredentials } from \"./Credentials.ts\";\n\nexport type ManagementClient = ReturnType<typeof createManagementClient>;\nexport type DeploymentClient = ReturnType<typeof createDeploymentClient>;\n\n/** Shape of every openapi-fetch result we consume. */\nexport interface FetchResult<T> {\n readonly data?: T;\n readonly error?: unknown;\n readonly response: Response;\n}\n\n/**\n * One error for every control-plane and deployment call. Resources branch on\n * `status` (404 means absent for read and delete), so the class is load\n * bearing, not decorative.\n */\nexport class ConvexApiError extends Schema.TaggedError<ConvexApiError>()(\"ConvexApiError\", {\n operation: Schema.String,\n status: Schema.Number,\n code: Schema.optionalKey(Schema.String),\n message: Schema.String,\n}) {}\n\nconst ErrorBody = Schema.Struct({\n code: Schema.optionalKey(Schema.String),\n message: Schema.optionalKey(Schema.String),\n});\n\nconst toApiError = (operation: string, result: FetchResult<unknown>) => {\n const body = Schema.decodeUnknownSync(Schema.NullishOr(ErrorBody))(result.error ?? null);\n const code = body?.code;\n return new ConvexApiError({\n operation,\n status: result.response.status,\n ...(code === undefined ? {} : { code }),\n message: body?.message ?? `${operation} failed with HTTP ${result.response.status}`,\n });\n};\n\nexport interface ManagementApiService {\n /** Run one management call with the resolved credentials. */\n readonly request: <T>(\n operation: string,\n run: (client: ManagementClient) => Promise<FetchResult<T>>,\n ) => Effect.Effect<T, ConvexApiError>;\n /** Run one management call whose success response has no body. */\n readonly requestVoid: (\n operation: string,\n run: (client: ManagementClient) => Promise<FetchResult<unknown>>,\n ) => Effect.Effect<void, ConvexApiError>;\n /** Run one deployment-scoped call authenticated with a deploy key. */\n readonly deploymentRequest: <T>(\n operation: string,\n deploymentUrlOrName: string,\n deployKey: Redacted.Redacted<string>,\n run: (client: DeploymentClient) => Promise<FetchResult<T>>,\n ) => Effect.Effect<T, ConvexApiError>;\n /** Team id for a slug or numeric id. */\n readonly resolveTeamId: (team: string | number) => Effect.Effect<number, ConvexApiError>;\n /**\n * True when a deploy key that Convex returned carries the token of the\n * Management API credential itself. With an OAuth token, create_deploy_key\n * and create_preview_deploy_key create no new key: they return the OAuth\n * token with a new prefix, and the part after \"|\" is the same. A delete of\n * that key would revoke the credential.\n */\n readonly isCredentialToken: (secret: string) => Effect.Effect<boolean>;\n /**\n * The same calls with another bearer token, such as a preview deploy key,\n * which the Management API takes for the preview deployments of its project.\n */\n readonly withToken: (token: Redacted.Redacted<string>) => ManagementApiService;\n}\n\n/** The part of a Convex token after the first \"|\", or the whole value when it has none. */\nconst tokenPart = (value: string) => value.slice(value.indexOf(\"|\") + 1);\n\nexport class ManagementApi extends Context.Service<ManagementApi, ManagementApiService>()(\n \"@samebase/alchemy-convex/ManagementApi\",\n) {}\n\nconst attempt = <T>(operation: string, run: () => Promise<FetchResult<T>>) =>\n Effect.tryPromise({\n try: run,\n catch: (cause) =>\n new ConvexApiError({\n operation,\n status: 0,\n message: cause instanceof Error ? cause.message : String(cause),\n }),\n });\n\n/** Reads `data` or fails with the HTTP status and the API's own code and message. */\nexport const settle = <T>(\n operation: string,\n run: () => Promise<FetchResult<T>>,\n): Effect.Effect<T, ConvexApiError> =>\n attempt(operation, run).pipe(\n Effect.flatMap((result) =>\n result.response.ok && result.data !== undefined\n ? Effect.succeed(result.data)\n : Effect.fail(toApiError(operation, result)),\n ),\n );\n\n/** For endpoints that answer with an empty body, such as delete calls. */\nexport const settleVoid = (\n operation: string,\n run: () => Promise<FetchResult<unknown>>,\n): Effect.Effect<void, ConvexApiError> =>\n attempt(operation, run).pipe(\n Effect.flatMap((result) =>\n result.response.ok ? Effect.void : Effect.fail(toApiError(operation, result)),\n ),\n );\n\n/**\n * True when an idempotent write can succeed on a new attempt:\n *\n * - A Convex write conflict. Two parallel update_environment_variables calls\n * on one deployment gave HTTP 503 `OptimisticConcurrencyControlFailure`,\n * \"Data read or written in this mutation changed while it was being run\",\n * in a live run. The platform codes `OCC` and `WriteConflict` and the\n * message \"... changed while this mutation was being run ...\" mean the same.\n * - Any other 5xx answer. Two parallel delete_preview_deploy_key calls on one\n * project gave HTTP 500 `InternalServerError`, \"Your request couldn't be\n * completed. Try again later.\", in a live run. The next attempt succeeded.\n */\nexport const isRetryableWriteError = (error: ConvexApiError): boolean =>\n error.code === \"OptimisticConcurrencyControlFailure\" ||\n error.code === \"OCC\" ||\n error.code === \"WriteConflict\" ||\n /changed while (it|this mutation) was being run/.test(error.message) ||\n error.status >= 500;\n\n/**\n * Runs an idempotent write again after a retryable Convex error: at most\n * four more attempts, with exponential backoff from 100 ms and jitter. Other\n * errors fail at once, and so does the last retryable error. Use it only for\n * a write that has the same result when it runs twice, such as setting a\n * value or deleting by id. Never for a create that does not check first.\n */\nexport const retryIdempotentWrite = <A, E, R>(\n effect: Effect.Effect<A, E, R>,\n): Effect.Effect<A, E, R> =>\n effect.pipe(\n Effect.retry({\n while: (error: E) => error instanceof ConvexApiError && isRetryableWriteError(error),\n times: 4,\n schedule: Schedule.exponential(\"100 millis\").pipe(Schedule.jittered),\n }),\n );\n\n/** Turns a 404 into `undefined` so read and delete stay idempotent. */\nexport const absentAsUndefined = <A, R>(\n effect: Effect.Effect<A, ConvexApiError, R>,\n): Effect.Effect<A | undefined, ConvexApiError, R> =>\n effect.pipe(\n Effect.catchIf(\n (error) => error.status === 404,\n () => Effect.succeed(undefined),\n ),\n );\n\nconst TeamRow = Schema.Struct({ id: Schema.Number, slug: Schema.String });\nconst TeamRows = Schema.Array(TeamRow);\n\n/** The service for one way to get the bearer token. */\nconst makeService = (credentials: Effect.Effect<ResolvedCredentials>): ManagementApiService => {\n const client = Effect.cached(\n credentials.pipe(\n Effect.map((resolved) => createManagementClient(Redacted.value(resolved.accessToken))),\n ),\n ).pipe(Effect.flatten);\n\n const request: ManagementApiService[\"request\"] = (operation, run) =>\n client.pipe(Effect.flatMap((c) => settle(operation, () => run(c))));\n\n const requestVoid: ManagementApiService[\"requestVoid\"] = (operation, run) =>\n client.pipe(Effect.flatMap((c) => settleVoid(operation, () => run(c))));\n\n const deploymentRequest: ManagementApiService[\"deploymentRequest\"] = (\n operation,\n deploymentUrlOrName,\n deployKey,\n run,\n ) =>\n settle(operation, () =>\n run(createDeploymentClient(deploymentUrlOrName, Redacted.value(deployKey))),\n );\n\n // The Management API addresses teams by numeric id. The only slug lookup\n // it offers is per project, so a slug falls back to the dashboard's team\n // list, which is unofficial. Pass the numeric team id to skip this.\n const resolveTeamId: ManagementApiService[\"resolveTeamId\"] = (team) =>\n Effect.gen(function* () {\n if (typeof team === \"number\") return team;\n if (/^\\d+$/.test(team)) return Number(team);\n const resolved = yield* credentials;\n const rows = yield* Effect.tryPromise({\n try: async () => {\n const response = await fetch(\"https://api.convex.dev/api/dashboard/teams\", {\n headers: { Authorization: `Bearer ${Redacted.value(resolved.accessToken)}` },\n });\n if (!response.ok) {\n throw new Error(`team lookup for \"${team}\" failed with HTTP ${response.status}`);\n }\n return Schema.decodeUnknownSync(TeamRows)(await response.json());\n },\n catch: (cause) =>\n new ConvexApiError({\n operation: \"resolve team\",\n status: 0,\n message: cause instanceof Error ? cause.message : String(cause),\n }),\n });\n const match = rows.find((row) => row.slug === team);\n if (match === undefined) {\n return yield* new ConvexApiError({\n operation: \"resolve team\",\n status: 404,\n message: `no team with slug \"${team}\" for this token`,\n });\n }\n return match.id;\n });\n\n const isCredentialToken: ManagementApiService[\"isCredentialToken\"] = (secret) =>\n credentials.pipe(\n Effect.map(\n (resolved) => tokenPart(Redacted.value(resolved.accessToken)) === tokenPart(secret),\n ),\n );\n\n const withToken: ManagementApiService[\"withToken\"] = (token) =>\n makeService(Effect.succeed({ accessToken: token, source: \"explicit\" }));\n\n return {\n request,\n requestVoid,\n deploymentRequest,\n resolveTeamId,\n isCredentialToken,\n withToken,\n };\n};\n\nexport const ManagementApiLive = (): Layer.Layer<ManagementApi, never, Credentials> =>\n Layer.effect(\n ManagementApi,\n Effect.gen(function* () {\n const credentials = yield* Credentials;\n return makeService(credentials.accessToken);\n }),\n );\n","// The push of a Convex.Deployment: a short-lived deploy key, the `env`\n// variables, and `convex deploy` with the Convex CLI that the app installed.\n//\n// - The key is created for one push with the Management API credential and\n// deleted after it, also after a failure. It can only deploy and read and\n// write variables (with a push command: every action), and it expires\n// after PUSH_KEY_LIFETIME_MS, so a run that stops before the delete leaves\n// no key that works for long. No key\n// goes into state, into an output, or to another resource.\n// - With an OAuth token as the credential, Convex creates no new key: it\n// returns the OAuth token with a new prefix. The push uses it, and the\n// delete is skipped, because it would revoke the OAuth token.\n// - The key reaches the CLI only through an env file (`--env-file`) with\n// mode 0600 in a new temporary directory. The directory is removed after\n// the run, on success, on failure, and on interruption. It is also the home\n// directory of the CLI, so the CLI cannot read the Convex login of this\n// machine. Variables named `CONVEX_*` are not passed on to the CLI.\n// - The CLI output stays out of the logs. A failure shows its last lines with\n// the key removed.\n//\n// The CLI runner follows Confect `packages/alchemy/src/internal/CommandRunner.ts`\n// (https://github.com/rjdellecese/confect, ISC license, see NOTICE).\nimport { createHash } from \"node:crypto\";\nimport { access, mkdtemp, readFile, rm, writeFile } from \"node:fs/promises\";\nimport { createRequire } from \"node:module\";\nimport { tmpdir } from \"node:os\";\nimport { dirname, join, relative, resolve } from \"node:path\";\nimport { stripVTControlCharacters } from \"node:util\";\nimport { createDeploymentClient } from \"@convex-dev/platform\";\nimport { hashDirectory } from \"alchemy/Command/Memo\";\nimport * as Clock from \"effect/Clock\";\nimport * as Effect from \"effect/Effect\";\nimport * as ChildProcess from \"effect/process/ChildProcess\";\nimport * as ChildProcessSpawner from \"effect/process/ChildProcessSpawner\";\nimport * as Redacted from \"effect/Redacted\";\nimport * as Schema from \"effect/Schema\";\nimport * as Stream from \"effect/Stream\";\nimport {\n absentAsUndefined,\n type ManagementApiService,\n retryIdempotentWrite,\n settle,\n settleVoid,\n} from \"./ManagementApi.ts\";\n\n/** A value of the `env` prop: a string, or a secret such as `Config.Redacted(\"AUTH_SECRET\")`. */\nexport type EnvValue = string | Redacted.Redacted<string>;\n\n/**\n * The `source` prop: the Convex functions directory, such as `./convex`, or\n * that directory with a push command and more files for the content identity.\n */\nexport type Source =\n | string\n | {\n /** The Convex functions directory, such as `./convex`. */\n readonly path: string;\n /**\n * Replaces `convex deploy`: a program and its arguments, run in the app\n * directory with CONVEX_DEPLOY_KEY in its environment, such as\n * `[\"pnpm\", \"exec\", \"convex-hosting\", \"deploy\", \"--build\", \"pnpm run build\", \"--dist\", \"dist\"]`.\n * It must push with `convex deploy`, such as through `--cmd`, so that\n * its output has the CLI's \"Deployed Convex functions to\" line.\n */\n readonly command?: readonly [string, ...string[]];\n /**\n * The files of the content identity, as globs relative to the app\n * directory, next to `path`, package.json, convex.json, and the\n * lockfile, such as the build inputs `[\"src/**\", \"vite.config.ts\"]`.\n * By default, every file of the app that git does not ignore.\n */\n readonly include?: readonly string[];\n };\n\nconst sourceOf = (source: Source) =>\n typeof source === \"string\"\n ? { path: source, command: undefined, include: undefined }\n : { path: source.path, command: source.command, include: source.include };\n\n/** Lifetime of a push key. Long enough for a slow push with index backfills. */\nexport const PUSH_KEY_LIFETIME_MS = 2 * 60 * 60 * 1000;\n\n/** The only actions a push key gets. */\nconst PUSH_KEY_ACTIONS = [\n \"deployment:deploy\",\n \"deployment:env:view\",\n \"deployment:env:write\",\n] as const;\n\n/** POST /deployments/{deployment_name}/create_deploy_key */\nconst CreatedDeployKey = Schema.Struct({ deployKey: Schema.String });\n\n/** GET https://<deployment>.convex.cloud/api/v1/list_environment_variables */\nconst EnvironmentVariableList = Schema.Struct({\n environmentVariables: Schema.Record(Schema.String, Schema.String),\n});\n\n/** No `convex` package resolves from the app directory. */\nexport class ConvexCliNotFound extends Schema.TaggedError<ConvexCliNotFound>()(\n \"ConvexCliNotFound\",\n { cwd: Schema.String },\n) {\n override get message() {\n return `Convex.Deployment found no installed convex package from ${this.cwd}, and it does not download one. Install convex in the app (npm install convex), or set source to the functions directory of the app.`;\n }\n}\n\n/** No directory at or above the parent of `source` has a package.json. */\nexport class ConvexAppNotFound extends Schema.TaggedError<ConvexAppNotFound>()(\n \"ConvexAppNotFound\",\n { source: Schema.String },\n) {\n override get message() {\n return `Convex.Deployment found no package.json at or above the parent of ${this.source}. Set source to the functions directory of a Convex app, such as \"./convex\".`;\n }\n}\n\n/** The Convex CLI failed, or exited 0 without the deployment URL. The output tail never contains the key. */\nexport class CodePushFailed extends Schema.TaggedError<CodePushFailed>()(\"CodePushFailed\", {\n /** Exit code of the CLI. Undefined when it did not start or a signal stopped it. */\n exitCode: Schema.UndefinedOr(Schema.Number),\n /** The last lines of the CLI output, with the deploy key removed. */\n outputTail: Schema.String,\n}) {\n override get message() {\n return this.exitCode === 0\n ? `convex deploy exited 0 but printed no \"Deployed Convex functions to <url>\" line. Last output, with the deploy key removed:\\n${this.outputTail}`\n : `convex deploy failed${this.exitCode === undefined ? \"\" : ` with exit code ${this.exitCode}`}. Last output, with the deploy key removed:\\n${this.outputTail}`;\n }\n}\n\n/** The CLI pushed to another deployment than the one of the resource. Checked after the push. */\nexport class PushTargetMismatch extends Schema.TaggedError<PushTargetMismatch>()(\n \"PushTargetMismatch\",\n { expected: Schema.String, actual: Schema.String },\n) {\n override get message() {\n return `The Convex CLI pushed the functions to deployment ${this.actual}, but Convex.Deployment expected ${this.expected}. Check that convex.json does not select another deployment.`;\n }\n}\n\n/** Variables in `env` exist on the deployment with other values, and adoption is off. */\nexport class VariablesOwnedBySomeoneElse extends Schema.TaggedError<VariablesOwnedBySomeoneElse>()(\n \"VariablesOwnedBySomeoneElse\",\n { deployment: Schema.String, names: Schema.Array(Schema.String) },\n) {\n override get message() {\n return `Environment variables ${this.names.join(\", \")} already exist on deployment ${this.deployment} with other values. Re-run with --adopt to take them over and overwrite them, or remove them from env.`;\n }\n}\n\n/** A preview deploy key cannot set variables: the deployment API takes only a deploy key of the deployment. */\nexport class EnvironmentNeedsDeployKey extends Schema.TaggedError<EnvironmentNeedsDeployKey>()(\n \"EnvironmentNeedsDeployKey\",\n { deployment: Schema.String },\n) {\n override get message() {\n return `Convex.Deployment cannot set or remove env variables on preview deployment ${this.deployment} with a preview deploy key: Convex lets that key create, push to, and delete preview deployments, but not change their variables. Set CONVEX_ACCESS_TOKEN for this stage, or set the values as project default environment variables for preview deployments in the Convex dashboard.`;\n }\n}\n\n/**\n * What a deploy key targets, from its prefix: `<type>:<deployment>|<secret>`\n * (or `<deployment>|<secret>` in old keys) for one deployment, and\n * `preview:<team>:<project>|<secret>` for the preview deployments of a\n * project. Same rules as convex 1.46 `cli/lib/deployment.js`.\n */\nexport const keyTargetOf = (\n key: string,\n):\n | { readonly kind: \"deployment\"; readonly deployment: string }\n | { readonly kind: \"preview\"; readonly team: string; readonly project: string }\n | { readonly kind: \"other\" } => {\n const bar = key.indexOf(\"|\");\n // A key in the env file must be one unquoted dotenv value.\n if (bar <= 0 || /[\\s#'\"`]/.test(key)) return { kind: \"other\" };\n const [first, second, third, ...rest] = key.slice(0, bar).split(\":\");\n if (rest.length > 0) return { kind: \"other\" };\n if (first === \"preview\" && second && third)\n return { kind: \"preview\", team: second, project: third };\n if (third !== undefined) return { kind: \"other\" };\n if (second) return { kind: \"deployment\", deployment: second };\n if (first && second === undefined) return { kind: \"deployment\", deployment: first };\n return { kind: \"other\" };\n};\n\n/**\n * The CLI prints this line with `logFinishedStep` after the push succeeds, to\n * stderr (convex 1.46 `cli/lib/deploy2.js`). The host is\n * `<deployment>.convex.cloud` or `<deployment>.<region>.convex.cloud`.\n */\nconst DEPLOYED_LINE =\n /Deployed Convex functions to (https:\\/\\/([a-z0-9]+(?:-[a-z0-9]+)*)(?:\\.[a-z0-9]+(?:-[a-z0-9]+)*)?\\.convex\\.cloud)\\/?(?=\\s|$)/m;\n\n/** Reads the deployment URL from `convex deploy` output. ANSI escape codes are removed first. */\nexport const parseDeployOutput = (\n text: string,\n): { url: string; deploymentName: string } | undefined => {\n const match = DEPLOYED_LINE.exec(stripVTControlCharacters(text));\n const url = match?.[1];\n const deploymentName = match?.[2];\n return url === undefined || deploymentName === undefined ? undefined : { url, deploymentName };\n};\n\n/** Number of output lines that a failure quotes. */\nconst OUTPUT_TAIL_LINES = 20;\n\n/** The last non-empty lines of `text`, without escape codes and with every secret replaced. */\nconst outputTail = (text: string, secrets: readonly string[]) =>\n secrets\n .reduce(\n (redacted, secret) => redacted.split(secret).join(\"[REDACTED]\"),\n stripVTControlCharacters(text),\n )\n .split(/\\r?\\n|\\r/)\n .filter((line) => line.trim() !== \"\")\n .slice(-OUTPUT_TAIL_LINES)\n .join(\"\\n\");\n\nconst valueOf = (value: EnvValue) => (Redacted.isRedacted(value) ? Redacted.value(value) : value);\n\n/** The app directory: the nearest directory at or above the parent of `source` with a package.json. */\nconst appDirectoryOf = (source: string) =>\n Effect.tryPromise({\n try: async () => {\n let directory = dirname(resolve(source));\n while (true) {\n try {\n await access(join(directory, \"package.json\"));\n return directory;\n } catch {\n const parent = dirname(directory);\n if (parent === directory) throw new Error(\"no package.json\");\n directory = parent;\n }\n }\n },\n catch: () => new ConvexAppNotFound({ source }),\n });\n\n/** `source` is not the functions directory that the Convex CLI pushes from this app. */\nexport class SourceMismatch extends Schema.TaggedError<SourceMismatch>()(\"SourceMismatch\", {\n source: Schema.String,\n functions: Schema.String,\n}) {\n override get message() {\n return `Convex.Deployment source is ${this.source}, but the Convex CLI pushes ${this.functions} in this app (the \"functions\" field of convex.json, or convex/ by default). Set source to ${this.functions}.`;\n }\n}\n\nconst ConvexJson = Schema.Struct({ functions: Schema.optionalKey(Schema.String) });\n\n/** Fails with {@link SourceMismatch} when `path` is not the functions directory of the app in `cwd`. */\nconst checkFunctionsDirectory = (cwd: string, path: string) =>\n Effect.gen(function* () {\n const text = yield* Effect.promise(() =>\n readFile(join(cwd, \"convex.json\"), \"utf8\").catch(() => undefined),\n );\n const configured =\n text === undefined\n ? undefined\n : Schema.decodeUnknownSync(Schema.fromJsonString(ConvexJson))(text).functions;\n const functions = resolve(cwd, configured ?? \"convex\");\n if (functions !== resolve(path)) {\n return yield* new SourceMismatch({ source: resolve(path), functions });\n }\n });\n\nconst CliManifest = Schema.Struct({\n bin: Schema.Union([Schema.String, Schema.Record(Schema.String, Schema.String)]),\n});\n\n/** `[node, <convex bin>]` for the `convex` package that `cwd` resolves. Never downloads. */\nconst installedCli = (cwd: string) =>\n Effect.tryPromise({\n try: async (): Promise<readonly [string, ...string[]]> => {\n const manifestPath = createRequire(join(cwd, \"package.json\")).resolve(\"convex/package.json\");\n const { bin } = Schema.decodeUnknownSync(Schema.fromJsonString(CliManifest))(\n await readFile(manifestPath, \"utf8\"),\n );\n const entry = typeof bin === \"string\" ? bin : bin[\"convex\"];\n if (entry === undefined) throw new Error(\"the convex package has no convex bin\");\n return [process.execPath, resolve(dirname(manifestPath), entry)];\n },\n catch: () => new ConvexCliNotFound({ cwd }),\n });\n\n/**\n * The content identity of a push: the files of the app directory that git\n * does not ignore (or `path`, the manifests, and the `include` globs), the\n * nearest lockfile, the target deployment, and the `env` names and values.\n * A change in a workspace package outside the app directory is not seen.\n */\nexport const pushHash = (options: {\n readonly source: Source | undefined;\n readonly deployment: string;\n readonly env: Readonly<Record<string, EnvValue>>;\n}) =>\n Effect.gen(function* () {\n const source = options.source === undefined ? undefined : sourceOf(options.source);\n const files =\n source === undefined\n ? undefined\n : yield* appDirectoryOf(source.path).pipe(\n Effect.flatMap((cwd) =>\n hashDirectory({\n cwd,\n // By default every file of the app that git does not ignore,\n // such as a module outside `source` that a function imports.\n // `include` narrows it to the functions, the manifests, and\n // the listed globs.\n memo:\n source.include === undefined\n ? {}\n : {\n include: [\n `${relative(cwd, resolve(source.path)).split(\"\\\\\").join(\"/\")}/**`,\n \"package.json\",\n \"convex.json\",\n ...source.include,\n ],\n lockfile: true,\n },\n }),\n ),\n );\n const env = Object.entries(options.env)\n .map(([name, value]): readonly [string, string] => [name, valueOf(value)])\n .sort(([a], [b]) => (a < b ? -1 : 1));\n return createHash(\"sha256\")\n .update(JSON.stringify({ files, deployment: options.deployment, env }))\n .digest(\"hex\");\n });\n\n/**\n * Runs `use` with an env file that holds the key, in a new temporary\n * directory, and removes the directory afterwards: on success, on failure,\n * and on interruption.\n */\nconst withKeyFile = <A, E, R>(\n key: string,\n use: (paths: { readonly envFile: string; readonly home: string }) => Effect.Effect<A, E, R>,\n) =>\n Effect.acquireUseRelease(\n Effect.promise(() => mkdtemp(join(tmpdir(), \"alchemy-convex-\"))),\n (home) =>\n Effect.promise(() =>\n writeFile(join(home, \"deploy.env\"), `CONVEX_DEPLOY_KEY=${key}\\n`, { mode: 0o600 }),\n ).pipe(Effect.andThen(use({ envFile: join(home, \"deploy.env\"), home }))),\n (home) => Effect.promise(() => rm(home, { recursive: true, force: true })),\n );\n\n/** This process's variables without `CONVEX_*`, with `home` as the home directory. */\nconst cliEnvironment = (home: string): Record<string, string | undefined> => ({\n ...Object.fromEntries(\n Object.entries(process.env).filter(([name]) => !name.toUpperCase().startsWith(\"CONVEX_\")),\n ),\n HOME: home,\n USERPROFILE: home,\n XDG_CONFIG_HOME: home,\n});\n\n/**\n * Creates a deploy key for one push, runs `use` with it, and deletes it\n * afterwards. Without a push command, the key can only deploy and read and\n * write variables. The delete is skipped for a key that is the OAuth credential.\n * A failed delete is logged: the key expires anyway.\n */\nexport const withPushKey = <A, E, R>(\n api: ManagementApiService,\n deployment: string,\n source: Source | undefined,\n use: (key: Redacted.Redacted<string>) => Effect.Effect<A, E, R>,\n) =>\n Effect.acquireUseRelease(\n Effect.gen(function* () {\n const now = yield* Clock.currentTimeMillis;\n const created = yield* api.request(\"create deploy key\", (client) =>\n client.POST(\"/deployments/{deployment_name}/create_deploy_key\", {\n params: { path: { deployment_name: deployment } },\n body: {\n name: \"alchemy-push\",\n // A push command can do more than a push, such as the uploads of\n // convex-hosting through `convex run`, so its key has every action.\n ...(source === undefined || sourceOf(source).command === undefined\n ? { allowedActions: [...PUSH_KEY_ACTIONS] }\n : {}),\n expiresAt: now + PUSH_KEY_LIFETIME_MS,\n },\n }),\n );\n return Redacted.make(Schema.decodeUnknownSync(CreatedDeployKey)(created).deployKey);\n }),\n use,\n (key) =>\n Effect.gen(function* () {\n if (yield* api.isCredentialToken(Redacted.value(key))) return;\n yield* absentAsUndefined(\n retryIdempotentWrite(\n api.requestVoid(\"delete deploy key\", (client) =>\n client.POST(\"/deployments/{deployment_name}/delete_deploy_key\", {\n params: { path: { deployment_name: deployment } },\n body: { id: Redacted.value(key) },\n }),\n ),\n ),\n );\n }).pipe(\n Effect.catch((error) =>\n Effect.logWarning(\n `Convex.Deployment could not delete its push key on ${deployment} (${error.message}). The key expires on its own within ${PUSH_KEY_LIFETIME_MS / 60_000} minutes.`,\n ),\n ),\n ),\n );\n\n/** Every variable of the deployment with its value. */\nconst listVariables = (url: string, key: Redacted.Redacted<string>) =>\n settle(\"list environment variables\", () =>\n createDeploymentClient(url, Redacted.value(key)).GET(\"/list_environment_variables\"),\n ).pipe(\n Effect.map(\n (body) => Schema.decodeUnknownSync(EnvironmentVariableList)(body).environmentVariables,\n ),\n );\n\n/** One call that sets variables, or removes those whose value is null. */\nconst writeVariables = (\n url: string,\n key: Redacted.Redacted<string>,\n changes: ReadonlyArray<{ readonly name: string; readonly value: string | null }>,\n) =>\n settleVoid(\"update environment variables\", () =>\n createDeploymentClient(url, Redacted.value(key)).POST(\"/update_environment_variables\", {\n body: { changes: changes.map(({ name, value }) => ({ name, value })) },\n }),\n );\n\nexport interface PushOptions {\n /** Deployment name, such as `happy-animal-123`. */\n readonly deployment: string;\n /** Client URL of the deployment. */\n readonly url: string;\n /** The functions directory, or it with a push command. Without it, only the variables change. */\n readonly source: Source | undefined;\n readonly env: Readonly<Record<string, EnvValue>>;\n /** Names that an earlier push set on this deployment. Names that left `env` are removed. */\n readonly previousEnvNames: readonly string[];\n /** True when the resource may overwrite variables that it did not set. */\n readonly adopt: boolean;\n /**\n * The preview name for `convex deploy --preview-name`, when `key` is a\n * preview deploy key. Such a key cannot set variables.\n */\n readonly previewName: string | undefined;\n}\n\n/**\n * The app directory and the program of a push. Fails before any change when\n * `source` is not the functions directory of the app, or when the app has no\n * installed Convex CLI and no push command.\n */\nexport const checkSource = (input: Source) =>\n Effect.gen(function* () {\n const source = sourceOf(input);\n const cwd = yield* appDirectoryOf(source.path);\n yield* checkFunctionsDirectory(cwd, source.path);\n const program = source.command ?? (yield* installedCli(cwd));\n return { cwd, program };\n });\n\n/**\n * Sets the `env` variables and pushes the functions of `source` to one\n * deployment with `key`: a deploy key of the deployment, or a preview deploy\n * key of its project with `previewName`. Returns the URL that the CLI\n * printed, or undefined without `source`.\n */\nexport const push = (\n spawner: ChildProcessSpawner.ChildProcessSpawner[\"Service\"],\n key: Redacted.Redacted<string>,\n options: PushOptions,\n) =>\n Effect.gen(function* () {\n const source = options.source === undefined ? undefined : sourceOf(options.source);\n const resolved = options.source === undefined ? undefined : yield* checkSource(options.source);\n const cwd = resolved?.cwd;\n const program = resolved?.program;\n const env = Object.entries(options.env).sort(([a], [b]) => (a < b ? -1 : 1));\n const removed = options.previousEnvNames.filter((name) => !Object.hasOwn(options.env, name));\n\n // 1. Variables before the push, so the push sees them. Each attempt\n // reads the current values first, so a retry after a write conflict never\n // overwrites a value that another writer set in the meantime. Only\n // changed values are written, and the earlier ones are kept for a\n // rollback.\n const written =\n env.length === 0 && removed.length === 0\n ? { current: {}, changes: [] }\n : yield* retryIdempotentWrite(\n Effect.gen(function* () {\n const current = yield* listVariables(options.url, key);\n if (!options.adopt) {\n // The same value loses nothing, such as a value that an\n // earlier run set before its push failed.\n const taken = env\n .filter(\n ([name, value]) =>\n !options.previousEnvNames.includes(name) &&\n Object.hasOwn(current, name) &&\n current[name] !== valueOf(value),\n )\n .map(([name]) => name);\n if (taken.length > 0) {\n return yield* new VariablesOwnedBySomeoneElse({\n deployment: options.deployment,\n names: taken,\n });\n }\n }\n const changes = [\n ...env\n .filter(([name, value]) => current[name] !== valueOf(value))\n .map(([name, value]) => ({ name, value: valueOf(value) })),\n ...removed\n .filter((name) => Object.hasOwn(current, name))\n .map((name) => ({ name, value: null })),\n ];\n if (changes.length > 0) yield* writeVariables(options.url, key, changes);\n return { current, changes };\n }),\n );\n\n /**\n * After a failed push, the variables go back to their earlier values, so\n * that the deployment matches the hash in state. A failed rollback is\n * logged: the push error is the one to report.\n */\n const rollback =\n written.changes.length === 0\n ? Effect.void\n : retryIdempotentWrite(\n writeVariables(\n options.url,\n key,\n written.changes.map(({ name }) => ({\n name,\n value: Object.hasOwn(written.current, name)\n ? (written.current[name] ?? null)\n : null,\n })),\n ),\n ).pipe(\n Effect.catch((error) =>\n Effect.logWarning(\n `Convex.Deployment could not set the env variables of ${options.deployment} back after the failed push (${error.message}). Run the deploy again.`,\n ),\n ),\n );\n\n // 2. The push, with the key only in the env file.\n if (source === undefined || cwd === undefined || program === undefined) return undefined;\n return yield* runPush(spawner, key, { ...options, cwd, program, command: source.command }).pipe(\n Effect.onError(() => rollback),\n );\n });\n\n/** Runs the installed CLI or the push command once, and checks the deployment that it names. */\nconst runPush = (\n spawner: ChildProcessSpawner.ChildProcessSpawner[\"Service\"],\n key: Redacted.Redacted<string>,\n options: PushOptions & {\n readonly cwd: string;\n readonly program: readonly [string, ...string[]];\n readonly command: readonly [string, ...string[]] | undefined;\n },\n) =>\n Effect.gen(function* () {\n const { cwd, program } = options;\n const secret = Redacted.value(key);\n const secrets = [secret, secret.slice(secret.indexOf(\"|\") + 1)].filter(\n (value) => value.length >= 8,\n );\n const result = yield* withKeyFile(secret, ({ envFile, home }) =>\n Effect.gen(function* () {\n const [command, ...programArgs] = program;\n // The installed CLI reads the key from the env file. A push command\n // gets it as CONVEX_DEPLOY_KEY, which the CLI that it runs reads.\n const args =\n options.command === undefined\n ? [\n ...programArgs,\n \"deploy\",\n ...(options.previewName === undefined\n ? []\n : [\"--preview-name\", options.previewName]),\n \"--env-file\",\n envFile,\n ]\n : programArgs;\n const child = yield* spawner.spawn(\n ChildProcess.make(command, args, {\n cwd,\n env: {\n ...cliEnvironment(home),\n ...(options.command === undefined ? {} : { CONVEX_DEPLOY_KEY: secret }),\n },\n extendEnv: false,\n stdin: \"ignore\",\n stdout: \"pipe\",\n stderr: \"pipe\",\n }),\n );\n const [exitCode, stdout, stderr] = yield* Effect.all(\n [\n child.exitCode,\n Stream.mkString(Stream.decodeText(child.stdout)),\n Stream.mkString(Stream.decodeText(child.stderr)),\n ],\n { concurrency: \"unbounded\" },\n );\n return { exitCode: Number(exitCode), output: `${stdout}\\n${stderr}` };\n }).pipe(Effect.scoped),\n ).pipe(\n Effect.mapError(\n (error) =>\n new CodePushFailed({\n exitCode: undefined,\n outputTail: outputTail(error.message, secrets),\n }),\n ),\n );\n const deployed = parseDeployOutput(result.output);\n if (result.exitCode !== 0 || deployed === undefined) {\n return yield* new CodePushFailed({\n exitCode: result.exitCode,\n outputTail: outputTail(result.output, secrets),\n });\n }\n if (deployed.deploymentName !== options.deployment) {\n return yield* new PushTargetMismatch({\n expected: options.deployment,\n actual: deployed.deploymentName,\n });\n }\n return deployed.url;\n });\n","// Convex.Deployment: one deployment of a Convex project, its environment\n// variables, and its functions, with the URLs that a frontend or a Worker\n// needs. This is the Convex plane of a stack: no deploy key leaves it.\n//\n// - `source` is the Convex functions directory, such as `./convex`. The\n// update pushes it with the Convex CLI that the app installed (Push.ts).\n// The content identity of the push is a hash of the source files, the\n// app's package.json, convex.json, and lockfile, the deployment name, and\n// `env`. The same hash is a no-op. The hash is taken again after the push,\n// so files that `convex deploy` generates are part of it.\n// `source.command` replaces `convex deploy`, such as `convex-hosting\n// deploy`, and `source.include` adds the files that it reads to the hash.\n// - `env` is set on the deployment before the push. A name that leaves `env`\n// is removed. A variable that exists with another value and that this\n// resource did not set is someone else's: it is overwritten only with\n// --adopt. Delete leaves the variables: they go with the deployment.\n// - Credentials by scope (see Access below): a deploy key of the deployment,\n// a preview deploy key of the project, or the Management API token.\n// - `prod` is the project's default production deployment. Convex creates it\n// with the project, so this resource never creates one. It takes the\n// deployment over without --adopt: it never changes or deletes a production\n// deployment, so the takeover cannot lose data. It follows the default:\n// when another production deployment becomes the default, the next deploy\n// outputs that one. With a deploy key, `prod` is the production deployment\n// of that key. To delete a production deployment, delete its project\n// (Convex.Project with RemovalPolicy.destroy()). Delete reads the live type\n// first, so a dev or preview deployment that became a production\n// deployment is not deleted either.\n// - `dev` and `preview` are created with POST\n// /projects/{project_id}/create_deployment and the `name` prop as the\n// reference. Convex keeps a dev reference as given. For a preview, Convex\n// records `name` as the preview identifier, the name that\n// `npx convex deploy --preview-name <name>` finds, and derives the reference\n// from it (`preview/<slug>`). A create for a preview name that already has\n// a preview deployment deletes that deployment and creates a new one, so\n// reconcile always looks the name up first and never creates over an\n// existing deployment. A dev or preview deployment that exists but is not\n// in state belongs to someone else: the resource takes it over only with\n// --adopt.\n// - `projectId`, `type`, and `name` are the identity. A change fails with\n// DeploymentIdentityChange; the resource is never replaced.\n// - The removal policy is `retain` for every type. A preview deployment\n// expires on Convex's schedule (14 days by default). To delete a dev or\n// preview deployment with the resource, add RemovalPolicy.destroy().\n//\n// Patterns from Confect `packages/alchemy/src/Deployment.ts`\n// (https://github.com/rjdellecese/confect, ISC license, see NOTICE).\nimport { Resource } from \"alchemy\";\nimport { OwnedBySomeoneElse, Unowned } from \"alchemy/AdoptPolicy\";\nimport { isResolved } from \"alchemy/Diff\";\nimport * as Provider from \"alchemy/Provider\";\nimport * as Effect from \"effect/Effect\";\nimport * as ChildProcessSpawner from \"effect/process/ChildProcessSpawner\";\nimport * as Redacted from \"effect/Redacted\";\nimport * as Schema from \"effect/Schema\";\nimport { shouldAdopt } from \"./Adoption.ts\";\nimport { Credentials } from \"./Credentials.ts\";\nimport {\n absentAsUndefined,\n type ConvexApiError,\n ManagementApi,\n type ManagementApiService,\n retryIdempotentWrite,\n} from \"./ManagementApi.ts\";\nimport type { Providers } from \"./Providers.ts\";\nimport {\n checkSource,\n EnvironmentNeedsDeployKey,\n type EnvValue,\n keyTargetOf,\n push,\n pushHash,\n type Source,\n withPushKey,\n} from \"./Push.ts\";\n\ninterface DeploymentInputs {\n /** The project: a Convex.Project resource, or `{ projectId }`. Cannot change. */\n readonly project: { readonly projectId: number };\n /**\n * The Convex functions directory, such as `./convex`, or that directory\n * with a push command and more hashed files. The push runs in the nearest\n * directory above it with a package.json. Without `source`, the resource\n * pushes nothing.\n */\n readonly source?: Source;\n /** Environment variables to set on the deployment before the push. */\n readonly env?: Readonly<Record<string, EnvValue>>;\n}\n\nexport type DeploymentProps =\n | (DeploymentInputs & {\n /** The project's default production deployment. Cannot change. */\n readonly type: \"prod\";\n })\n | (DeploymentInputs & {\n /** A dev deployment or a preview deployment that this resource creates. Cannot change. */\n readonly type: \"dev\" | \"preview\";\n /**\n * The dev reference, such as `staging`, or the preview name, such as\n * the stage name. Unique in the project. Cannot change.\n */\n readonly name: string;\n });\n\n/** The deployment itself, without the state of the push. */\ninterface DeploymentTarget {\n readonly projectId: number;\n readonly type: DeploymentProps[\"type\"];\n /** Deployment name, such as `happy-animal-123`. */\n readonly name: string;\n /** The reference that Convex lists, such as `production`, `staging`, or `preview/pr-42`. */\n readonly reference: string;\n /** The preview name of a preview deployment. Undefined for prod and dev. */\n readonly previewName: string | undefined;\n /** Client URL, such as `https://happy-animal-123.convex.cloud`. */\n readonly url: string;\n /** HTTP actions URL, such as `https://happy-animal-123.convex.site`. */\n readonly siteUrl: string;\n}\n\nexport interface DeploymentAttributes extends DeploymentTarget {\n /** Content identity of the last push and `env`. Undefined when the resource pushed nothing. */\n readonly hash: string | undefined;\n /** The names of the `env` variables that this resource set on the deployment, sorted. */\n readonly envNames: readonly string[];\n}\n\nexport type Deployment = Resource<\n \"Convex.Deployment\",\n DeploymentProps,\n DeploymentAttributes,\n never,\n Providers\n>;\nexport const Deployment = Resource<Deployment>(\"Convex.Deployment\", {\n defaultRemovalPolicy: \"retain\",\n});\n\n/** The props name another deployment than the one in state. */\nexport class DeploymentIdentityChange extends Schema.TaggedError<DeploymentIdentityChange>()(\n \"DeploymentIdentityChange\",\n {\n /** Name of the deployment in state, such as `happy-animal-123`. */\n deployment: Schema.String,\n field: Schema.Literals([\"projectId\", \"type\", \"name\"]),\n current: Schema.String,\n requested: Schema.String,\n },\n) {\n override get message() {\n return `Convex.Deployment cannot change the ${this.field} of deployment ${this.deployment} from ${this.current} to ${this.requested}. Set ${this.field} back to ${this.current}. For another deployment, create a new resource with a new logical id.`;\n }\n}\n\n/** The project has no default production deployment for a `prod` resource to take over. */\nexport class ProductionDeploymentNotFound extends Schema.TaggedError<ProductionDeploymentNotFound>()(\n \"ProductionDeploymentNotFound\",\n { projectId: Schema.Number },\n) {\n override get message() {\n return `Project ${this.projectId} has no default production deployment, and Convex.Deployment does not create one. Create it in the Convex dashboard, or with \\`npx convex deployment create --type prod --default\\` in the project, then run the deploy again.`;\n }\n}\n\n/** More than one deployment of the project has the name, so the lookup cannot choose one. */\nexport class AmbiguousDeployment extends Schema.TaggedError<AmbiguousDeployment>()(\n \"AmbiguousDeployment\",\n {\n projectId: Schema.Number,\n type: Schema.Literals([\"dev\", \"preview\"]),\n name: Schema.String,\n deployments: Schema.Array(Schema.String),\n },\n) {\n override get message() {\n return `Project ${this.projectId} has ${this.deployments.length} ${this.type} deployments named \"${this.name}\" (${this.deployments.join(\", \")}). Convex.Deployment does not choose one. Delete the extra deployments in the Convex dashboard, or use another name.`;\n }\n}\n\n/**\n * The URL of a Convex cloud deployment: `https://<name>.convex.cloud`, or\n * `https://<name>.<region>.convex.cloud` outside US East.\n */\nconst CLOUD_URL =\n /^https:\\/\\/[a-z0-9]+(?:-[a-z0-9]+)*(?:\\.[a-z0-9]+(?:-[a-z0-9]+)*)?\\.convex\\.cloud$/;\n\n/**\n * The HTTP actions URL of a deployment: the client URL with `.convex.site`\n * for `.convex.cloud`, as Convex sets CONVEX_SITE_URL. Custom domains are\n * not covered.\n */\nexport const siteUrlOf = (url: string): string => url.replace(/\\.convex\\.cloud$/, \".convex.site\");\n\n/** One row of list_deployments, GET /deployments/{name}, and create_deployment. Only the fields the provider uses. */\nexport const DeploymentRow = Schema.Struct({\n name: Schema.String,\n projectId: Schema.Number,\n deploymentType: Schema.String,\n isDefault: Schema.Boolean,\n reference: Schema.String,\n /** Set in list_deployments and create_deployment rows only: GET /deployments/{name} answers null. */\n previewIdentifier: Schema.optionalKey(Schema.NullOr(Schema.String)),\n deploymentUrl: Schema.String.check(Schema.isPattern(CLOUD_URL)),\n /** Absent or null until the first push: list_deployments leaves it out for a new deployment. */\n lastDeployTime: Schema.optionalKey(Schema.NullOr(Schema.Number)),\n});\ntype DeploymentRow = typeof DeploymentRow.Type;\nconst DeploymentRows = Schema.Array(DeploymentRow);\n\n/** GET https://<deployment>/api/v1/deployment_info, for a cloud deployment. Only the fields the provider uses. */\nconst DeploymentInfo = Schema.Struct({\n kind: Schema.Literal(\"cloud\"),\n projectId: Schema.Number,\n deploymentType: Schema.String,\n reference: Schema.optionalKey(Schema.NullOr(Schema.String)),\n});\n\n/** GET https://<deployment>/api/v1/get_canonical_urls */\nconst CanonicalUrls = Schema.Struct({\n convexCloudUrl: Schema.String,\n convexSiteUrl: Schema.String,\n});\n\nconst targetOf = (\n row: DeploymentRow,\n type: DeploymentProps[\"type\"],\n previewName: string | undefined,\n): DeploymentTarget => ({\n projectId: row.projectId,\n type,\n name: row.name,\n reference: row.reference,\n previewName: type === \"preview\" ? previewName : undefined,\n url: row.deploymentUrl,\n siteUrl: siteUrlOf(row.deploymentUrl),\n});\n\n/** True when the deployment has received a push. */\nconst isDeployed = (row: DeploymentRow) =>\n row.lastDeployTime !== undefined && row.lastDeployTime !== null;\n\n/** The `name` prop of a deployment: the dev reference or the preview name. */\nconst nameOf = (target: DeploymentTarget) =>\n target.type === \"dev\"\n ? target.reference\n : target.type === \"preview\"\n ? target.previewName\n : undefined;\n\n/**\n * Fails with {@link DeploymentIdentityChange} when the props name another\n * deployment than `current`: the attributes in state, or a live deployment.\n */\nconst checkIdentity = (current: DeploymentTarget, news: DeploymentProps) => {\n const change = (field: \"projectId\" | \"type\" | \"name\", from: string, to: string) =>\n Effect.fail(\n new DeploymentIdentityChange({\n deployment: current.name,\n field,\n current: from,\n requested: to,\n }),\n );\n if (current.projectId !== news.project.projectId) {\n return change(\"projectId\", String(current.projectId), String(news.project.projectId));\n }\n if (current.type !== news.type) return change(\"type\", current.type, news.type);\n const currentName = nameOf(current);\n if (news.type !== \"prod\" && currentName !== news.name) {\n return change(\"name\", currentName ?? \"(none)\", news.name);\n }\n return Effect.void;\n};\n\n/** The deployment that a resource addresses: its project, type, and dev or preview name. */\ninterface Address {\n readonly projectId: number;\n readonly type: DeploymentProps[\"type\"];\n readonly name: string | undefined;\n}\n\nconst addressOf = (props: DeploymentProps): Address => ({\n projectId: props.project.projectId,\n type: props.type,\n name: props.type === \"prod\" ? undefined : props.name,\n});\n\n/** True when an update writes or removes variables: `env` has names, or state has names to remove. */\nconst changesEnv = (news: DeploymentProps, output: DeploymentAttributes | undefined) =>\n Object.keys(news.env ?? {}).length > 0 || envNamesOf(output).length > 0;\n\n/** The `env` names in state. State from 0.3 has none. */\nconst envNamesOf = (output: DeploymentAttributes | undefined): readonly string[] =>\n output?.envNames ?? [];\n\n/** The address of the deployment in state. */\nconst addressInState = (output: DeploymentAttributes): Address => ({\n projectId: output.projectId,\n type: output.type,\n name: nameOf(output),\n});\n\n/**\n * How the provider reaches one deployment, by the narrowest credential that\n * fits:\n *\n * - `deployKey`: the configured deploy key belongs to this deployment. The\n * deployment API answers its identity and URLs, the key sets variables and\n * pushes, and no Management API call is made.\n * - `previewKey`: the configured preview deploy key belongs to this project.\n * The Management API takes it for the preview deployments of the project,\n * and the CLI pushes with it and `--preview-name`.\n * - `token`: the Management API access token. Each push gets a short-lived\n * deploy key (Push.ts).\n */\ntype Access =\n | {\n readonly kind: \"deployKey\";\n readonly key: Redacted.Redacted<string>;\n readonly target: DeploymentTarget;\n }\n | {\n readonly kind: \"previewKey\";\n readonly key: Redacted.Redacted<string>;\n readonly api: ManagementApiService;\n }\n | { readonly kind: \"token\"; readonly api: ManagementApiService };\n\nconst ProjectSlugs = Schema.Struct({ slug: Schema.String, teamSlug: Schema.String });\n\n/** True for an answer that says this credential cannot read the object. */\nconst isRefused = (error: ConvexApiError) =>\n error.status === 400 || error.status === 401 || error.status === 403 || error.status === 404;\n\nexport const DeploymentProvider = () =>\n Provider.effect(\n Deployment,\n Effect.gen(function* () {\n const api = yield* ManagementApi;\n const credentials = yield* Credentials;\n const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;\n\n /** The live deployment, or undefined after a 404. GET /deployments/{name} answers no preview identifier. */\n const getByName = (management: ManagementApiService, name: string) =>\n absentAsUndefined(\n management.request(\"get deployment\", (client) =>\n client.GET(\"/deployments/{deployment_name}\", {\n params: { path: { deployment_name: name } },\n }),\n ),\n ).pipe(\n Effect.map((body) =>\n body === undefined ? undefined : Schema.decodeUnknownSync(DeploymentRow)(body),\n ),\n );\n\n const listDeployments = (\n management: ManagementApiService,\n projectId: number,\n type: DeploymentProps[\"type\"],\n isDefault?: boolean,\n ) =>\n management\n .request(\"list deployments\", (client) =>\n client.GET(\"/projects/{project_id}/list_deployments\", {\n params: {\n path: { project_id: projectId },\n query: { deploymentType: type, ...(isDefault === undefined ? {} : { isDefault }) },\n },\n }),\n )\n .pipe(Effect.map((body) => Schema.decodeUnknownSync(DeploymentRows)(body)));\n\n /** The row of the project's default production deployment, or undefined. */\n const productionRow = (management: ManagementApiService, projectId: number) =>\n listDeployments(management, projectId, \"prod\", true).pipe(\n Effect.map((rows) =>\n rows.find((candidate) => candidate.deploymentType === \"prod\" && candidate.isDefault),\n ),\n );\n\n /** The project's default production deployment, or undefined. */\n const production = (management: ManagementApiService, projectId: number) =>\n productionRow(management, projectId).pipe(\n Effect.map((row) => (row === undefined ? undefined : targetOf(row, \"prod\", undefined))),\n );\n\n /**\n * The one dev deployment with this reference, or the one preview\n * deployment with this preview name, or undefined.\n */\n const findByName = (\n management: ManagementApiService,\n projectId: number,\n type: \"dev\" | \"preview\",\n name: string,\n ) =>\n Effect.gen(function* () {\n const matches = (yield* listDeployments(management, projectId, type)).filter(\n (row) =>\n row.deploymentType === type &&\n (type === \"dev\" ? row.reference === name : row.previewIdentifier === name),\n );\n if (matches.length > 1) {\n return yield* new AmbiguousDeployment({\n projectId,\n type,\n name,\n deployments: matches.map((row) => row.name),\n });\n }\n return matches[0];\n });\n\n /** The deployment that the address names, through the Management API, or undefined. */\n const lookup = (management: ManagementApiService, address: Address) =>\n address.type === \"prod\" || address.name === undefined\n ? production(management, address.projectId)\n : findByName(management, address.projectId, address.type, address.name).pipe(\n Effect.map((row) =>\n row === undefined ? undefined : targetOf(row, address.type, address.name),\n ),\n );\n\n /** The deployment of a deploy key, when it is the deployment that the address names. */\n const deployKeyTarget = (\n key: Redacted.Redacted<string>,\n deployment: string,\n address: Address,\n ) =>\n Effect.gen(function* () {\n const info = Schema.decodeUnknownSync(DeploymentInfo)(\n yield* api.deploymentRequest(\"get deployment info\", deployment, key, (client) =>\n client.GET(\"/deployment_info\"),\n ),\n );\n const reference = info.reference ?? \"\";\n if (\n info.projectId !== address.projectId ||\n info.deploymentType !== address.type ||\n (address.type === \"dev\" && reference !== address.name)\n ) {\n return undefined;\n }\n const urls = Schema.decodeUnknownSync(CanonicalUrls)(\n yield* api.deploymentRequest(\"get canonical urls\", deployment, key, (client) =>\n client.GET(\"/get_canonical_urls\"),\n ),\n );\n return {\n projectId: info.projectId,\n type: address.type,\n name: deployment,\n reference,\n previewName: undefined,\n url: urls.convexCloudUrl,\n siteUrl: urls.convexSiteUrl,\n } satisfies DeploymentTarget;\n }).pipe(Effect.catchIf(isRefused, () => Effect.succeed(undefined)));\n\n /** True when the preview deploy key belongs to the project. */\n const previewKeyFits = (\n management: ManagementApiService,\n slugs: { readonly team: string; readonly project: string },\n projectId: number,\n ) =>\n management\n .request(\"get project\", (client) =>\n client.GET(\"/projects/{project_id}\", { params: { path: { project_id: projectId } } }),\n )\n .pipe(\n Effect.map((body) => {\n const project = Schema.decodeUnknownSync(ProjectSlugs)(body);\n return project.slug === slugs.project && project.teamSlug === slugs.team;\n }),\n Effect.catchIf(isRefused, () => Effect.succeed(false)),\n );\n\n /**\n * The narrowest credential that reaches the deployment. See {@link Access}.\n * When `changesEnv`, a preview deploy key gives way to the access token,\n * because it cannot change variables.\n */\n const accessFor = (address: Address, changesEnv: boolean) =>\n Effect.gen(function* (): Effect.fn.Return<Access, ConvexApiError> {\n const key = yield* credentials.deployKey;\n if (key !== undefined) {\n const target = keyTargetOf(Redacted.value(key));\n if (target.kind === \"deployment\" && address.type !== \"preview\") {\n const found = yield* deployKeyTarget(key, target.deployment, address);\n if (found !== undefined) return { kind: \"deployKey\", key, target: found };\n }\n if (target.kind === \"preview\" && address.type === \"preview\") {\n const scoped = api.withToken(key);\n if (\n !(changesEnv && (yield* credentials.hasAccessToken)) &&\n (yield* previewKeyFits(scoped, target, address.projectId))\n ) {\n return { kind: \"previewKey\", key, api: scoped };\n }\n }\n }\n return { kind: \"token\", api };\n });\n\n /** The live deployment of a resource in state, or undefined when it is gone. */\n const live = (access: Access, output: DeploymentAttributes) =>\n Effect.gen(function* () {\n if (access.kind === \"deployKey\") return access.target;\n // 404 for a deleted project: its production deployment is gone too.\n if (output.type === \"prod\")\n return yield* absentAsUndefined(production(access.api, output.projectId));\n const row = yield* getByName(access.api, output.name);\n return row === undefined ? undefined : targetOf(row, output.type, output.previewName);\n });\n\n /** The content identity of `source` and `env` on a deployment, or undefined when there is nothing to push. */\n const wantedHash = (news: DeploymentProps, deployment: string) =>\n news.source === undefined && Object.keys(news.env ?? {}).length === 0\n ? Effect.succeed(undefined)\n : pushHash({ source: news.source, deployment, env: news.env ?? {} });\n\n return {\n // `name`, `reference`, and the URLs change when an expired preview is\n // created again, or when another production deployment becomes the\n // default.\n stables: [\"projectId\", \"type\", \"previewName\"],\n\n // Compares with the attributes: after a refused change, `olds` are\n // the refused props.\n diff: Effect.fn(function* ({ news, output }) {\n if (!isResolved(news) || output === undefined) return undefined;\n yield* checkIdentity(output, news);\n const access = yield* accessFor(addressOf(news), changesEnv(news, output));\n // A preview expires, anyone can delete a deployment, and another\n // production deployment can become the default. Reconcile then\n // finds or creates the right one, so the stack never hands out the\n // URL of a deployment that is gone.\n const current = yield* live(access, output);\n if (current?.name !== output.name) return { action: \"update\" } as const;\n const hash = yield* wantedHash(news, output.name);\n return hash === output.hash\n ? ({ action: \"noop\" } as const)\n : ({ action: \"update\" } as const);\n }),\n\n read: Effect.fn(function* ({ olds, output }) {\n if (output !== undefined) {\n const access = yield* accessFor(addressInState(output), false);\n const current = yield* live(access, output);\n return current === undefined ? undefined : { ...output, ...current };\n }\n const address = addressOf(olds);\n const access = yield* accessFor(address, false);\n if (access.kind === \"deployKey\") {\n // The deployment API does not say whether the deployment has code.\n return Unowned({ ...access.target, hash: undefined, envNames: [] });\n }\n if (olds.type === \"prod\") {\n const row = yield* productionRow(access.api, address.projectId);\n if (row === undefined) return undefined;\n const attributes = {\n ...targetOf(row, \"prod\", undefined),\n hash: undefined,\n envNames: [],\n };\n // A production deployment that never received a push, such as\n // the one of a project that this stack created, loses nothing to\n // a push. One with code is someone else's until --adopt.\n return isDeployed(row) ? Unowned(attributes) : attributes;\n }\n const found = yield* lookup(access.api, address);\n if (found === undefined) return undefined;\n // A dev or preview deployment that is not in state is someone\n // else's until the user passes --adopt.\n return Unowned({ ...found, hash: undefined, envNames: [] });\n }),\n\n reconcile: Effect.fn(function* ({ fqn, news, output }) {\n // Also here: with an unresolved prop in plan, diff could not check.\n if (output !== undefined) yield* checkIdentity(output, news);\n // The functions directory and the program, before any change.\n if (news.source !== undefined) yield* checkSource(news.source);\n const address = addressOf(news);\n const access = yield* accessFor(address, changesEnv(news, output));\n const env = news.env ?? {};\n // Before any create: a preview deploy key cannot change variables,\n // and accessFor chose it because there is no access token.\n if (access.kind === \"previewKey\" && changesEnv(news, output)) {\n return yield* new EnvironmentNeedsDeployKey({\n deployment: output?.name ?? address.name ?? \"(new)\",\n });\n }\n const adopt = yield* shouldAdopt(fqn);\n const refuse = (name: string) =>\n new OwnedBySomeoneElse({\n message: `Project ${address.projectId} already has ${news.type} deployment ${name}${news.type === \"prod\" ? \" with code\" : ` named \"${news.name}\"`}. Re-run with --adopt to take it over${news.type === \"prod\" ? \"\" : \", or use another name\"}.`,\n resourceType: Deployment.Type,\n physicalName: name,\n });\n\n // 1. The deployment. `created` is true when this reconcile created it.\n const { target, created } = yield* Effect.gen(function* () {\n if (access.kind === \"deployKey\") {\n // read() refused it without --adopt; this covers an apply without a plan.\n if (output === undefined && !adopt) return yield* refuse(access.target.name);\n return { target: access.target, created: false };\n }\n if (news.type === \"prod\") {\n // Always the current default, also when another production\n // deployment became the default after the last deploy.\n const row = yield* productionRow(access.api, address.projectId);\n if (row === undefined) {\n return yield* new ProductionDeploymentNotFound({ projectId: address.projectId });\n }\n // Code that appeared after the plan is someone else's.\n if (output === undefined && isDeployed(row) && !adopt) return yield* refuse(row.name);\n return { target: targetOf(row, \"prod\", undefined), created: false };\n }\n if (output !== undefined) {\n const row = yield* getByName(access.api, output.name);\n if (row !== undefined) {\n if (row.deploymentType !== output.type) {\n return yield* new DeploymentIdentityChange({\n deployment: row.name,\n field: \"type\",\n current: row.deploymentType,\n requested: news.type,\n });\n }\n const current = targetOf(row, output.type, output.previewName);\n // The live deployment can have moved to another project.\n yield* checkIdentity(current, news);\n return { target: current, created: false };\n }\n // The deployment in state is gone, such as an expired preview.\n // Find or create it below like a resource without state.\n }\n // Never create over an existing deployment: a preview create\n // replaces the preview deployment with the same name. Another\n // writer can still create one between this lookup and the create.\n const existing = yield* lookup(access.api, address);\n if (existing !== undefined) {\n if (!adopt) return yield* refuse(existing.name);\n return { target: existing, created: false };\n }\n const row = yield* access.api.request(\"create deployment\", (client) =>\n client.POST(\"/projects/{project_id}/create_deployment\", {\n params: { path: { project_id: address.projectId } },\n body: { type: news.type, reference: news.name },\n }),\n );\n return {\n target: targetOf(Schema.decodeUnknownSync(DeploymentRow)(row), news.type, news.name),\n created: true,\n };\n });\n\n // 2. The variables and the push, only when their content changed.\n // Variables set on another deployment stay there: they are not ours\n // on this one.\n const previousEnvNames = output?.name === target.name ? envNamesOf(output) : [];\n const before = yield* wantedHash(news, target.name);\n if (before === undefined && previousEnvNames.length === 0) {\n return { ...target, hash: undefined, envNames: [] };\n }\n if (output?.name === target.name && before === output.hash) {\n return { ...target, hash: output.hash, envNames: previousEnvNames };\n }\n const options = {\n deployment: target.name,\n url: target.url,\n source: news.source,\n env,\n previousEnvNames,\n adopt,\n };\n const pushed =\n access.kind === \"deployKey\"\n ? push(spawner, access.key, { ...options, previewName: undefined })\n : access.kind === \"previewKey\"\n ? push(spawner, access.key, { ...options, previewName: target.previewName })\n : withPushKey(access.api, target.name, news.source, (key) =>\n push(spawner, key, { ...options, previewName: undefined }),\n );\n yield* pushed.pipe(\n // A deployment that this reconcile created and could not push to\n // would be someone else's on the next run, and a dev deployment\n // never expires. It is new and empty, so it goes.\n Effect.onError(() =>\n created && access.kind !== \"deployKey\"\n ? absentAsUndefined(\n retryIdempotentWrite(\n access.api.requestVoid(\"delete deployment\", (client) =>\n client.POST(\"/deployments/{deployment_name}/delete\", {\n params: { path: { deployment_name: target.name } },\n }),\n ),\n ),\n ).pipe(\n Effect.catch((error) =>\n Effect.logWarning(\n `Convex.Deployment could not delete ${target.name} after the failed push (${error.message}). The next run takes it over only with --adopt.`,\n ),\n ),\n )\n : Effect.void,\n ),\n );\n // Taken again after the push, so that files the push generates,\n // such as convex/_generated, are part of the identity.\n return {\n ...target,\n hash: yield* wantedHash(news, target.name),\n envNames: Object.keys(env).sort(),\n };\n }),\n\n // Runs only with RemovalPolicy.destroy(): the default policy is\n // `retain`. The variables go with the deployment.\n delete: Effect.fn(function* ({ output }) {\n const keep = Effect.logWarning(\n `Convex.Deployment does not delete production deployment ${output.name}: it belongs to project ${output.projectId}. To delete it, delete the project with RemovalPolicy.destroy() on Convex.Project.`,\n );\n if (output.type === \"prod\") return yield* keep;\n const access = yield* accessFor(addressInState(output), false);\n // A deploy key cannot delete its deployment.\n const management = access.kind === \"deployKey\" ? api : access.api;\n // The type in state can be old: a dev or preview deployment can\n // become a production deployment in Convex. The live type decides.\n const row = yield* getByName(management, output.name);\n // 404: an earlier attempt, the expiry, or someone else deleted it.\n if (row === undefined) return;\n if (row.deploymentType === \"prod\") return yield* keep;\n yield* absentAsUndefined(\n retryIdempotentWrite(\n management.requestVoid(\"delete deployment\", (client) =>\n client.POST(\"/deployments/{deployment_name}/delete\", {\n params: { path: { deployment_name: output.name } },\n }),\n ),\n ),\n );\n }),\n };\n }),\n );\n","// Convex.Project: a project in a Convex team, with its default production deployment.\n//\n// Deleting a project deletes all of its deployments and data, so this\n// resource never replaces a project and keeps it by default:\n//\n// - A name change is an update in place: PATCH /projects/{project_id} with\n// the new name. The slug stays the same.\n// - `team`, `deploymentType`, and `deploymentRegion` cannot change on an\n// existing project. A change fails with a typed error that names the fix.\n// - The removal policy is `retain`. Alchemy deletes the project only when the\n// resource has `RemovalPolicy.destroy()`.\n// - With state, every call addresses the project by `output.projectId`. Only\n// a resource without state looks a project up by name, and it takes over a\n// project that it finds only when adoption is on.\n// - With `slug` instead of `name`, the resource is an existing project,\n// found by GET /teams/{team}/projects/{slug}. It never creates, renames, or\n// (by default) deletes that project. A stack that only pushes to an\n// existing project can pass `{ projectId }` to Convex.Deployment instead\n// and needs no Management API token for the project.\nimport { Resource } from \"alchemy\";\nimport { OwnedBySomeoneElse, Unowned } from \"alchemy/AdoptPolicy\";\nimport { isResolved } from \"alchemy/Diff\";\nimport * as Provider from \"alchemy/Provider\";\nimport * as Effect from \"effect/Effect\";\nimport * as Schema from \"effect/Schema\";\nimport type { components } from \"@convex-dev/platform/managementApi\";\nimport { shouldAdopt } from \"./Adoption.ts\";\nimport { absentAsUndefined, ConvexApiError, ManagementApi } from \"./ManagementApi.ts\";\nimport type { Providers } from \"./Providers.ts\";\n\n/** Region names the Management API accepts, from the generated schema. */\nexport type DeploymentRegion = components[\"schemas\"][\"RegionName\"];\n\nexport type ProjectProps =\n | {\n /** Team slug or numeric team id. A slug costs one extra lookup per run. Cannot change. */\n readonly team: string | number;\n /** Display name. Convex derives the slug from it at creation. A change renames the project. */\n readonly name: string;\n /** Region of the deployment created with the project. Defaults to the team default. Cannot change. */\n readonly deploymentRegion?: DeploymentRegion;\n /** Deployment created with the project. Defaults to `prod`. Cannot change. */\n readonly deploymentType?: \"prod\" | \"dev\";\n }\n | {\n /** Team slug or numeric team id. Cannot change. */\n readonly team: string | number;\n /** Slug of an existing project, such as `score-four`. The resource never creates a project. Cannot change. */\n readonly slug: string;\n };\n\nexport interface ProjectAttributes {\n readonly projectId: number;\n readonly slug: string;\n readonly name: string;\n readonly teamId: number;\n readonly prodDeploymentName: string | undefined;\n readonly prodDeploymentUrl: string | undefined;\n}\n\nexport type Project = Resource<\"Convex.Project\", ProjectProps, ProjectAttributes, never, Providers>;\nexport const Project = Resource<Project>(\"Convex.Project\", { defaultRemovalPolicy: \"retain\" });\n\n/** The props change the team of an existing project. Convex cannot move a project. */\nexport class ProjectTeamChange extends Schema.TaggedError<ProjectTeamChange>()(\n \"ProjectTeamChange\",\n { projectId: Schema.Number, teamId: Schema.Number, requestedTeamId: Schema.Number },\n) {\n override get message() {\n return `Convex.Project cannot move project ${this.projectId} from team ${this.teamId} to team ${this.requestedTeamId}. Set team back to ${this.teamId}. To use the other team, create a new resource with a new logical id and move the data yourself.`;\n }\n}\n\n/**\n * The props change `deploymentType` or `deploymentRegion` of an existing\n * project. Convex uses them only when it creates the project.\n */\nexport class ProjectDeploymentChange extends Schema.TaggedError<ProjectDeploymentChange>()(\n \"ProjectDeploymentChange\",\n {\n projectId: Schema.Number,\n field: Schema.Literals([\"deploymentType\", \"deploymentRegion\"]),\n current: Schema.UndefinedOr(Schema.String),\n requested: Schema.UndefinedOr(Schema.String),\n },\n) {\n override get message() {\n const show = (value: string | undefined) => (value === undefined ? \"(not set)\" : value);\n return `Convex.Project cannot change ${this.field} of project ${this.projectId} from ${show(this.current)} to ${show(this.requested)}: Convex uses it only when it creates a project. Set ${this.field} back to ${show(this.current)}. For a new deployment, create a new resource with a new logical id and move the data yourself.`;\n }\n}\n\n/** More than one project in the team has the name, so the lookup cannot choose one. */\nexport class AmbiguousProject extends Schema.TaggedError<AmbiguousProject>()(\"AmbiguousProject\", {\n teamId: Schema.Number,\n name: Schema.String,\n projectIds: Schema.Array(Schema.Number),\n}) {\n override get message() {\n return `Team ${this.teamId} has ${this.projectIds.length} projects named \"${this.name}\" (ids ${this.projectIds.join(\", \")}). Convex.Project does not choose one. Rename the projects in the Convex dashboard so that only one has this name, or use a different name.`;\n }\n}\n\n/** Convex answered a create call but then did not return the project. */\nexport class CreatedProjectNotFound extends Schema.TaggedError<CreatedProjectNotFound>()(\n \"CreatedProjectNotFound\",\n { projectId: Schema.Number },\n) {\n override get message() {\n return `Convex created project ${this.projectId} but GET /projects/${this.projectId} did not return it. Run the deploy again with --adopt to take over project ${this.projectId}.`;\n }\n}\n\n/** No project in the team has the slug. A `slug` resource never creates one. */\nexport class ProjectNotFound extends Schema.TaggedError<ProjectNotFound>()(\"ProjectNotFound\", {\n team: Schema.String,\n slug: Schema.String,\n}) {\n override get message() {\n return `Team ${this.team} has no project with the slug \"${this.slug}\", and a Convex.Project with a slug never creates one. Check the slug in the project URL of the Convex dashboard, or use name to create a project.`;\n }\n}\n\n/** The props change the slug of a `slug` resource: that is another project. */\nexport class ProjectSlugChange extends Schema.TaggedError<ProjectSlugChange>()(\n \"ProjectSlugChange\",\n { projectId: Schema.Number, slug: Schema.String, requestedSlug: Schema.String },\n) {\n override get message() {\n return `Convex.Project ${this.projectId} has the slug \"${this.slug}\", and the props ask for \"${this.requestedSlug}\", which is another project. Set slug back to \"${this.slug}\". For the other project, create a new resource with a new logical id.`;\n }\n}\n\n/** Fields of GET /projects/{id}, PATCH /projects/{id}, and GET /teams/{team}/projects rows that the provider uses. */\nconst ProjectDetails = Schema.Struct({\n id: Schema.Number,\n name: Schema.String,\n slug: Schema.String,\n teamId: Schema.Number,\n teamSlug: Schema.String,\n prodDeploymentName: Schema.NullOr(Schema.String),\n});\ntype ProjectDetails = typeof ProjectDetails.Type;\n\n/** GET /teams/{team_id}/projects: one page of projects. */\nexport const ProjectPage = Schema.Struct({\n items: Schema.Array(ProjectDetails),\n pagination: Schema.Struct({\n hasMore: Schema.Boolean,\n nextCursor: Schema.optionalKey(Schema.NullOr(Schema.String)),\n }),\n});\n\n/** POST /teams/{team_id}/create_project. Only the id: everything else comes from GET /projects/{id}. */\nconst CreatedProject = Schema.Struct({ projectId: Schema.Number });\n\nconst DeploymentRow = Schema.Struct({\n name: Schema.String,\n deploymentType: Schema.String,\n isDefault: Schema.Boolean,\n deploymentUrl: Schema.String,\n});\nconst DeploymentRows = Schema.Array(DeploymentRow);\n\n/**\n * Fails with {@link ProjectDeploymentChange} when a create-time prop\n * changed. An omitted `deploymentType` means `prod`.\n */\nconst checkCreateTimeProps = (\n projectId: number,\n olds: Extract<ProjectProps, { name: string }>,\n news: Extract<ProjectProps, { name: string }>,\n) => {\n const oldType = olds.deploymentType ?? \"prod\";\n const newType = news.deploymentType ?? \"prod\";\n if (oldType !== newType) {\n return Effect.fail(\n new ProjectDeploymentChange({\n projectId,\n field: \"deploymentType\",\n current: oldType,\n requested: newType,\n }),\n );\n }\n if (olds.deploymentRegion !== news.deploymentRegion) {\n return Effect.fail(\n new ProjectDeploymentChange({\n projectId,\n field: \"deploymentRegion\",\n current: olds.deploymentRegion,\n requested: news.deploymentRegion,\n }),\n );\n }\n return Effect.void;\n};\n\n/** True when `team`, a slug or a numeric id, names the team of the project. */\nconst isTeamOf = (details: ProjectDetails, team: string | number) =>\n typeof team === \"number\" || /^\\d+$/.test(team)\n ? details.teamId === Number(team)\n : details.teamSlug === team;\n\nexport const ProjectProvider = () =>\n Provider.effect(\n Project,\n Effect.gen(function* () {\n const api = yield* ManagementApi;\n\n const prodDeployment = (projectId: number) =>\n api\n .request(\"list deployments\", (client) =>\n client.GET(\"/projects/{project_id}/list_deployments\", {\n params: { path: { project_id: projectId } },\n }),\n )\n .pipe(\n Effect.map((rows) =>\n Schema.decodeUnknownSync(DeploymentRows)(rows).find(\n (row) => row.deploymentType === \"prod\" && row.isDefault,\n ),\n ),\n );\n\n const attributesOf = (details: ProjectDetails) =>\n prodDeployment(details.id).pipe(\n Effect.map((prod): ProjectAttributes => ({\n projectId: details.id,\n slug: details.slug,\n name: details.name,\n teamId: details.teamId,\n prodDeploymentName: prod?.name ?? details.prodDeploymentName ?? undefined,\n prodDeploymentUrl: prod?.deploymentUrl,\n })),\n );\n\n const getById = (projectId: number) =>\n absentAsUndefined(\n api.request(\"get project\", (client) =>\n client.GET(\"/projects/{project_id}\", { params: { path: { project_id: projectId } } }),\n ),\n ).pipe(\n Effect.map((body) =>\n body === undefined ? undefined : Schema.decodeUnknownSync(ProjectDetails)(body),\n ),\n );\n\n /** The project with this slug in the team, or undefined. Official endpoint; the team can be a slug. */\n const getBySlug = (team: string | number, slug: string) =>\n absentAsUndefined(\n api.request(\"get project by slug\", (client) =>\n client.GET(\"/teams/{team_id_or_slug}/projects/{project_slug}\", {\n params: { path: { team_id_or_slug: String(team), project_slug: slug } },\n }),\n ),\n ).pipe(\n Effect.map((body) =>\n body === undefined ? undefined : Schema.decodeUnknownSync(ProjectDetails)(body),\n ),\n );\n\n /**\n * The one project in the team with exactly this name, or undefined.\n * Reads every page. `q` narrows the listing on the server, and the\n * exact match here decides. Pattern from Confect\n * `packages/alchemy/src/ConvexClient.ts` and `Project.ts`\n * (https://github.com/rjdellecese/confect, ISC license).\n */\n const findByName = (teamId: number, name: string) =>\n Effect.gen(function* () {\n const matches: ProjectDetails[] = [];\n const seenCursors = new Set<string>();\n let cursor: string | undefined;\n while (true) {\n const body = yield* api.request(\"list projects\", (client) =>\n client.GET(\"/teams/{team_id}/projects\", {\n params: {\n path: { team_id: teamId },\n query: { q: name, ...(cursor === undefined ? {} : { cursor }) },\n },\n }),\n );\n const page = Schema.decodeUnknownSync(ProjectPage)(body);\n matches.push(...page.items.filter((row) => row.name === name));\n if (!page.pagination.hasMore) break;\n const next = page.pagination.nextCursor;\n if (next === undefined || next === null || seenCursors.has(next)) {\n return yield* new ConvexApiError({\n operation: \"list projects\",\n status: 0,\n code: \"InvalidPagination\",\n message: `The project listing of team ${teamId} reports more pages but gives no new cursor. Convex.Project stops so that it does not miss a project named \"${name}\".`,\n });\n }\n seenCursors.add(next);\n cursor = next;\n }\n if (matches.length > 1) {\n return yield* new AmbiguousProject({\n teamId,\n name,\n projectIds: matches.map((row) => row.id),\n });\n }\n return matches[0];\n });\n\n /**\n * Brings an existing project to the desired name. The team cannot\n * change, so a project in another team fails.\n */\n const converge = (details: ProjectDetails, teamId: number, name: string) =>\n Effect.gen(function* () {\n if (details.teamId !== teamId) {\n return yield* new ProjectTeamChange({\n projectId: details.id,\n teamId: details.teamId,\n requestedTeamId: teamId,\n });\n }\n if (details.name === name) return yield* attributesOf(details);\n const updated = yield* api.request(\"update project\", (client) =>\n client.PATCH(\"/projects/{project_id}\", {\n params: { path: { project_id: details.id } },\n body: { name },\n }),\n );\n return yield* attributesOf(Schema.decodeUnknownSync(ProjectDetails)(updated));\n });\n\n return {\n stables: [\"projectId\", \"slug\", \"teamId\"],\n\n diff: Effect.fn(function* ({ olds, news, output }) {\n if (!isResolved(news)) return undefined;\n // Nothing exists yet, so nothing can be lost.\n if (output === undefined) return undefined;\n if (\"slug\" in news) {\n if (news.slug !== output.slug) {\n return yield* new ProjectSlugChange({\n projectId: output.projectId,\n slug: output.slug,\n requestedSlug: news.slug,\n });\n }\n if (olds.team !== news.team) {\n const details = yield* getById(output.projectId);\n if (details !== undefined && !isTeamOf(details, news.team)) {\n return yield* new ProjectTeamChange({\n projectId: output.projectId,\n teamId: output.teamId,\n requestedTeamId: yield* api.resolveTeamId(news.team),\n });\n }\n }\n // The resource changes nothing on the project.\n return { action: \"noop\" } as const;\n }\n // A deploymentType or deploymentRegion change fails in reconcile,\n // before any API call. Reconcile compares with the props of the last\n // successful deploy. Here, `olds` can be the props of a refused\n // update, so a check here would also refuse the props that fix it.\n if (olds.team !== news.team) {\n const requestedTeamId = yield* api.resolveTeamId(news.team);\n if (requestedTeamId !== output.teamId) {\n return yield* new ProjectTeamChange({\n projectId: output.projectId,\n teamId: output.teamId,\n requestedTeamId,\n });\n }\n }\n // Never \"replace\". A name change is an update; reconcile renames\n // the project with PATCH. Otherwise the engine compares the props.\n return \"name\" in olds && olds.name === news.name\n ? undefined\n : ({ action: \"update\" } as const);\n }),\n\n read: Effect.fn(function* ({ olds, output }) {\n if (output !== undefined) {\n const details = yield* getById(output.projectId);\n return details === undefined ? undefined : yield* attributesOf(details);\n }\n // No state: an existing project belongs to someone else until the\n // user passes --adopt. Convex has no ownership tags.\n const existing =\n \"slug\" in olds\n ? yield* getBySlug(olds.team, olds.slug)\n : yield* findByName(yield* api.resolveTeamId(olds.team), olds.name);\n return existing === undefined ? undefined : Unowned(yield* attributesOf(existing));\n }),\n\n reconcile: Effect.fn(function* ({ fqn, olds, news, output }) {\n if (\"slug\" in news) {\n // An existing project: found, checked, never created or changed.\n const details =\n output === undefined\n ? yield* getBySlug(news.team, news.slug)\n : yield* getById(output.projectId);\n if (details === undefined) {\n return yield* new ProjectNotFound({ team: String(news.team), slug: news.slug });\n }\n if (details.slug !== news.slug) {\n return yield* new ProjectSlugChange({\n projectId: details.id,\n slug: details.slug,\n requestedSlug: news.slug,\n });\n }\n if (!isTeamOf(details, news.team)) {\n return yield* new ProjectTeamChange({\n projectId: details.id,\n teamId: details.teamId,\n requestedTeamId: yield* api.resolveTeamId(news.team),\n });\n }\n if (output === undefined && !(yield* shouldAdopt(fqn))) {\n return yield* new OwnedBySomeoneElse({\n message: `Convex project ${details.id} (\"${news.slug}\") exists and is not in this stack's state. Re-run with --adopt to take it over.`,\n resourceType: Project.Type,\n physicalName: news.slug,\n });\n }\n return yield* attributesOf(details);\n }\n const teamId = yield* api.resolveTeamId(news.team);\n if (output !== undefined) {\n // State names the project. Never look it up by name here.\n if (olds !== undefined && \"name\" in olds) {\n yield* checkCreateTimeProps(output.projectId, olds, news);\n }\n if (output.teamId !== teamId) {\n return yield* new ProjectTeamChange({\n projectId: output.projectId,\n teamId: output.teamId,\n requestedTeamId: teamId,\n });\n }\n const details = yield* getById(output.projectId);\n if (details !== undefined) return yield* converge(details, teamId, news.name);\n // The project in state was deleted outside Alchemy. Creating a\n // new project below loses nothing.\n } else {\n // No state: a project with this name is someone else's unless\n // adoption is on. The engine checked this in plan; this check\n // covers a project that appeared after the plan.\n const existing = yield* findByName(teamId, news.name);\n if (existing !== undefined) {\n if (!(yield* shouldAdopt(fqn))) {\n return yield* new OwnedBySomeoneElse({\n message: `Convex project ${existing.id} in team ${teamId} already has the name \"${news.name}\". Re-run with --adopt to take it over, or use a different name.`,\n resourceType: Project.Type,\n physicalName: news.name,\n });\n }\n return yield* converge(existing, teamId, news.name);\n }\n }\n const created = yield* api.request(\"create project\", (client) =>\n client.POST(\"/teams/{team_id}/create_project\", {\n params: { path: { team_id: teamId } },\n body: {\n projectName: news.name,\n deploymentType: news.deploymentType ?? \"prod\",\n ...(news.deploymentRegion === undefined\n ? {}\n : { deploymentRegion: news.deploymentRegion }),\n },\n }),\n );\n // Identity comes from the create response, never from a name lookup.\n const { projectId } = Schema.decodeUnknownSync(CreatedProject)(created);\n const details = yield* getById(projectId);\n if (details === undefined) return yield* new CreatedProjectNotFound({ projectId });\n return yield* converge(details, teamId, news.name);\n }),\n\n // Runs only with `RemovalPolicy.destroy()`: the default policy is `retain`.\n delete: Effect.fn(function* ({ output }) {\n yield* absentAsUndefined(\n api.requestVoid(\"delete project\", (client) =>\n client.POST(\"/projects/{project_id}/delete\", {\n params: { path: { project_id: output.projectId } },\n }),\n ),\n );\n }),\n };\n }),\n );\n","// The provider collection users merge into a stack:\n// providers: Layer.mergeAll(Cloudflare.providers(), Convex.providers())\nimport * as Provider from \"alchemy/Provider\";\nimport * as Layer from \"effect/Layer\";\nimport { type Credentials, fromConfig } from \"./Credentials.ts\";\nimport { Deployment, DeploymentProvider } from \"./Deployment.ts\";\nimport { ManagementApiLive } from \"./ManagementApi.ts\";\nimport { Project, ProjectProvider } from \"./Project.ts\";\n\nexport class Providers extends Provider.ProviderCollection<Providers>()(\"Convex\") {}\n\n/**\n * The Convex resource providers. Pass a credentials layer to override the\n * default lookup (`CONVEX_ACCESS_TOKEN`, then the Convex CLI login, and\n * `CONVEX_DEPLOY_KEY`).\n */\nexport const providers = (credentials: Layer.Layer<Credentials> = fromConfig()) =>\n Layer.effect(Providers, Provider.collection([Project, Deployment])).pipe(\n Layer.provide(Layer.mergeAll(ProjectProvider(), DeploymentProvider())),\n Layer.provide(ManagementApiLive()),\n Layer.provide(credentials),\n Layer.orDie,\n );\n","// Alchemy state in Convex: `state: Convex.state()` in `Alchemy.Stack`.\n//\n// The state of every stage lives in the alchemyState component\n// (`@samebase/alchemy-convex/convex.config`), which the app mounts and pushes\n// to the production deployment of its project. The store calls the component\n// functions through POST <deployment>/api/function with a component path, the\n// call that `convex run --component` makes, with the deploy key in\n// CONVEX_STATE_DEPLOY_KEY. Measured: a component query needs the key action\n// `deployment:data:view`, a component mutation `deployment:data:write`, and a\n// call without a key gets HTTP 403. See docs/design/convex-state.md.\n//\n// Bootstrap: Alchemy reads state before the first push, when the deployment\n// has no alchemyState component yet. The store asks the component list of the\n// deployment, and only a deployment without the component means empty state.\n// The store then keeps the state of the run in memory and moves it to the\n// component on the first write after the component is active: the first\n// write after the push. A run that ends with its state still in memory fails\n// at the stack output. An unmounted component keeps its rows, so it fails.\n//\n// The function names of the component are a wire contract. An older\n// component must answer a newer store, so a name is never renamed or removed.\nimport * as Config from \"effect/Config\";\nimport * as Effect from \"effect/Effect\";\nimport * as Layer from \"effect/Layer\";\nimport * as Redacted from \"effect/Redacted\";\nimport * as Schedule from \"effect/Schedule\";\nimport * as Schema from \"effect/Schema\";\nimport {\n encodeState,\n InMemoryService,\n type PersistedState,\n type ReplacedResourceState,\n reviveState,\n State,\n type StateService,\n STATE_STORE_VERSION,\n StateStoreError,\n} from \"alchemy/State\";\nimport { keyTargetOf } from \"./Push.ts\";\n\n/** Environment variable with the deploy key of the deployment that holds the state. */\nexport const STATE_DEPLOY_KEY_ENV = \"CONVEX_STATE_DEPLOY_KEY\";\n\n/** The component path of alchemyState in the app: its default name. */\nconst COMPONENT_PATH = \"alchemyState\";\n\n/** The body of POST /api/function and /api/query, with HTTP 200 or 560 for a function error. */\nconst Reply = Schema.Union([\n Schema.Struct({ status: Schema.Literal(\"success\"), value: Schema.Unknown }),\n Schema.Struct({ status: Schema.Literal(\"error\"), errorMessage: Schema.String }),\n]);\n\n/** The value of `_system/frontend/components:list`: the root has path \"\", a removed mount is \"unmounted\". */\nconst Components = Schema.Array(Schema.Struct({ path: Schema.String, state: Schema.String }));\n\nconst failure = (message: string) => new StateStoreError({ message: `Convex state: ${message}` });\n\n/** No reply, HTTP 429, or HTTP 5xx: a new attempt can succeed. Every call of the store is idempotent. */\nconst isTransient = (error: StateStoreError) =>\n error.http !== undefined &&\n (error.http.status === undefined || error.http.status === 429 || error.http.status >= 500);\n\nconst post = (\n url: string,\n headers: Record<string, string>,\n body: unknown,\n): Effect.Effect<unknown, StateStoreError> =>\n Effect.tryPromise({\n try: () =>\n fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", ...headers },\n body: JSON.stringify(body),\n }),\n catch: () => new StateStoreError({ message: `Convex state: POST ${url} failed`, http: {} }),\n }).pipe(\n Effect.flatMap((response) =>\n response.ok || response.status === 560\n ? Effect.tryPromise({\n try: (): Promise<unknown> => response.json(),\n catch: () => failure(`${url} gave no JSON`),\n })\n : Effect.fail(\n new StateStoreError({\n message: `Convex state: POST ${url} failed with HTTP ${response.status}`,\n http: { status: response.status },\n }),\n ),\n ),\n Effect.retry({\n while: isTransient,\n schedule: Schedule.exponential(\"100 millis\").pipe(Schedule.jittered),\n times: 5,\n }),\n );\n\nconst decode =\n <S extends Schema.Codec<unknown, unknown>>(schema: S, what: string) =>\n (value: unknown) =>\n Schema.decodeUnknownEffect(schema)(value).pipe(Effect.mapError(() => failure(`bad ${what}`)));\n\n/**\n * The deployment URL of a deploy key. The Convex CLI makes the same unofficial\n * call for every deploy key (convex 1.46 `cli/lib/deploymentSelection.js`).\n */\nconst urlForKey = (key: Redacted.Redacted<string>) =>\n post(\n \"https://api.convex.dev/api/deployment/url_for_key\",\n {},\n { deployKey: Redacted.value(key) },\n ).pipe(Effect.flatMap(decode(Schema.String, \"deployment URL\")));\n\n/** The Convex function API of one deployment, with an admin key. */\nexport interface FunctionApi {\n /** Runs a function of the component, or a system function of the root with `componentPath` undefined. */\n readonly call: (\n path: string,\n args: Record<string, string | undefined>,\n componentPath?: string,\n ) => Effect.Effect<unknown, StateStoreError>;\n}\n\nexport const makeFunctionApi = (url: string, key: Redacted.Redacted<string>): FunctionApi => ({\n call: (path, args, componentPath) =>\n post(\n // A component function answers only through /api/function. A system query\n // of the root answers only through /api/query (measured).\n `${url}/api/${componentPath === undefined ? \"query\" : \"function\"}`,\n { Authorization: `Convex ${Redacted.value(key)}` },\n { ...(componentPath === undefined ? {} : { componentPath }), path, args, format: \"json\" },\n ).pipe(\n Effect.flatMap(decode(Reply, `reply of ${path}`)),\n Effect.flatMap((reply) =>\n reply.status === \"success\"\n ? Effect.succeed(reply.value)\n : // The message names the function and the cause, such as a missing key\n // action. The key is a header, and Convex does not echo arguments.\n Effect.fail(failure(reply.errorMessage.trim())),\n ),\n ),\n});\n\n/** The state of the alchemyState mount: \"active\", \"unmounted\" (its rows are kept), or undefined. */\nconst mountOf = (api: FunctionApi) =>\n api.call(\"_system/frontend/components:list\", {}).pipe(\n Effect.flatMap(decode(Components, \"component list\")),\n Effect.map((components) => components.find((c) => c.path === COMPONENT_PATH)?.state),\n );\n\n/** The component functions with Alchemy's encoding: the JSON text of encodeState. */\nconst remoteOf = (api: FunctionApi) => {\n const run = (name: string, args: Record<string, string | undefined>) =>\n api.call(`state:${name}`, args, COMPONENT_PATH);\n const strings = (name: string, args: Record<string, string>) =>\n run(name, args).pipe(Effect.flatMap(decode(Schema.Array(Schema.String), name)));\n const optional = (name: string, args: Record<string, string>) =>\n run(name, args).pipe(Effect.flatMap(decode(Schema.NullOr(Schema.String), name)));\n const encode = (value: unknown) => JSON.stringify(encodeState(value));\n return {\n listStacks: () => strings(\"stacks\", {}),\n listStages: (stack: string) => strings(\"stages\", { stack }),\n list: (r: { stack: string; stage: string }) =>\n strings(\"list\", { stack: r.stack, stage: r.stage }),\n // Like Alchemy's own stores, the store gives back the state that it got.\n get: (r: { stack: string; stage: string; fqn: string }) =>\n optional(\"get\", { stack: r.stack, stage: r.stage, fqn: r.fqn }).pipe(\n Effect.map((text): PersistedState | undefined =>\n text === null ? undefined : JSON.parse(text, reviveState),\n ),\n ),\n getReplacedResources: (r: { stack: string; stage: string }) =>\n strings(\"replaced\", { stack: r.stack, stage: r.stage }).pipe(\n Effect.map((texts) =>\n texts.map((text): ReplacedResourceState => JSON.parse(text, reviveState)),\n ),\n ),\n getOutput: (r: { stack: string; stage: string }) =>\n optional(\"getOutput\", { stack: r.stack, stage: r.stage }).pipe(\n Effect.map((text): unknown => (text === null ? undefined : JSON.parse(text, reviveState))),\n ),\n set: (r: { stack: string; stage: string; fqn: string; value: PersistedState }) =>\n run(\"set\", { stack: r.stack, stage: r.stage, fqn: r.fqn, value: encode(r.value) }),\n delete: (r: { stack: string; stage: string; fqn: string }) =>\n run(\"remove\", { stack: r.stack, stage: r.stage, fqn: r.fqn }),\n deleteStack: (r: { stack: string; stage?: string }) =>\n run(\"removeStack\", { stack: r.stack, stage: r.stage }),\n setOutput: (r: { stack: string; stage: string; value: unknown }) =>\n run(\"setOutput\", { stack: r.stack, stage: r.stage, value: encode(r.value) }),\n };\n};\n\nconst unmounted = failure(\n `the ${COMPONENT_PATH} component of the deployment is unmounted. Its rows are kept: mount @samebase/alchemy-convex/convex.config in convex/convex.config.ts again.`,\n);\n\n/**\n * The StateService over `api`. Without an alchemyState component at\n * the start, the state of the run stays in memory until a write finds the\n * component active.\n */\nexport const makeConvexState = (api: FunctionApi) =>\n Effect.gen(function* () {\n const remote = remoteOf(api);\n const mount = yield* mountOf(api);\n if (mount === \"unmounted\") return yield* unmounted;\n let pending = mount === undefined;\n\n // The records that InMemoryService writes to, read again by the flush.\n const rows: Record<string, Record<string, Record<string, PersistedState>>> = {};\n const outputs: Record<string, Record<string, unknown>> = {};\n const memory = yield* InMemoryService(\n // @ts-expect-error InMemoryService types the records as ResourceState, and its set stores every PersistedState.\n rows,\n outputs,\n );\n\n /** Moves the memory to the component once it is active. Rows that the run did not read stop it. */\n const flush = Effect.gen(function* () {\n const now = yield* mountOf(api);\n if (now === undefined) return;\n if (now !== \"active\") return yield* unmounted;\n const stages = [...new Set([...Object.keys(rows), ...Object.keys(outputs)])].flatMap(\n (stack) =>\n [\n ...new Set([...Object.keys(rows[stack] ?? {}), ...Object.keys(outputs[stack] ?? {})]),\n ].map((stage) => ({ stack, stage })),\n );\n for (const { stack, stage } of stages) {\n const found = yield* remote.list({ stack, stage });\n if (found.length > 0) {\n return yield* failure(\n `${stack}/${stage} has ${found.length} rows in the deployment that this run did not read, so the run wrote none. Run it again.`,\n );\n }\n }\n for (const { stack, stage } of stages) {\n for (const [fqn, value] of Object.entries(rows[stack]?.[stage] ?? {})) {\n yield* remote.set({ stack, stage, fqn, value });\n }\n const byStage = outputs[stack];\n if (byStage !== undefined && stage in byStage) {\n yield* remote.setOutput({ stack, stage, value: byStage[stage] });\n }\n }\n pending = false;\n });\n\n const read = <A>(\n inMemory: Effect.Effect<A, StateStoreError>,\n inConvex: Effect.Effect<A, StateStoreError>,\n ) => Effect.suspend(() => (pending ? inMemory : inConvex));\n const write = <A>(\n inMemory: Effect.Effect<A, StateStoreError>,\n inConvex: Effect.Effect<unknown, StateStoreError>,\n result: A,\n ) =>\n Effect.suspend(() =>\n pending ? Effect.tap(inMemory, () => flush) : Effect.as(inConvex, result),\n );\n\n const service: StateService = {\n id: \"convex\",\n getVersion: () => Effect.succeed(STATE_STORE_VERSION),\n listStacks: () => read(memory.listStacks(), remote.listStacks()),\n listStages: (stack) => read(memory.listStages(stack), remote.listStages(stack)),\n list: (request) => read(memory.list(request), remote.list(request)),\n get: (request) => read(memory.get(request), remote.get(request)),\n getReplacedResources: (request) =>\n read(memory.getReplacedResources(request), remote.getReplacedResources(request)),\n getOutput: (request) => read(memory.getOutput(request), remote.getOutput(request)),\n set: (request) => write(memory.set(request), remote.set(request), request.value),\n delete: (request) => write(memory.delete(request), remote.delete(request), undefined),\n deleteStack: (request) =>\n write(memory.deleteStack(request), remote.deleteStack(request), undefined),\n // Alchemy writes the stack output last, so state still in memory here is lost.\n setOutput: (request) =>\n write(memory.setOutput(request), remote.setOutput(request), request.value).pipe(\n Effect.tap(() =>\n pending\n ? Effect.fail(\n failure(\n `the deployment of ${STATE_DEPLOY_KEY_ENV} has no ${COMPONENT_PATH} component at the end of the run, so this run saved no state. Mount @samebase/alchemy-convex/convex.config in convex/convex.config.ts.`,\n ),\n )\n : Effect.void,\n ),\n ),\n };\n return service;\n });\n\n/**\n * Alchemy state in the alchemyState component of the deployment that the\n * deploy key in CONVEX_STATE_DEPLOY_KEY names: the production deployment of\n * the project. The key needs the actions `deployment:data:view` and\n * `deployment:data:write`.\n */\nexport const state = (): Layer.Layer<State> =>\n Layer.effect(\n State,\n Effect.gen(function* () {\n // The stack's ConfigProvider, for the read of the key on first use.\n const context = yield* Effect.context<never>();\n return yield* Effect.cached(\n Effect.gen(function* () {\n const key = yield* Config.Redacted(STATE_DEPLOY_KEY_ENV);\n if (keyTargetOf(Redacted.value(key)).kind !== \"deployment\") {\n return yield* failure(\n `${STATE_DEPLOY_KEY_ENV} must be the deploy key of one deployment, such as prod:<name>|..., not a preview deploy key.`,\n );\n }\n return yield* makeConvexState(makeFunctionApi(yield* urlForKey(key), key));\n }).pipe(Effect.provideContext(context), Effect.orDie),\n );\n }),\n );\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["valueOf","DeploymentRow","DeploymentRows"],"sources":["../src/Credentials.ts","../src/Adoption.ts","../src/ManagementApi.ts","../src/Push.ts","../src/Deployment.ts","../src/Project.ts","../src/Providers.ts","../src/State.ts"],"sourcesContent":["// Convex credentials for the provider, by scope.\n//\n// - The access token works on the Management API: a team access token, an\n// OAuth token, or the Convex CLI login. Convex.Project needs it. A\n// Convex.Deployment needs it only when the deploy key does not fit.\n// - The deploy key is optional. A deploy key of one deployment\n// (`prod:<name>|...`, `dev:<name>|...`) lets Convex.Deployment set\n// variables and push to that deployment with no access token. A preview\n// deploy key of a project (`preview:<team>:<project>|...`) lets it create,\n// push to, and delete preview deployments of that project with no access\n// token.\n//\n// Credentials are a layer, never props: they do not go into Alchemy state.\n// Both values are Effects, so that building the providers layer never touches\n// the environment or the filesystem. A value is read on the first call that\n// needs it, which keeps `alchemy plan` on an unrelated stack free of Convex\n// credential errors.\nimport { readFile } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport * as Config from \"effect/Config\";\nimport * as Context from \"effect/Context\";\nimport * as Effect from \"effect/Effect\";\nimport * as Layer from \"effect/Layer\";\nimport * as Option from \"effect/Option\";\nimport * as Redacted from \"effect/Redacted\";\nimport * as Result from \"effect/Result\";\nimport * as Schema from \"effect/Schema\";\n\nexport interface ResolvedCredentials {\n /** Bearer token accepted by https://api.convex.dev/v1: a team access token, an OAuth token, or the Convex CLI login. */\n readonly accessToken: Redacted.Redacted<string>;\n /** Where the token came from, for error messages only. */\n readonly source: \"env\" | \"explicit\" | \"convex-cli-login\";\n}\n\nexport interface CredentialsService {\n /** The Management API token. Dies when there is none. */\n readonly accessToken: Effect.Effect<ResolvedCredentials>;\n /** True when there is a Management API token. */\n readonly hasAccessToken: Effect.Effect<boolean>;\n /** A deploy key or a preview deploy key, or undefined. */\n readonly deployKey: Effect.Effect<Redacted.Redacted<string> | undefined>;\n}\n\nexport class Credentials extends Context.Service<Credentials, CredentialsService>()(\n \"@samebase/alchemy-convex/Credentials\",\n) {}\n\n/** Environment variable for the access token, read by {@link fromConfig}. */\nexport const ACCESS_TOKEN_ENV = \"CONVEX_ACCESS_TOKEN\";\n\n/** Environment variable for the deploy key, read by {@link fromConfig}. The Convex CLI reads the same name. */\nexport const DEPLOY_KEY_ENV = \"CONVEX_DEPLOY_KEY\";\n\n/** The Convex CLI stores its device login here after `npx convex login`. */\nexport const convexCliConfigPath = () => join(homedir(), \".convex\", \"config.json\");\n\nconst CliConfig = Schema.Struct({ accessToken: Schema.String });\n\nexport class CredentialsError extends Schema.TaggedError<CredentialsError>()(\"CredentialsError\", {\n reason: Schema.String,\n}) {}\n\n/**\n * Token the Convex CLI saved on this machine. It works on the Management API\n * for the teams the logged-in user belongs to. Fails when nobody is logged in.\n */\nexport const readConvexCliLogin: Effect.Effect<ResolvedCredentials, CredentialsError> = Effect.gen(\n function* () {\n const path = convexCliConfigPath();\n const text = yield* Effect.tryPromise({\n try: () => readFile(path, \"utf8\"),\n catch: () =>\n new CredentialsError({\n reason: `This step needs the Convex Management API. Set ${ACCESS_TOKEN_ENV} to a team access token, or run \\`npx convex login\\`. There is no Convex CLI login at ${path}.`,\n }),\n });\n const parsed = yield* Schema.decodeUnknownEffect(Schema.fromJsonString(CliConfig))(text).pipe(\n Effect.mapError(() => new CredentialsError({ reason: `${path} has no accessToken` })),\n );\n return { accessToken: Redacted.make(parsed.accessToken), source: \"convex-cli-login\" } as const;\n },\n);\n\n/**\n * Default resolution through the stack ConfigProvider (process env, `.env`,\n * stack secrets): `CONVEX_ACCESS_TOKEN`, then the Convex CLI login on this\n * machine, for the access token; `CONVEX_DEPLOY_KEY` for the deploy key. A\n * developer who ran `npx convex login` needs nothing. CI sets only the\n * deploy key when the stack pushes to deployments that exist, and the access\n * token when the stack also creates projects or deployments.\n */\nexport const fromConfig = (): Layer.Layer<Credentials> =>\n Layer.effect(\n Credentials,\n Effect.gen(function* () {\n const resolved = yield* Effect.cached(\n Config.Redacted(ACCESS_TOKEN_ENV).pipe(\n Effect.map((token): ResolvedCredentials => ({ accessToken: token, source: \"env\" })),\n Effect.catch(() => readConvexCliLogin),\n Effect.result,\n ),\n );\n const deployKey = yield* Effect.cached(\n Config.option(Config.Redacted(DEPLOY_KEY_ENV)).pipe(\n Effect.map(Option.getOrUndefined),\n Effect.orDie,\n ),\n );\n return {\n accessToken: resolved.pipe(Effect.flatMap(Effect.fromResult), Effect.orDie),\n hasAccessToken: resolved.pipe(Effect.map(Result.isSuccess)),\n deployKey,\n };\n }),\n );\n\n/** Explicit values, for tests or callers that already hold them. */\nexport const fromValues = (values: {\n readonly accessToken?: Redacted.Redacted<string>;\n readonly deployKey?: Redacted.Redacted<string>;\n}): Layer.Layer<Credentials> =>\n Layer.succeed(Credentials, {\n accessToken:\n values.accessToken === undefined\n ? Effect.die(\n new CredentialsError({\n reason:\n \"This step needs the Convex Management API, and fromValues got no accessToken.\",\n }),\n )\n : Effect.succeed({ accessToken: values.accessToken, source: \"explicit\" } as const),\n hasAccessToken: Effect.succeed(values.accessToken !== undefined),\n deployKey: Effect.succeed(values.deployKey),\n });\n","// Adoption check for reconcile.\n//\n// The engine checks ownership during plan: `read` returns `Unowned(...)` for\n// an object that is not in state, and the engine then needs `--adopt`. A\n// reconcile without state can still find an existing object, for example\n// after a replacement, after an interrupted create, or when another run\n// created it between plan and apply. Reconcile takes that object over only\n// when adoption is on. The order is the same as in the engine: the\n// resource's own `adopt(...)`, then the AdoptPolicy service, then the\n// `--adopt` flag in AlchemyContext.\n//\n// Pattern from Confect, `packages/alchemy/src/internal/Lifecycle.ts`\n// (https://github.com/rjdellecese/confect, ISC license).\nimport { AdoptPolicy } from \"alchemy/AdoptPolicy\";\nimport { AlchemyContext } from \"alchemy/AlchemyContext\";\nimport { Stack } from \"alchemy/Stack\";\nimport * as Effect from \"effect/Effect\";\nimport * as Option from \"effect/Option\";\n\n/** True when the resource `fqn` may take over an object that is not in state. */\nexport const shouldAdopt = (fqn: string): Effect.Effect<boolean> =>\n Effect.gen(function* () {\n const stack = yield* Effect.serviceOption(Stack);\n const own = Option.isSome(stack) ? stack.value.resources[fqn]?.Adopt : undefined;\n if (own !== undefined) return own;\n const policy = yield* Effect.serviceOption(AdoptPolicy);\n if (Option.isSome(policy)) return policy.value;\n const context = yield* Effect.serviceOption(AlchemyContext);\n return Option.isSome(context) && context.value.adopt;\n });\n","// Effect wrapper around the official Convex platform client.\n//\n// `@convex-dev/platform` is an openapi-fetch client: every call resolves to\n// `{ data, error, response }`. This service turns that into an Effect with one\n// typed error, resolves credentials lazily, and validates the fields the\n// provider relies on at runtime.\nimport { createDeploymentClient, createManagementClient } from \"@convex-dev/platform\";\nimport * as Context from \"effect/Context\";\nimport * as Effect from \"effect/Effect\";\nimport * as Layer from \"effect/Layer\";\nimport * as Redacted from \"effect/Redacted\";\nimport * as Schedule from \"effect/Schedule\";\nimport * as Schema from \"effect/Schema\";\nimport { Credentials, type ResolvedCredentials } from \"./Credentials.ts\";\n\nexport type ManagementClient = ReturnType<typeof createManagementClient>;\nexport type DeploymentClient = ReturnType<typeof createDeploymentClient>;\n\n/** Shape of every openapi-fetch result we consume. */\nexport interface FetchResult<T> {\n readonly data?: T;\n readonly error?: unknown;\n readonly response: Response;\n}\n\n/**\n * One error for every control-plane and deployment call. Resources branch on\n * `status` (404 means absent for read and delete), so the class is load\n * bearing, not decorative.\n */\nexport class ConvexApiError extends Schema.TaggedError<ConvexApiError>()(\"ConvexApiError\", {\n operation: Schema.String,\n status: Schema.Number,\n code: Schema.optionalKey(Schema.String),\n message: Schema.String,\n}) {}\n\nconst ErrorBody = Schema.Struct({\n code: Schema.optionalKey(Schema.String),\n message: Schema.optionalKey(Schema.String),\n});\n\nconst toApiError = (operation: string, result: FetchResult<unknown>) => {\n const body = Schema.decodeUnknownSync(Schema.NullishOr(ErrorBody))(result.error ?? null);\n const code = body?.code;\n return new ConvexApiError({\n operation,\n status: result.response.status,\n ...(code === undefined ? {} : { code }),\n message: body?.message ?? `${operation} failed with HTTP ${result.response.status}`,\n });\n};\n\nexport interface ManagementApiService {\n /** Run one management call with the resolved credentials. */\n readonly request: <T>(\n operation: string,\n run: (client: ManagementClient) => Promise<FetchResult<T>>,\n ) => Effect.Effect<T, ConvexApiError>;\n /** Run one management call whose success response has no body. */\n readonly requestVoid: (\n operation: string,\n run: (client: ManagementClient) => Promise<FetchResult<unknown>>,\n ) => Effect.Effect<void, ConvexApiError>;\n /** Run one deployment-scoped call authenticated with a deploy key. */\n readonly deploymentRequest: <T>(\n operation: string,\n deploymentUrlOrName: string,\n deployKey: Redacted.Redacted<string>,\n run: (client: DeploymentClient) => Promise<FetchResult<T>>,\n ) => Effect.Effect<T, ConvexApiError>;\n /**\n * Team id for a numeric id, a slug, or nothing. A team access token names\n * its team (`GET /token_details`); a slug is then checked against the\n * `teamSlug` of the team's projects, so a token of another team fails. The\n * Convex CLI login and a personal token answer 403 there, so a slug goes to\n * the dashboard's team list, and nothing is an error.\n */\n readonly resolveTeamId: (\n team: string | number | undefined,\n ) => Effect.Effect<number, ConvexApiError>;\n /**\n * True when a deploy key that Convex returned carries the token of the\n * Management API credential itself. With an OAuth token, create_deploy_key\n * and create_preview_deploy_key create no new key: they return the OAuth\n * token with a new prefix, and the part after \"|\" is the same. A delete of\n * that key would revoke the credential.\n */\n readonly isCredentialToken: (secret: string) => Effect.Effect<boolean>;\n /**\n * The same calls with another bearer token, such as a preview deploy key,\n * which the Management API takes for the preview deployments of its project.\n */\n readonly withToken: (token: Redacted.Redacted<string>) => ManagementApiService;\n}\n\n/** The part of a Convex token after the first \"|\", or the whole value when it has none. */\nconst tokenPart = (value: string) => value.slice(value.indexOf(\"|\") + 1);\n\nexport class ManagementApi extends Context.Service<ManagementApi, ManagementApiService>()(\n \"@samebase/alchemy-convex/ManagementApi\",\n) {}\n\nconst attempt = <T>(operation: string, run: () => Promise<FetchResult<T>>) =>\n Effect.tryPromise({\n try: run,\n catch: (cause) =>\n new ConvexApiError({\n operation,\n status: 0,\n message: cause instanceof Error ? cause.message : String(cause),\n }),\n });\n\n/** Reads `data` or fails with the HTTP status and the API's own code and message. */\nexport const settle = <T>(\n operation: string,\n run: () => Promise<FetchResult<T>>,\n): Effect.Effect<T, ConvexApiError> =>\n attempt(operation, run).pipe(\n Effect.flatMap((result) =>\n result.response.ok && result.data !== undefined\n ? Effect.succeed(result.data)\n : Effect.fail(toApiError(operation, result)),\n ),\n );\n\n/** For endpoints that answer with an empty body, such as delete calls. */\nexport const settleVoid = (\n operation: string,\n run: () => Promise<FetchResult<unknown>>,\n): Effect.Effect<void, ConvexApiError> =>\n attempt(operation, run).pipe(\n Effect.flatMap((result) =>\n result.response.ok ? Effect.void : Effect.fail(toApiError(operation, result)),\n ),\n );\n\n/**\n * True when an idempotent write can succeed on a new attempt:\n *\n * - A Convex write conflict. Two parallel update_environment_variables calls\n * on one deployment gave HTTP 503 `OptimisticConcurrencyControlFailure`,\n * \"Data read or written in this mutation changed while it was being run\",\n * in a live run. The platform codes `OCC` and `WriteConflict` and the\n * message \"... changed while this mutation was being run ...\" mean the same.\n * - Any other 5xx answer. Two parallel delete_preview_deploy_key calls on one\n * project gave HTTP 500 `InternalServerError`, \"Your request couldn't be\n * completed. Try again later.\", in a live run. The next attempt succeeded.\n */\nexport const isRetryableWriteError = (error: ConvexApiError): boolean =>\n error.code === \"OptimisticConcurrencyControlFailure\" ||\n error.code === \"OCC\" ||\n error.code === \"WriteConflict\" ||\n /changed while (it|this mutation) was being run/.test(error.message) ||\n error.status >= 500;\n\n/**\n * Runs an idempotent write again after a retryable Convex error: at most\n * four more attempts, with exponential backoff from 100 ms and jitter. Other\n * errors fail at once, and so does the last retryable error. Use it only for\n * a write that has the same result when it runs twice, such as setting a\n * value or deleting by id. Never for a create that does not check first.\n */\nexport const retryIdempotentWrite = <A, E, R>(\n effect: Effect.Effect<A, E, R>,\n): Effect.Effect<A, E, R> =>\n effect.pipe(\n Effect.retry({\n while: (error: E) => error instanceof ConvexApiError && isRetryableWriteError(error),\n times: 4,\n schedule: Schedule.exponential(\"100 millis\").pipe(Schedule.jittered),\n }),\n );\n\n/** Turns a 404 into `undefined` so read and delete stay idempotent. */\nexport const absentAsUndefined = <A, R>(\n effect: Effect.Effect<A, ConvexApiError, R>,\n): Effect.Effect<A | undefined, ConvexApiError, R> =>\n effect.pipe(\n Effect.catchIf(\n (error) => error.status === 404,\n () => Effect.succeed(undefined),\n ),\n );\n\nconst TeamRow = Schema.Struct({ id: Schema.Number, slug: Schema.String });\nconst TeamRows = Schema.Array(TeamRow);\n\n/** The first page of GET /teams/{team_id}/projects: every row carries the slug of the team. */\nconst ProjectSlugRows = Schema.Struct({\n items: Schema.Array(Schema.Struct({ teamSlug: Schema.String })),\n});\n\n/** GET /token_details: the team of a team token, or the project of a project token. */\nconst TokenDetails = Schema.Union([\n Schema.Struct({ type: Schema.Literal(\"teamToken\"), teamId: Schema.Number }),\n Schema.Struct({ type: Schema.Literal(\"projectToken\"), projectId: Schema.Number }),\n]);\n\n/** The service for one way to get the bearer token. */\nconst makeService = (credentials: Effect.Effect<ResolvedCredentials>): ManagementApiService => {\n const client = Effect.cached(\n credentials.pipe(\n Effect.map((resolved) => createManagementClient(Redacted.value(resolved.accessToken))),\n ),\n ).pipe(Effect.flatten);\n\n const request: ManagementApiService[\"request\"] = (operation, run) =>\n client.pipe(Effect.flatMap((c) => settle(operation, () => run(c))));\n\n const requestVoid: ManagementApiService[\"requestVoid\"] = (operation, run) =>\n client.pipe(Effect.flatMap((c) => settleVoid(operation, () => run(c))));\n\n const deploymentRequest: ManagementApiService[\"deploymentRequest\"] = (\n operation,\n deploymentUrlOrName,\n deployKey,\n run,\n ) =>\n settle(operation, () =>\n run(createDeploymentClient(deploymentUrlOrName, Redacted.value(deployKey))),\n );\n\n // Measured: a team access token answers `GET /token_details` with its\n // team id and gets HTTP 403 from the dashboard's team list; the Convex CLI\n // login answers the team list and gets HTTP 403 `NotOAuthTeamToken` from\n // token_details. Read once for each service.\n // `Effect.cached` only allocates the cache, so runSync makes one for this service.\n const tokenDetails = Effect.runSync(\n Effect.cached(\n request(\"get token details\", (c) => c.GET(\"/token_details\")).pipe(\n Effect.map((body) => Schema.decodeUnknownSync(TokenDetails)(body)),\n Effect.catchIf(\n (error) => error.status === 403,\n () => Effect.succeed(undefined),\n ),\n ),\n ),\n );\n\n /** The slug of the team, from the first project of its listing, or undefined for a team without one. Read once. */\n const teamSlug = (teamId: number) =>\n request(\"list projects\", (c) =>\n c.GET(\"/teams/{team_id}/projects\", { params: { path: { team_id: teamId } } }),\n ).pipe(\n Effect.map((body) => Schema.decodeUnknownSync(ProjectSlugRows)(body).items[0]?.teamSlug),\n );\n\n // The Management API addresses teams by numeric id. The only slug lookup\n // it offers is per project, so a slug falls back to the dashboard's team\n // list, which is unofficial. Pass the numeric team id to skip this.\n const resolveTeamId: ManagementApiService[\"resolveTeamId\"] = (team) =>\n Effect.gen(function* () {\n if (typeof team === \"number\") return team;\n if (team !== undefined && /^\\d+$/.test(team)) return Number(team);\n const details = yield* tokenDetails;\n if (details?.type === \"teamToken\") {\n if (team === undefined) return details.teamId;\n // The Management API has no team-by-id call, so the slug of the\n // team comes from any of its projects. A team without a project\n // cannot be checked: the numeric id, or no team, is the fix.\n const slug = yield* teamSlug(details.teamId);\n if (slug === undefined) {\n return yield* new ConvexApiError({\n operation: \"resolve team\",\n status: 0,\n message: `team \"${team}\" cannot be checked against the access token: team ${details.teamId} has no project yet. Set team to ${details.teamId}, or leave it out.`,\n });\n }\n if (slug !== team) {\n return yield* new ConvexApiError({\n operation: \"resolve team\",\n status: 403,\n message: `the access token belongs to team ${details.teamId} (\"${slug}\"), and team is \"${team}\". Use a token of \"${team}\", or set team to ${details.teamId}.`,\n });\n }\n return details.teamId;\n }\n if (details?.type === \"projectToken\") {\n return yield* new ConvexApiError({\n operation: \"resolve team\",\n status: 403,\n message: `the access token belongs to project ${details.projectId}, and a project token cannot create projects. Use a team access token.`,\n });\n }\n if (team === undefined) {\n return yield* new ConvexApiError({\n operation: \"resolve team\",\n status: 0,\n message:\n \"set team to the slug or the id of the Convex team: this access token does not name a team.\",\n });\n }\n const resolved = yield* credentials;\n const rows = yield* Effect.tryPromise({\n try: async () => {\n const response = await fetch(\"https://api.convex.dev/api/dashboard/teams\", {\n headers: { Authorization: `Bearer ${Redacted.value(resolved.accessToken)}` },\n });\n if (!response.ok) {\n throw new Error(`team lookup for \"${team}\" failed with HTTP ${response.status}`);\n }\n return Schema.decodeUnknownSync(TeamRows)(await response.json());\n },\n catch: (cause) =>\n new ConvexApiError({\n operation: \"resolve team\",\n status: 0,\n message: cause instanceof Error ? cause.message : String(cause),\n }),\n });\n const match = rows.find((row) => row.slug === team);\n if (match === undefined) {\n return yield* new ConvexApiError({\n operation: \"resolve team\",\n status: 404,\n message: `no team with slug \"${team}\" for this token`,\n });\n }\n return match.id;\n });\n\n const isCredentialToken: ManagementApiService[\"isCredentialToken\"] = (secret) =>\n credentials.pipe(\n Effect.map(\n (resolved) => tokenPart(Redacted.value(resolved.accessToken)) === tokenPart(secret),\n ),\n );\n\n const withToken: ManagementApiService[\"withToken\"] = (token) =>\n makeService(Effect.succeed({ accessToken: token, source: \"explicit\" }));\n\n return {\n request,\n requestVoid,\n deploymentRequest,\n resolveTeamId,\n isCredentialToken,\n withToken,\n };\n};\n\nexport const ManagementApiLive = (): Layer.Layer<ManagementApi, never, Credentials> =>\n Layer.effect(\n ManagementApi,\n Effect.gen(function* () {\n const credentials = yield* Credentials;\n return makeService(credentials.accessToken);\n }),\n );\n","// The push of a Convex.Deployment: a short-lived deploy key, the `env`\n// variables, and `convex deploy` with the Convex CLI that the app installed.\n//\n// - The key is created for one push with the Management API credential and\n// deleted after it, also after a failure. It can only deploy and read and\n// write variables (with a push command: every action), and it expires\n// after PUSH_KEY_LIFETIME_MS, so a run that stops before the delete leaves\n// no key that works for long. No key\n// goes into state, into an output, or to another resource.\n// - With an OAuth token as the credential, Convex creates no new key: it\n// returns the OAuth token with a new prefix. The push uses it, and the\n// delete is skipped, because it would revoke the OAuth token.\n// - The key reaches the CLI only through an env file (`--env-file`) with\n// mode 0600 in a new temporary directory. The directory is removed after\n// the run, on success, on failure, and on interruption. It is also the home\n// directory of the CLI, so the CLI cannot read the Convex login of this\n// machine. Variables named `CONVEX_*` are not passed on to the CLI.\n// - The CLI output stays out of the logs. A failure shows its last lines with\n// the key removed.\n//\n// The CLI runner follows Confect `packages/alchemy/src/internal/CommandRunner.ts`\n// (https://github.com/rjdellecese/confect, ISC license, see NOTICE).\nimport { createHash } from \"node:crypto\";\nimport { access, mkdtemp, readFile, rm, writeFile } from \"node:fs/promises\";\nimport { createRequire } from \"node:module\";\nimport { tmpdir } from \"node:os\";\nimport { dirname, join, relative, resolve } from \"node:path\";\nimport { stripVTControlCharacters } from \"node:util\";\nimport { createDeploymentClient } from \"@convex-dev/platform\";\nimport type { paths } from \"@convex-dev/platform/managementApi\";\nimport { hashDirectory } from \"alchemy/Command/Memo\";\nimport * as Clock from \"effect/Clock\";\nimport * as Effect from \"effect/Effect\";\nimport * as ChildProcess from \"effect/process/ChildProcess\";\nimport * as ChildProcessSpawner from \"effect/process/ChildProcessSpawner\";\nimport * as Redacted from \"effect/Redacted\";\nimport * as Schema from \"effect/Schema\";\nimport * as Stream from \"effect/Stream\";\nimport {\n absentAsUndefined,\n type ManagementApiService,\n retryIdempotentWrite,\n settle,\n settleVoid,\n} from \"./ManagementApi.ts\";\n\n/** A value of the `env` prop: a string, or a secret such as `Config.Redacted(\"AUTH_SECRET\")`. */\nexport type EnvValue = string | Redacted.Redacted<string>;\n\n/**\n * The `source` prop: the Convex functions directory, such as `./convex`, or\n * that directory with a push command and more files for the content identity.\n */\nexport type Source =\n | string\n | {\n /** The Convex functions directory, such as `./convex`. */\n readonly path: string;\n /**\n * Replaces `convex deploy`: a program and its arguments, run in the app\n * directory with CONVEX_DEPLOY_KEY in its environment, such as\n * `[\"pnpm\", \"exec\", \"convex-hosting\", \"deploy\", \"--build\", \"pnpm run build\", \"--dist\", \"dist\"]`.\n * It must push with `convex deploy`, such as through `--cmd`, so that\n * its output has the CLI's \"Deployed Convex functions to\" line.\n */\n readonly command?: readonly [string, ...string[]];\n /**\n * The files of the content identity, as globs relative to the app\n * directory, next to `path`, package.json, convex.json, and the\n * lockfile, such as the build inputs `[\"src/**\", \"vite.config.ts\"]`.\n * By default, every file of the app that git does not ignore.\n */\n readonly include?: readonly string[];\n };\n\nconst sourceOf = (source: Source) =>\n typeof source === \"string\"\n ? { path: source, command: undefined, include: undefined }\n : { path: source.path, command: source.command, include: source.include };\n\n/** Lifetime of a push key. Long enough for a slow push with index backfills. */\nexport const PUSH_KEY_LIFETIME_MS = 2 * 60 * 60 * 1000;\n\n/** An action of a deploy key, such as `deployment:deploy`, from the generated schema. */\nexport type DeployKeyAction = NonNullable<\n NonNullable<\n paths[\"/deployments/{deployment_name}/create_deploy_key\"][\"post\"][\"requestBody\"]\n >[\"content\"][\"application/json\"][\"allowedActions\"]\n>[number];\n\n/** The only actions a key for `convex deploy` gets. */\nexport const PUSH_KEY_ACTIONS = [\n \"deployment:deploy\",\n \"deployment:env:view\",\n \"deployment:env:write\",\n] as const satisfies readonly DeployKeyAction[];\n\n/** POST /deployments/{deployment_name}/create_deploy_key */\nconst CreatedDeployKey = Schema.Struct({ deployKey: Schema.String });\n\n/** GET https://<deployment>.convex.cloud/api/v1/list_environment_variables */\nconst EnvironmentVariableList = Schema.Struct({\n environmentVariables: Schema.Record(Schema.String, Schema.String),\n});\n\n/** No `convex` package resolves from the app directory. */\nexport class ConvexCliNotFound extends Schema.TaggedError<ConvexCliNotFound>()(\n \"ConvexCliNotFound\",\n { cwd: Schema.String },\n) {\n override get message() {\n return `Convex.Deployment found no installed convex package from ${this.cwd}, and it does not download one. Install convex in the app (npm install convex), or set source to the functions directory of the app.`;\n }\n}\n\n/** No directory at or above the parent of `source` has a package.json. */\nexport class ConvexAppNotFound extends Schema.TaggedError<ConvexAppNotFound>()(\n \"ConvexAppNotFound\",\n { source: Schema.String },\n) {\n override get message() {\n return `Convex.Deployment found no package.json at or above the parent of ${this.source}. Set source to the functions directory of a Convex app, such as \"./convex\".`;\n }\n}\n\n/** The Convex CLI failed, or exited 0 without the deployment URL. The output tail never contains the key. */\nexport class CodePushFailed extends Schema.TaggedError<CodePushFailed>()(\"CodePushFailed\", {\n /** Exit code of the CLI. Undefined when it did not start or a signal stopped it. */\n exitCode: Schema.UndefinedOr(Schema.Number),\n /** The last lines of the CLI output, with the deploy key removed. */\n outputTail: Schema.String,\n}) {\n override get message() {\n return this.exitCode === 0\n ? `convex deploy exited 0 but printed no \"Deployed Convex functions to <url>\" line. Last output, with the deploy key removed:\\n${this.outputTail}`\n : `convex deploy failed${this.exitCode === undefined ? \"\" : ` with exit code ${this.exitCode}`}. Last output, with the deploy key removed:\\n${this.outputTail}`;\n }\n}\n\n/** The CLI pushed to another deployment than the one of the resource. Checked after the push. */\nexport class PushTargetMismatch extends Schema.TaggedError<PushTargetMismatch>()(\n \"PushTargetMismatch\",\n { expected: Schema.String, actual: Schema.String },\n) {\n override get message() {\n return `The Convex CLI pushed the functions to deployment ${this.actual}, but Convex.Deployment expected ${this.expected}. Check that convex.json does not select another deployment.`;\n }\n}\n\n/** Variables in `env` exist on the deployment with other values, and adoption is off. */\nexport class VariablesOwnedBySomeoneElse extends Schema.TaggedError<VariablesOwnedBySomeoneElse>()(\n \"VariablesOwnedBySomeoneElse\",\n { deployment: Schema.String, names: Schema.Array(Schema.String) },\n) {\n override get message() {\n return `Environment variables ${this.names.join(\", \")} already exist on deployment ${this.deployment} with other values. Re-run with --adopt to take them over and overwrite them, or remove them from env.`;\n }\n}\n\n/** A preview deploy key cannot set variables: the deployment API takes only a deploy key of the deployment. */\nexport class EnvironmentNeedsDeployKey extends Schema.TaggedError<EnvironmentNeedsDeployKey>()(\n \"EnvironmentNeedsDeployKey\",\n { deployment: Schema.String },\n) {\n override get message() {\n return `Convex.Deployment cannot set or remove env variables on preview deployment ${this.deployment} with a preview deploy key: Convex lets that key create, push to, and delete preview deployments, but not change their variables. Set CONVEX_ACCESS_TOKEN for this stage, or set the values as project default environment variables for preview deployments in the Convex dashboard.`;\n }\n}\n\n/**\n * What a deploy key targets, from its prefix: `<type>:<deployment>|<secret>`\n * (or `<deployment>|<secret>` in old keys) for one deployment, and\n * `preview:<team>:<project>|<secret>` for the preview deployments of a\n * project. Same rules as convex 1.46 `cli/lib/deployment.js`.\n */\nexport const keyTargetOf = (\n key: string,\n):\n | { readonly kind: \"deployment\"; readonly deployment: string }\n | { readonly kind: \"preview\"; readonly team: string; readonly project: string }\n | { readonly kind: \"other\" } => {\n const bar = key.indexOf(\"|\");\n // A key in the env file must be one unquoted dotenv value.\n if (bar <= 0 || /[\\s#'\"`]/.test(key)) return { kind: \"other\" };\n const [first, second, third, ...rest] = key.slice(0, bar).split(\":\");\n if (rest.length > 0) return { kind: \"other\" };\n if (first === \"preview\" && second && third)\n return { kind: \"preview\", team: second, project: third };\n if (third !== undefined) return { kind: \"other\" };\n if (second) return { kind: \"deployment\", deployment: second };\n if (first && second === undefined) return { kind: \"deployment\", deployment: first };\n return { kind: \"other\" };\n};\n\n/**\n * The CLI prints this line with `logFinishedStep` after the push succeeds, to\n * stderr (convex 1.46 `cli/lib/deploy2.js`). The host is\n * `<deployment>.convex.cloud` or `<deployment>.<region>.convex.cloud`.\n */\nconst DEPLOYED_LINE =\n /Deployed Convex functions to (https:\\/\\/([a-z0-9]+(?:-[a-z0-9]+)*)(?:\\.[a-z0-9]+(?:-[a-z0-9]+)*)?\\.convex\\.cloud)\\/?(?=\\s|$)/m;\n\n/** Reads the deployment URL from `convex deploy` output. ANSI escape codes are removed first. */\nexport const parseDeployOutput = (\n text: string,\n): { url: string; deploymentName: string } | undefined => {\n const match = DEPLOYED_LINE.exec(stripVTControlCharacters(text));\n const url = match?.[1];\n const deploymentName = match?.[2];\n return url === undefined || deploymentName === undefined ? undefined : { url, deploymentName };\n};\n\n/** Number of output lines that a failure quotes. */\nconst OUTPUT_TAIL_LINES = 20;\n\n/** The last non-empty lines of `text`, without escape codes and with every secret replaced. */\nconst outputTail = (text: string, secrets: readonly string[]) =>\n secrets\n .reduce(\n (redacted, secret) => redacted.split(secret).join(\"[REDACTED]\"),\n stripVTControlCharacters(text),\n )\n .split(/\\r?\\n|\\r/)\n .filter((line) => line.trim() !== \"\")\n .slice(-OUTPUT_TAIL_LINES)\n .join(\"\\n\");\n\nconst valueOf = (value: EnvValue) => (Redacted.isRedacted(value) ? Redacted.value(value) : value);\n\n/** The app directory: the nearest directory at or above the parent of `source` with a package.json. */\nconst appDirectoryOf = (source: string) =>\n Effect.tryPromise({\n try: async () => {\n let directory = dirname(resolve(source));\n while (true) {\n try {\n await access(join(directory, \"package.json\"));\n return directory;\n } catch {\n const parent = dirname(directory);\n if (parent === directory) throw new Error(\"no package.json\");\n directory = parent;\n }\n }\n },\n catch: () => new ConvexAppNotFound({ source }),\n });\n\n/** `source` is not the functions directory that the Convex CLI pushes from this app. */\nexport class SourceMismatch extends Schema.TaggedError<SourceMismatch>()(\"SourceMismatch\", {\n source: Schema.String,\n functions: Schema.String,\n}) {\n override get message() {\n return `Convex.Deployment source is ${this.source}, but the Convex CLI pushes ${this.functions} in this app (the \"functions\" field of convex.json, or convex/ by default). Set source to ${this.functions}.`;\n }\n}\n\nconst ConvexJson = Schema.Struct({ functions: Schema.optionalKey(Schema.String) });\n\n/** Fails with {@link SourceMismatch} when `path` is not the functions directory of the app in `cwd`. */\nconst checkFunctionsDirectory = (cwd: string, path: string) =>\n Effect.gen(function* () {\n const text = yield* Effect.promise(() =>\n readFile(join(cwd, \"convex.json\"), \"utf8\").catch(() => undefined),\n );\n const configured =\n text === undefined\n ? undefined\n : Schema.decodeUnknownSync(Schema.fromJsonString(ConvexJson))(text).functions;\n const functions = resolve(cwd, configured ?? \"convex\");\n if (functions !== resolve(path)) {\n return yield* new SourceMismatch({ source: resolve(path), functions });\n }\n });\n\nconst CliManifest = Schema.Struct({\n bin: Schema.Union([Schema.String, Schema.Record(Schema.String, Schema.String)]),\n});\n\n/** `[node, <convex bin>]` for the `convex` package that `cwd` resolves. Never downloads. */\nexport const installedCli = (cwd: string) =>\n Effect.tryPromise({\n try: async (): Promise<readonly [string, ...string[]]> => {\n const manifestPath = createRequire(join(cwd, \"package.json\")).resolve(\"convex/package.json\");\n const { bin } = Schema.decodeUnknownSync(Schema.fromJsonString(CliManifest))(\n await readFile(manifestPath, \"utf8\"),\n );\n const entry = typeof bin === \"string\" ? bin : bin[\"convex\"];\n if (entry === undefined) throw new Error(\"the convex package has no convex bin\");\n return [process.execPath, resolve(dirname(manifestPath), entry)];\n },\n catch: () => new ConvexCliNotFound({ cwd }),\n });\n\n/**\n * The content identity of a push: the files of the app directory that git\n * does not ignore (or `path`, the manifests, and the `include` globs), the\n * nearest lockfile, the target deployment, and the `env` names and values.\n * A change in a workspace package outside the app directory is not seen.\n */\nexport const pushHash = (options: {\n readonly source: Source | undefined;\n readonly deployment: string;\n readonly env: Readonly<Record<string, EnvValue>>;\n}) =>\n Effect.gen(function* () {\n const source = options.source === undefined ? undefined : sourceOf(options.source);\n const files =\n source === undefined\n ? undefined\n : yield* appDirectoryOf(source.path).pipe(\n Effect.flatMap((cwd) =>\n hashDirectory({\n cwd,\n // By default every file of the app that git does not ignore,\n // such as a module outside `source` that a function imports.\n // `include` narrows it to the functions, the manifests, and\n // the listed globs.\n memo:\n source.include === undefined\n ? {}\n : {\n include: [\n `${relative(cwd, resolve(source.path)).split(\"\\\\\").join(\"/\")}/**`,\n \"package.json\",\n \"convex.json\",\n ...source.include,\n ],\n lockfile: true,\n },\n }),\n ),\n );\n const env = Object.entries(options.env)\n .map(([name, value]): readonly [string, string] => [name, valueOf(value)])\n .sort(([a], [b]) => (a < b ? -1 : 1));\n return createHash(\"sha256\")\n .update(JSON.stringify({ files, deployment: options.deployment, env }))\n .digest(\"hex\");\n });\n\n/**\n * Runs `use` with an env file that holds the key, in a new temporary\n * directory, and removes the directory afterwards: on success, on failure,\n * and on interruption.\n */\nconst withKeyFile = <A, E, R>(\n key: string,\n use: (paths: { readonly envFile: string; readonly home: string }) => Effect.Effect<A, E, R>,\n) =>\n Effect.acquireUseRelease(\n Effect.promise(() => mkdtemp(join(tmpdir(), \"alchemy-convex-\"))),\n (home) =>\n Effect.promise(() =>\n writeFile(join(home, \"deploy.env\"), `CONVEX_DEPLOY_KEY=${key}\\n`, { mode: 0o600 }),\n ).pipe(Effect.andThen(use({ envFile: join(home, \"deploy.env\"), home }))),\n (home) => Effect.promise(() => rm(home, { recursive: true, force: true })),\n );\n\n/** This process's variables without `CONVEX_*`, with `home` as the home directory. */\nconst cliEnvironment = (home: string): Record<string, string | undefined> => ({\n ...Object.fromEntries(\n Object.entries(process.env).filter(([name]) => !name.toUpperCase().startsWith(\"CONVEX_\")),\n ),\n HOME: home,\n USERPROFILE: home,\n XDG_CONFIG_HOME: home,\n});\n\n/**\n * A deploy key of `deployment` that expires after PUSH_KEY_LIFETIME_MS, with\n * only `allowedActions`, or every action when that is undefined. Delete it\n * with {@link deleteDeployKey} when the work is done.\n */\nexport const createDeployKey = (\n api: ManagementApiService,\n deployment: string,\n name: string,\n allowedActions: readonly DeployKeyAction[] | undefined,\n) =>\n Effect.gen(function* () {\n const now = yield* Clock.currentTimeMillis;\n const created = yield* api.request(\"create deploy key\", (client) =>\n client.POST(\"/deployments/{deployment_name}/create_deploy_key\", {\n params: { path: { deployment_name: deployment } },\n body: {\n name,\n ...(allowedActions === undefined ? {} : { allowedActions: [...allowedActions] }),\n expiresAt: now + PUSH_KEY_LIFETIME_MS,\n },\n }),\n );\n return Redacted.make(Schema.decodeUnknownSync(CreatedDeployKey)(created).deployKey);\n });\n\n/**\n * Deletes a key that {@link createDeployKey} made. The delete is skipped for\n * a key that is the OAuth credential. A failed delete is logged: the key\n * expires anyway.\n */\nexport const deleteDeployKey = (\n api: ManagementApiService,\n deployment: string,\n key: Redacted.Redacted<string>,\n) =>\n Effect.gen(function* () {\n if (yield* api.isCredentialToken(Redacted.value(key))) return;\n yield* absentAsUndefined(\n retryIdempotentWrite(\n api.requestVoid(\"delete deploy key\", (client) =>\n client.POST(\"/deployments/{deployment_name}/delete_deploy_key\", {\n params: { path: { deployment_name: deployment } },\n body: { id: Redacted.value(key) },\n }),\n ),\n ),\n );\n }).pipe(\n Effect.catch((error) =>\n Effect.logWarning(\n `Convex.Deployment could not delete its key on ${deployment} (${error.message}). The key expires on its own within ${PUSH_KEY_LIFETIME_MS / 60_000} minutes.`,\n ),\n ),\n );\n\n/**\n * Creates a deploy key for one push, runs `use` with it, and deletes it\n * afterwards, also after a failure. `allowedActions` is PUSH_KEY_ACTIONS for\n * `convex deploy`, or undefined for a push command, which can do more than a\n * push, such as the uploads of convex-hosting through `convex run`.\n */\nexport const withPushKey = <A, E, R>(\n api: ManagementApiService,\n deployment: string,\n allowedActions: readonly DeployKeyAction[] | undefined,\n use: (key: Redacted.Redacted<string>) => Effect.Effect<A, E, R>,\n) =>\n Effect.acquireUseRelease(\n createDeployKey(api, deployment, \"alchemy-push\", allowedActions),\n use,\n (key) => deleteDeployKey(api, deployment, key),\n );\n\n/** Every variable of the deployment with its value. */\nconst listVariables = (url: string, key: Redacted.Redacted<string>) =>\n settle(\"list environment variables\", () =>\n createDeploymentClient(url, Redacted.value(key)).GET(\"/list_environment_variables\"),\n ).pipe(\n Effect.map(\n (body) => Schema.decodeUnknownSync(EnvironmentVariableList)(body).environmentVariables,\n ),\n );\n\n/** One call that sets variables, or removes those whose value is null. */\nconst writeVariables = (\n url: string,\n key: Redacted.Redacted<string>,\n changes: ReadonlyArray<{ readonly name: string; readonly value: string | null }>,\n) =>\n settleVoid(\"update environment variables\", () =>\n createDeploymentClient(url, Redacted.value(key)).POST(\"/update_environment_variables\", {\n body: { changes: changes.map(({ name, value }) => ({ name, value })) },\n }),\n );\n\nexport interface PushOptions {\n /** Deployment name, such as `happy-animal-123`. */\n readonly deployment: string;\n /** Client URL of the deployment. */\n readonly url: string;\n /** The functions directory, or it with a push command. Without it, only the variables change. */\n readonly source: Source | undefined;\n readonly env: Readonly<Record<string, EnvValue>>;\n /** Names that an earlier push set on this deployment. Names that left `env` are removed. */\n readonly previousEnvNames: readonly string[];\n /** True when the resource may overwrite variables that it did not set. */\n readonly adopt: boolean;\n /**\n * The preview name for `convex deploy --preview-name`, when `key` is a\n * preview deploy key. Such a key cannot set variables.\n */\n readonly previewName: string | undefined;\n}\n\n/**\n * The app directory and the program of a push. Fails before any change when\n * `source` is not the functions directory of the app, or when the app has no\n * installed Convex CLI and no push command.\n */\nexport const checkSource = (input: Source) =>\n Effect.gen(function* () {\n const source = sourceOf(input);\n const cwd = yield* appDirectoryOf(source.path);\n yield* checkFunctionsDirectory(cwd, source.path);\n const program = source.command ?? (yield* installedCli(cwd));\n return { cwd, program };\n });\n\n/**\n * Sets the `env` variables and pushes the functions of `source` to one\n * deployment with `key`: a deploy key of the deployment, or a preview deploy\n * key of its project with `previewName`. Returns the URL that the CLI\n * printed, or undefined without `source`.\n */\nexport const push = (\n spawner: ChildProcessSpawner.ChildProcessSpawner[\"Service\"],\n key: Redacted.Redacted<string>,\n options: PushOptions,\n) =>\n Effect.gen(function* () {\n const source = options.source === undefined ? undefined : sourceOf(options.source);\n const resolved = options.source === undefined ? undefined : yield* checkSource(options.source);\n const cwd = resolved?.cwd;\n const program = resolved?.program;\n const env = Object.entries(options.env).sort(([a], [b]) => (a < b ? -1 : 1));\n const removed = options.previousEnvNames.filter((name) => !Object.hasOwn(options.env, name));\n\n // 1. Variables before the push, so the push sees them. Each attempt\n // reads the current values first, so a retry after a write conflict never\n // overwrites a value that another writer set in the meantime. Only\n // changed values are written, and the earlier ones are kept for a\n // rollback.\n const written =\n env.length === 0 && removed.length === 0\n ? { current: {}, changes: [] }\n : yield* retryIdempotentWrite(\n Effect.gen(function* () {\n const current = yield* listVariables(options.url, key);\n if (!options.adopt) {\n // The same value loses nothing, such as a value that an\n // earlier run set before its push failed.\n const taken = env\n .filter(\n ([name, value]) =>\n !options.previousEnvNames.includes(name) &&\n Object.hasOwn(current, name) &&\n current[name] !== valueOf(value),\n )\n .map(([name]) => name);\n if (taken.length > 0) {\n return yield* new VariablesOwnedBySomeoneElse({\n deployment: options.deployment,\n names: taken,\n });\n }\n }\n const changes = [\n ...env\n .filter(([name, value]) => current[name] !== valueOf(value))\n .map(([name, value]) => ({ name, value: valueOf(value) })),\n ...removed\n .filter((name) => Object.hasOwn(current, name))\n .map((name) => ({ name, value: null })),\n ];\n if (changes.length > 0) yield* writeVariables(options.url, key, changes);\n return { current, changes };\n }),\n );\n\n /**\n * After a failed push, the variables go back to their earlier values, so\n * that the deployment matches the hash in state. A failed rollback is\n * logged: the push error is the one to report.\n */\n const rollback =\n written.changes.length === 0\n ? Effect.void\n : retryIdempotentWrite(\n writeVariables(\n options.url,\n key,\n written.changes.map(({ name }) => ({\n name,\n value: Object.hasOwn(written.current, name)\n ? (written.current[name] ?? null)\n : null,\n })),\n ),\n ).pipe(\n Effect.catch((error) =>\n Effect.logWarning(\n `Convex.Deployment could not set the env variables of ${options.deployment} back after the failed push (${error.message}). Run the deploy again.`,\n ),\n ),\n );\n\n // 2. The push, with the key only in the env file.\n if (source === undefined || cwd === undefined || program === undefined) return undefined;\n return yield* runPush(spawner, key, { ...options, cwd, program, command: source.command }).pipe(\n Effect.onError(() => rollback),\n );\n });\n\n/** Runs the installed CLI or the push command once, and checks the deployment that it names. */\nconst runPush = (\n spawner: ChildProcessSpawner.ChildProcessSpawner[\"Service\"],\n key: Redacted.Redacted<string>,\n options: PushOptions & {\n readonly cwd: string;\n readonly program: readonly [string, ...string[]];\n readonly command: readonly [string, ...string[]] | undefined;\n },\n) =>\n Effect.gen(function* () {\n const { cwd, program } = options;\n const secret = Redacted.value(key);\n const secrets = [secret, secret.slice(secret.indexOf(\"|\") + 1)].filter(\n (value) => value.length >= 8,\n );\n const result = yield* withKeyFile(secret, ({ envFile, home }) =>\n Effect.gen(function* () {\n const [command, ...programArgs] = program;\n // The installed CLI reads the key from the env file. A push command\n // gets it as CONVEX_DEPLOY_KEY, which the CLI that it runs reads.\n const args =\n options.command === undefined\n ? [\n ...programArgs,\n \"deploy\",\n ...(options.previewName === undefined\n ? []\n : [\"--preview-name\", options.previewName]),\n \"--env-file\",\n envFile,\n ]\n : programArgs;\n const child = yield* spawner.spawn(\n ChildProcess.make(command, args, {\n cwd,\n env: {\n ...cliEnvironment(home),\n ...(options.command === undefined ? {} : { CONVEX_DEPLOY_KEY: secret }),\n },\n extendEnv: false,\n stdin: \"ignore\",\n stdout: \"pipe\",\n stderr: \"pipe\",\n }),\n );\n const [exitCode, stdout, stderr] = yield* Effect.all(\n [\n child.exitCode,\n Stream.mkString(Stream.decodeText(child.stdout)),\n Stream.mkString(Stream.decodeText(child.stderr)),\n ],\n { concurrency: \"unbounded\" },\n );\n return { exitCode: Number(exitCode), output: `${stdout}\\n${stderr}` };\n }).pipe(Effect.scoped),\n ).pipe(\n Effect.mapError(\n (error) =>\n new CodePushFailed({\n exitCode: undefined,\n outputTail: outputTail(error.message, secrets),\n }),\n ),\n );\n const deployed = parseDeployOutput(result.output);\n if (result.exitCode !== 0 || deployed === undefined) {\n return yield* new CodePushFailed({\n exitCode: result.exitCode,\n outputTail: outputTail(result.output, secrets),\n });\n }\n if (deployed.deploymentName !== options.deployment) {\n return yield* new PushTargetMismatch({\n expected: options.deployment,\n actual: deployed.deploymentName,\n });\n }\n return deployed.url;\n });\n","// Convex.Deployment: one deployment of a Convex project, its environment\n// variables, and its functions, with the URLs that a frontend or a Worker\n// needs. This is the Convex plane of a stack: no deploy key leaves it.\n//\n// - `source` is the Convex functions directory, such as `./convex`. The\n// update pushes it with the Convex CLI that the app installed (Push.ts).\n// The content identity of the push is a hash of the source files, the\n// app's package.json, convex.json, and lockfile, the deployment name, and\n// `env`. The same hash is a no-op. The hash is taken again after the push,\n// so files that `convex deploy` generates are part of it.\n// `source.command` replaces `convex deploy`, such as `convex-hosting\n// deploy`, and `source.include` adds the files that it reads to the hash.\n// - `env` is set on the deployment before the push. A name that leaves `env`\n// is removed. A variable that exists with another value and that this\n// resource did not set is someone else's: it is overwritten only with\n// --adopt. Delete leaves the variables: they go with the deployment.\n// - Credentials by scope (see Access below): a deploy key of the deployment,\n// a preview deploy key of the project, or the Management API token.\n// - `prod` is the project's default production deployment. Convex creates it\n// with the project, so this resource never creates one. It takes the\n// deployment over without --adopt: it never changes or deletes a production\n// deployment, so the takeover cannot lose data. It follows the default:\n// when another production deployment becomes the default, the next deploy\n// outputs that one. With a deploy key, `prod` is the production deployment\n// of that key. To delete a production deployment, delete its project\n// (Convex.Project with RemovalPolicy.destroy()). Delete reads the live type\n// first, so a dev or preview deployment that became a production\n// deployment is not deleted either.\n// - `dev` and `preview` are created with POST\n// /projects/{project_id}/create_deployment and the `name` prop as the\n// reference. Convex keeps a dev reference as given. For a preview, Convex\n// records `name` as the preview identifier, the name that\n// `npx convex deploy --preview-name <name>` finds, and derives the reference\n// from it (`preview/<slug>`). A create for a preview name that already has\n// a preview deployment deletes that deployment and creates a new one, so\n// reconcile always looks the name up first and never creates over an\n// existing deployment. A dev or preview deployment that exists but is not\n// in state belongs to someone else: the resource takes it over only with\n// --adopt.\n// - `projectId`, `type`, and `name` are the identity. A change fails with\n// DeploymentIdentityChange; the resource is never replaced.\n// - The removal policy is `retain` for every type. A preview deployment\n// expires on Convex's schedule (14 days by default). To delete a dev or\n// preview deployment with the resource, add RemovalPolicy.destroy().\n//\n// Patterns from Confect `packages/alchemy/src/Deployment.ts`\n// (https://github.com/rjdellecese/confect, ISC license, see NOTICE).\nimport { Resource } from \"alchemy\";\nimport { OwnedBySomeoneElse, Unowned } from \"alchemy/AdoptPolicy\";\nimport { isResolved } from \"alchemy/Diff\";\nimport * as Provider from \"alchemy/Provider\";\nimport * as Effect from \"effect/Effect\";\nimport * as ChildProcessSpawner from \"effect/process/ChildProcessSpawner\";\nimport * as Redacted from \"effect/Redacted\";\nimport * as Schema from \"effect/Schema\";\nimport { shouldAdopt } from \"./Adoption.ts\";\nimport { Credentials } from \"./Credentials.ts\";\nimport {\n absentAsUndefined,\n type ConvexApiError,\n ManagementApi,\n type ManagementApiService,\n retryIdempotentWrite,\n} from \"./ManagementApi.ts\";\nimport type { Providers } from \"./Providers.ts\";\nimport {\n checkSource,\n EnvironmentNeedsDeployKey,\n type EnvValue,\n keyTargetOf,\n push,\n PUSH_KEY_ACTIONS,\n pushHash,\n type Source,\n withPushKey,\n} from \"./Push.ts\";\n\ninterface DeploymentInputs {\n /** The project: a Convex.Project resource, or `{ projectId }`. Cannot change. */\n readonly project: { readonly projectId: number };\n /**\n * The Convex functions directory, such as `./convex`, or that directory\n * with a push command and more hashed files. The push runs in the nearest\n * directory above it with a package.json. Without `source`, the resource\n * pushes nothing.\n */\n readonly source?: Source;\n /** Environment variables to set on the deployment before the push. */\n readonly env?: Readonly<Record<string, EnvValue>>;\n}\n\nexport type DeploymentProps =\n | (DeploymentInputs & {\n /** The project's default production deployment. Cannot change. */\n readonly type: \"prod\";\n })\n | (DeploymentInputs & {\n /** A dev deployment or a preview deployment that this resource creates. Cannot change. */\n readonly type: \"dev\" | \"preview\";\n /**\n * The dev reference, such as `staging`, or the preview name, such as\n * the stage name. Unique in the project. Cannot change.\n */\n readonly name: string;\n });\n\n/** The deployment itself, without the state of the push. */\ninterface DeploymentTarget {\n readonly projectId: number;\n readonly type: DeploymentProps[\"type\"];\n /** Deployment name, such as `happy-animal-123`. */\n readonly name: string;\n /** The reference that Convex lists, such as `production`, `staging`, or `preview/pr-42`. */\n readonly reference: string;\n /** The preview name of a preview deployment. Undefined for prod and dev. */\n readonly previewName: string | undefined;\n /** Client URL, such as `https://happy-animal-123.convex.cloud`. */\n readonly url: string;\n /** HTTP actions URL, such as `https://happy-animal-123.convex.site`. */\n readonly siteUrl: string;\n}\n\nexport interface DeploymentAttributes extends DeploymentTarget {\n /** Content identity of the last push and `env`. Undefined when the resource pushed nothing. */\n readonly hash: string | undefined;\n /** The names of the `env` variables that this resource set on the deployment, sorted. */\n readonly envNames: readonly string[];\n}\n\nexport type Deployment = Resource<\n \"Convex.Deployment\",\n DeploymentProps,\n DeploymentAttributes,\n never,\n Providers\n>;\nexport const Deployment = Resource<Deployment>(\"Convex.Deployment\", {\n defaultRemovalPolicy: \"retain\",\n});\n\n/** The props name another deployment than the one in state. */\nexport class DeploymentIdentityChange extends Schema.TaggedError<DeploymentIdentityChange>()(\n \"DeploymentIdentityChange\",\n {\n /** Name of the deployment in state, such as `happy-animal-123`. */\n deployment: Schema.String,\n field: Schema.Literals([\"projectId\", \"type\", \"name\"]),\n current: Schema.String,\n requested: Schema.String,\n },\n) {\n override get message() {\n return `Convex.Deployment cannot change the ${this.field} of deployment ${this.deployment} from ${this.current} to ${this.requested}. Set ${this.field} back to ${this.current}. For another deployment, create a new resource with a new logical id.`;\n }\n}\n\n/** The project has no default production deployment for a `prod` resource to take over. */\nexport class ProductionDeploymentNotFound extends Schema.TaggedError<ProductionDeploymentNotFound>()(\n \"ProductionDeploymentNotFound\",\n { projectId: Schema.Number },\n) {\n override get message() {\n return `Project ${this.projectId} has no default production deployment, and Convex.Deployment does not create one. Create it in the Convex dashboard, or with \\`npx convex deployment create --type prod --default\\` in the project, then run the deploy again.`;\n }\n}\n\n/** More than one deployment of the project has the name, so the lookup cannot choose one. */\nexport class AmbiguousDeployment extends Schema.TaggedError<AmbiguousDeployment>()(\n \"AmbiguousDeployment\",\n {\n projectId: Schema.Number,\n type: Schema.Literals([\"dev\", \"preview\"]),\n name: Schema.String,\n deployments: Schema.Array(Schema.String),\n },\n) {\n override get message() {\n return `Project ${this.projectId} has ${this.deployments.length} ${this.type} deployments named \"${this.name}\" (${this.deployments.join(\", \")}). Convex.Deployment does not choose one. Delete the extra deployments in the Convex dashboard, or use another name.`;\n }\n}\n\n/**\n * The URL of a Convex cloud deployment: `https://<name>.convex.cloud`, or\n * `https://<name>.<region>.convex.cloud` outside US East.\n */\nconst CLOUD_URL =\n /^https:\\/\\/[a-z0-9]+(?:-[a-z0-9]+)*(?:\\.[a-z0-9]+(?:-[a-z0-9]+)*)?\\.convex\\.cloud$/;\n\n/**\n * The HTTP actions URL of a deployment: the client URL with `.convex.site`\n * for `.convex.cloud`, as Convex sets CONVEX_SITE_URL. Custom domains are\n * not covered.\n */\nexport const siteUrlOf = (url: string): string => url.replace(/\\.convex\\.cloud$/, \".convex.site\");\n\n/** One row of list_deployments, GET /deployments/{name}, and create_deployment. Only the fields the provider uses. */\nexport const DeploymentRow = Schema.Struct({\n name: Schema.String,\n projectId: Schema.Number,\n deploymentType: Schema.String,\n isDefault: Schema.Boolean,\n reference: Schema.String,\n /** Set in list_deployments and create_deployment rows only: GET /deployments/{name} answers null. */\n previewIdentifier: Schema.optionalKey(Schema.NullOr(Schema.String)),\n deploymentUrl: Schema.String.check(Schema.isPattern(CLOUD_URL)),\n /** Absent or null until the first push: list_deployments leaves it out for a new deployment. */\n lastDeployTime: Schema.optionalKey(Schema.NullOr(Schema.Number)),\n});\ntype DeploymentRow = typeof DeploymentRow.Type;\nconst DeploymentRows = Schema.Array(DeploymentRow);\n\n/** GET https://<deployment>/api/v1/deployment_info, for a cloud deployment. Only the fields the provider uses. */\nconst DeploymentInfo = Schema.Struct({\n kind: Schema.Literal(\"cloud\"),\n projectId: Schema.Number,\n deploymentType: Schema.String,\n reference: Schema.optionalKey(Schema.NullOr(Schema.String)),\n});\n\n/** GET https://<deployment>/api/v1/get_canonical_urls */\nconst CanonicalUrls = Schema.Struct({\n convexCloudUrl: Schema.String,\n convexSiteUrl: Schema.String,\n});\n\nconst targetOf = (\n row: DeploymentRow,\n type: DeploymentProps[\"type\"],\n previewName: string | undefined,\n): DeploymentTarget => ({\n projectId: row.projectId,\n type,\n name: row.name,\n reference: row.reference,\n previewName: type === \"preview\" ? previewName : undefined,\n url: row.deploymentUrl,\n siteUrl: siteUrlOf(row.deploymentUrl),\n});\n\n/** True when the deployment has received a push. */\nconst isDeployed = (row: DeploymentRow) =>\n row.lastDeployTime !== undefined && row.lastDeployTime !== null;\n\n/** The `name` prop of a deployment: the dev reference or the preview name. */\nconst nameOf = (target: DeploymentTarget) =>\n target.type === \"dev\"\n ? target.reference\n : target.type === \"preview\"\n ? target.previewName\n : undefined;\n\n/**\n * Fails with {@link DeploymentIdentityChange} when the props name another\n * deployment than `current`: the attributes in state, or a live deployment.\n */\nconst checkIdentity = (current: DeploymentTarget, news: DeploymentProps) => {\n const change = (field: \"projectId\" | \"type\" | \"name\", from: string, to: string) =>\n Effect.fail(\n new DeploymentIdentityChange({\n deployment: current.name,\n field,\n current: from,\n requested: to,\n }),\n );\n if (current.projectId !== news.project.projectId) {\n return change(\"projectId\", String(current.projectId), String(news.project.projectId));\n }\n if (current.type !== news.type) return change(\"type\", current.type, news.type);\n const currentName = nameOf(current);\n if (news.type !== \"prod\" && currentName !== news.name) {\n return change(\"name\", currentName ?? \"(none)\", news.name);\n }\n return Effect.void;\n};\n\n/** The deployment that a resource addresses: its project, type, and dev or preview name. */\ninterface Address {\n readonly projectId: number;\n readonly type: DeploymentProps[\"type\"];\n readonly name: string | undefined;\n}\n\nconst addressOf = (props: DeploymentProps): Address => ({\n projectId: props.project.projectId,\n type: props.type,\n name: props.type === \"prod\" ? undefined : props.name,\n});\n\n/** True when an update writes or removes variables: `env` has names, or state has names to remove. */\nconst changesEnv = (news: DeploymentProps, output: DeploymentAttributes | undefined) =>\n Object.keys(news.env ?? {}).length > 0 || envNamesOf(output).length > 0;\n\n/** The `env` names in state. State from 0.3 has none. */\nconst envNamesOf = (output: DeploymentAttributes | undefined): readonly string[] =>\n output?.envNames ?? [];\n\n/** The address of the deployment in state. */\nconst addressInState = (output: DeploymentAttributes): Address => ({\n projectId: output.projectId,\n type: output.type,\n name: nameOf(output),\n});\n\n/**\n * How the provider reaches one deployment, by the narrowest credential that\n * fits:\n *\n * - `deployKey`: the configured deploy key belongs to this deployment. The\n * deployment API answers its identity and URLs, the key sets variables and\n * pushes, and no Management API call is made.\n * - `previewKey`: the configured preview deploy key belongs to this project.\n * The Management API takes it for the preview deployments of the project,\n * and the CLI pushes with it and `--preview-name`.\n * - `token`: the Management API access token. Each push gets a short-lived\n * deploy key (Push.ts).\n */\ntype Access =\n | {\n readonly kind: \"deployKey\";\n readonly key: Redacted.Redacted<string>;\n readonly target: DeploymentTarget;\n }\n | {\n readonly kind: \"previewKey\";\n readonly key: Redacted.Redacted<string>;\n readonly api: ManagementApiService;\n }\n | { readonly kind: \"token\"; readonly api: ManagementApiService };\n\nconst ProjectSlugs = Schema.Struct({ slug: Schema.String, teamSlug: Schema.String });\n\n/** True for an answer that says this credential cannot read the object. */\nconst isRefused = (error: ConvexApiError) =>\n error.status === 400 || error.status === 401 || error.status === 403 || error.status === 404;\n\nexport const DeploymentProvider = () =>\n Provider.effect(\n Deployment,\n Effect.gen(function* () {\n const api = yield* ManagementApi;\n const credentials = yield* Credentials;\n const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;\n\n /** The live deployment, or undefined after a 404. GET /deployments/{name} answers no preview identifier. */\n const getByName = (management: ManagementApiService, name: string) =>\n absentAsUndefined(\n management.request(\"get deployment\", (client) =>\n client.GET(\"/deployments/{deployment_name}\", {\n params: { path: { deployment_name: name } },\n }),\n ),\n ).pipe(\n Effect.map((body) =>\n body === undefined ? undefined : Schema.decodeUnknownSync(DeploymentRow)(body),\n ),\n );\n\n const listDeployments = (\n management: ManagementApiService,\n projectId: number,\n type: DeploymentProps[\"type\"],\n isDefault?: boolean,\n ) =>\n management\n .request(\"list deployments\", (client) =>\n client.GET(\"/projects/{project_id}/list_deployments\", {\n params: {\n path: { project_id: projectId },\n query: { deploymentType: type, ...(isDefault === undefined ? {} : { isDefault }) },\n },\n }),\n )\n .pipe(Effect.map((body) => Schema.decodeUnknownSync(DeploymentRows)(body)));\n\n /** The row of the project's default production deployment, or undefined. */\n const productionRow = (management: ManagementApiService, projectId: number) =>\n listDeployments(management, projectId, \"prod\", true).pipe(\n Effect.map((rows) =>\n rows.find((candidate) => candidate.deploymentType === \"prod\" && candidate.isDefault),\n ),\n );\n\n /** The project's default production deployment, or undefined. */\n const production = (management: ManagementApiService, projectId: number) =>\n productionRow(management, projectId).pipe(\n Effect.map((row) => (row === undefined ? undefined : targetOf(row, \"prod\", undefined))),\n );\n\n /**\n * The one dev deployment with this reference, or the one preview\n * deployment with this preview name, or undefined.\n */\n const findByName = (\n management: ManagementApiService,\n projectId: number,\n type: \"dev\" | \"preview\",\n name: string,\n ) =>\n Effect.gen(function* () {\n const matches = (yield* listDeployments(management, projectId, type)).filter(\n (row) =>\n row.deploymentType === type &&\n (type === \"dev\" ? row.reference === name : row.previewIdentifier === name),\n );\n if (matches.length > 1) {\n return yield* new AmbiguousDeployment({\n projectId,\n type,\n name,\n deployments: matches.map((row) => row.name),\n });\n }\n return matches[0];\n });\n\n /** The deployment that the address names, through the Management API, or undefined. */\n const lookup = (management: ManagementApiService, address: Address) =>\n address.type === \"prod\" || address.name === undefined\n ? production(management, address.projectId)\n : findByName(management, address.projectId, address.type, address.name).pipe(\n Effect.map((row) =>\n row === undefined ? undefined : targetOf(row, address.type, address.name),\n ),\n );\n\n /** The deployment of a deploy key, when it is the deployment that the address names. */\n const deployKeyTarget = (\n key: Redacted.Redacted<string>,\n deployment: string,\n address: Address,\n ) =>\n Effect.gen(function* () {\n const info = Schema.decodeUnknownSync(DeploymentInfo)(\n yield* api.deploymentRequest(\"get deployment info\", deployment, key, (client) =>\n client.GET(\"/deployment_info\"),\n ),\n );\n const reference = info.reference ?? \"\";\n if (\n info.projectId !== address.projectId ||\n info.deploymentType !== address.type ||\n (address.type === \"dev\" && reference !== address.name)\n ) {\n return undefined;\n }\n const urls = Schema.decodeUnknownSync(CanonicalUrls)(\n yield* api.deploymentRequest(\"get canonical urls\", deployment, key, (client) =>\n client.GET(\"/get_canonical_urls\"),\n ),\n );\n return {\n projectId: info.projectId,\n type: address.type,\n name: deployment,\n reference,\n previewName: undefined,\n url: urls.convexCloudUrl,\n siteUrl: urls.convexSiteUrl,\n } satisfies DeploymentTarget;\n }).pipe(Effect.catchIf(isRefused, () => Effect.succeed(undefined)));\n\n /** True when the preview deploy key belongs to the project. */\n const previewKeyFits = (\n management: ManagementApiService,\n slugs: { readonly team: string; readonly project: string },\n projectId: number,\n ) =>\n management\n .request(\"get project\", (client) =>\n client.GET(\"/projects/{project_id}\", { params: { path: { project_id: projectId } } }),\n )\n .pipe(\n Effect.map((body) => {\n const project = Schema.decodeUnknownSync(ProjectSlugs)(body);\n return project.slug === slugs.project && project.teamSlug === slugs.team;\n }),\n Effect.catchIf(isRefused, () => Effect.succeed(false)),\n );\n\n /**\n * The narrowest credential that reaches the deployment. See {@link Access}.\n * When `changesEnv`, a preview deploy key gives way to the access token,\n * because it cannot change variables.\n */\n const accessFor = (address: Address, changesEnv: boolean) =>\n Effect.gen(function* (): Effect.fn.Return<Access, ConvexApiError> {\n const key = yield* credentials.deployKey;\n if (key !== undefined) {\n const target = keyTargetOf(Redacted.value(key));\n if (target.kind === \"deployment\" && address.type !== \"preview\") {\n const found = yield* deployKeyTarget(key, target.deployment, address);\n if (found !== undefined) return { kind: \"deployKey\", key, target: found };\n }\n if (target.kind === \"preview\" && address.type === \"preview\") {\n const scoped = api.withToken(key);\n if (\n !(changesEnv && (yield* credentials.hasAccessToken)) &&\n (yield* previewKeyFits(scoped, target, address.projectId))\n ) {\n return { kind: \"previewKey\", key, api: scoped };\n }\n }\n }\n return { kind: \"token\", api };\n });\n\n /** The live deployment of a resource in state, or undefined when it is gone. */\n const live = (access: Access, output: DeploymentAttributes) =>\n Effect.gen(function* () {\n if (access.kind === \"deployKey\") return access.target;\n // 404 for a deleted project: its production deployment is gone too.\n if (output.type === \"prod\")\n return yield* absentAsUndefined(production(access.api, output.projectId));\n const row = yield* getByName(access.api, output.name);\n return row === undefined ? undefined : targetOf(row, output.type, output.previewName);\n });\n\n /** The content identity of `source` and `env` on a deployment, or undefined when there is nothing to push. */\n const wantedHash = (news: DeploymentProps, deployment: string) =>\n news.source === undefined && Object.keys(news.env ?? {}).length === 0\n ? Effect.succeed(undefined)\n : pushHash({ source: news.source, deployment, env: news.env ?? {} });\n\n return {\n // `name`, `reference`, and the URLs change when an expired preview is\n // created again, or when another production deployment becomes the\n // default.\n stables: [\"projectId\", \"type\", \"previewName\"],\n\n // Compares with the attributes: after a refused change, `olds` are\n // the refused props.\n diff: Effect.fn(function* ({ news, output }) {\n if (!isResolved(news) || output === undefined) return undefined;\n yield* checkIdentity(output, news);\n const access = yield* accessFor(addressOf(news), changesEnv(news, output));\n // A preview expires, anyone can delete a deployment, and another\n // production deployment can become the default. Reconcile then\n // finds or creates the right one, so the stack never hands out the\n // URL of a deployment that is gone.\n const current = yield* live(access, output);\n if (current?.name !== output.name) return { action: \"update\" } as const;\n const hash = yield* wantedHash(news, output.name);\n return hash === output.hash\n ? ({ action: \"noop\" } as const)\n : ({ action: \"update\" } as const);\n }),\n\n read: Effect.fn(function* ({ olds, output }) {\n if (output !== undefined) {\n const access = yield* accessFor(addressInState(output), false);\n const current = yield* live(access, output);\n return current === undefined ? undefined : { ...output, ...current };\n }\n const address = addressOf(olds);\n const access = yield* accessFor(address, false);\n if (access.kind === \"deployKey\") {\n // The deployment API does not say whether the deployment has code.\n return Unowned({ ...access.target, hash: undefined, envNames: [] });\n }\n if (olds.type === \"prod\") {\n const row = yield* productionRow(access.api, address.projectId);\n if (row === undefined) return undefined;\n const attributes = {\n ...targetOf(row, \"prod\", undefined),\n hash: undefined,\n envNames: [],\n };\n // A production deployment that never received a push, such as\n // the one of a project that this stack created, loses nothing to\n // a push. One with code is someone else's until --adopt.\n return isDeployed(row) ? Unowned(attributes) : attributes;\n }\n const found = yield* lookup(access.api, address);\n if (found === undefined) return undefined;\n // A dev or preview deployment that is not in state is someone\n // else's until the user passes --adopt.\n return Unowned({ ...found, hash: undefined, envNames: [] });\n }),\n\n reconcile: Effect.fn(function* ({ fqn, news, output }) {\n // Also here: with an unresolved prop in plan, diff could not check.\n if (output !== undefined) yield* checkIdentity(output, news);\n // The functions directory and the program, before any change.\n if (news.source !== undefined) yield* checkSource(news.source);\n const address = addressOf(news);\n const access = yield* accessFor(address, changesEnv(news, output));\n const env = news.env ?? {};\n // Before any create: a preview deploy key cannot change variables,\n // and accessFor chose it because there is no access token.\n if (access.kind === \"previewKey\" && changesEnv(news, output)) {\n return yield* new EnvironmentNeedsDeployKey({\n deployment: output?.name ?? address.name ?? \"(new)\",\n });\n }\n const adopt = yield* shouldAdopt(fqn);\n const refuse = (name: string) =>\n new OwnedBySomeoneElse({\n message: `Project ${address.projectId} already has ${news.type} deployment ${name}${news.type === \"prod\" ? \" with code\" : ` named \"${news.name}\"`}. Re-run with --adopt to take it over${news.type === \"prod\" ? \"\" : \", or use another name\"}.`,\n resourceType: Deployment.Type,\n physicalName: name,\n });\n\n // 1. The deployment. `created` is true when this reconcile created it.\n const { target, created } = yield* Effect.gen(function* () {\n if (access.kind === \"deployKey\") {\n // read() refused it without --adopt; this covers an apply without a plan.\n if (output === undefined && !adopt) return yield* refuse(access.target.name);\n return { target: access.target, created: false };\n }\n if (news.type === \"prod\") {\n // Always the current default, also when another production\n // deployment became the default after the last deploy.\n const row = yield* productionRow(access.api, address.projectId);\n if (row === undefined) {\n return yield* new ProductionDeploymentNotFound({ projectId: address.projectId });\n }\n // Code that appeared after the plan is someone else's.\n if (output === undefined && isDeployed(row) && !adopt) return yield* refuse(row.name);\n return { target: targetOf(row, \"prod\", undefined), created: false };\n }\n if (output !== undefined) {\n const row = yield* getByName(access.api, output.name);\n if (row !== undefined) {\n if (row.deploymentType !== output.type) {\n return yield* new DeploymentIdentityChange({\n deployment: row.name,\n field: \"type\",\n current: row.deploymentType,\n requested: news.type,\n });\n }\n const current = targetOf(row, output.type, output.previewName);\n // The live deployment can have moved to another project.\n yield* checkIdentity(current, news);\n return { target: current, created: false };\n }\n // The deployment in state is gone, such as an expired preview.\n // Find or create it below like a resource without state.\n }\n // Never create over an existing deployment: a preview create\n // replaces the preview deployment with the same name. Another\n // writer can still create one between this lookup and the create.\n const existing = yield* lookup(access.api, address);\n if (existing !== undefined) {\n if (!adopt) return yield* refuse(existing.name);\n return { target: existing, created: false };\n }\n const row = yield* access.api.request(\"create deployment\", (client) =>\n client.POST(\"/projects/{project_id}/create_deployment\", {\n params: { path: { project_id: address.projectId } },\n body: { type: news.type, reference: news.name },\n }),\n );\n return {\n target: targetOf(Schema.decodeUnknownSync(DeploymentRow)(row), news.type, news.name),\n created: true,\n };\n });\n\n // 2. The variables and the push, only when their content changed.\n // Variables set on another deployment stay there: they are not ours\n // on this one.\n const previousEnvNames = output?.name === target.name ? envNamesOf(output) : [];\n const before = yield* wantedHash(news, target.name);\n if (before === undefined && previousEnvNames.length === 0) {\n return { ...target, hash: undefined, envNames: [] };\n }\n if (output?.name === target.name && before === output.hash) {\n return { ...target, hash: output.hash, envNames: previousEnvNames };\n }\n const options = {\n deployment: target.name,\n url: target.url,\n source: news.source,\n env,\n previousEnvNames,\n adopt,\n };\n const pushed =\n access.kind === \"deployKey\"\n ? push(spawner, access.key, { ...options, previewName: undefined })\n : access.kind === \"previewKey\"\n ? push(spawner, access.key, { ...options, previewName: target.previewName })\n : withPushKey(\n access.api,\n target.name,\n // A push command gets every action; `convex deploy` only its own.\n typeof news.source === \"object\" && news.source.command !== undefined\n ? undefined\n : PUSH_KEY_ACTIONS,\n (key) => push(spawner, key, { ...options, previewName: undefined }),\n );\n yield* pushed.pipe(\n // A deployment that this reconcile created and could not push to\n // would be someone else's on the next run, and a dev deployment\n // never expires. It is new and empty, so it goes.\n Effect.onError(() =>\n created && access.kind !== \"deployKey\"\n ? absentAsUndefined(\n retryIdempotentWrite(\n access.api.requestVoid(\"delete deployment\", (client) =>\n client.POST(\"/deployments/{deployment_name}/delete\", {\n params: { path: { deployment_name: target.name } },\n }),\n ),\n ),\n ).pipe(\n Effect.catch((error) =>\n Effect.logWarning(\n `Convex.Deployment could not delete ${target.name} after the failed push (${error.message}). The next run takes it over only with --adopt.`,\n ),\n ),\n )\n : Effect.void,\n ),\n );\n // Taken again after the push, so that files the push generates,\n // such as convex/_generated, are part of the identity.\n return {\n ...target,\n hash: yield* wantedHash(news, target.name),\n envNames: Object.keys(env).sort(),\n };\n }),\n\n // Runs only with RemovalPolicy.destroy(): the default policy is\n // `retain`. The variables go with the deployment.\n delete: Effect.fn(function* ({ output }) {\n const keep = Effect.logWarning(\n `Convex.Deployment does not delete production deployment ${output.name}: it belongs to project ${output.projectId}. To delete it, delete the project with RemovalPolicy.destroy() on Convex.Project.`,\n );\n if (output.type === \"prod\") return yield* keep;\n const access = yield* accessFor(addressInState(output), false);\n // A deploy key cannot delete its deployment.\n const management = access.kind === \"deployKey\" ? api : access.api;\n // The type in state can be old: a dev or preview deployment can\n // become a production deployment in Convex. The live type decides.\n const row = yield* getByName(management, output.name);\n // 404: an earlier attempt, the expiry, or someone else deleted it.\n if (row === undefined) return;\n if (row.deploymentType === \"prod\") return yield* keep;\n yield* absentAsUndefined(\n retryIdempotentWrite(\n management.requestVoid(\"delete deployment\", (client) =>\n client.POST(\"/deployments/{deployment_name}/delete\", {\n params: { path: { deployment_name: output.name } },\n }),\n ),\n ),\n );\n }),\n };\n }),\n );\n","// Convex.Project: a project in a Convex team, with its default production deployment.\n//\n// Deleting a project deletes all of its deployments and data, so this\n// resource never replaces a project and keeps it by default:\n//\n// - A name change is an update in place: PATCH /projects/{project_id} with\n// the new name. The slug stays the same.\n// - `team`, `deploymentType`, and `deploymentRegion` cannot change on an\n// existing project. A change fails with a typed error that names the fix.\n// - The removal policy is `retain`. Alchemy deletes the project only when the\n// resource has `RemovalPolicy.destroy()`.\n// - With state, every call addresses the project by `output.projectId`. Only\n// a resource without state looks a project up by name, and it takes over a\n// project that it finds only when adoption is on.\n// - With `slug` instead of `name`, the resource is an existing project,\n// found by GET /teams/{team}/projects/{slug}. It never creates, renames, or\n// (by default) deletes that project. A stack that only pushes to an\n// existing project can pass `{ projectId }` to Convex.Deployment instead\n// and needs no Management API token for the project.\nimport { Resource } from \"alchemy\";\nimport { OwnedBySomeoneElse, Unowned } from \"alchemy/AdoptPolicy\";\nimport { isResolved } from \"alchemy/Diff\";\nimport * as Provider from \"alchemy/Provider\";\nimport * as Effect from \"effect/Effect\";\nimport * as Schema from \"effect/Schema\";\nimport type { components } from \"@convex-dev/platform/managementApi\";\nimport { shouldAdopt } from \"./Adoption.ts\";\nimport {\n absentAsUndefined,\n ConvexApiError,\n ManagementApi,\n type ManagementApiService,\n} from \"./ManagementApi.ts\";\nimport type { Providers } from \"./Providers.ts\";\n\n/** Region names the Management API accepts, from the generated schema. */\nexport type DeploymentRegion = components[\"schemas\"][\"RegionName\"];\n\nexport type ProjectProps =\n | {\n /** Team slug or numeric team id. A slug costs one extra lookup per run. Cannot change. */\n readonly team: string | number;\n /** Display name. Convex derives the slug from it at creation. A change renames the project. */\n readonly name: string;\n /** Region of the deployment created with the project. Defaults to the team default. Cannot change. */\n readonly deploymentRegion?: DeploymentRegion;\n /** Deployment created with the project. Defaults to `prod`. Cannot change. */\n readonly deploymentType?: \"prod\" | \"dev\";\n }\n | {\n /** Team slug or numeric team id. Cannot change. */\n readonly team: string | number;\n /** Slug of an existing project, such as `score-four`. The resource never creates a project. Cannot change. */\n readonly slug: string;\n };\n\nexport interface ProjectAttributes {\n readonly projectId: number;\n readonly slug: string;\n readonly name: string;\n readonly teamId: number;\n readonly prodDeploymentName: string | undefined;\n readonly prodDeploymentUrl: string | undefined;\n}\n\nexport type Project = Resource<\"Convex.Project\", ProjectProps, ProjectAttributes, never, Providers>;\nexport const Project = Resource<Project>(\"Convex.Project\", { defaultRemovalPolicy: \"retain\" });\n\n/** The props change the team of an existing project. Convex cannot move a project. */\nexport class ProjectTeamChange extends Schema.TaggedError<ProjectTeamChange>()(\n \"ProjectTeamChange\",\n { projectId: Schema.Number, teamId: Schema.Number, requestedTeamId: Schema.Number },\n) {\n override get message() {\n return `Convex.Project cannot move project ${this.projectId} from team ${this.teamId} to team ${this.requestedTeamId}. Set team back to ${this.teamId}. To use the other team, create a new resource with a new logical id and move the data yourself.`;\n }\n}\n\n/**\n * The props change `deploymentType` or `deploymentRegion` of an existing\n * project. Convex uses them only when it creates the project.\n */\nexport class ProjectDeploymentChange extends Schema.TaggedError<ProjectDeploymentChange>()(\n \"ProjectDeploymentChange\",\n {\n projectId: Schema.Number,\n field: Schema.Literals([\"deploymentType\", \"deploymentRegion\"]),\n current: Schema.UndefinedOr(Schema.String),\n requested: Schema.UndefinedOr(Schema.String),\n },\n) {\n override get message() {\n const show = (value: string | undefined) => (value === undefined ? \"(not set)\" : value);\n return `Convex.Project cannot change ${this.field} of project ${this.projectId} from ${show(this.current)} to ${show(this.requested)}: Convex uses it only when it creates a project. Set ${this.field} back to ${show(this.current)}. For a new deployment, create a new resource with a new logical id and move the data yourself.`;\n }\n}\n\n/** More than one project in the team has the name, so the lookup cannot choose one. */\nexport class AmbiguousProject extends Schema.TaggedError<AmbiguousProject>()(\"AmbiguousProject\", {\n teamId: Schema.Number,\n name: Schema.String,\n projectIds: Schema.Array(Schema.Number),\n}) {\n override get message() {\n return `Team ${this.teamId} has ${this.projectIds.length} projects named \"${this.name}\" (ids ${this.projectIds.join(\", \")}). Convex.Project does not choose one. Rename the projects in the Convex dashboard so that only one has this name, or use a different name.`;\n }\n}\n\n/** Convex answered a create call but then did not return the project. */\nexport class CreatedProjectNotFound extends Schema.TaggedError<CreatedProjectNotFound>()(\n \"CreatedProjectNotFound\",\n { projectId: Schema.Number },\n) {\n override get message() {\n return `Convex created project ${this.projectId} but GET /projects/${this.projectId} did not return it. Run the deploy again with --adopt to take over project ${this.projectId}.`;\n }\n}\n\n/** No project in the team has the slug. A `slug` resource never creates one. */\nexport class ProjectNotFound extends Schema.TaggedError<ProjectNotFound>()(\"ProjectNotFound\", {\n team: Schema.String,\n slug: Schema.String,\n}) {\n override get message() {\n return `Team ${this.team} has no project with the slug \"${this.slug}\", and a Convex.Project with a slug never creates one. Check the slug in the project URL of the Convex dashboard, or use name to create a project.`;\n }\n}\n\n/** The props change the slug of a `slug` resource: that is another project. */\nexport class ProjectSlugChange extends Schema.TaggedError<ProjectSlugChange>()(\n \"ProjectSlugChange\",\n { projectId: Schema.Number, slug: Schema.String, requestedSlug: Schema.String },\n) {\n override get message() {\n return `Convex.Project ${this.projectId} has the slug \"${this.slug}\", and the props ask for \"${this.requestedSlug}\", which is another project. Set slug back to \"${this.slug}\". For the other project, create a new resource with a new logical id.`;\n }\n}\n\n/** Fields of GET /projects/{id}, PATCH /projects/{id}, and GET /teams/{team}/projects rows that the provider uses. */\nconst ProjectDetails = Schema.Struct({\n id: Schema.Number,\n name: Schema.String,\n slug: Schema.String,\n teamId: Schema.Number,\n teamSlug: Schema.String,\n prodDeploymentName: Schema.NullOr(Schema.String),\n});\ntype ProjectDetails = typeof ProjectDetails.Type;\n\n/** GET /teams/{team_id}/projects: one page of projects. */\nexport const ProjectPage = Schema.Struct({\n items: Schema.Array(ProjectDetails),\n pagination: Schema.Struct({\n hasMore: Schema.Boolean,\n nextCursor: Schema.optionalKey(Schema.NullOr(Schema.String)),\n }),\n});\n\n/** POST /teams/{team_id}/create_project. Only the id: everything else comes from GET /projects/{id}. */\nconst CreatedProject = Schema.Struct({ projectId: Schema.Number });\n\nconst DeploymentRow = Schema.Struct({\n name: Schema.String,\n deploymentType: Schema.String,\n isDefault: Schema.Boolean,\n deploymentUrl: Schema.String,\n /** Absent or null until the first push. */\n lastDeployTime: Schema.optionalKey(Schema.NullOr(Schema.Number)),\n});\nconst DeploymentRows = Schema.Array(DeploymentRow);\n\n/**\n * Fails with {@link ProjectDeploymentChange} when a create-time prop\n * changed. An omitted `deploymentType` means `prod`.\n */\nconst checkCreateTimeProps = (\n projectId: number,\n olds: Extract<ProjectProps, { name: string }>,\n news: Extract<ProjectProps, { name: string }>,\n) => {\n const oldType = olds.deploymentType ?? \"prod\";\n const newType = news.deploymentType ?? \"prod\";\n if (oldType !== newType) {\n return Effect.fail(\n new ProjectDeploymentChange({\n projectId,\n field: \"deploymentType\",\n current: oldType,\n requested: newType,\n }),\n );\n }\n if (olds.deploymentRegion !== news.deploymentRegion) {\n return Effect.fail(\n new ProjectDeploymentChange({\n projectId,\n field: \"deploymentRegion\",\n current: olds.deploymentRegion,\n requested: news.deploymentRegion,\n }),\n );\n }\n return Effect.void;\n};\n\n/** True when `team`, a slug or a numeric id, names the team of the project. */\nconst isTeamOf = (details: ProjectDetails, team: string | number) =>\n typeof team === \"number\" || /^\\d+$/.test(team)\n ? details.teamId === Number(team)\n : details.teamSlug === team;\n\n/** The row of the project's default production deployment, or undefined. */\nexport const prodDeploymentOf = (api: ManagementApiService, projectId: number) =>\n api\n .request(\"list deployments\", (client) =>\n client.GET(\"/projects/{project_id}/list_deployments\", {\n params: { path: { project_id: projectId } },\n }),\n )\n .pipe(\n Effect.map((rows) =>\n Schema.decodeUnknownSync(DeploymentRows)(rows).find(\n (row) => row.deploymentType === \"prod\" && row.isDefault,\n ),\n ),\n );\n\n/** GET /projects/{id}, or undefined after a 404. */\nexport const getProjectById = (api: ManagementApiService, projectId: number) =>\n absentAsUndefined(\n api.request(\"get project\", (client) =>\n client.GET(\"/projects/{project_id}\", { params: { path: { project_id: projectId } } }),\n ),\n ).pipe(\n Effect.map((body) =>\n body === undefined ? undefined : Schema.decodeUnknownSync(ProjectDetails)(body),\n ),\n );\n\n/**\n * Every project in the team with exactly this name, in the order of the\n * listing. Reads every page. `q` narrows the listing on the server, and the\n * exact match here decides. Pattern from Confect\n * `packages/alchemy/src/ConvexClient.ts` and `Project.ts`\n * (https://github.com/rjdellecese/confect, ISC license).\n */\nexport const listProjectsByName = (api: ManagementApiService, teamId: number, name: string) =>\n Effect.gen(function* () {\n const matches: ProjectDetails[] = [];\n const seenCursors = new Set<string>();\n let cursor: string | undefined;\n while (true) {\n const body = yield* api.request(\"list projects\", (client) =>\n client.GET(\"/teams/{team_id}/projects\", {\n params: {\n path: { team_id: teamId },\n query: { q: name, ...(cursor === undefined ? {} : { cursor }) },\n },\n }),\n );\n const page = Schema.decodeUnknownSync(ProjectPage)(body);\n matches.push(...page.items.filter((row) => row.name === name));\n if (!page.pagination.hasMore) break;\n const next = page.pagination.nextCursor;\n if (next === undefined || next === null || seenCursors.has(next)) {\n return yield* new ConvexApiError({\n operation: \"list projects\",\n status: 0,\n code: \"InvalidPagination\",\n message: `The project listing of team ${teamId} reports more pages but gives no new cursor. Convex.Project stops so that it does not miss a project named \"${name}\".`,\n });\n }\n seenCursors.add(next);\n cursor = next;\n }\n return matches;\n });\n\n/** The one project in the team with exactly this name, or undefined. More than one is an error. */\nexport const findProjectByName = (api: ManagementApiService, teamId: number, name: string) =>\n listProjectsByName(api, teamId, name).pipe(\n Effect.flatMap((matches) =>\n matches.length > 1\n ? new AmbiguousProject({ teamId, name, projectIds: matches.map((row) => row.id) })\n : Effect.succeed(matches[0]),\n ),\n );\n\n/**\n * POST /teams/{team_id}/create_project, then GET /projects/{id}. The identity\n * comes from the create response, never from a name lookup.\n */\nexport const createProject = (\n api: ManagementApiService,\n teamId: number,\n props: {\n readonly name: string;\n readonly deploymentType: \"prod\" | \"dev\";\n readonly deploymentRegion: DeploymentRegion | undefined;\n },\n) =>\n Effect.gen(function* () {\n const created = yield* api.request(\"create project\", (client) =>\n client.POST(\"/teams/{team_id}/create_project\", {\n params: { path: { team_id: teamId } },\n body: {\n projectName: props.name,\n deploymentType: props.deploymentType,\n ...(props.deploymentRegion === undefined\n ? {}\n : { deploymentRegion: props.deploymentRegion }),\n },\n }),\n );\n const { projectId } = Schema.decodeUnknownSync(CreatedProject)(created);\n const details = yield* getProjectById(api, projectId);\n if (details === undefined) return yield* new CreatedProjectNotFound({ projectId });\n return details;\n });\n\nexport const ProjectProvider = () =>\n Provider.effect(\n Project,\n Effect.gen(function* () {\n const api = yield* ManagementApi;\n\n const attributesOf = (details: ProjectDetails) =>\n prodDeploymentOf(api, details.id).pipe(\n Effect.map((prod): ProjectAttributes => ({\n projectId: details.id,\n slug: details.slug,\n name: details.name,\n teamId: details.teamId,\n prodDeploymentName: prod?.name ?? details.prodDeploymentName ?? undefined,\n prodDeploymentUrl: prod?.deploymentUrl,\n })),\n );\n\n const getById = (projectId: number) => getProjectById(api, projectId);\n\n /** The project with this slug in the team, or undefined. Official endpoint; the team can be a slug. */\n const getBySlug = (team: string | number, slug: string) =>\n absentAsUndefined(\n api.request(\"get project by slug\", (client) =>\n client.GET(\"/teams/{team_id_or_slug}/projects/{project_slug}\", {\n params: { path: { team_id_or_slug: String(team), project_slug: slug } },\n }),\n ),\n ).pipe(\n Effect.map((body) =>\n body === undefined ? undefined : Schema.decodeUnknownSync(ProjectDetails)(body),\n ),\n );\n\n const findByName = (teamId: number, name: string) => findProjectByName(api, teamId, name);\n\n /**\n * Brings an existing project to the desired name. The team cannot\n * change, so a project in another team fails.\n */\n const converge = (details: ProjectDetails, teamId: number, name: string) =>\n Effect.gen(function* () {\n if (details.teamId !== teamId) {\n return yield* new ProjectTeamChange({\n projectId: details.id,\n teamId: details.teamId,\n requestedTeamId: teamId,\n });\n }\n if (details.name === name) return yield* attributesOf(details);\n const updated = yield* api.request(\"update project\", (client) =>\n client.PATCH(\"/projects/{project_id}\", {\n params: { path: { project_id: details.id } },\n body: { name },\n }),\n );\n return yield* attributesOf(Schema.decodeUnknownSync(ProjectDetails)(updated));\n });\n\n return {\n stables: [\"projectId\", \"slug\", \"teamId\"],\n\n diff: Effect.fn(function* ({ olds, news, output }) {\n if (!isResolved(news)) return undefined;\n // Nothing exists yet, so nothing can be lost.\n if (output === undefined) return undefined;\n if (\"slug\" in news) {\n if (news.slug !== output.slug) {\n return yield* new ProjectSlugChange({\n projectId: output.projectId,\n slug: output.slug,\n requestedSlug: news.slug,\n });\n }\n if (olds.team !== news.team) {\n const details = yield* getById(output.projectId);\n if (details !== undefined && !isTeamOf(details, news.team)) {\n return yield* new ProjectTeamChange({\n projectId: output.projectId,\n teamId: output.teamId,\n requestedTeamId: yield* api.resolveTeamId(news.team),\n });\n }\n }\n // The resource changes nothing on the project.\n return { action: \"noop\" } as const;\n }\n // A deploymentType or deploymentRegion change fails in reconcile,\n // before any API call. Reconcile compares with the props of the last\n // successful deploy. Here, `olds` can be the props of a refused\n // update, so a check here would also refuse the props that fix it.\n if (olds.team !== news.team) {\n const requestedTeamId = yield* api.resolveTeamId(news.team);\n if (requestedTeamId !== output.teamId) {\n return yield* new ProjectTeamChange({\n projectId: output.projectId,\n teamId: output.teamId,\n requestedTeamId,\n });\n }\n }\n // Never \"replace\". A name change is an update; reconcile renames\n // the project with PATCH. Otherwise the engine compares the props.\n return \"name\" in olds && olds.name === news.name\n ? undefined\n : ({ action: \"update\" } as const);\n }),\n\n read: Effect.fn(function* ({ olds, output }) {\n if (output !== undefined) {\n const details = yield* getById(output.projectId);\n return details === undefined ? undefined : yield* attributesOf(details);\n }\n // No state: an existing project belongs to someone else until the\n // user passes --adopt. Convex has no ownership tags.\n const existing =\n \"slug\" in olds\n ? yield* getBySlug(olds.team, olds.slug)\n : yield* findByName(yield* api.resolveTeamId(olds.team), olds.name);\n return existing === undefined ? undefined : Unowned(yield* attributesOf(existing));\n }),\n\n reconcile: Effect.fn(function* ({ fqn, olds, news, output }) {\n if (\"slug\" in news) {\n // An existing project: found, checked, never created or changed.\n const details =\n output === undefined\n ? yield* getBySlug(news.team, news.slug)\n : yield* getById(output.projectId);\n if (details === undefined) {\n return yield* new ProjectNotFound({ team: String(news.team), slug: news.slug });\n }\n if (details.slug !== news.slug) {\n return yield* new ProjectSlugChange({\n projectId: details.id,\n slug: details.slug,\n requestedSlug: news.slug,\n });\n }\n if (!isTeamOf(details, news.team)) {\n return yield* new ProjectTeamChange({\n projectId: details.id,\n teamId: details.teamId,\n requestedTeamId: yield* api.resolveTeamId(news.team),\n });\n }\n if (output === undefined && !(yield* shouldAdopt(fqn))) {\n return yield* new OwnedBySomeoneElse({\n message: `Convex project ${details.id} (\"${news.slug}\") exists and is not in this stack's state. Re-run with --adopt to take it over.`,\n resourceType: Project.Type,\n physicalName: news.slug,\n });\n }\n return yield* attributesOf(details);\n }\n const teamId = yield* api.resolveTeamId(news.team);\n if (output !== undefined) {\n // State names the project. Never look it up by name here.\n if (olds !== undefined && \"name\" in olds) {\n yield* checkCreateTimeProps(output.projectId, olds, news);\n }\n if (output.teamId !== teamId) {\n return yield* new ProjectTeamChange({\n projectId: output.projectId,\n teamId: output.teamId,\n requestedTeamId: teamId,\n });\n }\n const details = yield* getById(output.projectId);\n if (details !== undefined) return yield* converge(details, teamId, news.name);\n // The project in state was deleted outside Alchemy. Creating a\n // new project below loses nothing.\n } else {\n // No state: a project with this name is someone else's unless\n // adoption is on. The engine checked this in plan; this check\n // covers a project that appeared after the plan.\n const existing = yield* findByName(teamId, news.name);\n if (existing !== undefined) {\n if (!(yield* shouldAdopt(fqn))) {\n return yield* new OwnedBySomeoneElse({\n message: `Convex project ${existing.id} in team ${teamId} already has the name \"${news.name}\". Re-run with --adopt to take it over, or use a different name.`,\n resourceType: Project.Type,\n physicalName: news.name,\n });\n }\n return yield* converge(existing, teamId, news.name);\n }\n }\n const details = yield* createProject(api, teamId, {\n name: news.name,\n deploymentType: news.deploymentType ?? \"prod\",\n deploymentRegion: news.deploymentRegion,\n });\n return yield* converge(details, teamId, news.name);\n }),\n\n // Runs only with `RemovalPolicy.destroy()`: the default policy is `retain`.\n delete: Effect.fn(function* ({ output }) {\n yield* absentAsUndefined(\n api.requestVoid(\"delete project\", (client) =>\n client.POST(\"/projects/{project_id}/delete\", {\n params: { path: { project_id: output.projectId } },\n }),\n ),\n );\n }),\n };\n }),\n );\n","// The provider collection users merge into a stack:\n// providers: Layer.mergeAll(Cloudflare.providers(), Convex.providers())\nimport * as Provider from \"alchemy/Provider\";\nimport * as Layer from \"effect/Layer\";\nimport { type Credentials, fromConfig } from \"./Credentials.ts\";\nimport { Deployment, DeploymentProvider } from \"./Deployment.ts\";\nimport { ManagementApiLive } from \"./ManagementApi.ts\";\nimport { Project, ProjectProvider } from \"./Project.ts\";\n\nexport class Providers extends Provider.ProviderCollection<Providers>()(\"Convex\") {}\n\n/**\n * The Convex resource providers. Pass a credentials layer to override the\n * default lookup (`CONVEX_ACCESS_TOKEN`, then the Convex CLI login, and\n * `CONVEX_DEPLOY_KEY`).\n */\nexport const providers = (credentials: Layer.Layer<Credentials> = fromConfig()) =>\n Layer.effect(Providers, Provider.collection([Project, Deployment])).pipe(\n Layer.provide(Layer.mergeAll(ProjectProvider(), DeploymentProvider())),\n Layer.provide(ManagementApiLive()),\n Layer.provide(credentials),\n Layer.orDie,\n );\n","// Alchemy state in Convex: `state: Convex.state({ team })` in `Alchemy.Stack`.\n//\n// One project for each Convex team, `alchemy-state`, holds the state of\n// every stack and stage of the team in its production deployment: the\n// tables `resources (stack, stage, fqn, value)` and `outputs (stack, stage,\n// value)`, served by the functions of src/store/convex. The store lives\n// outside every resource that a stack manages, so a stack can create and\n// destroy its own project. See docs/design/convex-state.md.\n//\n// Bootstrap, on the first call of the run: the team token (CONVEX_ACCESS_TOKEN,\n// or the Convex CLI login) finds the project by name, or creates it; a deploy\n// key of its production deployment that can run internal queries and\n// mutations, and nothing else, is created for the run and deleted at its\n// end; the `state:version` query says whether the deployment has the store\n// of this version. Without one, or with an older one, the installed Convex\n// CLI pushes src/store/convex to it, with a push key that is deleted after\n// the push. The functions are internal, so only POST /api/function with such\n// a key reaches them: a public function of a root app answers anyone who\n// knows the deployment URL (measured). A key that stops working during a\n// long run (it expires after two hours) is replaced once per call.\n//\n// Two first runs of a team can both create a project named `alchemy-state`.\n// The run whose project is not the oldest deletes its own, before it writes\n// anything, and uses the oldest: both runs end on one store.\n//\n// The function names are a wire contract: Samebase reads `stacks` and\n// `getOutput` by name, and an older client calls an older set of names. A\n// name is never renamed or removed. STORE_VERSION rises when a function\n// changes in a way that an older client cannot use, and a client never\n// pushes an older store over a newer one.\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport * as Effect from \"effect/Effect\";\nimport * as Layer from \"effect/Layer\";\nimport * as ChildProcessSpawner from \"effect/process/ChildProcessSpawner\";\nimport * as Redacted from \"effect/Redacted\";\nimport * as Schedule from \"effect/Schedule\";\nimport * as Schema from \"effect/Schema\";\nimport * as Scope from \"effect/Scope\";\nimport {\n encodeState,\n type PersistedState,\n type ReplacedResourceState,\n reviveState,\n State,\n type StateService,\n STATE_STORE_VERSION,\n StateStoreError,\n} from \"alchemy/State\";\nimport { fromConfig } from \"./Credentials.ts\";\nimport { ProductionDeploymentNotFound } from \"./Deployment.ts\";\nimport {\n absentAsUndefined,\n ManagementApi,\n ManagementApiLive,\n type ManagementApiService,\n retryIdempotentWrite,\n} from \"./ManagementApi.ts\";\nimport {\n createProject,\n findProjectByName,\n listProjectsByName,\n prodDeploymentOf,\n} from \"./Project.ts\";\nimport {\n createDeployKey,\n deleteDeployKey,\n installedCli,\n push,\n PUSH_KEY_ACTIONS,\n withPushKey,\n} from \"./Push.ts\";\nimport { STORE_VERSION } from \"./store/convex/version.ts\";\n\n/** The name of the state project in each team. */\nexport const STORE_PROJECT_NAME = \"alchemy-state\";\n\n/**\n * The actions of the key of one run: the internal queries and mutations of\n * the store, nothing else. Measured: `deployment:data:view` and\n * `deployment:data:write` do not run an internal function.\n */\nexport const RUN_KEY_ACTIONS = [\n \"deployment:functions:runInternalQueries\",\n \"deployment:functions:runInternalMutations\",\n] as const;\n\n/** The body of POST /api/function, with HTTP 200 for a function error too. */\nconst Reply = Schema.Union([\n Schema.Struct({ status: Schema.Literal(\"success\"), value: Schema.Unknown }),\n Schema.Struct({ status: Schema.Literal(\"error\"), errorMessage: Schema.String }),\n]);\ntype Reply = typeof Reply.Type;\n\n/** The error reply of /api/function for a function that the deployment does not have (recorded). */\nconst MISSING_FUNCTION = /Could not find function for '/;\n\n/** HTTP 401 or 403 from the function API: the key is gone or expired (recorded: 403 without a key). */\nconst isUnauthorized = (error: StateStoreError) =>\n error.http?.status === 401 || error.http?.status === 403;\n\nconst failure = (message: string) => new StateStoreError({ message: `Convex state: ${message}` });\n\n/** No reply, HTTP 429, or HTTP 5xx: a new attempt can succeed. Every call of the store is idempotent. */\nconst isTransient = (error: StateStoreError) =>\n error.http !== undefined &&\n (error.http.status === undefined || error.http.status === 429 || error.http.status >= 500);\n\nconst post = (\n url: string,\n headers: Record<string, string>,\n body: unknown,\n): Effect.Effect<unknown, StateStoreError> =>\n Effect.tryPromise({\n try: () =>\n fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", ...headers },\n body: JSON.stringify(body),\n }),\n catch: () => new StateStoreError({ message: `Convex state: POST ${url} failed`, http: {} }),\n }).pipe(\n Effect.flatMap((response) =>\n response.ok || response.status === 560\n ? Effect.tryPromise({\n try: (): Promise<unknown> => response.json(),\n catch: () => failure(`${url} gave no JSON`),\n })\n : Effect.fail(\n new StateStoreError({\n message: `Convex state: POST ${url} failed with HTTP ${response.status}`,\n http: { status: response.status },\n }),\n ),\n ),\n Effect.retry({\n while: isTransient,\n schedule: Schedule.exponential(\"100 millis\").pipe(Schedule.jittered),\n times: 5,\n }),\n );\n\nconst decode =\n <S extends Schema.Codec<unknown, unknown>>(schema: S, what: string) =>\n (value: unknown) =>\n Schema.decodeUnknownEffect(schema)(value).pipe(Effect.mapError(() => failure(`bad ${what}`)));\n\n/** The function API of the store deployment, with a deploy key. */\nexport interface FunctionApi {\n /** POST /api/function, the call that `convex run` makes: the reply, which can be a function error. */\n readonly call: (\n path: string,\n args: Record<string, string | undefined>,\n ) => Effect.Effect<Reply, StateStoreError>;\n}\n\nexport const makeFunctionApi = (url: string, key: Redacted.Redacted<string>): FunctionApi => ({\n call: (path, args) =>\n post(\n `${url}/api/function`,\n { Authorization: `Convex ${Redacted.value(key)}` },\n { path, args, format: \"json\" },\n ).pipe(Effect.flatMap(decode(Reply, `reply of ${path}`))),\n});\n\n/** The value of a reply, or the Convex message, which names the function and the cause, such as a missing key action. */\nconst valueOf = (reply: Reply) =>\n reply.status === \"success\"\n ? Effect.succeed(reply.value)\n : Effect.fail(failure(reply.errorMessage.trim()));\n\n/** The functions of the store with Alchemy's encoding: the JSON text of encodeState. */\nconst remoteOf = (api: FunctionApi) => {\n const run = (name: string, args: Record<string, string | undefined>) =>\n api.call(`state:${name}`, args).pipe(Effect.flatMap(valueOf));\n const strings = (name: string, args: Record<string, string>) =>\n run(name, args).pipe(Effect.flatMap(decode(Schema.Array(Schema.String), name)));\n const optional = (name: string, args: Record<string, string>) =>\n run(name, args).pipe(Effect.flatMap(decode(Schema.NullOr(Schema.String), name)));\n const encode = (value: unknown) => JSON.stringify(encodeState(value));\n return {\n listStacks: () => strings(\"stacks\", {}),\n listStages: (stack: string) => strings(\"stages\", { stack }),\n list: (r: { stack: string; stage: string }) =>\n strings(\"list\", { stack: r.stack, stage: r.stage }),\n // Like Alchemy's own stores, the store gives back the state that it got.\n get: (r: { stack: string; stage: string; fqn: string }) =>\n optional(\"get\", { stack: r.stack, stage: r.stage, fqn: r.fqn }).pipe(\n Effect.map((text): PersistedState | undefined =>\n text === null ? undefined : JSON.parse(text, reviveState),\n ),\n ),\n getReplacedResources: (r: { stack: string; stage: string }) =>\n strings(\"replaced\", { stack: r.stack, stage: r.stage }).pipe(\n Effect.map((texts) =>\n texts.map((text): ReplacedResourceState => JSON.parse(text, reviveState)),\n ),\n ),\n getOutput: (r: { stack: string; stage: string }) =>\n optional(\"getOutput\", { stack: r.stack, stage: r.stage }).pipe(\n Effect.map((text): unknown => (text === null ? undefined : JSON.parse(text, reviveState))),\n ),\n set: (r: { stack: string; stage: string; fqn: string; value: PersistedState }) =>\n run(\"set\", { stack: r.stack, stage: r.stage, fqn: r.fqn, value: encode(r.value) }),\n delete: (r: { stack: string; stage: string; fqn: string }) =>\n run(\"remove\", { stack: r.stack, stage: r.stage, fqn: r.fqn }),\n deleteStack: (r: { stack: string; stage?: string }) =>\n run(\"removeStack\", { stack: r.stack, stage: r.stage }),\n setOutput: (r: { stack: string; stage: string; value: unknown }) =>\n run(\"setOutput\", { stack: r.stack, stage: r.stage, value: encode(r.value) }),\n };\n};\n\n/** The version that the store answers, or undefined when the deployment has no `state:version`. */\nconst storeVersion = (api: FunctionApi) =>\n api\n .call(\"state:version\", {})\n .pipe(\n Effect.flatMap((reply) =>\n reply.status === \"error\" && MISSING_FUNCTION.test(reply.errorMessage)\n ? Effect.succeed(undefined)\n : valueOf(reply).pipe(Effect.flatMap(decode(Schema.Number, \"store version\"))),\n ),\n );\n\n/**\n * The functions directory of the store app, `src/store/convex` of this\n * package. This file is `src/State.ts` in a checkout and a chunk in `lib/`\n * in the installed package, which ships `src` too, so the directory is\n * `../src/store/convex` from either place.\n */\nexport const storeDirectory = () =>\n join(dirname(fileURLToPath(import.meta.url)), \"..\", \"src\", \"store\", \"convex\");\n\nexport interface StoreOptions {\n /** Team slug or numeric team id of the `alchemy-state` project, or undefined with a team access token, which names its team. */\n readonly team: string | number | undefined;\n readonly api: ManagementApiService;\n readonly spawner: ChildProcessSpawner.ChildProcessSpawner[\"Service\"];\n /** The key of the run is deleted when this scope closes. */\n readonly scope: Scope.Scope;\n /** The functions directory that an outdated store gets: {@link storeDirectory}. */\n readonly store: string;\n}\n\n/**\n * Pushes `store` to the production deployment of the state project with the\n * installed Convex CLI: no typecheck, no codegen, the key only in the\n * environment of the CLI.\n */\nconst pushStore = (\n options: StoreOptions,\n deployment: { readonly name: string; readonly deploymentUrl: string },\n) =>\n Effect.gen(function* () {\n const cli = yield* installedCli(join(options.store, \"..\"));\n yield* Effect.logInfo(\n `Convex state: pushing the store version ${STORE_VERSION} to ${deployment.name}`,\n );\n yield* withPushKey(options.api, deployment.name, PUSH_KEY_ACTIONS, (key) =>\n push(options.spawner, key, {\n deployment: deployment.name,\n url: deployment.deploymentUrl,\n source: {\n path: options.store,\n command: [...cli, \"deploy\", \"--typecheck\", \"disable\", \"--codegen\", \"disable\"],\n },\n env: {},\n previousEnvNames: [],\n adopt: false,\n previewName: undefined,\n }),\n );\n });\n\n/**\n * Creates the state project of the team. Two first runs can both create one:\n * the run whose project is not the oldest deletes its own, which holds\n * nothing yet, and uses the oldest, so that every run ends on one store.\n */\nconst createStoreProject = (api: ManagementApiService, teamId: number, team: string | number) =>\n Effect.gen(function* () {\n yield* Effect.logInfo(\n `Convex state: creating the project ${STORE_PROJECT_NAME} in team ${team}`,\n );\n const created = yield* createProject(api, teamId, {\n name: STORE_PROJECT_NAME,\n deploymentType: \"prod\",\n deploymentRegion: undefined,\n });\n const all = yield* listProjectsByName(api, teamId, STORE_PROJECT_NAME);\n const oldest = all.reduce((a, b) => (b.id < a.id ? b : a), created);\n if (oldest.id === created.id) return created;\n yield* Effect.logInfo(\n `Convex state: another run created ${STORE_PROJECT_NAME} ${oldest.id} first; project ${created.id} is deleted again.`,\n );\n yield* absentAsUndefined(\n retryIdempotentWrite(\n api.requestVoid(\"delete project\", (client) =>\n client.POST(\"/projects/{project_id}/delete\", {\n params: { path: { project_id: created.id } },\n }),\n ),\n ),\n );\n return oldest;\n });\n\n/**\n * The StateService over the `alchemy-state` project of the team: found or\n * created, its store pushed when it is missing or older, and read and\n * written with the keys of this run.\n */\nexport const makeConvexState = (options: StoreOptions) =>\n Effect.gen(function* () {\n const { api } = options;\n const teamId = yield* api.resolveTeamId(options.team);\n const team = options.team ?? teamId;\n const found = yield* findProjectByName(api, teamId, STORE_PROJECT_NAME);\n const project = found ?? (yield* createStoreProject(api, teamId, team));\n const deployment = yield* prodDeploymentOf(api, project.id);\n if (deployment === undefined) {\n return yield* new ProductionDeploymentNotFound({ projectId: project.id });\n }\n\n // The keys of this run, deleted together when the scope closes. A call\n // that the current key no longer authorizes gets one new key and one\n // more attempt.\n const keys: Redacted.Redacted<string>[] = [];\n yield* Scope.addFinalizer(\n options.scope,\n Effect.suspend(() =>\n Effect.forEach(keys, (key) => deleteDeployKey(api, deployment.name, key), {\n discard: true,\n }),\n ),\n );\n const mint = createDeployKey(api, deployment.name, \"alchemy-state\", RUN_KEY_ACTIONS).pipe(\n Effect.map((key) => {\n keys.push(key);\n return makeFunctionApi(deployment.deploymentUrl, key);\n }),\n Effect.mapError((error) => failure(`no key for ${deployment.name}: ${error.message}`)),\n );\n let current = yield* mint;\n const functions: FunctionApi = {\n call: (path, args) =>\n current.call(path, args).pipe(\n Effect.catchIf(isUnauthorized, () =>\n mint.pipe(\n Effect.flatMap((next) => {\n current = next;\n return next.call(path, args);\n }),\n ),\n ),\n ),\n };\n\n const version = yield* storeVersion(functions);\n if (version === undefined || version < STORE_VERSION) {\n // Code without `state:version` is another app with the name of the store.\n if (version === undefined && deployment.lastDeployTime) {\n return yield* failure(\n `project ${STORE_PROJECT_NAME} (${project.id}) of team ${team} has code that is not the state store, and Convex.state does not push over it. Rename that project in the Convex dashboard.`,\n );\n }\n // Another run can push a newer store in the meantime: read again right\n // before the push. The push itself has no lock (see the design note).\n const now = yield* storeVersion(functions);\n if (now === undefined || now < STORE_VERSION) {\n yield* pushStore(options, deployment);\n const pushed = yield* storeVersion(functions);\n if (pushed === undefined || pushed < STORE_VERSION) {\n return yield* failure(\n `${deployment.name} answers store version ${pushed ?? \"none\"} after the push of version ${STORE_VERSION}.`,\n );\n }\n }\n } else if (version > STORE_VERSION) {\n // The names are a wire contract, so a newer store serves this client.\n yield* Effect.logInfo(\n `Convex state: the store of team ${team} is version ${version}, newer than version ${STORE_VERSION} of this package, and it stays.`,\n );\n }\n\n const remote = remoteOf(functions);\n const service: StateService = {\n id: \"convex\",\n getVersion: () => Effect.succeed(STATE_STORE_VERSION),\n listStacks: remote.listStacks,\n listStages: remote.listStages,\n list: remote.list,\n get: remote.get,\n getReplacedResources: remote.getReplacedResources,\n getOutput: remote.getOutput,\n set: (request) => remote.set(request).pipe(Effect.as(request.value)),\n delete: (request) => remote.delete(request).pipe(Effect.asVoid),\n deleteStack: (request) => remote.deleteStack(request).pipe(Effect.asVoid),\n setOutput: (request) => remote.setOutput(request).pipe(Effect.as(request.value)),\n };\n return service;\n });\n\n/**\n * Alchemy state in the `alchemy-state` project of `team`, with the team token\n * in CONVEX_ACCESS_TOKEN or the Convex CLI login. A team access token names\n * its team, so `team` is optional with one; the Convex CLI login needs the\n * slug or the id. The first use of the run finds or creates the project and\n * pushes the store when it is missing or older. `alchemy plan` on another\n * stack never touches Convex.\n */\nexport const state = (\n options: { readonly team?: string | number } = {},\n): Layer.Layer<State, never, ChildProcessSpawner.ChildProcessSpawner> =>\n Layer.effect(\n State,\n Effect.gen(function* () {\n const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;\n const scope = yield* Scope.Scope;\n // The stack's ConfigProvider, for the read of the token on first use.\n const context = yield* Effect.context<never>();\n return yield* Effect.cached(\n Effect.gen(function* () {\n const api = yield* ManagementApi.pipe(\n Effect.provide(ManagementApiLive().pipe(Layer.provide(fromConfig()))),\n );\n return yield* makeConvexState({\n team: options.team,\n api,\n spawner,\n scope,\n store: storeDirectory(),\n });\n }).pipe(Effect.provideContext(context), Effect.orDie),\n );\n }),\n );\n"],"mappings":"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"}