@samebase/alchemy-convex 0.2.0 → 0.3.0

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":["checkIdentity"],"sources":["../src/Credentials.ts","../src/Adoption.ts","../src/ManagementApi.ts","../src/EnvironmentVariable.ts","../src/DefaultEnvironmentVariable.ts","../src/Deploy.ts","../src/DeployKey.ts","../src/PreviewDeployKey.ts","../src/Project.ts","../src/Providers.ts"],"sourcesContent":["// Convex control-plane credentials for the provider.\n//\n// The service value is an Effect so that building the providers layer never\n// touches the environment or the filesystem. The token is read on the first\n// lifecycle call, which keeps `alchemy plan` on an unrelated stack free of\n// Convex 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 Redacted from \"effect/Redacted\";\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 class Credentials extends Context.Service<Credentials, Effect.Effect<ResolvedCredentials>>()(\n \"@samebase/alchemy-convex/Credentials\",\n) {}\n\n/** Environment variable read by {@link fromConfig}. */\nexport const ACCESS_TOKEN_ENV = \"CONVEX_ACCESS_TOKEN\";\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\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: () => new CredentialsError({ reason: `no Convex CLI login at ${path}` }),\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\nexport class CredentialsError extends Schema.TaggedError<CredentialsError>()(\"CredentialsError\", {\n reason: Schema.String,\n}) {}\n\n/**\n * Default resolution: `CONVEX_ACCESS_TOKEN` from the stack ConfigProvider\n * (process env, `.env`, stack secrets), then the Convex CLI login on this\n * machine. CI sets the variable; a developer who ran `npx convex login` needs\n * nothing.\n */\nexport const fromConfig = (): Layer.Layer<Credentials> =>\n Layer.succeed(\n Credentials,\n Effect.cached(\n Config.Redacted(ACCESS_TOKEN_ENV).pipe(\n Effect.map((accessToken): ResolvedCredentials => ({ accessToken, source: \"env\" })),\n Effect.catch(() => readConvexCliLogin),\n Effect.orDie,\n ),\n ).pipe(Effect.flatten),\n );\n\n/** Explicit token, for tests or callers that already hold a value. */\nexport const fromToken = (accessToken: Redacted.Redacted<string>): Layer.Layer<Credentials> =>\n Layer.succeed(Credentials, Effect.succeed({ accessToken, source: \"explicit\" } as const));\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 } 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\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\nexport const ManagementApiLive = (): Layer.Layer<ManagementApi, never, Credentials> =>\n Layer.effect(\n ManagementApi,\n Effect.gen(function* () {\n const credentials = yield* Credentials;\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 return { request, requestVoid, deploymentRequest, resolveTeamId, isCredentialToken };\n }),\n );\n","// Convex.EnvironmentVariable: one environment variable on one deployment.\n//\n// Environment variables live on the deployment API\n// (https://<deployment>.convex.cloud/api/v1), which authenticates with a\n// deploy key, not with the Management API token. Setting a variable and\n// removing it are the same call: update_environment_variables with\n// `value: null` removes the variable.\n//\n// A variable that exists but is not in state belongs to someone else: its\n// old value is lost when this resource writes it. Alchemy takes it over only\n// with --adopt.\n//\n// The variable's name and deployment cannot change. A change fails with\n// VariableIdentityChange: use a new resource with a new logical id. A\n// replacement could let the engine delete an old generation that names the\n// live variable, and a rename in place needs a cleanup that can fail and\n// leave a variable or a revoked key behind.\n//\n// The attributes keep the deploy key of the variable's deployment. After a\n// refused change, the props can name another deployment and its key, so\n// read and delete use the attributes, not the props.\nimport { createDeploymentClient } from \"@convex-dev/platform\";\nimport { Resource } from \"alchemy\";\nimport { isResolved } from \"alchemy/Diff\";\nimport { OwnedBySomeoneElse, Unowned } from \"alchemy/AdoptPolicy\";\nimport * as Provider from \"alchemy/Provider\";\nimport * as Effect from \"effect/Effect\";\nimport * as Redacted from \"effect/Redacted\";\nimport * as Schema from \"effect/Schema\";\nimport { shouldAdopt } from \"./Adoption.ts\";\nimport {\n absentAsUndefined,\n ManagementApi,\n type ManagementApiService,\n retryIdempotentWrite,\n settleVoid,\n} from \"./ManagementApi.ts\";\nimport type { Providers } from \"./Providers.ts\";\n\n/**\n * The variable's identity when the listing has `name`. Own keys only: a\n * valid variable name such as `toString` must not match the object prototype.\n */\nexport const findVariable = (\n list: typeof EnvironmentVariableList.Type,\n deployment: string,\n name: string,\n): { readonly deployment: string; readonly name: string } | undefined =>\n Object.hasOwn(list.environmentVariables, name) ? { deployment, name } : undefined;\n\n/**\n * One attempt to set one variable, or to remove it when `value` is null. The\n * deployment answers 200 with an empty body, so this reads no response data.\n */\nconst writeVariable = (\n deployment: string,\n deployKey: Redacted.Redacted<string>,\n name: string,\n value: string | Redacted.Redacted<string> | null,\n) =>\n settleVoid(\"update environment variables\", () =>\n createDeploymentClient(deployment, Redacted.value(deployKey)).POST(\n \"/update_environment_variables\",\n {\n body: {\n changes: [{ name, value: Redacted.isRedacted(value) ? Redacted.value(value) : value }],\n },\n },\n ),\n );\n\n/**\n * Sets one variable, or removes it when `value` is null. The call sets a\n * value, so it runs again after a write conflict or a 5xx answer, for example\n * when another resource writes a variable of the same deployment at the same\n * time. Use it only where the variable is already ours to set.\n */\nexport const updateVariable = (\n deployment: string,\n deployKey: Redacted.Redacted<string>,\n name: string,\n value: string | Redacted.Redacted<string> | null,\n) => retryIdempotentWrite(writeVariable(deployment, deployKey, name, value));\n\n/** GET https://<deployment>.convex.cloud/api/v1/list_environment_variables */\nexport const EnvironmentVariableList = Schema.Struct({\n environmentVariables: Schema.Record(Schema.String, Schema.String),\n});\n\n/** The variable's identity, or undefined when the variable or the deployment is absent. */\nconst readVariable = (\n api: ManagementApiService,\n deployment: string,\n deployKey: Redacted.Redacted<string>,\n name: string,\n) =>\n // 404: the deployment no longer exists, so neither does the variable.\n absentAsUndefined(\n api.deploymentRequest(\"list environment variables\", deployment, deployKey, (client) =>\n client.GET(\"/list_environment_variables\"),\n ),\n ).pipe(\n Effect.map((body) =>\n body === undefined\n ? undefined\n : findVariable(Schema.decodeUnknownSync(EnvironmentVariableList)(body), deployment, name),\n ),\n );\n\nexport interface EnvironmentVariableProps {\n /** Deployment name, or its URL for deployments outside US East. */\n readonly deployment: string;\n /** Deploy key for `deployment`, such as `deployKey.deployKey`. */\n readonly deployKey: Redacted.Redacted<string>;\n readonly name: string;\n readonly value: string | Redacted.Redacted<string>;\n}\n\nexport interface EnvironmentVariableAttributes {\n readonly deployment: string;\n readonly name: string;\n /** Deploy key for `deployment`, for read and delete. Undefined in state from 0.1.x. */\n readonly deployKey: Redacted.Redacted<string> | undefined;\n}\n\nexport type EnvironmentVariable = Resource<\n \"Convex.EnvironmentVariable\",\n EnvironmentVariableProps,\n EnvironmentVariableAttributes,\n never,\n Providers\n>;\nexport const EnvironmentVariable = Resource<EnvironmentVariable>(\"Convex.EnvironmentVariable\");\n\n/**\n * The props name another variable than the one in state. Used by\n * Convex.EnvironmentVariable and Convex.DefaultEnvironmentVariable.\n */\nexport class VariableIdentityChange extends Schema.TaggedError<VariableIdentityChange>()(\n \"VariableIdentityChange\",\n {\n resourceType: Schema.String,\n field: Schema.Literals([\"name\", \"deployment\", \"projectId\", \"deploymentType\"]),\n current: Schema.String,\n requested: Schema.String,\n },\n) {\n override get message() {\n return `${this.resourceType} cannot change its ${this.field} from ${this.current} to ${this.requested}. Create a new resource with a new logical id for the new name or deployment, and remove this one.`;\n }\n}\n\n/** Fails with {@link VariableIdentityChange} when the props name another variable than the one in state. */\nconst checkIdentity = (output: EnvironmentVariableAttributes, news: EnvironmentVariableProps) =>\n output.name !== news.name\n ? Effect.fail(\n new VariableIdentityChange({\n resourceType: EnvironmentVariable.Type,\n field: \"name\",\n current: output.name,\n requested: news.name,\n }),\n )\n : output.deployment !== news.deployment\n ? Effect.fail(\n new VariableIdentityChange({\n resourceType: EnvironmentVariable.Type,\n field: \"deployment\",\n current: output.deployment,\n requested: news.deployment,\n }),\n )\n : Effect.void;\n\n/**\n * The deploy key for the variable in state: from the attributes, or, for\n * state from 0.1.x, from props that name the same deployment.\n */\nconst keyOf = (\n output: EnvironmentVariableAttributes,\n olds: EnvironmentVariableProps | undefined,\n): Redacted.Redacted<string> | undefined =>\n output.deployKey ?? (olds?.deployment === output.deployment ? olds.deployKey : undefined);\n\nexport const EnvironmentVariableProvider = () =>\n Provider.effect(\n EnvironmentVariable,\n Effect.gen(function* () {\n const api = yield* ManagementApi;\n\n return {\n // Compares with the attributes: after a refused change, `olds` are\n // the refused props. Otherwise undefined: the engine updates when any\n // prop changed and compares Redacted values, such as the value and\n // the deploy key, by content.\n diff: Effect.fn(function* ({ news, output }) {\n if (!isResolved(news) || output === undefined) return undefined;\n yield* checkIdentity(output, news);\n return undefined;\n }),\n\n read: Effect.fn(function* ({ olds, output }) {\n if (output !== undefined) {\n const key = keyOf(output, olds);\n // Without a key for the deployment in state, keep the state as it is.\n if (key === undefined) return output;\n const found = yield* readVariable(api, output.deployment, key, output.name);\n return found === undefined ? undefined : output;\n }\n const found = yield* readVariable(api, olds.deployment, olds.deployKey, olds.name);\n // No state: the variable belongs to someone else until the user passes --adopt.\n return found === undefined ? undefined : Unowned({ ...found, deployKey: olds.deployKey });\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 const write = writeVariable(news.deployment, news.deployKey, news.name, news.value);\n if (output !== undefined || (yield* shouldAdopt(fqn))) {\n // In state, or adopted: the variable is ours to set.\n yield* retryIdempotentWrite(write);\n } else {\n // Not in state: overwriting a variable that exists loses its\n // value, so that needs adoption. Each attempt checks first, so a\n // retry after a write conflict never overwrites a variable that\n // another writer created in the meantime.\n yield* retryIdempotentWrite(\n Effect.gen(function* () {\n const existing = yield* readVariable(\n api,\n news.deployment,\n news.deployKey,\n news.name,\n );\n if (existing !== undefined) {\n return yield* new OwnedBySomeoneElse({\n message: `Environment variable ${news.name} already exists on deployment ${news.deployment}. Re-run with --adopt to take it over and overwrite its value, or use a different name.`,\n resourceType: EnvironmentVariable.Type,\n physicalName: news.name,\n });\n }\n yield* write;\n }),\n );\n }\n return { deployment: news.deployment, name: news.name, deployKey: news.deployKey };\n }),\n\n delete: Effect.fn(function* ({ olds, output }) {\n const key = keyOf(output, olds);\n if (key === undefined) {\n yield* Effect.logWarning(\n `Environment variable ${output.name} on deployment ${output.deployment} stays: Alchemy has no deploy key for that deployment. Remove it in the Convex dashboard.`,\n );\n return;\n }\n // Removing an absent variable succeeds; 404 means the deployment is gone.\n yield* absentAsUndefined(updateVariable(output.deployment, key, output.name, null));\n }),\n };\n }),\n );\n","// Convex.DefaultEnvironmentVariable: a project default environment variable\n// for one deployment type. Convex sets it on each new deployment of that type,\n// such as auth keys that every pull request preview deployment needs.\n//\n// Defaults live on the Management API and authenticate with the team\n// credential, not with a deploy key. Setting a default and removing it are the\n// same call: update_default_environment_variables with `value: null` removes\n// the default, and removing an absent default also answers 200.\n//\n// A default that exists but is not in state belongs to someone else: its old\n// value is lost when this resource writes it. Alchemy takes it over only with\n// --adopt.\n//\n// The default's project, name, and deployment type cannot change. A change\n// fails with VariableIdentityChange: use a new resource with a new logical\n// id. Read and delete use the identity in the attributes: after a refused\n// change, the props name the refused one.\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 Redacted from \"effect/Redacted\";\nimport * as Schema from \"effect/Schema\";\nimport type { components } from \"@convex-dev/platform/managementApi\";\nimport { shouldAdopt } from \"./Adoption.ts\";\nimport { VariableIdentityChange } from \"./EnvironmentVariable.ts\";\nimport {\n absentAsUndefined,\n ManagementApi,\n type ManagementApiService,\n retryIdempotentWrite,\n} from \"./ManagementApi.ts\";\nimport type { Providers } from \"./Providers.ts\";\n\n/** Deployment types a default can target, from the generated schema. */\nexport type DeploymentType = components[\"schemas\"][\"DeploymentType\"];\n\n/**\n * Attributes when the listing has `name` for `deploymentType`. An unfiltered\n * listing merges the deployment types that share one value into one row, so\n * the match checks membership in `deploymentTypes`.\n */\nexport const findDefault = (\n list: typeof DefaultEnvironmentVariableList.Type,\n projectId: number,\n name: string,\n deploymentType: DeploymentType,\n): DefaultEnvironmentVariableAttributes | undefined =>\n list.items.some((item) => item.name === name && item.deploymentTypes.includes(deploymentType))\n ? { projectId, name, deploymentType }\n : undefined;\n\n/**\n * Lists the defaults named `name` for `deploymentType`. Convex filters on\n * both, so the listing has at most one row and needs no pagination.\n */\nexport const listDefaults = (\n api: ManagementApiService,\n projectId: number,\n name: string,\n deploymentType: DeploymentType,\n) =>\n api\n .request(\"list default environment variables\", (client) =>\n client.GET(\"/projects/{project_id}/list_default_environment_variables\", {\n params: { path: { project_id: projectId }, query: { name, deploymentType } },\n }),\n )\n .pipe(Effect.map((body) => Schema.decodeUnknownSync(DefaultEnvironmentVariableList)(body)));\n\n/** One attempt to set one default, or to remove it when `value` is null. */\nconst writeDefault = (\n api: ManagementApiService,\n projectId: number,\n name: string,\n deploymentType: DeploymentType,\n value: string | Redacted.Redacted<string> | null,\n) =>\n api.requestVoid(\"update default environment variables\", (client) =>\n client.POST(\"/projects/{project_id}/update_default_environment_variables\", {\n params: { path: { project_id: projectId } },\n body: {\n changes: [\n {\n name,\n deploymentType,\n value: Redacted.isRedacted(value) ? Redacted.value(value) : value,\n },\n ],\n },\n }),\n );\n\n/**\n * Sets one default, or removes it when `value` is null. Convex answers 200\n * with an empty body, so this reads no response data. The call sets a value,\n * so it runs again after a write conflict or a 5xx answer, for example when\n * another resource writes a default of the same project at the same time.\n */\nexport const updateDefault = (\n api: ManagementApiService,\n projectId: number,\n name: string,\n deploymentType: DeploymentType,\n value: string | Redacted.Redacted<string> | null,\n) => retryIdempotentWrite(writeDefault(api, projectId, name, deploymentType, value));\n\n/** The default's identity, or undefined when the default or the project is absent. */\nconst readDefault = (\n api: ManagementApiService,\n projectId: number,\n name: string,\n deploymentType: DeploymentType,\n) =>\n // 404 ProjectNotFound: the project no longer exists, so neither does the default.\n absentAsUndefined(listDefaults(api, projectId, name, deploymentType)).pipe(\n Effect.map((list) =>\n list === undefined ? undefined : findDefault(list, projectId, name, deploymentType),\n ),\n );\n\n/**\n * GET /projects/{project_id}/list_default_environment_variables. Only the\n * fields the provider uses: the row's `value` is the secret in plain text.\n */\nexport const DefaultEnvironmentVariableList = Schema.Struct({\n items: Schema.Array(\n Schema.Struct({ name: Schema.String, deploymentTypes: Schema.Array(Schema.String) }),\n ),\n});\n\nexport interface DefaultEnvironmentVariableProps {\n /** Numeric project id, such as `project.projectId`. */\n readonly projectId: number;\n readonly name: string;\n readonly value: string | Redacted.Redacted<string>;\n /** Deployments of this type that Convex creates from now on get the variable. */\n readonly deploymentType: DeploymentType;\n}\n\nexport interface DefaultEnvironmentVariableAttributes {\n readonly projectId: number;\n readonly name: string;\n readonly deploymentType: DeploymentType;\n}\n\nexport type DefaultEnvironmentVariable = Resource<\n \"Convex.DefaultEnvironmentVariable\",\n DefaultEnvironmentVariableProps,\n DefaultEnvironmentVariableAttributes,\n never,\n Providers\n>;\nexport const DefaultEnvironmentVariable = Resource<DefaultEnvironmentVariable>(\n \"Convex.DefaultEnvironmentVariable\",\n);\n\n/** Fails with VariableIdentityChange when the props name another default than the one in state. */\nconst checkIdentity = (\n output: DefaultEnvironmentVariableAttributes,\n news: DefaultEnvironmentVariableProps,\n) => {\n const changed =\n output.projectId !== news.projectId\n ? ({\n field: \"projectId\",\n current: `${output.projectId}`,\n requested: `${news.projectId}`,\n } as const)\n : output.name !== news.name\n ? ({ field: \"name\", current: output.name, requested: news.name } as const)\n : output.deploymentType !== news.deploymentType\n ? ({\n field: \"deploymentType\",\n current: output.deploymentType,\n requested: news.deploymentType,\n } as const)\n : undefined;\n return changed === undefined\n ? Effect.void\n : Effect.fail(\n new VariableIdentityChange({ resourceType: DefaultEnvironmentVariable.Type, ...changed }),\n );\n};\n\nexport const DefaultEnvironmentVariableProvider = () =>\n Provider.effect(\n DefaultEnvironmentVariable,\n Effect.gen(function* () {\n const api = yield* ManagementApi;\n\n return {\n // Compares with the attributes: after a refused change, `olds` are\n // the refused props. Otherwise undefined: the engine updates when any\n // prop changed and compares a Redacted value by content.\n diff: Effect.fn(function* ({ news, output }) {\n if (!isResolved(news) || output === undefined) return undefined;\n yield* checkIdentity(output, news);\n return undefined;\n }),\n\n read: Effect.fn(function* ({ olds, output }) {\n const at = output ?? olds;\n const found = yield* readDefault(api, at.projectId, at.name, at.deploymentType);\n if (found === undefined) return undefined;\n // No state: the default belongs to someone else until the user passes --adopt.\n return output ?? Unowned(found);\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 const write = writeDefault(\n api,\n news.projectId,\n news.name,\n news.deploymentType,\n news.value,\n );\n if (output !== undefined || (yield* shouldAdopt(fqn))) {\n // In state, or adopted: the default is ours to set.\n yield* retryIdempotentWrite(write);\n } else {\n // Not in state: overwriting a default that exists loses its\n // value, so that needs adoption. Each attempt checks first, so a\n // retry after a write conflict never overwrites a default that\n // another writer created in the meantime.\n yield* retryIdempotentWrite(\n Effect.gen(function* () {\n const existing = yield* readDefault(\n api,\n news.projectId,\n news.name,\n news.deploymentType,\n );\n if (existing !== undefined) {\n return yield* new OwnedBySomeoneElse({\n message: `Project ${news.projectId} already has a ${news.deploymentType} default environment variable ${news.name}. Re-run with --adopt to take it over and overwrite its value, or use a different name.`,\n resourceType: DefaultEnvironmentVariable.Type,\n physicalName: news.name,\n });\n }\n yield* write;\n }),\n );\n }\n return {\n projectId: news.projectId,\n name: news.name,\n deploymentType: news.deploymentType,\n };\n }),\n\n delete: Effect.fn(function* ({ output }) {\n // Removing an absent default succeeds; 404 ProjectNotFound means the project is gone.\n yield* absentAsUndefined(\n updateDefault(api, output.projectId, output.name, output.deploymentType, null),\n );\n }),\n };\n }),\n );\n","// Convex.Deploy: pushes the functions in a `convex/` directory with\n// `npx convex deploy` and exposes the deployment URL for a frontend build.\n//\n// The deployment itself belongs to the project, so delete leaves the last\n// pushed functions running. The URL comes from the CLI's own output because\n// the deploy key, not this resource, decides which deployment receives the push.\nimport { stripVTControlCharacters } from \"node:util\";\nimport { Resource } from \"alchemy\";\nimport { CommandExecutor, type CommandRunProps } from \"alchemy/Command\";\nimport { hashDirectory, type MemoOptions } from \"alchemy/Command/Memo\";\nimport { havePropsChanged, isResolved } from \"alchemy/Diff\";\nimport * as Provider from \"alchemy/Provider\";\nimport * as Effect from \"effect/Effect\";\nimport type * as Redacted from \"effect/Redacted\";\nimport * as Schema from \"effect/Schema\";\nimport type { Providers } from \"./Providers.ts\";\n\nexport interface DeployProps extends Pick<CommandRunProps, \"cwd\" | \"env\" | \"timeout\"> {\n /**\n * Deploy key that selects the target deployment: a production, development,\n * project, or preview deploy key. The CLI receives it as `CONVEX_DEPLOY_KEY`,\n * and Alchemy removes its value from the logged output.\n */\n readonly deployKey: Redacted.Redacted<string>;\n /**\n * Preview deployment name for a preview deploy key. The CLI reuses an\n * existing preview deployment with this name.\n */\n readonly previewName?: string;\n /**\n * Like {@link previewName}, but the CLI deletes and recreates an existing\n * preview deployment with this name, so every run gets a new URL.\n */\n readonly previewCreate?: string;\n /**\n * Function to run after the push, such as `init:seed`. The CLI runs it only\n * when the push created a new preview deployment.\n */\n readonly previewRun?: string;\n /**\n * More `convex deploy` flags, added after the preview flags. Alchemy splits\n * the command on whitespace, so an argument cannot contain whitespace: use\n * `--typecheck=disable`, not `--typecheck disable` as one argument.\n */\n readonly extraArgs?: readonly string[];\n /**\n * Files hashed to skip an unchanged push. By default every non-gitignored\n * file under `cwd` and the nearest lockfile. Use\n * `{ include: [\"convex/**\"], lockfile: true }` to ignore frontend changes,\n * or `false` to push on every deploy. A preview deploy (`previewName` or\n * `previewCreate`) pushes on every deploy: Convex can delete an expired\n * preview deployment, and the hash cannot show that.\n * @default true\n */\n readonly memo?: MemoOptions | boolean;\n}\n\nexport interface DeployAttributes {\n /** Client URL of the deployment that received the push, such as `https://happy-otter-123.convex.cloud`. */\n readonly url: string;\n /** First label of the URL host, such as `happy-otter-123`. */\n readonly deploymentName: string;\n /** Hash of the memoized input files after the push, or `undefined` when `memo` is `false`. */\n readonly hash: string | undefined;\n}\n\nexport type Deploy = Resource<\"Convex.Deploy\", DeployProps, DeployAttributes, never, Providers>;\nexport const Deploy = Resource<Deploy>(\"Convex.Deploy\");\n\n/**\n * The CLI prints this line with `logFinishedStep` after the push succeeds, to\n * stderr (convex 1.45 `cli/lib/deploy2.js` for existing deployments,\n * `cli/deploy.js` for preview deployments). 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/** The `convex deploy` argv, starting with `npx`. */\nexport const deployArgs = (\n props: Pick<DeployProps, \"previewName\" | \"previewCreate\" | \"previewRun\" | \"extraArgs\">,\n): readonly string[] => [\n \"npx\",\n \"convex\",\n \"deploy\",\n ...(props.previewName === undefined ? [] : [\"--preview-name\", props.previewName]),\n ...(props.previewCreate === undefined ? [] : [\"--preview-create\", props.previewCreate]),\n ...(props.previewRun === undefined ? [] : [\"--preview-run\", props.previewRun]),\n ...(props.extraArgs ?? []),\n];\n\n/** Number of output lines quoted when the CLI exits 0 without the deployed line. */\nconst OUTPUT_TAIL_LINES = 20;\n\n/** A `convex deploy` argument contains whitespace, which Alchemy's command runner splits on. */\nexport class DeployArgumentError extends Schema.TaggedError<DeployArgumentError>()(\n \"DeployArgumentError\",\n { argument: Schema.String },\n) {\n override get message() {\n return `Convex.Deploy argument \"${this.argument}\" contains whitespace, and Alchemy splits the command on whitespace. Use the --flag=value form, such as --typecheck=disable, and names without spaces.`;\n }\n}\n\n/** `npx convex deploy` exited 0 but did not print the deployment URL. */\nexport class DeployOutputError extends Schema.TaggedError<DeployOutputError>()(\n \"DeployOutputError\",\n { outputTail: Schema.String },\n) {\n override get message() {\n return `npx convex deploy exited 0 but printed no \"Deployed Convex functions to <url>\" line, so Convex.Deploy has no deployment URL. Remove --dry-run from extraArgs if it is there, and read the CLI output. Last output:\\n${this.outputTail}`;\n }\n}\n\nexport const DeployProvider = () =>\n Provider.effect(\n Deploy,\n Effect.gen(function* () {\n const { run } = yield* CommandExecutor;\n\n const hashOf = (props: DeployProps) =>\n props.memo === false\n ? Effect.succeed(undefined)\n : hashDirectory({\n ...(props.cwd === undefined ? {} : { cwd: props.cwd }),\n memo: props.memo === true || props.memo === undefined ? {} : props.memo,\n });\n\n return {\n // No `stables`: the same deploy key can push to a different URL. A\n // project deploy key follows the project's default production\n // deployment, and a preview deployment can expire or be recreated\n // under the same name.\n diff: Effect.fn(function* ({ olds, news, output }) {\n if (!isResolved(news)) return undefined;\n // A preview deployment can expire. The same hash then hides a\n // missing deployment, so a preview always pushes. The CLI reuses\n // a live preview with the same name.\n const preview = news.previewName !== undefined || news.previewCreate !== undefined;\n if (\n preview ||\n output === undefined ||\n output.hash === undefined ||\n havePropsChanged(olds, news)\n ) {\n return { action: \"update\" } as const;\n }\n return { action: (yield* hashOf(news)) === output.hash ? \"noop\" : \"update\" } as const;\n }),\n\n reconcile: Effect.fn(function* ({ news, session }) {\n const args = deployArgs(news);\n const spaced = args.find((arg) => /\\s/.test(arg));\n if (spaced !== undefined) return yield* new DeployArgumentError({ argument: spaced });\n // A push is idempotent: the CLI uploads the full function set every time.\n const { stdout, stderr } = yield* run(\n {\n command: args.join(\" \"),\n ...(news.cwd === undefined ? {} : { cwd: news.cwd }),\n ...(news.timeout === undefined ? {} : { timeout: news.timeout }),\n env: { ...news.env, CONVEX_DEPLOY_KEY: news.deployKey },\n },\n session,\n );\n // `run` returns output with the deploy key already replaced.\n const output = `${stdout}\\n${stderr}`;\n const deployed = parseDeployOutput(output);\n if (deployed === undefined) {\n const outputTail = stripVTControlCharacters(output)\n .split(/\\r?\\n|\\r/)\n .filter((line) => line.trim() !== \"\")\n .slice(-OUTPUT_TAIL_LINES)\n .join(\"\\n\");\n return yield* new DeployOutputError({ outputTail });\n }\n return { ...deployed, hash: yield* hashOf(news) };\n }),\n\n // The deployment belongs to the project; its functions stay deployed.\n delete: () => Effect.void,\n };\n }),\n );\n","// Convex.DeployKey: a deploy key for one deployment, such as the key\n// `npx convex deploy` reads from CONVEX_DEPLOY_KEY.\n//\n// Convex returns the secret only once, from create_deploy_key, and the\n// response has no id. The listing shows each key with a numeric id and a\n// name: the requested name, or, when a listed key already has that name, the\n// requested name plus a suffix such as \" (870993b4-ffe6-4911-adbd-e29f7fd712f2)\".\n//\n// One resource must never revoke the key of another resource:\n// - The requested name is the `name` prop plus a hash of the resource's fqn\n// and instance id, so two resources with the same `name` request\n// different names.\n// - After the create, exactly one listed key must have the requested name.\n// Otherwise the create fails with a typed error that lists the keys. State\n// keeps that key's numeric id.\n// - Delete sends the secret as `id`, so it can revoke only the key that this\n// resource created. It never deletes by a listed name.\n// - With an OAuth token as the Management API credential, Convex returns\n// that token as the \"new\" key. The provider never stores, revokes, or\n// deletes such a key: the create fails with DeployKeyIsCredential.\n// - Delete runs only for a key with a `keyId` in state. A 0.1.x key, which\n// has none, stays in Convex with a warning.\n// A key cannot change after creation, so every property change is a replacement.\nimport { createHash } from \"node:crypto\";\nimport { Resource } from \"alchemy\";\nimport { havePropsChanged, isResolved } from \"alchemy/Diff\";\nimport * as Provider from \"alchemy/Provider\";\nimport * as Effect from \"effect/Effect\";\nimport * as Redacted from \"effect/Redacted\";\nimport * as Schema from \"effect/Schema\";\nimport type { components } from \"@convex-dev/platform/managementApi\";\nimport {\n absentAsUndefined,\n type ConvexApiError,\n ManagementApi,\n retryIdempotentWrite,\n} from \"./ManagementApi.ts\";\nimport type { Providers } from \"./Providers.ts\";\n\n/** Actions a deploy key can be limited to, from the generated schema. */\nexport type DeployKeyAction = NonNullable<\n components[\"schemas\"][\"PlatformCreateDeployKeyArgs\"][\"allowedActions\"]\n>[number];\n\n/**\n * True when `listedName` is how Convex lists a key created as `name`: the\n * requested name itself, or the requested name, a space, and one\n * parenthesized suffix without spaces. The suffix check keeps `my-key` from\n * matching a key created as `my-key (old)`.\n */\nconst isListedAs = (listedName: string, name: string) => {\n const prefix = `${name} (`;\n return (\n listedName === name ||\n (listedName.startsWith(prefix) && /^[^\\s()]+\\)$/.test(listedName.slice(prefix.length)))\n );\n};\n\n/**\n * True when the listing still has the key in state: by numeric id, or by\n * listed name for state written by 0.1.x, which has no id.\n */\nexport const isKeyListed = (\n entries: ReadonlyArray<typeof ListedKey.Type>,\n key: { readonly keyId: number | undefined; readonly uniqueName: string },\n): boolean =>\n entries.some((entry) =>\n key.keyId === undefined ? entry.name === key.uniqueName : entry.id === key.keyId,\n );\n\n/** The listed keys that Convex shows for a key created as `name`. */\nexport const keysListedAs = (\n entries: ReadonlyArray<typeof ListedKey.Type>,\n name: string,\n): ReadonlyArray<typeof ListedKey.Type> => entries.filter((entry) => isListedAs(entry.name, name));\n\n/**\n * The name that a resource instance requests: `name`, a dash, and the first\n * 12 hex characters of sha256(\"<fqn>:<instanceId>\"). Two resources, or the\n * old and the new generation of one replaced resource, never request the\n * same name. Pattern from Confect `packages/alchemy/src/internal/ResourceIdentity.ts`\n * (https://github.com/rjdellecese/confect, ISC license).\n */\nexport const requestedKeyName = (name: string, fqn: string, instanceId: string): string =>\n `${name}-${createHash(\"sha256\").update(`${fqn}:${instanceId}`).digest(\"hex\").slice(0, 12)}`;\n\n/** One row of list_deploy_keys and list_preview_deploy_keys. Only the fields the providers use. */\nexport const ListedKey = Schema.Struct({\n id: Schema.Number,\n name: Schema.String,\n});\n\n/** GET /deployments/{deployment_name}/list_deploy_keys */\nexport const DeployKeyList = Schema.Array(ListedKey);\n\n/** POST /deployments/{deployment_name}/create_deploy_key */\nexport const CreatedDeployKey = Schema.Struct({ deployKey: Schema.String });\n\n/**\n * A key cannot be tied to one resource: before the create, listed keys\n * already have the requested name, or after the create, not exactly one has it.\n */\nexport class DeployKeyRecoveryRequired extends Schema.TaggedError<DeployKeyRecoveryRequired>()(\n \"DeployKeyRecoveryRequired\",\n {\n /** Where the keys live, such as `deployment happy-otter-123` or `project 3145389`. */\n target: Schema.String,\n /** The requested name. */\n name: Schema.String,\n /** The listed keys with the requested name. */\n keys: Schema.Array(ListedKey),\n /** True when this run created a key before the listing check failed. */\n afterCreate: Schema.Boolean,\n },\n) {\n override get message() {\n const listed =\n this.keys.length === 0\n ? \"no key\"\n : this.keys.map((key) => `\"${key.name}\" (id ${key.id})`).join(\", \");\n return this.afterCreate\n ? `Convex created deploy key \"${this.name}\" on ${this.target}, but the listing shows ${listed} with that name, not exactly one, so this resource cannot track the new key. Alchemy does not revoke it. Delete the keys with that name in the Convex dashboard, then run the deploy again.`\n : `${this.target} already lists ${listed} with the name \"${this.name}\", but Alchemy state has no such key. An interrupted run probably created it, and its secret is lost. Delete these keys in the Convex dashboard, then run the deploy again.`;\n }\n}\n\n/**\n * Convex returned the Management API credential itself as the new key. This\n * happens with an OAuth token: Convex creates no key. A delete of the\n * returned secret would revoke the credential, so the resource does not keep it.\n */\nexport class DeployKeyIsCredential extends Schema.TaggedError<DeployKeyIsCredential>()(\n \"DeployKeyIsCredential\",\n { target: Schema.String, name: Schema.String },\n) {\n override get message() {\n return `Convex returned the Management API credential itself as deploy key \"${this.name}\" on ${this.target}. With an OAuth token, Convex creates no new key, and deleting the returned key would revoke the OAuth token. Alchemy does not keep it. Use a team access token in CONVEX_ACCESS_TOKEN, or the Convex CLI login.`;\n }\n}\n\n/**\n * Creates a key named `name` and ties it to the caller. Fails before the\n * create when keys with that name already exist. After the create, fails\n * when the secret is the Management API credential itself, or when the\n * listing does not show exactly one key with that name. It never revokes a\n * key: the returned secret can be a shared credential.\n */\nexport const createTrackedKey = (options: {\n readonly target: string;\n readonly name: string;\n readonly list: Effect.Effect<ReadonlyArray<typeof ListedKey.Type>, ConvexApiError>;\n readonly create: Effect.Effect<string, ConvexApiError>;\n readonly isCredentialToken: (secret: string) => Effect.Effect<boolean>;\n}) =>\n Effect.gen(function* () {\n const { target, name } = options;\n const existing = keysListedAs(yield* options.list, name);\n if (existing.length > 0) {\n return yield* new DeployKeyRecoveryRequired({\n target,\n name,\n keys: existing,\n afterCreate: false,\n });\n }\n const secret = yield* options.create;\n if (yield* options.isCredentialToken(secret)) {\n return yield* new DeployKeyIsCredential({ target, name });\n }\n const listed = keysListedAs(yield* options.list, name);\n const [only] = listed;\n if (only === undefined || listed.length !== 1) {\n return yield* new DeployKeyRecoveryRequired({\n target,\n name,\n keys: listed,\n afterCreate: true,\n });\n }\n return { keyId: only.id, uniqueName: only.name, secret: Redacted.make(secret) };\n });\n\n/**\n * The secret to send to a delete call, or undefined when a delete is not\n * safe. Only a key with a `keyId` in state is known to be a new key that\n * this resource owns: createTrackedKey found exactly one new listed key, and\n * the secret was not the credential. State from 0.1.x has no `keyId`, and its\n * secret can be an OAuth token that Convex returned as a key, so a delete\n * could revoke that OAuth token. Such a key stays, and a warning names it.\n */\nexport const secretToDelete = (\n key: {\n readonly keyId: number | undefined;\n readonly secret: Redacted.Redacted<string> | undefined;\n },\n label: string,\n) =>\n Effect.gen(function* () {\n if (key.keyId === undefined || !Redacted.isRedacted(key.secret)) {\n yield* Effect.logWarning(\n `${label} has no verified key id and secret in state (state from 0.1.x, for example), so Alchemy does not delete it. Delete it in the Convex dashboard.`,\n );\n return undefined;\n }\n return Redacted.value(key.secret);\n });\n\nexport interface DeployKeyProps {\n /** Deployment name, such as `project.prodDeploymentName`. */\n readonly deployment: string;\n /**\n * Key name. The provider requests this name, a dash, and a hash of the\n * resource identity, so two resources with one `name` get different keys.\n */\n readonly name: string;\n /** Limits the key to these actions. Convex grants every deployment action when omitted. */\n readonly allowedActions?: readonly DeployKeyAction[];\n}\n\nexport interface DeployKeyAttributes {\n /** The name Convex lists the key under, such as \"ci-3f2a1b0c9d8e\". */\n readonly uniqueName: string;\n /** Numeric id of the key in the listing. Undefined in state written by 0.1.x. */\n readonly keyId: number | undefined;\n readonly deployment: string;\n /** The secret, such as `prod:<deployment>|<token>`. Convex returns it only at creation. */\n readonly deployKey: Redacted.Redacted<string>;\n}\n\nexport type DeployKey = Resource<\n \"Convex.DeployKey\",\n DeployKeyProps,\n DeployKeyAttributes,\n never,\n Providers\n>;\nexport const DeployKey = Resource<DeployKey>(\"Convex.DeployKey\");\n\nexport const DeployKeyProvider = () =>\n Provider.effect(\n DeployKey,\n Effect.gen(function* () {\n const api = yield* ManagementApi;\n\n const listKeys = (deployment: string) =>\n api\n .request(\"list deploy keys\", (client) =>\n client.GET(\"/deployments/{deployment_name}/list_deploy_keys\", {\n params: { path: { deployment_name: deployment } },\n }),\n )\n .pipe(Effect.map((body) => Schema.decodeUnknownSync(DeployKeyList)(body)));\n\n /**\n * `id` is the secret: Convex accepts it, and it matches only the key\n * that this resource created. A second delete answers 404.\n */\n const deleteKey = (deployment: string, secret: string) =>\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: secret },\n }),\n ),\n );\n\n return {\n stables: [\"uniqueName\", \"deployment\"],\n\n diff: ({ olds, news, output }) => {\n if (!isResolved(news)) return Effect.succeed(undefined);\n // State written without the secret cannot hand a key to dependents,\n // and Convex cannot return it again, so only a new key helps.\n return Effect.succeed(\n (output !== undefined && output.deployKey === undefined) || havePropsChanged(olds, news)\n ? ({ action: \"replace\" } as const)\n : ({ action: \"noop\" } as const),\n );\n },\n\n read: Effect.fn(function* ({ output }) {\n // A key that is not in state has no known secret, so it is never adopted.\n if (output === undefined) return undefined;\n const entries = yield* absentAsUndefined(listKeys(output.deployment));\n return entries !== undefined && isKeyListed(entries, output) ? output : undefined;\n }),\n\n reconcile: Effect.fn(function* ({ fqn, instanceId, news, output }) {\n if (output !== undefined) {\n // The secret cannot be read back. A key that still exists keeps the one in state.\n if (isKeyListed(yield* listKeys(news.deployment), output)) return output;\n }\n const name = requestedKeyName(news.name, fqn, instanceId);\n const { keyId, uniqueName, secret } = yield* createTrackedKey({\n target: `deployment ${news.deployment}`,\n name,\n list: listKeys(news.deployment),\n create: api\n .request(\"create deploy key\", (client) =>\n client.POST(\"/deployments/{deployment_name}/create_deploy_key\", {\n params: { path: { deployment_name: news.deployment } },\n body: {\n name,\n ...(news.allowedActions === undefined\n ? {}\n : { allowedActions: [...news.allowedActions] }),\n },\n }),\n )\n .pipe(\n Effect.map((body) => Schema.decodeUnknownSync(CreatedDeployKey)(body).deployKey),\n ),\n isCredentialToken: api.isCredentialToken,\n });\n return { uniqueName, keyId, deployment: news.deployment, deployKey: secret };\n }),\n\n delete: Effect.fn(function* ({ output }) {\n // Only the secret names this key alone: 0.1.x state can hold the\n // listed name of another resource's key.\n const secret = yield* secretToDelete(\n { keyId: output.keyId, secret: output.deployKey },\n `Convex.DeployKey \"${output.uniqueName}\" on ${output.deployment}`,\n );\n if (secret === undefined) return;\n // 404 DeployKeyNotFound: an earlier attempt or someone else deleted it.\n yield* absentAsUndefined(deleteKey(output.deployment, secret));\n }),\n };\n }),\n );\n","// Convex.PreviewDeployKey: a project key that creates and deploys preview\n// deployments, such as the key CI passes to `npx convex deploy` for a branch.\n//\n// Convex returns the secret only once, from create_preview_deploy_key. The\n// identity rules are the same as for Convex.DeployKey: a requested name that\n// is unique for each resource instance, exactly one listed key after the\n// create with its numeric id in state, delete by the secret only, and never\n// keep a key that is the OAuth credential itself. A key cannot change after\n// creation, so every property change is a replacement.\nimport { Resource } from \"alchemy\";\nimport { havePropsChanged, isResolved } from \"alchemy/Diff\";\nimport * as Provider from \"alchemy/Provider\";\nimport * as Effect from \"effect/Effect\";\nimport * as Redacted from \"effect/Redacted\";\nimport * as Schema from \"effect/Schema\";\nimport {\n createTrackedKey,\n isKeyListed,\n ListedKey,\n requestedKeyName,\n secretToDelete,\n} from \"./DeployKey.ts\";\nimport { absentAsUndefined, ManagementApi, retryIdempotentWrite } from \"./ManagementApi.ts\";\nimport type { Providers } from \"./Providers.ts\";\n\n/** GET /projects/{project_id}/list_preview_deploy_keys */\nexport const PreviewDeployKeyList = Schema.Struct({ items: Schema.Array(ListedKey) });\n\n/** POST /projects/{project_id}/create_preview_deploy_key */\nexport const CreatedPreviewDeployKey = Schema.Struct({ previewDeployKey: Schema.String });\n\nexport interface PreviewDeployKeyProps {\n /** Numeric project id, such as `project.projectId`. */\n readonly projectId: number;\n /**\n * Key name. The provider requests this name, a dash, and a hash of the\n * resource identity, so two resources with one `name` get different keys.\n */\n readonly name: string;\n}\n\nexport interface PreviewDeployKeyAttributes {\n /** The name Convex lists the key under, such as \"ci-3f2a1b0c9d8e\". */\n readonly uniqueName: string;\n /** Numeric id of the key in the listing. Undefined in state written by 0.1.x. */\n readonly keyId: number | undefined;\n readonly projectId: number;\n /** The secret, such as `preview:<team>:<project>|<token>`. Convex returns it only at creation. */\n readonly previewDeployKey: Redacted.Redacted<string>;\n}\n\nexport type PreviewDeployKey = Resource<\n \"Convex.PreviewDeployKey\",\n PreviewDeployKeyProps,\n PreviewDeployKeyAttributes,\n never,\n Providers\n>;\nexport const PreviewDeployKey = Resource<PreviewDeployKey>(\"Convex.PreviewDeployKey\");\n\nexport const PreviewDeployKeyProvider = () =>\n Provider.effect(\n PreviewDeployKey,\n Effect.gen(function* () {\n const api = yield* ManagementApi;\n\n const listKeys = (projectId: number) =>\n api\n .request(\"list preview deploy keys\", (client) =>\n client.GET(\"/projects/{project_id}/list_preview_deploy_keys\", {\n params: { path: { project_id: projectId } },\n }),\n )\n .pipe(Effect.map((body) => Schema.decodeUnknownSync(PreviewDeployKeyList)(body).items));\n\n /**\n * `id` is the secret: Convex accepts it, and it matches only the key\n * that this resource created. A second delete answers 404.\n */\n const deleteKey = (projectId: number, secret: string) =>\n retryIdempotentWrite(\n api.requestVoid(\"delete preview deploy key\", (client) =>\n client.POST(\"/projects/{project_id}/delete_preview_deploy_key\", {\n params: { path: { project_id: projectId } },\n body: { id: secret },\n }),\n ),\n );\n\n return {\n stables: [\"uniqueName\", \"projectId\"],\n\n diff: ({ olds, news, output }) => {\n if (!isResolved(news)) return Effect.succeed(undefined);\n // State written without the secret cannot hand a key to dependents,\n // and Convex cannot return it again, so only a new key helps.\n return Effect.succeed(\n (output !== undefined && output.previewDeployKey === undefined) ||\n havePropsChanged(olds, news)\n ? ({ action: \"replace\" } as const)\n : ({ action: \"noop\" } as const),\n );\n },\n\n read: Effect.fn(function* ({ output }) {\n // A key that is not in state has no known secret, so it is never adopted.\n if (output === undefined) return undefined;\n const entries = yield* absentAsUndefined(listKeys(output.projectId));\n return entries !== undefined && isKeyListed(entries, output) ? output : undefined;\n }),\n\n reconcile: Effect.fn(function* ({ fqn, instanceId, news, output }) {\n if (output !== undefined) {\n // The secret cannot be read back. A key that still exists keeps the one in state.\n if (isKeyListed(yield* listKeys(news.projectId), output)) return output;\n }\n const name = requestedKeyName(news.name, fqn, instanceId);\n const { keyId, uniqueName, secret } = yield* createTrackedKey({\n target: `project ${news.projectId}`,\n name,\n list: listKeys(news.projectId),\n create: api\n .request(\"create preview deploy key\", (client) =>\n client.POST(\"/projects/{project_id}/create_preview_deploy_key\", {\n params: { path: { project_id: news.projectId } },\n body: { name },\n }),\n )\n .pipe(\n Effect.map(\n (body) =>\n Schema.decodeUnknownSync(CreatedPreviewDeployKey)(body).previewDeployKey,\n ),\n ),\n isCredentialToken: api.isCredentialToken,\n });\n return { uniqueName, keyId, projectId: news.projectId, previewDeployKey: secret };\n }),\n\n delete: Effect.fn(function* ({ output }) {\n // Only the secret names this key alone: 0.1.x state can hold the\n // listed name of another resource's key.\n const secret = yield* secretToDelete(\n { keyId: output.keyId, secret: output.previewDeployKey },\n `Convex.PreviewDeployKey \"${output.uniqueName}\" in project ${output.projectId}`,\n );\n if (secret === undefined) return;\n // 404 PreviewDeployKeyNotFound: an earlier attempt or someone else deleted it.\n yield* absentAsUndefined(deleteKey(output.projectId, secret));\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.\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 interface ProjectProps {\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\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/** 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 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 = (projectId: number, olds: ProjectProps, news: ProjectProps) => {\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\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 /**\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 // 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 olds.name === news.name ? undefined : ({ 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 with this name belongs to someone\n // else until the user passes --adopt. Convex has no ownership tags.\n const existing = 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 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) yield* checkCreateTimeProps(output.projectId, olds, news);\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 { CommandExecutorLive } from \"alchemy/Command\";\nimport * as Provider from \"alchemy/Provider\";\nimport * as Layer from \"effect/Layer\";\nimport { type Credentials, fromConfig } from \"./Credentials.ts\";\nimport {\n DefaultEnvironmentVariable,\n DefaultEnvironmentVariableProvider,\n} from \"./DefaultEnvironmentVariable.ts\";\nimport { Deploy, DeployProvider } from \"./Deploy.ts\";\nimport { DeployKey, DeployKeyProvider } from \"./DeployKey.ts\";\nimport { EnvironmentVariable, EnvironmentVariableProvider } from \"./EnvironmentVariable.ts\";\nimport { ManagementApiLive } from \"./ManagementApi.ts\";\nimport { PreviewDeployKey, PreviewDeployKeyProvider } from \"./PreviewDeployKey.ts\";\nimport { Project, ProjectProvider } from \"./Project.ts\";\n\nexport class Providers extends Provider.ProviderCollection<Providers>()(\"Convex\") {}\n\n/**\n * All Convex resource providers. Pass a credentials layer to override the\n * default lookup (`CONVEX_ACCESS_TOKEN`, then the Convex CLI login).\n */\nexport const providers = (credentials: Layer.Layer<Credentials> = fromConfig()) =>\n Layer.effect(\n Providers,\n Provider.collection([\n Project,\n DeployKey,\n PreviewDeployKey,\n EnvironmentVariable,\n DefaultEnvironmentVariable,\n Deploy,\n ]),\n ).pipe(\n Layer.provide(\n Layer.mergeAll(\n ProjectProvider(),\n DeployKeyProvider(),\n PreviewDeployKeyProvider(),\n EnvironmentVariableProvider(),\n DefaultEnvironmentVariableProvider(),\n DeployProvider(),\n ),\n ),\n Layer.provide(ManagementApiLive()),\n Layer.provide(credentials),\n // Convex.Deploy runs the Convex CLI through Alchemy's command executor.\n Layer.provide(CommandExecutorLive()),\n Layer.orDie,\n );\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["DeploymentRow","DeploymentRows","checkIdentity","checkIdentity"],"sources":["../src/Adoption.ts","../src/Credentials.ts","../src/ManagementApi.ts","../src/Deployment.ts","../src/EnvironmentVariable.ts","../src/Code.ts","../src/DefaultEnvironmentVariable.ts","../src/Deploy.ts","../src/DeployKey.ts","../src/PreviewDeployKey.ts","../src/Project.ts","../src/Providers.ts"],"sourcesContent":["// 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","// Convex control-plane credentials for the provider.\n//\n// The service value is an Effect so that building the providers layer never\n// touches the environment or the filesystem. The token is read on the first\n// lifecycle call, which keeps `alchemy plan` on an unrelated stack free of\n// Convex 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 Redacted from \"effect/Redacted\";\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 class Credentials extends Context.Service<Credentials, Effect.Effect<ResolvedCredentials>>()(\n \"@samebase/alchemy-convex/Credentials\",\n) {}\n\n/** Environment variable read by {@link fromConfig}. */\nexport const ACCESS_TOKEN_ENV = \"CONVEX_ACCESS_TOKEN\";\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\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: () => new CredentialsError({ reason: `no Convex CLI login at ${path}` }),\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\nexport class CredentialsError extends Schema.TaggedError<CredentialsError>()(\"CredentialsError\", {\n reason: Schema.String,\n}) {}\n\n/**\n * Default resolution: `CONVEX_ACCESS_TOKEN` from the stack ConfigProvider\n * (process env, `.env`, stack secrets), then the Convex CLI login on this\n * machine. CI sets the variable; a developer who ran `npx convex login` needs\n * nothing.\n */\nexport const fromConfig = (): Layer.Layer<Credentials> =>\n Layer.succeed(\n Credentials,\n Effect.cached(\n Config.Redacted(ACCESS_TOKEN_ENV).pipe(\n Effect.map((accessToken): ResolvedCredentials => ({ accessToken, source: \"env\" })),\n Effect.catch(() => readConvexCliLogin),\n Effect.orDie,\n ),\n ).pipe(Effect.flatten),\n );\n\n/** Explicit token, for tests or callers that already hold a value. */\nexport const fromToken = (accessToken: Redacted.Redacted<string>): Layer.Layer<Credentials> =>\n Layer.succeed(Credentials, Effect.succeed({ accessToken, source: \"explicit\" } as const));\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 } 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\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\nexport const ManagementApiLive = (): Layer.Layer<ManagementApi, never, Credentials> =>\n Layer.effect(\n ManagementApi,\n Effect.gen(function* () {\n const credentials = yield* Credentials;\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 return { request, requestVoid, deploymentRequest, resolveTeamId, isCredentialToken };\n }),\n );\n","// Convex.Deployment: one deployment of a Convex project, with the URLs that a\n// frontend or a Worker needs.\n//\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. 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).\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 { shouldAdopt } from \"./Adoption.ts\";\nimport { absentAsUndefined, ManagementApi, retryIdempotentWrite } from \"./ManagementApi.ts\";\nimport type { Providers } from \"./Providers.ts\";\n\nexport type DeploymentProps =\n | {\n /** Numeric project id, such as `project.projectId`. Cannot change. */\n readonly projectId: number;\n /** The project's default production deployment. Cannot change. */\n readonly type: \"prod\";\n }\n | {\n /** Numeric project id, such as `project.projectId`. Cannot change. */\n readonly projectId: number;\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 a\n * pull request or stage name. Unique in the project. Cannot change.\n */\n readonly name: string;\n };\n\nexport interface DeploymentAttributes {\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 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});\ntype DeploymentRow = typeof DeploymentRow.Type;\nconst DeploymentRows = Schema.Array(DeploymentRow);\n\nconst attributesOf = (\n row: DeploymentRow,\n type: DeploymentProps[\"type\"],\n previewName: string | undefined,\n): DeploymentAttributes => ({\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/** The `name` prop of the deployment in state: the dev reference or the preview name. */\nconst nameOf = (attributes: DeploymentAttributes) =>\n attributes.type === \"dev\"\n ? attributes.reference\n : attributes.type === \"preview\"\n ? attributes.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 row.\n */\nconst checkIdentity = (current: DeploymentAttributes, 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.projectId) {\n return change(\"projectId\", String(current.projectId), String(news.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\nexport const DeploymentProvider = () =>\n Provider.effect(\n Deployment,\n Effect.gen(function* () {\n const api = yield* ManagementApi;\n\n /** The live deployment, or undefined after a 404. GET /deployments/{name} answers no preview identifier. */\n const getByName = (name: string) =>\n absentAsUndefined(\n api.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 projectId: number,\n type: DeploymentProps[\"type\"],\n isDefault?: boolean,\n ) =>\n api\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 project's default production deployment, or undefined. */\n const production = (projectId: number) =>\n listDeployments(projectId, \"prod\", true).pipe(\n Effect.map((rows) => {\n const row = rows.find(\n (candidate) => candidate.deploymentType === \"prod\" && candidate.isDefault,\n );\n return row === undefined ? undefined : attributesOf(row, \"prod\", undefined);\n }),\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 = (projectId: number, type: \"dev\" | \"preview\", name: string) =>\n Effect.gen(function* () {\n const matches = (yield* listDeployments(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 props name, for a resource without state. */\n const lookup = (news: DeploymentProps) =>\n news.type === \"prod\"\n ? production(news.projectId)\n : findByName(news.projectId, news.type, news.name).pipe(\n Effect.map((row) =>\n row === undefined ? undefined : attributesOf(row, news.type, news.name),\n ),\n );\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 // `prod` follows the project's default production deployment,\n // which can change in Convex. Reconcile then returns the new one.\n if (news.type === \"prod\") {\n // A 404 for a deleted project plans an update; reconcile then reports it.\n const current = yield* absentAsUndefined(production(news.projectId));\n return current?.name === output.name ? undefined : ({ action: \"update\" } as const);\n }\n // A preview expires, and anyone can delete a deployment. Reconcile\n // then finds or creates it again, so the stack never hands out the\n // URL of a deployment that is gone.\n const live = yield* getByName(output.name);\n return live === undefined ? ({ action: \"update\" } as const) : undefined;\n }),\n\n read: Effect.fn(function* ({ olds, output }) {\n if (output?.type === \"prod\") {\n // 404: the project is gone, and so is its production deployment.\n return yield* absentAsUndefined(production(output.projectId));\n }\n if (output !== undefined) {\n const live = yield* getByName(output.name);\n return live === undefined\n ? undefined\n : attributesOf(live, output.type, output.previewName);\n }\n const found = yield* lookup(olds);\n if (found === undefined) return undefined;\n // The production deployment comes with the project, and this\n // resource never changes or deletes it, so it is ours to read.\n // A dev or preview deployment that is not in state is someone\n // else's until the user passes --adopt.\n return olds.type === \"prod\" ? found : Unowned(found);\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 if (news.type === \"prod\") {\n // Always the current default, also when another production\n // deployment became the default after the last deploy.\n const current = yield* production(news.projectId);\n if (current === undefined) {\n return yield* new ProductionDeploymentNotFound({ projectId: news.projectId });\n }\n return current;\n }\n if (output !== undefined) {\n const live = yield* getByName(output.name);\n if (live !== undefined) {\n if (live.deploymentType !== output.type) {\n return yield* new DeploymentIdentityChange({\n deployment: live.name,\n field: \"type\",\n current: live.deploymentType,\n requested: news.type,\n });\n }\n const current = attributesOf(live, output.type, output.previewName);\n // The live deployment can have moved to another project.\n yield* checkIdentity(current, news);\n return current;\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(news);\n if (existing !== undefined) {\n if (!(yield* shouldAdopt(fqn))) {\n return yield* new OwnedBySomeoneElse({\n message: `Project ${news.projectId} already has ${news.type} deployment ${existing.name} named \"${news.name}\". Re-run with --adopt to take it over, or use another name.`,\n resourceType: Deployment.Type,\n physicalName: existing.name,\n });\n }\n return existing;\n }\n const created = yield* api.request(\"create deployment\", (client) =>\n client.POST(\"/projects/{project_id}/create_deployment\", {\n params: { path: { project_id: news.projectId } },\n body: { type: news.type, reference: news.name },\n }),\n );\n return attributesOf(\n Schema.decodeUnknownSync(DeploymentRow)(created),\n news.type,\n news.name,\n );\n }),\n\n // Runs only with RemovalPolicy.destroy(): the default policy is `retain`.\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 // 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 live = yield* getByName(output.name);\n // 404: an earlier attempt, the expiry, or someone else deleted it.\n if (live === undefined) return;\n if (live.deploymentType === \"prod\") return yield* keep;\n yield* absentAsUndefined(\n retryIdempotentWrite(\n api.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.EnvironmentVariable: one environment variable on one deployment.\n//\n// Environment variables live on the deployment API\n// (https://<deployment>.convex.cloud/api/v1), which authenticates with a\n// deploy key, not with the Management API token. Setting a variable and\n// removing it are the same call: update_environment_variables with\n// `value: null` removes the variable.\n//\n// A variable that exists but is not in state belongs to someone else: its\n// old value is lost when this resource writes it. Alchemy takes it over only\n// with --adopt.\n//\n// The variable's name and deployment cannot change. A change fails with\n// VariableIdentityChange: use a new resource with a new logical id. A\n// replacement could let the engine delete an old generation that names the\n// live variable, and a rename in place needs a cleanup that can fail and\n// leave a variable or a revoked key behind.\n//\n// The attributes keep the deploy key of the variable's deployment. After a\n// refused change, the props can name another deployment and its key, so\n// read and delete use the attributes, not the props.\nimport { createDeploymentClient } from \"@convex-dev/platform\";\nimport { Resource } from \"alchemy\";\nimport { isResolved } from \"alchemy/Diff\";\nimport { OwnedBySomeoneElse, Unowned } from \"alchemy/AdoptPolicy\";\nimport * as Provider from \"alchemy/Provider\";\nimport * as Effect from \"effect/Effect\";\nimport * as Redacted from \"effect/Redacted\";\nimport * as Schema from \"effect/Schema\";\nimport { shouldAdopt } from \"./Adoption.ts\";\nimport {\n absentAsUndefined,\n ManagementApi,\n type ManagementApiService,\n retryIdempotentWrite,\n settle,\n settleVoid,\n} from \"./ManagementApi.ts\";\nimport type { Providers } from \"./Providers.ts\";\n\n/**\n * The variable's identity when the listing has `name`. Own keys only: a\n * valid variable name such as `toString` must not match the object prototype.\n */\nexport const findVariable = (\n list: typeof EnvironmentVariableList.Type,\n deployment: string,\n name: string,\n): { readonly deployment: string; readonly name: string } | undefined =>\n Object.hasOwn(list.environmentVariables, name) ? { deployment, name } : undefined;\n\n/**\n * One attempt to set variables, or to remove those whose `value` is null, in\n * one call. The deployment answers 200 with an empty body, so this reads no\n * response data.\n */\nexport const writeVariables = (\n deployment: string,\n deployKey: Redacted.Redacted<string>,\n changes: ReadonlyArray<{\n readonly name: string;\n readonly value: string | Redacted.Redacted<string> | null;\n }>,\n) =>\n settleVoid(\"update environment variables\", () =>\n createDeploymentClient(deployment, Redacted.value(deployKey)).POST(\n \"/update_environment_variables\",\n {\n body: {\n changes: changes.map(({ name, value }) => ({\n name,\n value: Redacted.isRedacted(value) ? Redacted.value(value) : value,\n })),\n },\n },\n ),\n );\n\n/** One attempt to set one variable, or to remove it when `value` is null. */\nconst writeVariable = (\n deployment: string,\n deployKey: Redacted.Redacted<string>,\n name: string,\n value: string | Redacted.Redacted<string> | null,\n) => writeVariables(deployment, deployKey, [{ name, value }]);\n\n/**\n * Sets one variable, or removes it when `value` is null. The call sets a\n * value, so it runs again after a write conflict or a 5xx answer, for example\n * when another resource writes a variable of the same deployment at the same\n * time. Use it only where the variable is already ours to set.\n */\nexport const updateVariable = (\n deployment: string,\n deployKey: Redacted.Redacted<string>,\n name: string,\n value: string | Redacted.Redacted<string> | null,\n) => retryIdempotentWrite(writeVariable(deployment, deployKey, name, value));\n\n/** GET https://<deployment>.convex.cloud/api/v1/list_environment_variables */\nexport const EnvironmentVariableList = Schema.Struct({\n environmentVariables: Schema.Record(Schema.String, Schema.String),\n});\n\n/** Every variable of the deployment with its value. Fails with a 404 when the deployment is gone. */\nexport const listVariables = (deployment: string, deployKey: Redacted.Redacted<string>) =>\n settle(\"list environment variables\", () =>\n createDeploymentClient(deployment, Redacted.value(deployKey)).GET(\n \"/list_environment_variables\",\n ),\n ).pipe(\n Effect.map(\n (body) => Schema.decodeUnknownSync(EnvironmentVariableList)(body).environmentVariables,\n ),\n );\n\n/** The variable's identity, or undefined when the variable or the deployment is absent. */\nconst readVariable = (\n api: ManagementApiService,\n deployment: string,\n deployKey: Redacted.Redacted<string>,\n name: string,\n) =>\n // 404: the deployment no longer exists, so neither does the variable.\n absentAsUndefined(\n api.deploymentRequest(\"list environment variables\", deployment, deployKey, (client) =>\n client.GET(\"/list_environment_variables\"),\n ),\n ).pipe(\n Effect.map((body) =>\n body === undefined\n ? undefined\n : findVariable(Schema.decodeUnknownSync(EnvironmentVariableList)(body), deployment, name),\n ),\n );\n\nexport interface EnvironmentVariableProps {\n /** Deployment name, or its URL for deployments outside US East. */\n readonly deployment: string;\n /** Deploy key for `deployment`, such as `deployKey.deployKey`. */\n readonly deployKey: Redacted.Redacted<string>;\n readonly name: string;\n readonly value: string | Redacted.Redacted<string>;\n}\n\nexport interface EnvironmentVariableAttributes {\n readonly deployment: string;\n readonly name: string;\n /** Deploy key for `deployment`, for read and delete. Undefined in state from 0.1.x. */\n readonly deployKey: Redacted.Redacted<string> | undefined;\n}\n\nexport type EnvironmentVariable = Resource<\n \"Convex.EnvironmentVariable\",\n EnvironmentVariableProps,\n EnvironmentVariableAttributes,\n never,\n Providers\n>;\nexport const EnvironmentVariable = Resource<EnvironmentVariable>(\"Convex.EnvironmentVariable\");\n\n/**\n * The props name another variable than the one in state. Used by\n * Convex.EnvironmentVariable and Convex.DefaultEnvironmentVariable.\n */\nexport class VariableIdentityChange extends Schema.TaggedError<VariableIdentityChange>()(\n \"VariableIdentityChange\",\n {\n resourceType: Schema.String,\n field: Schema.Literals([\"name\", \"deployment\", \"projectId\", \"deploymentType\"]),\n current: Schema.String,\n requested: Schema.String,\n },\n) {\n override get message() {\n return `${this.resourceType} cannot change its ${this.field} from ${this.current} to ${this.requested}. Create a new resource with a new logical id for the new name or deployment, and remove this one.`;\n }\n}\n\n/** Fails with {@link VariableIdentityChange} when the props name another variable than the one in state. */\nconst checkIdentity = (output: EnvironmentVariableAttributes, news: EnvironmentVariableProps) =>\n output.name !== news.name\n ? Effect.fail(\n new VariableIdentityChange({\n resourceType: EnvironmentVariable.Type,\n field: \"name\",\n current: output.name,\n requested: news.name,\n }),\n )\n : output.deployment !== news.deployment\n ? Effect.fail(\n new VariableIdentityChange({\n resourceType: EnvironmentVariable.Type,\n field: \"deployment\",\n current: output.deployment,\n requested: news.deployment,\n }),\n )\n : Effect.void;\n\n/**\n * The deploy key for the variable in state: from the attributes, or, for\n * state from 0.1.x, from props that name the same deployment.\n */\nconst keyOf = (\n output: EnvironmentVariableAttributes,\n olds: EnvironmentVariableProps | undefined,\n): Redacted.Redacted<string> | undefined =>\n output.deployKey ?? (olds?.deployment === output.deployment ? olds.deployKey : undefined);\n\nexport const EnvironmentVariableProvider = () =>\n Provider.effect(\n EnvironmentVariable,\n Effect.gen(function* () {\n const api = yield* ManagementApi;\n\n return {\n // Compares with the attributes: after a refused change, `olds` are\n // the refused props. Otherwise undefined: the engine updates when any\n // prop changed and compares Redacted values, such as the value and\n // the deploy key, by content.\n diff: Effect.fn(function* ({ news, output }) {\n if (!isResolved(news) || output === undefined) return undefined;\n yield* checkIdentity(output, news);\n return undefined;\n }),\n\n read: Effect.fn(function* ({ olds, output }) {\n if (output !== undefined) {\n const key = keyOf(output, olds);\n // Without a key for the deployment in state, keep the state as it is.\n if (key === undefined) return output;\n const found = yield* readVariable(api, output.deployment, key, output.name);\n return found === undefined ? undefined : output;\n }\n const found = yield* readVariable(api, olds.deployment, olds.deployKey, olds.name);\n // No state: the variable belongs to someone else until the user passes --adopt.\n return found === undefined ? undefined : Unowned({ ...found, deployKey: olds.deployKey });\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 const write = writeVariable(news.deployment, news.deployKey, news.name, news.value);\n if (output !== undefined || (yield* shouldAdopt(fqn))) {\n // In state, or adopted: the variable is ours to set.\n yield* retryIdempotentWrite(write);\n } else {\n // Not in state: overwriting a variable that exists loses its\n // value, so that needs adoption. Each attempt checks first, so a\n // retry after a write conflict never overwrites a variable that\n // another writer created in the meantime.\n yield* retryIdempotentWrite(\n Effect.gen(function* () {\n const existing = yield* readVariable(\n api,\n news.deployment,\n news.deployKey,\n news.name,\n );\n if (existing !== undefined) {\n return yield* new OwnedBySomeoneElse({\n message: `Environment variable ${news.name} already exists on deployment ${news.deployment}. Re-run with --adopt to take it over and overwrite its value, or use a different name.`,\n resourceType: EnvironmentVariable.Type,\n physicalName: news.name,\n });\n }\n yield* write;\n }),\n );\n }\n return { deployment: news.deployment, name: news.name, deployKey: news.deployKey };\n }),\n\n delete: Effect.fn(function* ({ olds, output }) {\n const key = keyOf(output, olds);\n if (key === undefined) {\n yield* Effect.logWarning(\n `Environment variable ${output.name} on deployment ${output.deployment} stays: Alchemy has no deploy key for that deployment. Remove it in the Convex dashboard.`,\n );\n return;\n }\n // Removing an absent variable succeeds; 404 means the deployment is gone.\n yield* absentAsUndefined(updateVariable(output.deployment, key, output.name, null));\n }),\n };\n }),\n );\n","// Convex.Code: pushes the functions of a Convex app to one deployment with\n// the Convex CLI that the app has installed, and exposes the URLs that a\n// frontend or a Worker needs.\n//\n// - Every apply pushes. The resource does not hash the sources: a preview\n// deployment can expire, a push from outside Alchemy can change the\n// deployment, and a hash of the app directory misses changes in workspace\n// packages. The Convex CLI uploads only the modules that changed.\n// - The CLI is the `convex` package that `cwd` resolves, run with the Node.js\n// that runs Alchemy. Nothing is downloaded. The `command` prop replaces it.\n// - The deploy key reaches the CLI only through an env file (`--env-file`)\n// with mode 0600 in a new temporary directory. The directory is removed\n// after the run, on success, on failure, and on interruption. It is also the\n// home directory of the CLI, so the CLI cannot read the Convex login of this\n// machine and pushes with the deploy key only. Variables named `CONVEX_*`\n// 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 deploy key removed.\n// - Before the push, the key must fit the deployment: a deploy key of that\n// deployment, or a preview deploy key for a Convex.Deployment preview. After\n// the push, the deployment that the CLI names must be that deployment.\n// - `env` variables are set on the deployment before the push with the deploy\n// key, through the deployment API like Convex.EnvironmentVariable. A\n// variable that exists with another value and that this resource did not\n// set is someone else's: it is overwritten only with --adopt. A name that\n// leaves `env` is removed from the deployment.\n// - Delete does nothing. The functions and the variables stay on the\n// deployment: the deployed code can need them.\n//\n// Patterns from Confect `packages/alchemy/src/Code.ts`,\n// `internal/CodeDeployment.ts`, and `internal/CommandRunner.ts`\n// (https://github.com/rjdellecese/confect, ISC license).\nimport { mkdtemp, readFile, rm, writeFile } from \"node:fs/promises\";\nimport { createRequire } from \"node:module\";\nimport { tmpdir } from \"node:os\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { stripVTControlCharacters } from \"node:util\";\nimport { Resource } from \"alchemy\";\nimport { OwnedBySomeoneElse } from \"alchemy/AdoptPolicy\";\nimport * as Provider from \"alchemy/Provider\";\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 { shouldAdopt } from \"./Adoption.ts\";\nimport { type DeploymentAttributes, siteUrlOf } from \"./Deployment.ts\";\nimport { listVariables, writeVariables } from \"./EnvironmentVariable.ts\";\nimport { retryIdempotentWrite } from \"./ManagementApi.ts\";\nimport type { Providers } from \"./Providers.ts\";\n\n/** The attributes of a Convex.Deployment that a push needs. Pass the resource itself. */\nexport type CodeDeployment = Pick<DeploymentAttributes, \"name\" | \"type\" | \"url\" | \"previewName\">;\n\nexport interface CodeProps {\n /**\n * The deployment that receives the push: a Convex.Deployment resource, or a\n * deployment name such as `happy-animal-123`. A preview deploy key needs the\n * resource. For `env` on a deployment outside US East, pass the resource.\n */\n readonly deployment: string | CodeDeployment;\n /**\n * A deploy key of `deployment` (Convex.DeployKey), or, for a preview\n * deployment, a preview deploy key of its project (Convex.PreviewDeployKey).\n */\n readonly deployKey: Redacted.Redacted<string>;\n /** The Convex app directory: the one with `convex/` and the `convex` package installed. */\n readonly cwd: string;\n /**\n * The program and first arguments that run the Convex CLI, such as\n * `[\"pnpm\", \"exec\", \"convex\"]`. Code adds `deploy` and its flags. By\n * default, the `convex` package that `cwd` resolves, run with this Node.js.\n */\n readonly command?: readonly [string, ...string[]];\n /** Environment variables to set on the deployment before the push. Needs a deploy key of the deployment. */\n readonly env?: Readonly<Record<string, string | Redacted.Redacted<string>>>;\n /** `convex deploy --typecheck`. The CLI default is `try`. */\n readonly typecheck?: \"enable\" | \"try\" | \"disable\";\n /** `convex deploy --codegen`. The CLI default is `enable`. */\n readonly codegen?: \"enable\" | \"disable\";\n}\n\nexport interface CodeAttributes {\n /** The deployment that received the push, such as `happy-animal-123`. */\n readonly deploymentName: string;\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 /** When the push finished, in milliseconds since the Unix epoch. */\n readonly deployedAt: number;\n /** The names of the `env` variables that this resource set on the deployment, sorted. */\n readonly envNames: readonly string[];\n}\n\nexport type Code = Resource<\"Convex.Code\", CodeProps, CodeAttributes, never, Providers>;\nexport const Code = Resource<Code>(\"Convex.Code\");\n\n/**\n * The CLI prints this line with `logFinishedStep` after the push succeeds, to\n * stderr (convex 1.46 `cli/lib/deploy2.js` for existing deployments,\n * `cli/deploy.js` for preview deployments). 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/**\n * What a deploy key targets, from its prefix: `<type>:<deployment>|<secret>`\n * (or `<deployment>|<secret>` in old keys) for one deployment,\n * `preview:<team>:<project>|<secret>` for preview deployments of a project,\n * `project:<team>:<project>|<secret>` for the project's production\n * deployment. 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\" | \"project\" | \"unknown\" } => {\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: \"unknown\" };\n const parts = key.slice(0, bar).split(\":\");\n const [first, second] = parts;\n if (parts.length === 3 && first === \"preview\") return { kind: \"preview\" };\n if (parts.length === 3 && first === \"project\") return { kind: \"project\" };\n if (parts.length === 2 && second) return { kind: \"deployment\", deployment: second };\n if (parts.length === 1 && first) return { kind: \"deployment\", deployment: first };\n return { kind: \"unknown\" };\n};\n\n/** The deploy key does not fit the deployment. Checked before the push. */\nexport class DeployKeyMismatch extends Schema.TaggedError<DeployKeyMismatch>()(\n \"DeployKeyMismatch\",\n {\n /** The deployment that should receive the push. */\n deployment: Schema.String,\n /** What the key targets. */\n key: Schema.Literals([\"deployment\", \"preview\", \"project\", \"unknown\"]),\n /** For a deployment key: the deployment in the key prefix. Never the secret. */\n keyDeployment: Schema.UndefinedOr(Schema.String),\n },\n) {\n override get message() {\n switch (this.key) {\n case \"deployment\":\n return `The deploy key is for deployment ${this.keyDeployment}, not for ${this.deployment}. Pass a deploy key of ${this.deployment}, such as Convex.DeployKey with deployment ${this.deployment}.`;\n case \"preview\":\n return `A preview deploy key pushes to a preview deployment by its preview name, and ${this.deployment} is not a Convex.Deployment of type \"preview\". Pass the Convex.Deployment preview resource as deployment, or a deploy key of ${this.deployment}.`;\n case \"project\":\n return `Convex.Code does not take a project deploy key: it cannot check before the push that the key targets ${this.deployment}. Pass a deploy key of ${this.deployment} (Convex.DeployKey).`;\n case \"unknown\":\n return `deployKey is not a Convex deploy key (\"<type>:<deployment>|<secret>\" or \"preview:<team>:<project>|<secret>\"). Pass Convex.DeployKey(...).deployKey or Convex.PreviewDeployKey(...).previewDeployKey.`;\n }\n }\n}\n\n/** `env` needs the deployment API, which 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.Code cannot set or remove env variables on ${this.deployment} with a preview deploy key: the deployment API takes only a deploy key of the deployment. Pass a Convex.DeployKey of ${this.deployment}, or use Convex.DefaultEnvironmentVariable with deploymentType \"preview\" for values that every new preview deployment gets.`;\n }\n}\n\n/** No `convex` package resolves from `cwd`. */\nexport class ConvexCliNotFound extends Schema.TaggedError<ConvexCliNotFound>()(\n \"ConvexCliNotFound\",\n { cwd: Schema.String },\n) {\n override get message() {\n return `Convex.Code found no installed convex package from ${this.cwd}, and it does not download one. Install convex in the app (npm install convex), set cwd to the app directory, or set the command prop.`;\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, so Convex.Code has no deployment URL. 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 in the props. 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.Code expected ${this.expected}. With a preview deploy key, this happens when the key belongs to another project, or when the preview deployment ${this.expected} expired during the deploy and the CLI created ${this.actual} for the same preview name. Check the key. After an expiry, run the deploy again with --adopt, so that Convex.Deployment takes over ${this.actual}.`;\n }\n}\n\n/**\n * Checks that the key fits the deployment, and returns the preview name for\n * `--preview-name` when the key is a preview deploy key.\n */\nconst previewNameFor = (\n target: {\n readonly name: string;\n readonly type: CodeDeployment[\"type\"] | undefined;\n readonly previewName: string | undefined;\n },\n keyTarget: ReturnType<typeof keyTargetOf>,\n changesEnvironment: boolean,\n): Effect.Effect<string | undefined, DeployKeyMismatch | EnvironmentNeedsDeployKey> => {\n const mismatch = new DeployKeyMismatch({\n deployment: target.name,\n key: keyTarget.kind,\n keyDeployment: keyTarget.kind === \"deployment\" ? keyTarget.deployment : undefined,\n });\n switch (keyTarget.kind) {\n case \"deployment\":\n return keyTarget.deployment === target.name\n ? Effect.succeed(undefined)\n : Effect.fail(mismatch);\n case \"preview\":\n if (target.type !== \"preview\" || target.previewName === undefined) {\n return Effect.fail(mismatch);\n }\n return changesEnvironment\n ? Effect.fail(new EnvironmentNeedsDeployKey({ deployment: target.name }))\n : Effect.succeed(target.previewName);\n case \"project\":\n case \"unknown\":\n return Effect.fail(mismatch);\n default:\n return keyTarget satisfies never;\n }\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 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 * 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/**\n * The environment of the CLI: this process's variables without `CONVEX_*`,\n * with `home` as the home directory.\n */\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\nexport const CodeProvider = () =>\n Provider.effect(\n Code,\n Effect.gen(function* () {\n const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;\n\n /** Runs the CLI with piped output. Interruption stops its process group. */\n const run = (argv: readonly [string, ...string[]], cwd: string, home: string) =>\n Effect.gen(function* () {\n const [command, ...args] = argv;\n const child = yield* spawner.spawn(\n ChildProcess.make(command, args, {\n cwd,\n env: cliEnvironment(home),\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\n return {\n // Every apply pushes: see the top of this file.\n diff: () => Effect.succeed({ action: \"update\" } as const),\n\n reconcile: Effect.fn(function* ({ fqn, news, output }) {\n const target =\n typeof news.deployment === \"string\"\n ? {\n name: news.deployment,\n address: news.deployment,\n type: undefined,\n previewName: undefined,\n }\n : { ...news.deployment, address: news.deployment.url };\n const key = Redacted.value(news.deployKey);\n const secrets = [key, key.slice(key.indexOf(\"|\") + 1)].filter(\n (secret) => secret.length >= 8,\n );\n const env = Object.entries(news.env ?? {}).sort(([a], [b]) => (a < b ? -1 : 1));\n // Names set on another deployment stay there: this push does not own them.\n const previous =\n output !== undefined && output.deploymentName === target.name ? output.envNames : [];\n const removed = previous.filter((name) => !env.some(([envName]) => envName === name));\n\n // 1. The key must fit the deployment. No side effect before this.\n const previewName = yield* previewNameFor(\n target,\n keyTargetOf(key),\n env.length > 0 || removed.length > 0,\n );\n\n // 2. The CLI must exist before any variable changes.\n const cwd = resolve(news.cwd);\n const program = news.command ?? (yield* installedCli(cwd));\n\n // 3. Variables before the push, so the push sees them. Each\n // attempt checks first, so a retry after a write conflict never\n // overwrites a value that another writer set in the meantime.\n if (env.length > 0 || removed.length > 0) {\n const adopt = yield* shouldAdopt(fqn);\n const fresh = env.filter(([name]) => !previous.includes(name));\n yield* retryIdempotentWrite(\n Effect.gen(function* () {\n if (fresh.length > 0 && !adopt) {\n const current = yield* listVariables(target.address, news.deployKey);\n // The same value loses nothing, such as a value that an\n // earlier run set before its push failed.\n const taken = fresh\n .filter(\n ([name, value]) =>\n Object.hasOwn(current, name) &&\n current[name] !==\n (Redacted.isRedacted(value) ? Redacted.value(value) : value),\n )\n .map(([name]) => name);\n if (taken.length > 0) {\n return yield* new OwnedBySomeoneElse({\n message: `Environment variables ${taken.join(\", \")} already exist on deployment ${target.name} with other values. Re-run with --adopt to take them over and overwrite them, or remove them from env.`,\n resourceType: Code.Type,\n physicalName: target.name,\n });\n }\n }\n yield* writeVariables(target.address, news.deployKey, [\n ...env.map(([name, value]) => ({ name, value })),\n ...removed.map((name) => ({ name, value: null })),\n ]);\n }),\n );\n }\n\n // 4. The push.\n const args = [\n \"deploy\",\n ...(previewName === undefined ? [] : [\"--preview-name\", previewName]),\n ...(news.typecheck === undefined ? [] : [`--typecheck=${news.typecheck}`]),\n ...(news.codegen === undefined ? [] : [`--codegen=${news.codegen}`]),\n ];\n const result = yield* withKeyFile(key, ({ envFile, home }) =>\n run([...program, ...args, \"--env-file\", envFile], cwd, home),\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 !== target.name) {\n return yield* new PushTargetMismatch({\n expected: target.name,\n actual: deployed.deploymentName,\n });\n }\n return {\n deploymentName: deployed.deploymentName,\n url: deployed.url,\n siteUrl: siteUrlOf(deployed.url),\n deployedAt: yield* Clock.currentTimeMillis,\n envNames: env.map(([name]) => name),\n };\n }),\n\n // The functions and the variables stay: the deployment runs them.\n delete: () => Effect.void,\n };\n }),\n );\n","// Convex.DefaultEnvironmentVariable: a project default environment variable\n// for one deployment type. Convex sets it on each new deployment of that type,\n// such as auth keys that every pull request preview deployment needs.\n//\n// Defaults live on the Management API and authenticate with the team\n// credential, not with a deploy key. Setting a default and removing it are the\n// same call: update_default_environment_variables with `value: null` removes\n// the default, and removing an absent default also answers 200.\n//\n// A default that exists but is not in state belongs to someone else: its old\n// value is lost when this resource writes it. Alchemy takes it over only with\n// --adopt.\n//\n// The default's project, name, and deployment type cannot change. A change\n// fails with VariableIdentityChange: use a new resource with a new logical\n// id. Read and delete use the identity in the attributes: after a refused\n// change, the props name the refused one.\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 Redacted from \"effect/Redacted\";\nimport * as Schema from \"effect/Schema\";\nimport type { components } from \"@convex-dev/platform/managementApi\";\nimport { shouldAdopt } from \"./Adoption.ts\";\nimport { VariableIdentityChange } from \"./EnvironmentVariable.ts\";\nimport {\n absentAsUndefined,\n ManagementApi,\n type ManagementApiService,\n retryIdempotentWrite,\n} from \"./ManagementApi.ts\";\nimport type { Providers } from \"./Providers.ts\";\n\n/** Deployment types a default can target, from the generated schema. */\nexport type DeploymentType = components[\"schemas\"][\"DeploymentType\"];\n\n/**\n * Attributes when the listing has `name` for `deploymentType`. An unfiltered\n * listing merges the deployment types that share one value into one row, so\n * the match checks membership in `deploymentTypes`.\n */\nexport const findDefault = (\n list: typeof DefaultEnvironmentVariableList.Type,\n projectId: number,\n name: string,\n deploymentType: DeploymentType,\n): DefaultEnvironmentVariableAttributes | undefined =>\n list.items.some((item) => item.name === name && item.deploymentTypes.includes(deploymentType))\n ? { projectId, name, deploymentType }\n : undefined;\n\n/**\n * Lists the defaults named `name` for `deploymentType`. Convex filters on\n * both, so the listing has at most one row and needs no pagination.\n */\nexport const listDefaults = (\n api: ManagementApiService,\n projectId: number,\n name: string,\n deploymentType: DeploymentType,\n) =>\n api\n .request(\"list default environment variables\", (client) =>\n client.GET(\"/projects/{project_id}/list_default_environment_variables\", {\n params: { path: { project_id: projectId }, query: { name, deploymentType } },\n }),\n )\n .pipe(Effect.map((body) => Schema.decodeUnknownSync(DefaultEnvironmentVariableList)(body)));\n\n/** One attempt to set one default, or to remove it when `value` is null. */\nconst writeDefault = (\n api: ManagementApiService,\n projectId: number,\n name: string,\n deploymentType: DeploymentType,\n value: string | Redacted.Redacted<string> | null,\n) =>\n api.requestVoid(\"update default environment variables\", (client) =>\n client.POST(\"/projects/{project_id}/update_default_environment_variables\", {\n params: { path: { project_id: projectId } },\n body: {\n changes: [\n {\n name,\n deploymentType,\n value: Redacted.isRedacted(value) ? Redacted.value(value) : value,\n },\n ],\n },\n }),\n );\n\n/**\n * Sets one default, or removes it when `value` is null. Convex answers 200\n * with an empty body, so this reads no response data. The call sets a value,\n * so it runs again after a write conflict or a 5xx answer, for example when\n * another resource writes a default of the same project at the same time.\n */\nexport const updateDefault = (\n api: ManagementApiService,\n projectId: number,\n name: string,\n deploymentType: DeploymentType,\n value: string | Redacted.Redacted<string> | null,\n) => retryIdempotentWrite(writeDefault(api, projectId, name, deploymentType, value));\n\n/** The default's identity, or undefined when the default or the project is absent. */\nconst readDefault = (\n api: ManagementApiService,\n projectId: number,\n name: string,\n deploymentType: DeploymentType,\n) =>\n // 404 ProjectNotFound: the project no longer exists, so neither does the default.\n absentAsUndefined(listDefaults(api, projectId, name, deploymentType)).pipe(\n Effect.map((list) =>\n list === undefined ? undefined : findDefault(list, projectId, name, deploymentType),\n ),\n );\n\n/**\n * GET /projects/{project_id}/list_default_environment_variables. Only the\n * fields the provider uses: the row's `value` is the secret in plain text.\n */\nexport const DefaultEnvironmentVariableList = Schema.Struct({\n items: Schema.Array(\n Schema.Struct({ name: Schema.String, deploymentTypes: Schema.Array(Schema.String) }),\n ),\n});\n\nexport interface DefaultEnvironmentVariableProps {\n /** Numeric project id, such as `project.projectId`. */\n readonly projectId: number;\n readonly name: string;\n readonly value: string | Redacted.Redacted<string>;\n /** Deployments of this type that Convex creates from now on get the variable. */\n readonly deploymentType: DeploymentType;\n}\n\nexport interface DefaultEnvironmentVariableAttributes {\n readonly projectId: number;\n readonly name: string;\n readonly deploymentType: DeploymentType;\n}\n\nexport type DefaultEnvironmentVariable = Resource<\n \"Convex.DefaultEnvironmentVariable\",\n DefaultEnvironmentVariableProps,\n DefaultEnvironmentVariableAttributes,\n never,\n Providers\n>;\nexport const DefaultEnvironmentVariable = Resource<DefaultEnvironmentVariable>(\n \"Convex.DefaultEnvironmentVariable\",\n);\n\n/** Fails with VariableIdentityChange when the props name another default than the one in state. */\nconst checkIdentity = (\n output: DefaultEnvironmentVariableAttributes,\n news: DefaultEnvironmentVariableProps,\n) => {\n const changed =\n output.projectId !== news.projectId\n ? ({\n field: \"projectId\",\n current: `${output.projectId}`,\n requested: `${news.projectId}`,\n } as const)\n : output.name !== news.name\n ? ({ field: \"name\", current: output.name, requested: news.name } as const)\n : output.deploymentType !== news.deploymentType\n ? ({\n field: \"deploymentType\",\n current: output.deploymentType,\n requested: news.deploymentType,\n } as const)\n : undefined;\n return changed === undefined\n ? Effect.void\n : Effect.fail(\n new VariableIdentityChange({ resourceType: DefaultEnvironmentVariable.Type, ...changed }),\n );\n};\n\nexport const DefaultEnvironmentVariableProvider = () =>\n Provider.effect(\n DefaultEnvironmentVariable,\n Effect.gen(function* () {\n const api = yield* ManagementApi;\n\n return {\n // Compares with the attributes: after a refused change, `olds` are\n // the refused props. Otherwise undefined: the engine updates when any\n // prop changed and compares a Redacted value by content.\n diff: Effect.fn(function* ({ news, output }) {\n if (!isResolved(news) || output === undefined) return undefined;\n yield* checkIdentity(output, news);\n return undefined;\n }),\n\n read: Effect.fn(function* ({ olds, output }) {\n const at = output ?? olds;\n const found = yield* readDefault(api, at.projectId, at.name, at.deploymentType);\n if (found === undefined) return undefined;\n // No state: the default belongs to someone else until the user passes --adopt.\n return output ?? Unowned(found);\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 const write = writeDefault(\n api,\n news.projectId,\n news.name,\n news.deploymentType,\n news.value,\n );\n if (output !== undefined || (yield* shouldAdopt(fqn))) {\n // In state, or adopted: the default is ours to set.\n yield* retryIdempotentWrite(write);\n } else {\n // Not in state: overwriting a default that exists loses its\n // value, so that needs adoption. Each attempt checks first, so a\n // retry after a write conflict never overwrites a default that\n // another writer created in the meantime.\n yield* retryIdempotentWrite(\n Effect.gen(function* () {\n const existing = yield* readDefault(\n api,\n news.projectId,\n news.name,\n news.deploymentType,\n );\n if (existing !== undefined) {\n return yield* new OwnedBySomeoneElse({\n message: `Project ${news.projectId} already has a ${news.deploymentType} default environment variable ${news.name}. Re-run with --adopt to take it over and overwrite its value, or use a different name.`,\n resourceType: DefaultEnvironmentVariable.Type,\n physicalName: news.name,\n });\n }\n yield* write;\n }),\n );\n }\n return {\n projectId: news.projectId,\n name: news.name,\n deploymentType: news.deploymentType,\n };\n }),\n\n delete: Effect.fn(function* ({ output }) {\n // Removing an absent default succeeds; 404 ProjectNotFound means the project is gone.\n yield* absentAsUndefined(\n updateDefault(api, output.projectId, output.name, output.deploymentType, null),\n );\n }),\n };\n }),\n );\n","// Convex.Deploy (deprecated since 0.3.0, use Convex.Code): pushes the\n// functions in a `convex/` directory with `npx convex deploy` and exposes\n// the deployment URL for a frontend build. It stays so that stacks and state\n// from 0.1 and 0.2 keep working: Convex.Code has other props.\n//\n// The deployment itself belongs to the project, so delete leaves the last\n// pushed functions running. The URL comes from the CLI's own output because\n// the deploy key, not this resource, decides which deployment receives the push.\nimport { stripVTControlCharacters } from \"node:util\";\nimport { Resource } from \"alchemy\";\nimport { CommandExecutor, type CommandRunProps } from \"alchemy/Command\";\nimport { hashDirectory, type MemoOptions } from \"alchemy/Command/Memo\";\nimport { havePropsChanged, isResolved } from \"alchemy/Diff\";\nimport * as Provider from \"alchemy/Provider\";\nimport * as Effect from \"effect/Effect\";\nimport type * as Redacted from \"effect/Redacted\";\nimport * as Schema from \"effect/Schema\";\nimport { parseDeployOutput } from \"./Code.ts\";\nimport type { Providers } from \"./Providers.ts\";\n\nexport interface DeployProps extends Pick<CommandRunProps, \"cwd\" | \"env\" | \"timeout\"> {\n /**\n * Deploy key that selects the target deployment: a production, development,\n * project, or preview deploy key. The CLI receives it as `CONVEX_DEPLOY_KEY`,\n * and Alchemy removes its value from the logged output.\n */\n readonly deployKey: Redacted.Redacted<string>;\n /**\n * Preview deployment name for a preview deploy key. The CLI reuses an\n * existing preview deployment with this name.\n */\n readonly previewName?: string;\n /**\n * Like {@link previewName}, but the CLI deletes and recreates an existing\n * preview deployment with this name, so every run gets a new URL.\n */\n readonly previewCreate?: string;\n /**\n * Function to run after the push, such as `init:seed`. The CLI runs it only\n * when the push created a new preview deployment.\n */\n readonly previewRun?: string;\n /**\n * More `convex deploy` flags, added after the preview flags. Alchemy splits\n * the command on whitespace, so an argument cannot contain whitespace: use\n * `--typecheck=disable`, not `--typecheck disable` as one argument.\n */\n readonly extraArgs?: readonly string[];\n /**\n * Files hashed to skip an unchanged push. By default every non-gitignored\n * file under `cwd` and the nearest lockfile. Use\n * `{ include: [\"convex/**\"], lockfile: true }` to ignore frontend changes,\n * or `false` to push on every deploy. A preview deploy (`previewName` or\n * `previewCreate`) pushes on every deploy: Convex can delete an expired\n * preview deployment, and the hash cannot show that.\n * @default true\n */\n readonly memo?: MemoOptions | boolean;\n}\n\nexport interface DeployAttributes {\n /** Client URL of the deployment that received the push, such as `https://happy-otter-123.convex.cloud`. */\n readonly url: string;\n /** First label of the URL host, such as `happy-otter-123`. */\n readonly deploymentName: string;\n /** Hash of the memoized input files after the push, or `undefined` when `memo` is `false`. */\n readonly hash: string | undefined;\n}\n\nexport type Deploy = Resource<\"Convex.Deploy\", DeployProps, DeployAttributes, never, Providers>;\n/**\n * @deprecated Since 0.3.0. Use Convex.Code with a Convex.Deployment: it\n * runs the installed Convex CLI, keeps the deploy key out of the process\n * environment, checks that the key fits the deployment, and outputs the site\n * URL. Removing a Deploy resource changes nothing in Convex.\n */\nexport const Deploy = Resource<Deploy>(\"Convex.Deploy\");\n\n/** The `convex deploy` argv, starting with `npx`. */\nexport const deployArgs = (\n props: Pick<DeployProps, \"previewName\" | \"previewCreate\" | \"previewRun\" | \"extraArgs\">,\n): readonly string[] => [\n \"npx\",\n \"convex\",\n \"deploy\",\n ...(props.previewName === undefined ? [] : [\"--preview-name\", props.previewName]),\n ...(props.previewCreate === undefined ? [] : [\"--preview-create\", props.previewCreate]),\n ...(props.previewRun === undefined ? [] : [\"--preview-run\", props.previewRun]),\n ...(props.extraArgs ?? []),\n];\n\n/** Number of output lines quoted when the CLI exits 0 without the deployed line. */\nconst OUTPUT_TAIL_LINES = 20;\n\n/** A `convex deploy` argument contains whitespace, which Alchemy's command runner splits on. */\nexport class DeployArgumentError extends Schema.TaggedError<DeployArgumentError>()(\n \"DeployArgumentError\",\n { argument: Schema.String },\n) {\n override get message() {\n return `Convex.Deploy argument \"${this.argument}\" contains whitespace, and Alchemy splits the command on whitespace. Use the --flag=value form, such as --typecheck=disable, and names without spaces.`;\n }\n}\n\n/** `npx convex deploy` exited 0 but did not print the deployment URL. */\nexport class DeployOutputError extends Schema.TaggedError<DeployOutputError>()(\n \"DeployOutputError\",\n { outputTail: Schema.String },\n) {\n override get message() {\n return `npx convex deploy exited 0 but printed no \"Deployed Convex functions to <url>\" line, so Convex.Deploy has no deployment URL. Remove --dry-run from extraArgs if it is there, and read the CLI output. Last output:\\n${this.outputTail}`;\n }\n}\n\nexport const DeployProvider = () =>\n Provider.effect(\n Deploy,\n Effect.gen(function* () {\n const { run } = yield* CommandExecutor;\n\n const hashOf = (props: DeployProps) =>\n props.memo === false\n ? Effect.succeed(undefined)\n : hashDirectory({\n ...(props.cwd === undefined ? {} : { cwd: props.cwd }),\n memo: props.memo === true || props.memo === undefined ? {} : props.memo,\n });\n\n return {\n // No `stables`: the same deploy key can push to a different URL. A\n // project deploy key follows the project's default production\n // deployment, and a preview deployment can expire or be recreated\n // under the same name.\n diff: Effect.fn(function* ({ olds, news, output }) {\n if (!isResolved(news)) return undefined;\n // A preview deployment can expire. The same hash then hides a\n // missing deployment, so a preview always pushes. The CLI reuses\n // a live preview with the same name.\n const preview = news.previewName !== undefined || news.previewCreate !== undefined;\n if (\n preview ||\n output === undefined ||\n output.hash === undefined ||\n havePropsChanged(olds, news)\n ) {\n return { action: \"update\" } as const;\n }\n return { action: (yield* hashOf(news)) === output.hash ? \"noop\" : \"update\" } as const;\n }),\n\n reconcile: Effect.fn(function* ({ news, session }) {\n const args = deployArgs(news);\n const spaced = args.find((arg) => /\\s/.test(arg));\n if (spaced !== undefined) return yield* new DeployArgumentError({ argument: spaced });\n // A push is idempotent: the CLI uploads the full function set every time.\n const { stdout, stderr } = yield* run(\n {\n command: args.join(\" \"),\n ...(news.cwd === undefined ? {} : { cwd: news.cwd }),\n ...(news.timeout === undefined ? {} : { timeout: news.timeout }),\n env: { ...news.env, CONVEX_DEPLOY_KEY: news.deployKey },\n },\n session,\n );\n // `run` returns output with the deploy key already replaced.\n const output = `${stdout}\\n${stderr}`;\n const deployed = parseDeployOutput(output);\n if (deployed === undefined) {\n const outputTail = stripVTControlCharacters(output)\n .split(/\\r?\\n|\\r/)\n .filter((line) => line.trim() !== \"\")\n .slice(-OUTPUT_TAIL_LINES)\n .join(\"\\n\");\n return yield* new DeployOutputError({ outputTail });\n }\n return { ...deployed, hash: yield* hashOf(news) };\n }),\n\n // The deployment belongs to the project; its functions stay deployed.\n delete: () => Effect.void,\n };\n }),\n );\n","// Convex.DeployKey: a deploy key for one deployment, such as the key\n// `npx convex deploy` reads from CONVEX_DEPLOY_KEY.\n//\n// Convex returns the secret only once, from create_deploy_key, and the\n// response has no id. The listing shows each key with a numeric id and a\n// name: the requested name, or, when a listed key already has that name, the\n// requested name plus a suffix such as \" (870993b4-ffe6-4911-adbd-e29f7fd712f2)\".\n//\n// One resource must never revoke the key of another resource:\n// - The requested name is the `name` prop plus a hash of the resource's fqn\n// and instance id, so two resources with the same `name` request\n// different names.\n// - After the create, exactly one listed key must have the requested name.\n// Otherwise the create fails with a typed error that lists the keys. State\n// keeps that key's numeric id.\n// - Delete sends the secret as `id`, so it can revoke only the key that this\n// resource created. It never deletes by a listed name.\n// - With an OAuth token as the Management API credential, Convex returns\n// that token as the \"new\" key. The provider never stores, revokes, or\n// deletes such a key: the create fails with DeployKeyIsCredential.\n// - Delete runs only for a key with a `keyId` in state. A 0.1.x key, which\n// has none, stays in Convex with a warning.\n// A key cannot change after creation, so every property change is a replacement.\nimport { createHash } from \"node:crypto\";\nimport { Resource } from \"alchemy\";\nimport { havePropsChanged, isResolved } from \"alchemy/Diff\";\nimport * as Provider from \"alchemy/Provider\";\nimport * as Effect from \"effect/Effect\";\nimport * as Redacted from \"effect/Redacted\";\nimport * as Schema from \"effect/Schema\";\nimport type { components } from \"@convex-dev/platform/managementApi\";\nimport {\n absentAsUndefined,\n type ConvexApiError,\n ManagementApi,\n retryIdempotentWrite,\n} from \"./ManagementApi.ts\";\nimport type { Providers } from \"./Providers.ts\";\n\n/** Actions a deploy key can be limited to, from the generated schema. */\nexport type DeployKeyAction = NonNullable<\n components[\"schemas\"][\"PlatformCreateDeployKeyArgs\"][\"allowedActions\"]\n>[number];\n\n/**\n * True when `listedName` is how Convex lists a key created as `name`: the\n * requested name itself, or the requested name, a space, and one\n * parenthesized suffix without spaces. The suffix check keeps `my-key` from\n * matching a key created as `my-key (old)`.\n */\nconst isListedAs = (listedName: string, name: string) => {\n const prefix = `${name} (`;\n return (\n listedName === name ||\n (listedName.startsWith(prefix) && /^[^\\s()]+\\)$/.test(listedName.slice(prefix.length)))\n );\n};\n\n/**\n * True when the listing still has the key in state: by numeric id, or by\n * listed name for state written by 0.1.x, which has no id.\n */\nexport const isKeyListed = (\n entries: ReadonlyArray<typeof ListedKey.Type>,\n key: { readonly keyId: number | undefined; readonly uniqueName: string },\n): boolean =>\n entries.some((entry) =>\n key.keyId === undefined ? entry.name === key.uniqueName : entry.id === key.keyId,\n );\n\n/** The listed keys that Convex shows for a key created as `name`. */\nexport const keysListedAs = (\n entries: ReadonlyArray<typeof ListedKey.Type>,\n name: string,\n): ReadonlyArray<typeof ListedKey.Type> => entries.filter((entry) => isListedAs(entry.name, name));\n\n/**\n * The name that a resource instance requests: `name`, a dash, and the first\n * 12 hex characters of sha256(\"<fqn>:<instanceId>\"). Two resources, or the\n * old and the new generation of one replaced resource, never request the\n * same name. Pattern from Confect `packages/alchemy/src/internal/ResourceIdentity.ts`\n * (https://github.com/rjdellecese/confect, ISC license).\n */\nexport const requestedKeyName = (name: string, fqn: string, instanceId: string): string =>\n `${name}-${createHash(\"sha256\").update(`${fqn}:${instanceId}`).digest(\"hex\").slice(0, 12)}`;\n\n/** One row of list_deploy_keys and list_preview_deploy_keys. Only the fields the providers use. */\nexport const ListedKey = Schema.Struct({\n id: Schema.Number,\n name: Schema.String,\n});\n\n/** GET /deployments/{deployment_name}/list_deploy_keys */\nexport const DeployKeyList = Schema.Array(ListedKey);\n\n/** POST /deployments/{deployment_name}/create_deploy_key */\nexport const CreatedDeployKey = Schema.Struct({ deployKey: Schema.String });\n\n/**\n * A key cannot be tied to one resource: before the create, listed keys\n * already have the requested name, or after the create, not exactly one has it.\n */\nexport class DeployKeyRecoveryRequired extends Schema.TaggedError<DeployKeyRecoveryRequired>()(\n \"DeployKeyRecoveryRequired\",\n {\n /** Where the keys live, such as `deployment happy-otter-123` or `project 3145389`. */\n target: Schema.String,\n /** The requested name. */\n name: Schema.String,\n /** The listed keys with the requested name. */\n keys: Schema.Array(ListedKey),\n /** True when this run created a key before the listing check failed. */\n afterCreate: Schema.Boolean,\n },\n) {\n override get message() {\n const listed =\n this.keys.length === 0\n ? \"no key\"\n : this.keys.map((key) => `\"${key.name}\" (id ${key.id})`).join(\", \");\n return this.afterCreate\n ? `Convex created deploy key \"${this.name}\" on ${this.target}, but the listing shows ${listed} with that name, not exactly one, so this resource cannot track the new key. Alchemy does not revoke it. Delete the keys with that name in the Convex dashboard, then run the deploy again.`\n : `${this.target} already lists ${listed} with the name \"${this.name}\", but Alchemy state has no such key. An interrupted run probably created it, and its secret is lost. Delete these keys in the Convex dashboard, then run the deploy again.`;\n }\n}\n\n/**\n * Convex returned the Management API credential itself as the new key. This\n * happens with an OAuth token: Convex creates no key. A delete of the\n * returned secret would revoke the credential, so the resource does not keep it.\n */\nexport class DeployKeyIsCredential extends Schema.TaggedError<DeployKeyIsCredential>()(\n \"DeployKeyIsCredential\",\n { target: Schema.String, name: Schema.String },\n) {\n override get message() {\n return `Convex returned the Management API credential itself as deploy key \"${this.name}\" on ${this.target}. With an OAuth token, Convex creates no new key, and deleting the returned key would revoke the OAuth token. Alchemy does not keep it. Use a team access token in CONVEX_ACCESS_TOKEN, or the Convex CLI login.`;\n }\n}\n\n/**\n * Creates a key named `name` and ties it to the caller. Fails before the\n * create when keys with that name already exist. After the create, fails\n * when the secret is the Management API credential itself, or when the\n * listing does not show exactly one key with that name. It never revokes a\n * key: the returned secret can be a shared credential.\n */\nexport const createTrackedKey = (options: {\n readonly target: string;\n readonly name: string;\n readonly list: Effect.Effect<ReadonlyArray<typeof ListedKey.Type>, ConvexApiError>;\n readonly create: Effect.Effect<string, ConvexApiError>;\n readonly isCredentialToken: (secret: string) => Effect.Effect<boolean>;\n}) =>\n Effect.gen(function* () {\n const { target, name } = options;\n const existing = keysListedAs(yield* options.list, name);\n if (existing.length > 0) {\n return yield* new DeployKeyRecoveryRequired({\n target,\n name,\n keys: existing,\n afterCreate: false,\n });\n }\n const secret = yield* options.create;\n if (yield* options.isCredentialToken(secret)) {\n return yield* new DeployKeyIsCredential({ target, name });\n }\n const listed = keysListedAs(yield* options.list, name);\n const [only] = listed;\n if (only === undefined || listed.length !== 1) {\n return yield* new DeployKeyRecoveryRequired({\n target,\n name,\n keys: listed,\n afterCreate: true,\n });\n }\n return { keyId: only.id, uniqueName: only.name, secret: Redacted.make(secret) };\n });\n\n/**\n * The secret to send to a delete call, or undefined when a delete is not\n * safe. Only a key with a `keyId` in state is known to be a new key that\n * this resource owns: createTrackedKey found exactly one new listed key, and\n * the secret was not the credential. State from 0.1.x has no `keyId`, and its\n * secret can be an OAuth token that Convex returned as a key, so a delete\n * could revoke that OAuth token. Such a key stays, and a warning names it.\n */\nexport const secretToDelete = (\n key: {\n readonly keyId: number | undefined;\n readonly secret: Redacted.Redacted<string> | undefined;\n },\n label: string,\n) =>\n Effect.gen(function* () {\n if (key.keyId === undefined || !Redacted.isRedacted(key.secret)) {\n yield* Effect.logWarning(\n `${label} has no verified key id and secret in state (state from 0.1.x, for example), so Alchemy does not delete it. Delete it in the Convex dashboard.`,\n );\n return undefined;\n }\n return Redacted.value(key.secret);\n });\n\nexport interface DeployKeyProps {\n /** Deployment name, such as `project.prodDeploymentName`. */\n readonly deployment: string;\n /**\n * Key name. The provider requests this name, a dash, and a hash of the\n * resource identity, so two resources with one `name` get different keys.\n */\n readonly name: string;\n /** Limits the key to these actions. Convex grants every deployment action when omitted. */\n readonly allowedActions?: readonly DeployKeyAction[];\n}\n\nexport interface DeployKeyAttributes {\n /** The name Convex lists the key under, such as \"ci-3f2a1b0c9d8e\". */\n readonly uniqueName: string;\n /** Numeric id of the key in the listing. Undefined in state written by 0.1.x. */\n readonly keyId: number | undefined;\n readonly deployment: string;\n /** The secret, such as `prod:<deployment>|<token>`. Convex returns it only at creation. */\n readonly deployKey: Redacted.Redacted<string>;\n}\n\nexport type DeployKey = Resource<\n \"Convex.DeployKey\",\n DeployKeyProps,\n DeployKeyAttributes,\n never,\n Providers\n>;\nexport const DeployKey = Resource<DeployKey>(\"Convex.DeployKey\");\n\nexport const DeployKeyProvider = () =>\n Provider.effect(\n DeployKey,\n Effect.gen(function* () {\n const api = yield* ManagementApi;\n\n const listKeys = (deployment: string) =>\n api\n .request(\"list deploy keys\", (client) =>\n client.GET(\"/deployments/{deployment_name}/list_deploy_keys\", {\n params: { path: { deployment_name: deployment } },\n }),\n )\n .pipe(Effect.map((body) => Schema.decodeUnknownSync(DeployKeyList)(body)));\n\n /**\n * `id` is the secret: Convex accepts it, and it matches only the key\n * that this resource created. A second delete answers 404.\n */\n const deleteKey = (deployment: string, secret: string) =>\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: secret },\n }),\n ),\n );\n\n return {\n stables: [\"uniqueName\", \"deployment\"],\n\n diff: ({ olds, news, output }) => {\n if (!isResolved(news)) return Effect.succeed(undefined);\n // State written without the secret cannot hand a key to dependents,\n // and Convex cannot return it again, so only a new key helps.\n return Effect.succeed(\n (output !== undefined && output.deployKey === undefined) || havePropsChanged(olds, news)\n ? ({ action: \"replace\" } as const)\n : ({ action: \"noop\" } as const),\n );\n },\n\n read: Effect.fn(function* ({ output }) {\n // A key that is not in state has no known secret, so it is never adopted.\n if (output === undefined) return undefined;\n const entries = yield* absentAsUndefined(listKeys(output.deployment));\n return entries !== undefined && isKeyListed(entries, output) ? output : undefined;\n }),\n\n reconcile: Effect.fn(function* ({ fqn, instanceId, news, output }) {\n if (output !== undefined) {\n // The secret cannot be read back. A key that still exists keeps the one in state.\n if (isKeyListed(yield* listKeys(news.deployment), output)) return output;\n }\n const name = requestedKeyName(news.name, fqn, instanceId);\n const { keyId, uniqueName, secret } = yield* createTrackedKey({\n target: `deployment ${news.deployment}`,\n name,\n list: listKeys(news.deployment),\n create: api\n .request(\"create deploy key\", (client) =>\n client.POST(\"/deployments/{deployment_name}/create_deploy_key\", {\n params: { path: { deployment_name: news.deployment } },\n body: {\n name,\n ...(news.allowedActions === undefined\n ? {}\n : { allowedActions: [...news.allowedActions] }),\n },\n }),\n )\n .pipe(\n Effect.map((body) => Schema.decodeUnknownSync(CreatedDeployKey)(body).deployKey),\n ),\n isCredentialToken: api.isCredentialToken,\n });\n return { uniqueName, keyId, deployment: news.deployment, deployKey: secret };\n }),\n\n delete: Effect.fn(function* ({ output }) {\n // Only the secret names this key alone: 0.1.x state can hold the\n // listed name of another resource's key.\n const secret = yield* secretToDelete(\n { keyId: output.keyId, secret: output.deployKey },\n `Convex.DeployKey \"${output.uniqueName}\" on ${output.deployment}`,\n );\n if (secret === undefined) return;\n // 404 DeployKeyNotFound: an earlier attempt or someone else deleted it.\n yield* absentAsUndefined(deleteKey(output.deployment, secret));\n }),\n };\n }),\n );\n","// Convex.PreviewDeployKey: a project key that creates and deploys preview\n// deployments, such as the key CI passes to `npx convex deploy` for a branch.\n//\n// Convex returns the secret only once, from create_preview_deploy_key. The\n// identity rules are the same as for Convex.DeployKey: a requested name that\n// is unique for each resource instance, exactly one listed key after the\n// create with its numeric id in state, delete by the secret only, and never\n// keep a key that is the OAuth credential itself. A key cannot change after\n// creation, so every property change is a replacement.\nimport { Resource } from \"alchemy\";\nimport { havePropsChanged, isResolved } from \"alchemy/Diff\";\nimport * as Provider from \"alchemy/Provider\";\nimport * as Effect from \"effect/Effect\";\nimport * as Redacted from \"effect/Redacted\";\nimport * as Schema from \"effect/Schema\";\nimport {\n createTrackedKey,\n isKeyListed,\n ListedKey,\n requestedKeyName,\n secretToDelete,\n} from \"./DeployKey.ts\";\nimport { absentAsUndefined, ManagementApi, retryIdempotentWrite } from \"./ManagementApi.ts\";\nimport type { Providers } from \"./Providers.ts\";\n\n/** GET /projects/{project_id}/list_preview_deploy_keys */\nexport const PreviewDeployKeyList = Schema.Struct({ items: Schema.Array(ListedKey) });\n\n/** POST /projects/{project_id}/create_preview_deploy_key */\nexport const CreatedPreviewDeployKey = Schema.Struct({ previewDeployKey: Schema.String });\n\nexport interface PreviewDeployKeyProps {\n /** Numeric project id, such as `project.projectId`. */\n readonly projectId: number;\n /**\n * Key name. The provider requests this name, a dash, and a hash of the\n * resource identity, so two resources with one `name` get different keys.\n */\n readonly name: string;\n}\n\nexport interface PreviewDeployKeyAttributes {\n /** The name Convex lists the key under, such as \"ci-3f2a1b0c9d8e\". */\n readonly uniqueName: string;\n /** Numeric id of the key in the listing. Undefined in state written by 0.1.x. */\n readonly keyId: number | undefined;\n readonly projectId: number;\n /** The secret, such as `preview:<team>:<project>|<token>`. Convex returns it only at creation. */\n readonly previewDeployKey: Redacted.Redacted<string>;\n}\n\nexport type PreviewDeployKey = Resource<\n \"Convex.PreviewDeployKey\",\n PreviewDeployKeyProps,\n PreviewDeployKeyAttributes,\n never,\n Providers\n>;\nexport const PreviewDeployKey = Resource<PreviewDeployKey>(\"Convex.PreviewDeployKey\");\n\nexport const PreviewDeployKeyProvider = () =>\n Provider.effect(\n PreviewDeployKey,\n Effect.gen(function* () {\n const api = yield* ManagementApi;\n\n const listKeys = (projectId: number) =>\n api\n .request(\"list preview deploy keys\", (client) =>\n client.GET(\"/projects/{project_id}/list_preview_deploy_keys\", {\n params: { path: { project_id: projectId } },\n }),\n )\n .pipe(Effect.map((body) => Schema.decodeUnknownSync(PreviewDeployKeyList)(body).items));\n\n /**\n * `id` is the secret: Convex accepts it, and it matches only the key\n * that this resource created. A second delete answers 404.\n */\n const deleteKey = (projectId: number, secret: string) =>\n retryIdempotentWrite(\n api.requestVoid(\"delete preview deploy key\", (client) =>\n client.POST(\"/projects/{project_id}/delete_preview_deploy_key\", {\n params: { path: { project_id: projectId } },\n body: { id: secret },\n }),\n ),\n );\n\n return {\n stables: [\"uniqueName\", \"projectId\"],\n\n diff: ({ olds, news, output }) => {\n if (!isResolved(news)) return Effect.succeed(undefined);\n // State written without the secret cannot hand a key to dependents,\n // and Convex cannot return it again, so only a new key helps.\n return Effect.succeed(\n (output !== undefined && output.previewDeployKey === undefined) ||\n havePropsChanged(olds, news)\n ? ({ action: \"replace\" } as const)\n : ({ action: \"noop\" } as const),\n );\n },\n\n read: Effect.fn(function* ({ output }) {\n // A key that is not in state has no known secret, so it is never adopted.\n if (output === undefined) return undefined;\n const entries = yield* absentAsUndefined(listKeys(output.projectId));\n return entries !== undefined && isKeyListed(entries, output) ? output : undefined;\n }),\n\n reconcile: Effect.fn(function* ({ fqn, instanceId, news, output }) {\n if (output !== undefined) {\n // The secret cannot be read back. A key that still exists keeps the one in state.\n if (isKeyListed(yield* listKeys(news.projectId), output)) return output;\n }\n const name = requestedKeyName(news.name, fqn, instanceId);\n const { keyId, uniqueName, secret } = yield* createTrackedKey({\n target: `project ${news.projectId}`,\n name,\n list: listKeys(news.projectId),\n create: api\n .request(\"create preview deploy key\", (client) =>\n client.POST(\"/projects/{project_id}/create_preview_deploy_key\", {\n params: { path: { project_id: news.projectId } },\n body: { name },\n }),\n )\n .pipe(\n Effect.map(\n (body) =>\n Schema.decodeUnknownSync(CreatedPreviewDeployKey)(body).previewDeployKey,\n ),\n ),\n isCredentialToken: api.isCredentialToken,\n });\n return { uniqueName, keyId, projectId: news.projectId, previewDeployKey: secret };\n }),\n\n delete: Effect.fn(function* ({ output }) {\n // Only the secret names this key alone: 0.1.x state can hold the\n // listed name of another resource's key.\n const secret = yield* secretToDelete(\n { keyId: output.keyId, secret: output.previewDeployKey },\n `Convex.PreviewDeployKey \"${output.uniqueName}\" in project ${output.projectId}`,\n );\n if (secret === undefined) return;\n // 404 PreviewDeployKeyNotFound: an earlier attempt or someone else deleted it.\n yield* absentAsUndefined(deleteKey(output.projectId, secret));\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.\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 interface ProjectProps {\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\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/** 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 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 = (projectId: number, olds: ProjectProps, news: ProjectProps) => {\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\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 /**\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 // 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 olds.name === news.name ? undefined : ({ 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 with this name belongs to someone\n // else until the user passes --adopt. Convex has no ownership tags.\n const existing = 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 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) yield* checkCreateTimeProps(output.projectId, olds, news);\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 { CommandExecutorLive } from \"alchemy/Command\";\nimport * as Provider from \"alchemy/Provider\";\nimport * as Layer from \"effect/Layer\";\nimport { Code, CodeProvider } from \"./Code.ts\";\nimport { type Credentials, fromConfig } from \"./Credentials.ts\";\nimport {\n DefaultEnvironmentVariable,\n DefaultEnvironmentVariableProvider,\n} from \"./DefaultEnvironmentVariable.ts\";\nimport { Deploy, DeployProvider } from \"./Deploy.ts\";\nimport { DeployKey, DeployKeyProvider } from \"./DeployKey.ts\";\nimport { Deployment, DeploymentProvider } from \"./Deployment.ts\";\nimport { EnvironmentVariable, EnvironmentVariableProvider } from \"./EnvironmentVariable.ts\";\nimport { ManagementApiLive } from \"./ManagementApi.ts\";\nimport { PreviewDeployKey, PreviewDeployKeyProvider } from \"./PreviewDeployKey.ts\";\nimport { Project, ProjectProvider } from \"./Project.ts\";\n\nexport class Providers extends Provider.ProviderCollection<Providers>()(\"Convex\") {}\n\n/**\n * All Convex resource providers. Pass a credentials layer to override the\n * default lookup (`CONVEX_ACCESS_TOKEN`, then the Convex CLI login).\n */\nexport const providers = (credentials: Layer.Layer<Credentials> = fromConfig()) =>\n Layer.effect(\n Providers,\n Provider.collection([\n Project,\n Deployment,\n DeployKey,\n PreviewDeployKey,\n EnvironmentVariable,\n DefaultEnvironmentVariable,\n Code,\n Deploy,\n ]),\n ).pipe(\n Layer.provide(\n Layer.mergeAll(\n ProjectProvider(),\n DeploymentProvider(),\n DeployKeyProvider(),\n PreviewDeployKeyProvider(),\n EnvironmentVariableProvider(),\n DefaultEnvironmentVariableProvider(),\n CodeProvider(),\n DeployProvider(),\n ),\n ),\n Layer.provide(ManagementApiLive()),\n Layer.provide(credentials),\n // The deprecated Convex.Deploy runs the Convex CLI through Alchemy's\n // command executor. Convex.Code spawns it itself, so that its output\n // stays out of the logs.\n Layer.provide(CommandExecutorLive()),\n Layer.orDie,\n );\n"],"mappings":"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"}