@gaganref/confect-alchemy 10.3.1-fork.2 → 10.3.1-fork.21

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.
Files changed (51) hide show
  1. package/dist/Backend.d.ts +3 -3
  2. package/dist/Backend.d.ts.map +1 -1
  3. package/dist/Backend.js.map +1 -1
  4. package/dist/Code.d.ts +5 -5
  5. package/dist/Code.d.ts.map +1 -1
  6. package/dist/Code.js.map +1 -1
  7. package/dist/Confect.d.ts +1 -1
  8. package/dist/Confect.d.ts.map +1 -1
  9. package/dist/Confect.js.map +1 -1
  10. package/dist/Convex.d.ts +6 -6
  11. package/dist/Convex.d.ts.map +1 -1
  12. package/dist/Convex.js.map +1 -1
  13. package/dist/ConvexClient.js.map +1 -1
  14. package/dist/DeployKey.d.ts +7 -7
  15. package/dist/DeployKey.d.ts.map +1 -1
  16. package/dist/DeployKey.js.map +1 -1
  17. package/dist/Deployment.d.ts +6 -6
  18. package/dist/Deployment.d.ts.map +1 -1
  19. package/dist/Deployment.js.map +1 -1
  20. package/dist/EnvironmentVariables.d.ts +4 -4
  21. package/dist/EnvironmentVariables.d.ts.map +1 -1
  22. package/dist/EnvironmentVariables.js.map +1 -1
  23. package/dist/Project.d.ts +6 -6
  24. package/dist/Project.d.ts.map +1 -1
  25. package/dist/Project.js.map +1 -1
  26. package/dist/Providers.js.map +1 -1
  27. package/dist/index.d.ts +2 -2
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/internal/CodeDeployment.d.ts +4 -4
  30. package/dist/internal/CodeDeployment.d.ts.map +1 -1
  31. package/dist/internal/CodeDeployment.js.map +1 -1
  32. package/dist/internal/LocalBackend.js.map +1 -1
  33. package/dist/internal/LocalSidecar.d.ts +1 -1
  34. package/dist/internal/LocalSidecar.js.map +1 -1
  35. package/dist/internal/PushLock.js.map +1 -1
  36. package/package.json +3 -3
  37. package/src/Backend.ts +2 -2
  38. package/src/Code.ts +7 -4
  39. package/src/Confect.ts +1 -1
  40. package/src/Convex.ts +10 -6
  41. package/src/ConvexClient.ts +1 -1
  42. package/src/DeployKey.ts +5 -5
  43. package/src/Deployment.ts +5 -5
  44. package/src/EnvironmentVariables.ts +3 -3
  45. package/src/Project.ts +4 -4
  46. package/src/Providers.ts +8 -8
  47. package/src/index.ts +2 -2
  48. package/src/internal/CodeDeployment.ts +4 -4
  49. package/src/internal/LocalBackend.ts +5 -5
  50. package/src/internal/LocalSidecar.ts +1 -1
  51. package/src/internal/PushLock.ts +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"EnvironmentVariables.d.ts","sourceRoot":"","sources":["../src/EnvironmentVariables.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAW,MAAM,qBAAqB,CAAC;AAElE,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAEtC,OAAO,KAAK,QAAQ,MAAM,iBAAiB,CAAC;AAC5C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAExC,OAAO,KAAK,YAAY,MAAM,gBAAgB,CAAC;AAC/C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAG7C,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC9C,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAC1B,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CACnD,CAAC;CACH;AAED,MAAM,WAAW,8BAA8B;IAC7C,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC9C,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC3C,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IACxE,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;CACzE;AAED,MAAM,MAAM,oBAAoB,GAAG,QAAQ,CACzC,6BAA6B,EAC7B,yBAAyB,EACzB,8BAA8B,EAC9B,KAAK,EACL,SAAS,CACV,CAAC;AACF,eAAO,MAAM,oBAAoB,gEAEhC,CAAC;;;;AAEF,qBAAa,uBAAwB,SAAQ,4BAG5C;CAAG;AAEJ,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;aAvBL,MAAM;oBAEC,aAAa,CAAC,MAAM,CAAC;mBAEtB,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oCA+LvE,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;aA1MV,MAAM;oBAEC,aAAa,CAAC,MAAM,CAAC;mBAEtB,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oCAsNxE,CAAC;AAEF,eAAO,MAAM,KAAK,wFAAkD,CAAC;AACrE,eAAO,MAAM,UAAU,oEAStB,CAAC"}
1
+ {"version":3,"file":"EnvironmentVariables.d.ts","sourceRoot":"","sources":["../src/EnvironmentVariables.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAW,MAAM,qBAAqB,CAAC;AAElE,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAEtC,OAAO,KAAK,QAAQ,MAAM,iBAAiB,CAAC;AAC5C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAExC,OAAO,KAAK,YAAY,MAAM,mBAAmB,CAAC;AAClD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAGhD,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC9C,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAC1B,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CACnD,CAAC;CACH;AAED,MAAM,WAAW,8BAA8B;IAC7C,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC9C,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC3C,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IACxE,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;CACzE;AAED,MAAM,MAAM,oBAAoB,GAAG,QAAQ,CACzC,6BAA6B,EAC7B,yBAAyB,EACzB,8BAA8B,EAC9B,KAAK,EACL,SAAS,CACV,CAAC;AACF,eAAO,MAAM,oBAAoB,gEAEhC,CAAC;;;;AAEF,qBAAa,uBAAwB,SAAQ,4BAG5C;CAAG;AAEJ,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;aAvBL,MAAM;oBAEC,aAAa,CAAC,MAAM,CAAC;mBAEtB,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oCA+LvE,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;aA1MV,MAAM;oBAEC,aAAa,CAAC,MAAM,CAAC;mBAEtB,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oCAsNxE,CAAC;AAEF,eAAO,MAAM,KAAK,wFAAkD,CAAC;AACrE,eAAO,MAAM,UAAU,oEAStB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"EnvironmentVariables.js","names":["ConvexClient.ConvexClient","ConvexClient.layer"],"sources":["../src/EnvironmentVariables.ts"],"sourcesContent":["import { OwnedBySomeoneElse, Unowned } from \"alchemy/AdoptPolicy\";\nimport { isResolved } from \"alchemy/Diff\";\nimport * as Provider from \"alchemy/Provider\";\nimport { Resource } from \"alchemy/Resource\";\nimport * as Effect from \"effect/Effect\";\nimport * as Layer from \"effect/Layer\";\nimport * as FetchHttpClient from \"effect/http/FetchHttpClient\";\nimport * as Redacted from \"effect/Redacted\";\nimport * as Schema from \"effect/Schema\";\n\nimport * as ConvexClient from \"./ConvexClient\";\nimport type { Providers } from \"./Providers\";\nimport { checkpointCreate, shouldAdopt } from \"./internal/Lifecycle\";\n\nexport interface EnvironmentVariablesProps {\n readonly url: string;\n readonly deployKey: Redacted.Redacted<string>;\n readonly variables: Readonly<\n Record<string, string | Redacted.Redacted<string>>\n >;\n}\n\nexport interface EnvironmentVariablesAttributes {\n readonly url: string;\n readonly deployKey: Redacted.Redacted<string>;\n readonly ownedNames: ReadonlyArray<string>;\n readonly variables: Readonly<Record<string, Redacted.Redacted<string>>>;\n readonly originals: Readonly<Record<string, Redacted.Redacted<string>>>;\n}\n\nexport type EnvironmentVariables = Resource<\n \"Convex.EnvironmentVariables\",\n EnvironmentVariablesProps,\n EnvironmentVariablesAttributes,\n never,\n Providers\n>;\nexport const EnvironmentVariables = Resource<EnvironmentVariables>(\n \"Convex.EnvironmentVariables\",\n);\n\nexport class EnvironmentTargetChange extends Schema.TaggedError<EnvironmentTargetChange>()(\n \"EnvironmentTargetChange\",\n { url: Schema.String },\n) {}\n\nexport const provider = Effect.gen(function* () {\n const client = yield* ConvexClient.ConvexClient;\n const redacted = (value: string | Redacted.Redacted<string>) =>\n typeof value === \"string\" ? Redacted.make(value) : value;\n const valueAt = (\n variables: Readonly<Record<string, Redacted.Redacted<string>>>,\n name: string,\n ) => (Object.hasOwn(variables, name) ? variables[name] : undefined);\n const select = (\n variables: Readonly<Record<string, Redacted.Redacted<string>>>,\n names: ReadonlyArray<string>,\n ) =>\n Object.fromEntries(\n names.flatMap((name) =>\n !Object.hasOwn(variables, name) ? [] : [[name, variables[name]]],\n ),\n );\n return {\n diff: Effect.fn(\"EnvironmentVariables.diff\")(function* ({ news, output }) {\n if (!isResolved(news) || !output) return;\n if (news.url !== output.url)\n return yield* new EnvironmentTargetChange({\n url: output.url,\n });\n const names = Object.keys(news.variables);\n if (\n names.length !== output.ownedNames.length ||\n names.some((name) => !output.ownedNames.includes(name))\n )\n return { action: \"update\" };\n const variables = yield* client.listEnvironmentVariables(\n news.url,\n news.deployKey,\n );\n for (const [name, value] of Object.entries(news.variables)) {\n const observed = valueAt(variables, name);\n if (\n observed === undefined ||\n Redacted.value(observed) !== Redacted.value(redacted(value))\n )\n return { action: \"update\" };\n }\n }),\n read: Effect.fn(\"EnvironmentVariables.read\")(function* ({ olds, output }) {\n const url = output?.url ?? olds.url;\n if (url === undefined || olds.deployKey === undefined) return;\n const observed = yield* client.listEnvironmentVariables(\n url,\n olds.deployKey,\n );\n const ownedNames = output?.ownedNames ?? Object.keys(olds.variables);\n const variables = select(observed, ownedNames);\n if (output) return { ...output, deployKey: olds.deployKey, variables };\n if (Object.keys(variables).length === 0) return undefined;\n return Unowned({\n url,\n deployKey: olds.deployKey,\n ownedNames,\n variables,\n originals: variables,\n });\n }),\n reconcile: Effect.fn(\"EnvironmentVariables.reconcile\")(function* ({\n fqn,\n instanceId,\n news,\n output,\n }) {\n if (!output) yield* checkpointCreate(fqn, instanceId, news);\n if (output && output.url !== news.url)\n return yield* new EnvironmentTargetChange({\n url: output.url,\n });\n const observed = yield* client.listEnvironmentVariables(\n news.url,\n news.deployKey,\n );\n const ownedNames = Object.keys(news.variables);\n if (!output && (yield* shouldAdopt(fqn))) {\n const variables = select(observed, ownedNames);\n output = {\n url: news.url,\n deployKey: news.deployKey,\n ownedNames,\n variables,\n originals: variables,\n };\n yield* checkpointCreate(fqn, instanceId, news, output);\n }\n const previousNames = output?.ownedNames ?? [];\n for (const name of ownedNames) {\n if (\n !previousNames.includes(name) &&\n valueAt(observed, name) !== undefined\n )\n return yield* new OwnedBySomeoneElse({\n message:\n \"An existing environment variable requires explicit adoption in a separate resource.\",\n resourceType: EnvironmentVariables.Type,\n physicalName: name,\n });\n }\n const desired = Object.fromEntries(\n Object.entries(news.variables).map(([name, value]) => [\n name,\n redacted(value),\n ]),\n );\n const changes: Array<{\n name: string;\n value?: Redacted.Redacted<string>;\n }> = [];\n for (const [name, value] of Object.entries(desired)) {\n const current = valueAt(observed, name);\n if (\n current === undefined ||\n Redacted.value(current) !== Redacted.value(value)\n )\n changes.push({ name, value });\n }\n for (const name of previousNames) {\n if (Object.hasOwn(desired, name)) continue;\n const original = output ? valueAt(output.originals, name) : undefined;\n const current = valueAt(observed, name);\n if (original !== undefined) {\n if (\n current === undefined ||\n Redacted.value(current) !== Redacted.value(original)\n )\n changes.push({ name, value: original });\n } else if (current !== undefined) changes.push({ name });\n }\n if (changes.length > 0)\n yield* client.updateEnvironmentVariables(\n news.url,\n news.deployKey,\n changes,\n );\n return {\n url: news.url,\n deployKey: news.deployKey,\n ownedNames,\n variables: desired,\n originals: select(output?.originals ?? {}, ownedNames),\n };\n }),\n delete: Effect.fn(\"EnvironmentVariables.delete\")(function* ({ output }) {\n const observed = yield* client\n .listEnvironmentVariables(output.url, output.deployKey)\n .pipe(Effect.catchTag(\"ConvexNotFound\", () => Effect.void));\n if (observed === undefined) return;\n const changes: Array<{\n name: string;\n value?: Redacted.Redacted<string>;\n }> = [];\n for (const name of output.ownedNames) {\n const original = valueAt(output.originals, name);\n const current = valueAt(observed, name);\n if (original !== undefined) {\n if (\n current === undefined ||\n Redacted.value(current) !== Redacted.value(original)\n )\n changes.push({ name, value: original });\n } else if (current !== undefined) changes.push({ name });\n }\n if (changes.length > 0)\n yield* client\n .updateEnvironmentVariables(output.url, output.deployKey, changes)\n .pipe(Effect.catchTag(\"ConvexNotFound\", () => Effect.void));\n }),\n } satisfies Provider.ProviderServiceInput<EnvironmentVariables>;\n});\n\n/**\n * Under `alchemy dev` variables are managed on the local backend. A backend\n * that is not running keeps its variables in its retained data, so removing\n * them is skipped rather than failing the apply.\n */\nexport const localProvider = Effect.map(\n provider,\n (service) =>\n ({\n ...service,\n delete: (input) =>\n // oxlint-disable-next-line effecttsgo/any-unknown-in-error-context -- Alchemy's provider input type erases the delete error channel.\n service.delete(input).pipe(\n Effect.catchIf(\n (error) =>\n error._tag === \"ConvexApiError\" &&\n error.code === \"TransportError\",\n () => Effect.void,\n ),\n ),\n }) satisfies Provider.ProviderServiceInput<EnvironmentVariables>,\n);\n\nexport const layer = Provider.effect(EnvironmentVariables, provider);\nexport const localLayer = Provider.effect(\n EnvironmentVariables,\n localProvider,\n).pipe(\n Layer.provide(\n ConvexClient.layer({ mode: \"local\" }).pipe(\n Layer.provide(FetchHttpClient.layer),\n ),\n ),\n);\n"],"mappings":"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"}
1
+ {"version":3,"file":"EnvironmentVariables.js","names":["ConvexClient.ConvexClient","ConvexClient.layer"],"sources":["../src/EnvironmentVariables.ts"],"sourcesContent":["import { OwnedBySomeoneElse, Unowned } from \"alchemy/AdoptPolicy\";\nimport { isResolved } from \"alchemy/Diff\";\nimport * as Provider from \"alchemy/Provider\";\nimport { Resource } from \"alchemy/Resource\";\nimport * as Effect from \"effect/Effect\";\nimport * as Layer from \"effect/Layer\";\nimport * as FetchHttpClient from \"effect/http/FetchHttpClient\";\nimport * as Redacted from \"effect/Redacted\";\nimport * as Schema from \"effect/Schema\";\n\nimport * as ConvexClient from \"./ConvexClient.js\";\nimport type { Providers } from \"./Providers.js\";\nimport { checkpointCreate, shouldAdopt } from \"./internal/Lifecycle.js\";\n\nexport interface EnvironmentVariablesProps {\n readonly url: string;\n readonly deployKey: Redacted.Redacted<string>;\n readonly variables: Readonly<\n Record<string, string | Redacted.Redacted<string>>\n >;\n}\n\nexport interface EnvironmentVariablesAttributes {\n readonly url: string;\n readonly deployKey: Redacted.Redacted<string>;\n readonly ownedNames: ReadonlyArray<string>;\n readonly variables: Readonly<Record<string, Redacted.Redacted<string>>>;\n readonly originals: Readonly<Record<string, Redacted.Redacted<string>>>;\n}\n\nexport type EnvironmentVariables = Resource<\n \"Convex.EnvironmentVariables\",\n EnvironmentVariablesProps,\n EnvironmentVariablesAttributes,\n never,\n Providers\n>;\nexport const EnvironmentVariables = Resource<EnvironmentVariables>(\n \"Convex.EnvironmentVariables\",\n);\n\nexport class EnvironmentTargetChange extends Schema.TaggedError<EnvironmentTargetChange>()(\n \"EnvironmentTargetChange\",\n { url: Schema.String },\n) {}\n\nexport const provider = Effect.gen(function* () {\n const client = yield* ConvexClient.ConvexClient;\n const redacted = (value: string | Redacted.Redacted<string>) =>\n typeof value === \"string\" ? Redacted.make(value) : value;\n const valueAt = (\n variables: Readonly<Record<string, Redacted.Redacted<string>>>,\n name: string,\n ) => (Object.hasOwn(variables, name) ? variables[name] : undefined);\n const select = (\n variables: Readonly<Record<string, Redacted.Redacted<string>>>,\n names: ReadonlyArray<string>,\n ) =>\n Object.fromEntries(\n names.flatMap((name) =>\n !Object.hasOwn(variables, name) ? [] : [[name, variables[name]]],\n ),\n );\n return {\n diff: Effect.fn(\"EnvironmentVariables.diff\")(function* ({ news, output }) {\n if (!isResolved(news) || !output) return;\n if (news.url !== output.url)\n return yield* new EnvironmentTargetChange({\n url: output.url,\n });\n const names = Object.keys(news.variables);\n if (\n names.length !== output.ownedNames.length ||\n names.some((name) => !output.ownedNames.includes(name))\n )\n return { action: \"update\" };\n const variables = yield* client.listEnvironmentVariables(\n news.url,\n news.deployKey,\n );\n for (const [name, value] of Object.entries(news.variables)) {\n const observed = valueAt(variables, name);\n if (\n observed === undefined ||\n Redacted.value(observed) !== Redacted.value(redacted(value))\n )\n return { action: \"update\" };\n }\n }),\n read: Effect.fn(\"EnvironmentVariables.read\")(function* ({ olds, output }) {\n const url = output?.url ?? olds.url;\n if (url === undefined || olds.deployKey === undefined) return;\n const observed = yield* client.listEnvironmentVariables(\n url,\n olds.deployKey,\n );\n const ownedNames = output?.ownedNames ?? Object.keys(olds.variables);\n const variables = select(observed, ownedNames);\n if (output) return { ...output, deployKey: olds.deployKey, variables };\n if (Object.keys(variables).length === 0) return undefined;\n return Unowned({\n url,\n deployKey: olds.deployKey,\n ownedNames,\n variables,\n originals: variables,\n });\n }),\n reconcile: Effect.fn(\"EnvironmentVariables.reconcile\")(function* ({\n fqn,\n instanceId,\n news,\n output,\n }) {\n if (!output) yield* checkpointCreate(fqn, instanceId, news);\n if (output && output.url !== news.url)\n return yield* new EnvironmentTargetChange({\n url: output.url,\n });\n const observed = yield* client.listEnvironmentVariables(\n news.url,\n news.deployKey,\n );\n const ownedNames = Object.keys(news.variables);\n if (!output && (yield* shouldAdopt(fqn))) {\n const variables = select(observed, ownedNames);\n output = {\n url: news.url,\n deployKey: news.deployKey,\n ownedNames,\n variables,\n originals: variables,\n };\n yield* checkpointCreate(fqn, instanceId, news, output);\n }\n const previousNames = output?.ownedNames ?? [];\n for (const name of ownedNames) {\n if (\n !previousNames.includes(name) &&\n valueAt(observed, name) !== undefined\n )\n return yield* new OwnedBySomeoneElse({\n message:\n \"An existing environment variable requires explicit adoption in a separate resource.\",\n resourceType: EnvironmentVariables.Type,\n physicalName: name,\n });\n }\n const desired = Object.fromEntries(\n Object.entries(news.variables).map(([name, value]) => [\n name,\n redacted(value),\n ]),\n );\n const changes: Array<{\n name: string;\n value?: Redacted.Redacted<string>;\n }> = [];\n for (const [name, value] of Object.entries(desired)) {\n const current = valueAt(observed, name);\n if (\n current === undefined ||\n Redacted.value(current) !== Redacted.value(value)\n )\n changes.push({ name, value });\n }\n for (const name of previousNames) {\n if (Object.hasOwn(desired, name)) continue;\n const original = output ? valueAt(output.originals, name) : undefined;\n const current = valueAt(observed, name);\n if (original !== undefined) {\n if (\n current === undefined ||\n Redacted.value(current) !== Redacted.value(original)\n )\n changes.push({ name, value: original });\n } else if (current !== undefined) changes.push({ name });\n }\n if (changes.length > 0)\n yield* client.updateEnvironmentVariables(\n news.url,\n news.deployKey,\n changes,\n );\n return {\n url: news.url,\n deployKey: news.deployKey,\n ownedNames,\n variables: desired,\n originals: select(output?.originals ?? {}, ownedNames),\n };\n }),\n delete: Effect.fn(\"EnvironmentVariables.delete\")(function* ({ output }) {\n const observed = yield* client\n .listEnvironmentVariables(output.url, output.deployKey)\n .pipe(Effect.catchTag(\"ConvexNotFound\", () => Effect.void));\n if (observed === undefined) return;\n const changes: Array<{\n name: string;\n value?: Redacted.Redacted<string>;\n }> = [];\n for (const name of output.ownedNames) {\n const original = valueAt(output.originals, name);\n const current = valueAt(observed, name);\n if (original !== undefined) {\n if (\n current === undefined ||\n Redacted.value(current) !== Redacted.value(original)\n )\n changes.push({ name, value: original });\n } else if (current !== undefined) changes.push({ name });\n }\n if (changes.length > 0)\n yield* client\n .updateEnvironmentVariables(output.url, output.deployKey, changes)\n .pipe(Effect.catchTag(\"ConvexNotFound\", () => Effect.void));\n }),\n } satisfies Provider.ProviderServiceInput<EnvironmentVariables>;\n});\n\n/**\n * Under `alchemy dev` variables are managed on the local backend. A backend\n * that is not running keeps its variables in its retained data, so removing\n * them is skipped rather than failing the apply.\n */\nexport const localProvider = Effect.map(\n provider,\n (service) =>\n ({\n ...service,\n delete: (input) =>\n // oxlint-disable-next-line effecttsgo/any-unknown-in-error-context -- Alchemy's provider input type erases the delete error channel.\n service.delete(input).pipe(\n Effect.catchIf(\n (error) =>\n error._tag === \"ConvexApiError\" &&\n error.code === \"TransportError\",\n () => Effect.void,\n ),\n ),\n }) satisfies Provider.ProviderServiceInput<EnvironmentVariables>,\n);\n\nexport const layer = Provider.effect(EnvironmentVariables, provider);\nexport const localLayer = Provider.effect(\n EnvironmentVariables,\n localProvider,\n).pipe(\n Layer.provide(\n ConvexClient.layer({ mode: \"local\" }).pipe(\n Layer.provide(FetchHttpClient.layer),\n ),\n ),\n);\n"],"mappings":"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"}
package/dist/Project.d.ts CHANGED
@@ -3,8 +3,8 @@ import * as Provider from "alchemy/Provider";
3
3
  import { Resource } from "alchemy/Resource";
4
4
  import * as Effect from "effect/Effect";
5
5
  import * as Schema from "effect/Schema";
6
- import { ConvexClient } from "./ConvexClient";
7
- import type { Providers } from "./Providers";
6
+ import { ConvexClient } from "./ConvexClient.js";
7
+ import type { Providers } from "./Providers.js";
8
8
  export interface ProjectProps {
9
9
  readonly teamId: number;
10
10
  readonly name?: string;
@@ -43,14 +43,14 @@ export declare const provider: Effect.Effect<{
43
43
  output: ProjectAttributes | undefined;
44
44
  }) => Effect.Effect<{
45
45
  action: "update";
46
- } | undefined, import("./ConvexClient").ConvexApiError | import("./ConvexClient").ConvexConflict | ProjectTeamChange, never>;
46
+ } | undefined, import("./ConvexClient.js").ConvexApiError | import("./ConvexClient.js").ConvexConflict | ProjectTeamChange, never>;
47
47
  read: (args_0: {
48
48
  id: string;
49
49
  fqn: string;
50
50
  instanceId: string;
51
51
  olds: ProjectProps;
52
52
  output: ProjectAttributes | undefined;
53
- }) => Effect.Effect<ProjectAttributes | undefined, AmbiguousProject | import("./ConvexClient").ConvexApiError | import("./ConvexClient").ConvexConflict | import("./ConvexClient").ConvexNotFound, never>;
53
+ }) => Effect.Effect<ProjectAttributes | undefined, AmbiguousProject | import("./ConvexClient.js").ConvexApiError | import("./ConvexClient.js").ConvexConflict | import("./ConvexClient.js").ConvexNotFound, never>;
54
54
  reconcile: (args_0: {
55
55
  id: string;
56
56
  fqn: string;
@@ -60,7 +60,7 @@ export declare const provider: Effect.Effect<{
60
60
  output: ProjectAttributes | undefined;
61
61
  session: import("alchemy/Report").ScopedPlanStatusSession;
62
62
  bindings: import("alchemy/Resource").ResourceBinding<never>[];
63
- }) => Effect.Effect<ProjectAttributes, AmbiguousProject | import("./ConvexClient").ConvexApiError | import("./ConvexClient").ConvexConflict | import("./ConvexClient").ConvexNotFound | import("./internal/Lifecycle").LifecycleStateError | OwnedBySomeoneElse | ProjectTeamChange | import("alchemy/State/State").StateStoreError, never>;
63
+ }) => Effect.Effect<ProjectAttributes, AmbiguousProject | import("./ConvexClient.js").ConvexApiError | import("./ConvexClient.js").ConvexConflict | import("./ConvexClient.js").ConvexNotFound | import("./internal/Lifecycle.js").LifecycleStateError | OwnedBySomeoneElse | ProjectTeamChange | import("alchemy/State/State").StateStoreError, never>;
64
64
  delete: (args_0: {
65
65
  id: string;
66
66
  fqn: string;
@@ -70,7 +70,7 @@ export declare const provider: Effect.Effect<{
70
70
  session: import("alchemy/Report").ScopedPlanStatusSession;
71
71
  bindings: import("alchemy/Resource").ResourceBinding<never>[];
72
72
  force?: boolean;
73
- }) => Effect.Effect<void, import("./ConvexClient").ConvexApiError | import("./ConvexClient").ConvexConflict, never>;
73
+ }) => Effect.Effect<void, import("./ConvexClient.js").ConvexApiError | import("./ConvexClient.js").ConvexConflict, never>;
74
74
  }, never, ConvexClient>;
75
75
  /**
76
76
  * Under `alchemy dev` a project needs no Convex account: it is a fixed local
@@ -1 +1 @@
1
- {"version":3,"file":"Project.d.ts","sourceRoot":"","sources":["../src/Project.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAW,MAAM,qBAAqB,CAAC;AAElE,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAExC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAI7C,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,MAAM,OAAO,GAAG,QAAQ,CAC5B,gBAAgB,EAChB,YAAY,EACZ,iBAAiB,EACjB,KAAK,EACL,SAAS,CACV,CAAC;AACF,eAAO,MAAM,OAAO,mDAElB,CAAC;;;;;;AAEH,qBAAa,iBAAkB,SAAQ,sBAOtC;CAAG;;;;;;AAEJ,qBAAa,gBAAiB,SAAQ,qBAOrC;CAAG;AAEJ,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uBA+HnB,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;gBAeyB,CAAC;AAEpD,eAAO,MAAM,KAAK,+EAAqC,CAAC;AACxD,eAAO,MAAM,UAAU,wEAA0C,CAAC"}
1
+ {"version":3,"file":"Project.d.ts","sourceRoot":"","sources":["../src/Project.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAW,MAAM,qBAAqB,CAAC;AAElE,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAExC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAIhD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,MAAM,OAAO,GAAG,QAAQ,CAC5B,gBAAgB,EAChB,YAAY,EACZ,iBAAiB,EACjB,KAAK,EACL,SAAS,CACV,CAAC;AACF,eAAO,MAAM,OAAO,mDAElB,CAAC;;;;;;AAEH,qBAAa,iBAAkB,SAAQ,sBAOtC;CAAG;;;;;;AAEJ,qBAAa,gBAAiB,SAAQ,qBAOrC;CAAG;AAEJ,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uBA+HnB,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;gBAeyB,CAAC;AAEpD,eAAO,MAAM,KAAK,+EAAqC,CAAC;AACxD,eAAO,MAAM,UAAU,wEAA0C,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"Project.js","names":[],"sources":["../src/Project.ts"],"sourcesContent":["import { OwnedBySomeoneElse, Unowned } from \"alchemy/AdoptPolicy\";\nimport { isResolved } from \"alchemy/Diff\";\nimport * as Provider from \"alchemy/Provider\";\nimport { Resource } from \"alchemy/Resource\";\nimport * as Effect from \"effect/Effect\";\nimport * as Schema from \"effect/Schema\";\n\nimport { ConvexClient } from \"./ConvexClient\";\nimport type { Providers } from \"./Providers\";\nimport { resourceName } from \"./internal/ResourceIdentity\";\nimport { checkpointCreate, shouldAdopt } from \"./internal/Lifecycle\";\n\nexport interface ProjectProps {\n readonly teamId: number;\n readonly name?: string;\n}\n\nexport interface ProjectAttributes {\n readonly projectId: number;\n readonly teamId: number;\n readonly name: string;\n readonly slug: string;\n}\n\nexport type Project = Resource<\n \"Convex.Project\",\n ProjectProps,\n ProjectAttributes,\n never,\n Providers\n>;\nexport const Project = Resource<Project>(\"Convex.Project\", {\n defaultRemovalPolicy: \"retain\",\n});\n\nexport class ProjectTeamChange extends Schema.TaggedError<ProjectTeamChange>()(\n \"ProjectTeamChange\",\n {\n projectId: Schema.Finite,\n teamId: Schema.Finite,\n requestedTeamId: Schema.Finite,\n },\n) {}\n\nexport class AmbiguousProject extends Schema.TaggedError<AmbiguousProject>()(\n \"AmbiguousProject\",\n {\n teamId: Schema.Finite,\n name: Schema.String,\n projectIds: Schema.Array(Schema.Finite),\n },\n) {}\n\nexport const provider = Effect.gen(function* () {\n const client = yield* ConvexClient;\n const attributes = (project: {\n id: number;\n teamId: number;\n name: string;\n slug: string;\n }): ProjectAttributes => ({\n projectId: project.id,\n teamId: project.teamId,\n name: project.name,\n slug: project.slug,\n });\n const find = Effect.fn(\"Project.find\")(function* (\n teamId: number,\n name: string,\n ) {\n const matches = (yield* client.listProjects(teamId)).filter(\n (project) => project.name === name,\n );\n if (matches.length > 1)\n return yield* new AmbiguousProject({\n teamId,\n name,\n projectIds: matches.map((project) => project.id),\n });\n return matches[0];\n });\n return {\n diff: Effect.fn(\"Project.diff\")(function* ({ news, output }) {\n if (!isResolved(news) || !output) return;\n if (output.teamId !== news.teamId)\n return yield* new ProjectTeamChange({\n projectId: output.projectId,\n teamId: output.teamId,\n requestedTeamId: news.teamId,\n });\n const project = yield* client\n .getProject(output.projectId)\n .pipe(Effect.catchTag(\"ConvexNotFound\", () => Effect.void));\n if (!project) return { action: \"update\" };\n if (project.teamId !== news.teamId)\n return yield* new ProjectTeamChange({\n projectId: project.id,\n teamId: project.teamId,\n requestedTeamId: news.teamId,\n });\n if ((news.name ?? output.name) !== project.name)\n return { action: \"update\" };\n }),\n read: Effect.fn(\"Project.read\")(function* ({\n fqn,\n instanceId,\n olds,\n output,\n }) {\n if (output) {\n const project = yield* client\n .getProject(output.projectId)\n .pipe(Effect.catchTag(\"ConvexNotFound\", () => Effect.void));\n return project ? attributes(project) : undefined;\n }\n if (olds.teamId === undefined) return;\n const project = yield* find(\n olds.teamId,\n olds.name ?? (yield* resourceName(\"project\", fqn, instanceId)),\n );\n return project ? Unowned(attributes(project)) : undefined;\n }),\n reconcile: Effect.fn(\"Project.reconcile\")(function* ({\n fqn,\n instanceId,\n news,\n output,\n }) {\n if (!output) yield* checkpointCreate(fqn, instanceId, news);\n if (output && output.teamId !== news.teamId)\n return yield* new ProjectTeamChange({\n projectId: output.projectId,\n teamId: output.teamId,\n requestedTeamId: news.teamId,\n });\n let project = output\n ? yield* client\n .getProject(output.projectId)\n .pipe(Effect.catchTag(\"ConvexNotFound\", () => Effect.void))\n : undefined;\n const name =\n news.name ??\n output?.name ??\n (yield* resourceName(\"project\", fqn, instanceId));\n if (!project) {\n const existing = yield* find(news.teamId, name);\n if (existing && !(yield* shouldAdopt(fqn)))\n return yield* new OwnedBySomeoneElse({\n message: \"An existing project requires explicit adoption.\",\n resourceType: Project.Type,\n physicalName: name,\n });\n if (existing) {\n project = existing;\n yield* checkpointCreate(fqn, instanceId, news, attributes(existing));\n } else {\n const created = yield* client.createProject(news.teamId, {\n projectName: name,\n });\n project = yield* client.getProject(created.id);\n }\n }\n if (project.teamId !== news.teamId)\n return yield* new ProjectTeamChange({\n projectId: project.id,\n teamId: project.teamId,\n requestedTeamId: news.teamId,\n });\n if (project.name !== name)\n project = yield* client.updateProject(project.id, {\n name,\n });\n return attributes(project);\n }),\n delete: Effect.fn(\"Project.delete\")(function* ({ output }) {\n yield* client\n .deleteProject(output.projectId)\n .pipe(Effect.catchTag(\"ConvexNotFound\", () => Effect.void));\n }),\n } satisfies Provider.ProviderServiceInput<Project>;\n});\n\n/**\n * Under `alchemy dev` a project needs no Convex account: it is a fixed local\n * identity that local deployments ignore.\n */\nexport const localProvider = Effect.succeed({\n reconcile: Effect.fn(\"Project.localReconcile\")(function* ({\n fqn,\n instanceId,\n news,\n }) {\n const name = news.name ?? (yield* resourceName(\"project\", fqn, instanceId));\n return {\n projectId: 0,\n teamId: news.teamId,\n name,\n slug: name,\n } satisfies ProjectAttributes;\n }),\n delete: () => Effect.void,\n} satisfies Provider.ProviderServiceInput<Project>);\n\nexport const layer = Provider.effect(Project, provider);\nexport const localLayer = Provider.effect(Project, localProvider);\n"],"mappings":"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"}
1
+ {"version":3,"file":"Project.js","names":[],"sources":["../src/Project.ts"],"sourcesContent":["import { OwnedBySomeoneElse, Unowned } from \"alchemy/AdoptPolicy\";\nimport { isResolved } from \"alchemy/Diff\";\nimport * as Provider from \"alchemy/Provider\";\nimport { Resource } from \"alchemy/Resource\";\nimport * as Effect from \"effect/Effect\";\nimport * as Schema from \"effect/Schema\";\n\nimport { ConvexClient } from \"./ConvexClient.js\";\nimport type { Providers } from \"./Providers.js\";\nimport { resourceName } from \"./internal/ResourceIdentity.js\";\nimport { checkpointCreate, shouldAdopt } from \"./internal/Lifecycle.js\";\n\nexport interface ProjectProps {\n readonly teamId: number;\n readonly name?: string;\n}\n\nexport interface ProjectAttributes {\n readonly projectId: number;\n readonly teamId: number;\n readonly name: string;\n readonly slug: string;\n}\n\nexport type Project = Resource<\n \"Convex.Project\",\n ProjectProps,\n ProjectAttributes,\n never,\n Providers\n>;\nexport const Project = Resource<Project>(\"Convex.Project\", {\n defaultRemovalPolicy: \"retain\",\n});\n\nexport class ProjectTeamChange extends Schema.TaggedError<ProjectTeamChange>()(\n \"ProjectTeamChange\",\n {\n projectId: Schema.Finite,\n teamId: Schema.Finite,\n requestedTeamId: Schema.Finite,\n },\n) {}\n\nexport class AmbiguousProject extends Schema.TaggedError<AmbiguousProject>()(\n \"AmbiguousProject\",\n {\n teamId: Schema.Finite,\n name: Schema.String,\n projectIds: Schema.Array(Schema.Finite),\n },\n) {}\n\nexport const provider = Effect.gen(function* () {\n const client = yield* ConvexClient;\n const attributes = (project: {\n id: number;\n teamId: number;\n name: string;\n slug: string;\n }): ProjectAttributes => ({\n projectId: project.id,\n teamId: project.teamId,\n name: project.name,\n slug: project.slug,\n });\n const find = Effect.fn(\"Project.find\")(function* (\n teamId: number,\n name: string,\n ) {\n const matches = (yield* client.listProjects(teamId)).filter(\n (project) => project.name === name,\n );\n if (matches.length > 1)\n return yield* new AmbiguousProject({\n teamId,\n name,\n projectIds: matches.map((project) => project.id),\n });\n return matches[0];\n });\n return {\n diff: Effect.fn(\"Project.diff\")(function* ({ news, output }) {\n if (!isResolved(news) || !output) return;\n if (output.teamId !== news.teamId)\n return yield* new ProjectTeamChange({\n projectId: output.projectId,\n teamId: output.teamId,\n requestedTeamId: news.teamId,\n });\n const project = yield* client\n .getProject(output.projectId)\n .pipe(Effect.catchTag(\"ConvexNotFound\", () => Effect.void));\n if (!project) return { action: \"update\" };\n if (project.teamId !== news.teamId)\n return yield* new ProjectTeamChange({\n projectId: project.id,\n teamId: project.teamId,\n requestedTeamId: news.teamId,\n });\n if ((news.name ?? output.name) !== project.name)\n return { action: \"update\" };\n }),\n read: Effect.fn(\"Project.read\")(function* ({\n fqn,\n instanceId,\n olds,\n output,\n }) {\n if (output) {\n const project = yield* client\n .getProject(output.projectId)\n .pipe(Effect.catchTag(\"ConvexNotFound\", () => Effect.void));\n return project ? attributes(project) : undefined;\n }\n if (olds.teamId === undefined) return;\n const project = yield* find(\n olds.teamId,\n olds.name ?? (yield* resourceName(\"project\", fqn, instanceId)),\n );\n return project ? Unowned(attributes(project)) : undefined;\n }),\n reconcile: Effect.fn(\"Project.reconcile\")(function* ({\n fqn,\n instanceId,\n news,\n output,\n }) {\n if (!output) yield* checkpointCreate(fqn, instanceId, news);\n if (output && output.teamId !== news.teamId)\n return yield* new ProjectTeamChange({\n projectId: output.projectId,\n teamId: output.teamId,\n requestedTeamId: news.teamId,\n });\n let project = output\n ? yield* client\n .getProject(output.projectId)\n .pipe(Effect.catchTag(\"ConvexNotFound\", () => Effect.void))\n : undefined;\n const name =\n news.name ??\n output?.name ??\n (yield* resourceName(\"project\", fqn, instanceId));\n if (!project) {\n const existing = yield* find(news.teamId, name);\n if (existing && !(yield* shouldAdopt(fqn)))\n return yield* new OwnedBySomeoneElse({\n message: \"An existing project requires explicit adoption.\",\n resourceType: Project.Type,\n physicalName: name,\n });\n if (existing) {\n project = existing;\n yield* checkpointCreate(fqn, instanceId, news, attributes(existing));\n } else {\n const created = yield* client.createProject(news.teamId, {\n projectName: name,\n });\n project = yield* client.getProject(created.id);\n }\n }\n if (project.teamId !== news.teamId)\n return yield* new ProjectTeamChange({\n projectId: project.id,\n teamId: project.teamId,\n requestedTeamId: news.teamId,\n });\n if (project.name !== name)\n project = yield* client.updateProject(project.id, {\n name,\n });\n return attributes(project);\n }),\n delete: Effect.fn(\"Project.delete\")(function* ({ output }) {\n yield* client\n .deleteProject(output.projectId)\n .pipe(Effect.catchTag(\"ConvexNotFound\", () => Effect.void));\n }),\n } satisfies Provider.ProviderServiceInput<Project>;\n});\n\n/**\n * Under `alchemy dev` a project needs no Convex account: it is a fixed local\n * identity that local deployments ignore.\n */\nexport const localProvider = Effect.succeed({\n reconcile: Effect.fn(\"Project.localReconcile\")(function* ({\n fqn,\n instanceId,\n news,\n }) {\n const name = news.name ?? (yield* resourceName(\"project\", fqn, instanceId));\n return {\n projectId: 0,\n teamId: news.teamId,\n name,\n slug: name,\n } satisfies ProjectAttributes;\n }),\n delete: () => Effect.void,\n} satisfies Provider.ProviderServiceInput<Project>);\n\nexport const layer = Provider.effect(Project, provider);\nexport const localLayer = Provider.effect(Project, localProvider);\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"Providers.js","names":["Project.Project","Deployment.Deployment","DeployKey.DeployKey","EnvironmentVariables.EnvironmentVariables","Code.Code","Project.layer","Project.localLayer","Deployment.layer","Deployment.localLayer","DeployKey.layer","DeployKey.localLayer","EnvironmentVariables.layer","EnvironmentVariables.localLayer","Code.layer","Code.localLayer","ConvexClient.layer","CommandRunner.layer","PushLock.layer"],"sources":["../src/Providers.ts"],"sourcesContent":["import * as ProviderLayer from \"alchemy/Local/ProviderLayer\";\nimport * as Provider from \"alchemy/Provider\";\nimport type * as Redacted from \"effect/Redacted\";\nimport * as Layer from \"effect/Layer\";\nimport * as FetchHttpClient from \"effect/http/FetchHttpClient\";\nimport * as Code from \"./Code\";\nimport * as ConvexClient from \"./ConvexClient\";\nimport * as Deployment from \"./Deployment\";\nimport * as DeployKey from \"./DeployKey\";\nimport * as EnvironmentVariables from \"./EnvironmentVariables\";\nimport * as Project from \"./Project\";\nimport * as CommandRunner from \"./internal/CommandRunner\";\nimport * as PushLock from \"./internal/PushLock\";\n\nexport class Providers extends Provider.ProviderCollection<Providers>()(\n \"@confect/alchemy/Providers\",\n) {}\n\n/**\n * Register Convex resources without eagerly resolving management credentials.\n * `alchemy deploy` resolves each resource to its cloud provider; `alchemy dev`\n * resolves the same resources to local providers backed by a local Convex\n * backend, so one stack definition serves both.\n */\nexport const providers = (options?: {\n readonly token?: Redacted.Redacted<string>;\n}) =>\n Layer.effect(\n Providers,\n Provider.collection([\n Project.Project,\n Deployment.Deployment,\n DeployKey.DeployKey,\n EnvironmentVariables.EnvironmentVariables,\n Code.Code,\n ]),\n ).pipe(\n Layer.provide(\n Layer.mergeAll(\n ProviderLayer.dual(Project.Project, {\n live: () => Project.layer,\n local: () => Project.localLayer,\n }),\n ProviderLayer.dual(Deployment.Deployment, {\n live: () => Deployment.layer,\n local: () => Deployment.localLayer,\n }),\n ProviderLayer.dual(DeployKey.DeployKey, {\n live: () => DeployKey.layer,\n local: () => DeployKey.localLayer,\n }),\n ProviderLayer.dual(EnvironmentVariables.EnvironmentVariables, {\n live: () => EnvironmentVariables.layer,\n local: () => EnvironmentVariables.localLayer,\n }),\n ProviderLayer.dual(Code.Code, {\n live: () => Code.layer,\n local: () => Code.localLayer,\n }),\n ),\n ),\n Layer.provide(\n ConvexClient.layer(options).pipe(Layer.provide(FetchHttpClient.layer)),\n ),\n Layer.provide(CommandRunner.layer),\n Layer.provide(PushLock.layer()),\n );\n"],"mappings":";;;;;;;;;;;;;AAcA,IAAa,YAAb,cAA+B,SAAS,mBAA8B,CAAC,CACrE,4BACF,CAAC,CAAC,CAAC;;;;;;;AAQH,MAAa,aAAa,YAGxB,MAAM,OACJ,WACA,SAAS,WAAW;CAClBA;CACAC;CACAC;CACAC;CACAC;AACF,CAAC,CACH,CAAC,CAAC,KACA,MAAM,QACJ,MAAM,SACJ,cAAc,KAAKJ,SAAiB;CAClC,YAAYK;CACZ,aAAaC;AACf,CAAC,GACD,cAAc,KAAKL,YAAuB;CACxC,YAAYM;CACZ,aAAaC;AACf,CAAC,GACD,cAAc,KAAKN,WAAqB;CACtC,YAAYO;CACZ,aAAaC;AACf,CAAC,GACD,cAAc,KAAKP,sBAA2C;CAC5D,YAAYQ;CACZ,aAAaC;AACf,CAAC,GACD,cAAc,KAAKR,MAAW;CAC5B,YAAYS;CACZ,aAAaC;AACf,CAAC,CACH,CACF,GACA,MAAM,QACJC,QAAmB,OAAO,CAAC,CAAC,KAAK,MAAM,QAAQ,gBAAgB,KAAK,CAAC,CACvE,GACA,MAAM,QAAQC,KAAmB,GACjC,MAAM,QAAQC,QAAe,CAAC,CAChC"}
1
+ {"version":3,"file":"Providers.js","names":["Project.Project","Deployment.Deployment","DeployKey.DeployKey","EnvironmentVariables.EnvironmentVariables","Code.Code","Project.layer","Project.localLayer","Deployment.layer","Deployment.localLayer","DeployKey.layer","DeployKey.localLayer","EnvironmentVariables.layer","EnvironmentVariables.localLayer","Code.layer","Code.localLayer","ConvexClient.layer","CommandRunner.layer","PushLock.layer"],"sources":["../src/Providers.ts"],"sourcesContent":["import * as ProviderLayer from \"alchemy/Local/ProviderLayer\";\nimport * as Provider from \"alchemy/Provider\";\nimport type * as Redacted from \"effect/Redacted\";\nimport * as Layer from \"effect/Layer\";\nimport * as FetchHttpClient from \"effect/http/FetchHttpClient\";\nimport * as Code from \"./Code.js\";\nimport * as ConvexClient from \"./ConvexClient.js\";\nimport * as Deployment from \"./Deployment.js\";\nimport * as DeployKey from \"./DeployKey.js\";\nimport * as EnvironmentVariables from \"./EnvironmentVariables.js\";\nimport * as Project from \"./Project.js\";\nimport * as CommandRunner from \"./internal/CommandRunner.js\";\nimport * as PushLock from \"./internal/PushLock.js\";\n\nexport class Providers extends Provider.ProviderCollection<Providers>()(\n \"@confect/alchemy/Providers\",\n) {}\n\n/**\n * Register Convex resources without eagerly resolving management credentials.\n * `alchemy deploy` resolves each resource to its cloud provider; `alchemy dev`\n * resolves the same resources to local providers backed by a local Convex\n * backend, so one stack definition serves both.\n */\nexport const providers = (options?: {\n readonly token?: Redacted.Redacted<string>;\n}) =>\n Layer.effect(\n Providers,\n Provider.collection([\n Project.Project,\n Deployment.Deployment,\n DeployKey.DeployKey,\n EnvironmentVariables.EnvironmentVariables,\n Code.Code,\n ]),\n ).pipe(\n Layer.provide(\n Layer.mergeAll(\n ProviderLayer.dual(Project.Project, {\n live: () => Project.layer,\n local: () => Project.localLayer,\n }),\n ProviderLayer.dual(Deployment.Deployment, {\n live: () => Deployment.layer,\n local: () => Deployment.localLayer,\n }),\n ProviderLayer.dual(DeployKey.DeployKey, {\n live: () => DeployKey.layer,\n local: () => DeployKey.localLayer,\n }),\n ProviderLayer.dual(EnvironmentVariables.EnvironmentVariables, {\n live: () => EnvironmentVariables.layer,\n local: () => EnvironmentVariables.localLayer,\n }),\n ProviderLayer.dual(Code.Code, {\n live: () => Code.layer,\n local: () => Code.localLayer,\n }),\n ),\n ),\n Layer.provide(\n ConvexClient.layer(options).pipe(Layer.provide(FetchHttpClient.layer)),\n ),\n Layer.provide(CommandRunner.layer),\n Layer.provide(PushLock.layer()),\n );\n"],"mappings":";;;;;;;;;;;;;AAcA,IAAa,YAAb,cAA+B,SAAS,mBAA8B,CAAC,CACrE,4BACF,CAAC,CAAC,CAAC;;;;;;;AAQH,MAAa,aAAa,YAGxB,MAAM,OACJ,WACA,SAAS,WAAW;CAClBA;CACAC;CACAC;CACAC;CACAC;AACF,CAAC,CACH,CAAC,CAAC,KACA,MAAM,QACJ,MAAM,SACJ,cAAc,KAAKJ,SAAiB;CAClC,YAAYK;CACZ,aAAaC;AACf,CAAC,GACD,cAAc,KAAKL,YAAuB;CACxC,YAAYM;CACZ,aAAaC;AACf,CAAC,GACD,cAAc,KAAKN,WAAqB;CACtC,YAAYO;CACZ,aAAaC;AACf,CAAC,GACD,cAAc,KAAKP,sBAA2C;CAC5D,YAAYQ;CACZ,aAAaC;AACf,CAAC,GACD,cAAc,KAAKR,MAAW;CAC5B,YAAYS;CACZ,aAAaC;AACf,CAAC,CACH,CACF,GACA,MAAM,QACJC,QAAmB,OAAO,CAAC,CAAC,KAAK,MAAM,QAAQ,gBAAgB,KAAK,CAAC,CACvE,GACA,MAAM,QAAQC,KAAmB,GACjC,MAAM,QAAQC,QAAe,CAAC,CAChC"}
package/dist/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- export * as Convex from "./Convex";
2
- export * as Confect from "./Confect";
1
+ export * as Convex from "./Convex.js";
2
+ export * as Confect from "./Confect.js";
3
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,UAAU,CAAC;AACnC,OAAO,KAAK,OAAO,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AACtC,OAAO,KAAK,OAAO,MAAM,cAAc,CAAC"}
@@ -1,9 +1,9 @@
1
1
  import type { ProviderMode } from "alchemy/ProviderMode";
2
2
  import * as Effect from "effect/Effect";
3
3
  import * as Schema from "effect/Schema";
4
- import type { CodeProps } from "../Code";
5
- import { CommandRunner } from "./CommandRunner";
6
- import { PushLock } from "./PushLock";
4
+ import type { CodeProps } from "../Code.js";
5
+ import { CommandRunner } from "./CommandRunner.js";
6
+ import { PushLock } from "./PushLock.js";
7
7
  declare const InvalidDeploymentTarget_base: Schema.Class<InvalidDeploymentTarget, Schema.TaggedStruct<"InvalidDeploymentTarget", {
8
8
  readonly reason: Schema.Literals<readonly ["deployment", "deployKey"]>;
9
9
  }>, import("effect/Cause").YieldableError>;
@@ -12,6 +12,6 @@ export declare class InvalidDeploymentTarget extends InvalidDeploymentTarget_bas
12
12
  export declare const deploy: (props: CodeProps, mode?: ProviderMode | undefined) => Effect.Effect<{
13
13
  name: string;
14
14
  url: string;
15
- }, import("./CommandRunner").CommandError | InvalidDeploymentTarget | import("./PushLock").PushLockError, CommandRunner | PushLock>;
15
+ }, import("./CommandRunner.js").CommandError | InvalidDeploymentTarget | import("./PushLock.js").PushLockError, CommandRunner | PushLock>;
16
16
  export {};
17
17
  //# sourceMappingURL=CodeDeployment.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"CodeDeployment.d.ts","sourceRoot":"","sources":["../../src/internal/CodeDeployment.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAGxC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,EAAE,aAAa,EAAmB,MAAM,iBAAiB,CAAC;AAEjE,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;;;;AAEtC,qBAAa,uBAAwB,SAAQ,4BAG5C;CAAG;AAoDJ,eAAO,MAAM,MAAM;;;mIAejB,CAAC"}
1
+ {"version":3,"file":"CodeDeployment.d.ts","sourceRoot":"","sources":["../../src/internal/CodeDeployment.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAGxC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAmB,MAAM,oBAAoB,CAAC;AAEpE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;;;;AAEzC,qBAAa,uBAAwB,SAAQ,4BAG5C;CAAG;AAoDJ,eAAO,MAAM,MAAM;;;yIAejB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"CodeDeployment.js","names":["Loopback.isOrigin"],"sources":["../../src/internal/CodeDeployment.ts"],"sourcesContent":["import type { ProviderMode } from \"alchemy/ProviderMode\";\nimport * as Effect from \"effect/Effect\";\nimport * as Redacted from \"effect/Redacted\";\nimport * as Result from \"effect/Result\";\nimport * as Schema from \"effect/Schema\";\nimport type { CodeProps } from \"../Code\";\nimport { CommandRunner, type PushTarget } from \"./CommandRunner\";\nimport * as Loopback from \"./Loopback\";\nimport { PushLock } from \"./PushLock\";\n\nexport class InvalidDeploymentTarget extends Schema.TaggedError<InvalidDeploymentTarget>()(\n \"InvalidDeploymentTarget\",\n { reason: Schema.Literals([\"deployment\", \"deployKey\"]) },\n) {}\n\nconst deploymentName = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;\n\nconst cloudTarget = (\n props: CodeProps,\n): Result.Result<PushTarget, InvalidDeploymentTarget> => {\n const { name, url } = props.deployment;\n if (\n !deploymentName.test(name) ||\n !new RegExp(\n `^https://${name}(?:\\\\.[a-z]{2}-[a-z]+-[0-9]+)?\\\\.convex\\\\.cloud$`,\n ).test(url)\n )\n return Result.fail(new InvalidDeploymentTarget({ reason: \"deployment\" }));\n const key =\n /^(?:dev|prod|preview|custom):([a-z0-9]+(?:-[a-z0-9]+)*)\\|[a-zA-Z0-9+/=_-]+$/.exec(\n Redacted.value(props.deployKey),\n );\n if (!key || key[1] !== name)\n return Result.fail(new InvalidDeploymentTarget({ reason: \"deployKey\" }));\n return Result.succeed({\n _tag: \"Cloud\",\n deploymentName: name,\n deployKey: props.deployKey,\n });\n};\n\nconst localTarget = (\n props: CodeProps,\n): Result.Result<PushTarget, InvalidDeploymentTarget> => {\n const { name, url } = props.deployment;\n if (!deploymentName.test(name) || !Loopback.isOrigin(url))\n return Result.fail(new InvalidDeploymentTarget({ reason: \"deployment\" }));\n const key = /^([a-z0-9]+(?:-[a-z0-9]+)*)\\|[0-9a-f]+$/.exec(\n Redacted.value(props.deployKey),\n );\n if (!key || key[1] !== name)\n return Result.fail(new InvalidDeploymentTarget({ reason: \"deployKey\" }));\n return Result.succeed({\n _tag: \"SelfHosted\",\n deploymentName: name,\n url,\n adminKey: props.deployKey,\n });\n};\n\nconst targets = { live: cloudTarget, local: localTarget } satisfies Record<\n ProviderMode,\n (props: CodeProps) => Result.Result<PushTarget, InvalidDeploymentTarget>\n>;\n\nexport const deploy = Effect.fn(\"Code.deploy\")(function* (\n props: CodeProps,\n mode: ProviderMode = \"live\",\n) {\n const target = yield* Effect.fromResult(targets[mode](props));\n const runner = yield* CommandRunner;\n const lock = yield* PushLock;\n yield* lock.withLock(\n target.deploymentName,\n Effect.gen(function* () {\n if (props.prepare) yield* runner.prepare(props.prepare, props.cwd);\n yield* runner.deploy(target, props.cwd);\n }),\n );\n return { name: props.deployment.name, url: props.deployment.url };\n});\n"],"mappings":";;;;;;;;AAUA,IAAa,0BAAb,cAA6C,OAAO,YAAqC,CAAC,CACxF,2BACA,EAAE,QAAQ,OAAO,SAAS,CAAC,cAAc,WAAW,CAAC,EAAE,CACzD,CAAC,CAAC,CAAC;AAEH,MAAM,iBAAiB;AAEvB,MAAM,eACJ,UACuD;CACvD,MAAM,EAAE,MAAM,QAAQ,MAAM;CAC5B,IACE,CAAC,eAAe,KAAK,IAAI,KACzB,CAAC,IAAI,OACH,YAAY,KAAK,iDACnB,CAAC,CAAC,KAAK,GAAG,GAEV,OAAO,OAAO,KAAK,IAAI,wBAAwB,EAAE,QAAQ,aAAa,CAAC,CAAC;CAC1E,MAAM,MACJ,8EAA8E,KAC5E,SAAS,MAAM,MAAM,SAAS,CAChC;CACF,IAAI,CAAC,OAAO,IAAI,OAAO,MACrB,OAAO,OAAO,KAAK,IAAI,wBAAwB,EAAE,QAAQ,YAAY,CAAC,CAAC;CACzE,OAAO,OAAO,QAAQ;EACpB,MAAM;EACN,gBAAgB;EAChB,WAAW,MAAM;CACnB,CAAC;AACH;AAEA,MAAM,eACJ,UACuD;CACvD,MAAM,EAAE,MAAM,QAAQ,MAAM;CAC5B,IAAI,CAAC,eAAe,KAAK,IAAI,KAAK,CAACA,SAAkB,GAAG,GACtD,OAAO,OAAO,KAAK,IAAI,wBAAwB,EAAE,QAAQ,aAAa,CAAC,CAAC;CAC1E,MAAM,MAAM,0CAA0C,KACpD,SAAS,MAAM,MAAM,SAAS,CAChC;CACA,IAAI,CAAC,OAAO,IAAI,OAAO,MACrB,OAAO,OAAO,KAAK,IAAI,wBAAwB,EAAE,QAAQ,YAAY,CAAC,CAAC;CACzE,OAAO,OAAO,QAAQ;EACpB,MAAM;EACN,gBAAgB;EAChB;EACA,UAAU,MAAM;CAClB,CAAC;AACH;AAEA,MAAM,UAAU;CAAE,MAAM;CAAa,OAAO;AAAY;AAKxD,MAAa,SAAS,OAAO,GAAG,aAAa,CAAC,CAAC,WAC7C,OACA,OAAqB,QACrB;CACA,MAAM,SAAS,OAAO,OAAO,WAAW,QAAQ,KAAK,CAAC,KAAK,CAAC;CAC5D,MAAM,SAAS,OAAO;CAEtB,QAAO,OADa,SAAA,CACR,SACV,OAAO,gBACP,OAAO,IAAI,aAAa;EACtB,IAAI,MAAM,SAAS,OAAO,OAAO,QAAQ,MAAM,SAAS,MAAM,GAAG;EACjE,OAAO,OAAO,OAAO,QAAQ,MAAM,GAAG;CACxC,CAAC,CACH;CACA,OAAO;EAAE,MAAM,MAAM,WAAW;EAAM,KAAK,MAAM,WAAW;CAAI;AAClE,CAAC"}
1
+ {"version":3,"file":"CodeDeployment.js","names":["Loopback.isOrigin"],"sources":["../../src/internal/CodeDeployment.ts"],"sourcesContent":["import type { ProviderMode } from \"alchemy/ProviderMode\";\nimport * as Effect from \"effect/Effect\";\nimport * as Redacted from \"effect/Redacted\";\nimport * as Result from \"effect/Result\";\nimport * as Schema from \"effect/Schema\";\nimport type { CodeProps } from \"../Code.js\";\nimport { CommandRunner, type PushTarget } from \"./CommandRunner.js\";\nimport * as Loopback from \"./Loopback.js\";\nimport { PushLock } from \"./PushLock.js\";\n\nexport class InvalidDeploymentTarget extends Schema.TaggedError<InvalidDeploymentTarget>()(\n \"InvalidDeploymentTarget\",\n { reason: Schema.Literals([\"deployment\", \"deployKey\"]) },\n) {}\n\nconst deploymentName = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;\n\nconst cloudTarget = (\n props: CodeProps,\n): Result.Result<PushTarget, InvalidDeploymentTarget> => {\n const { name, url } = props.deployment;\n if (\n !deploymentName.test(name) ||\n !new RegExp(\n `^https://${name}(?:\\\\.[a-z]{2}-[a-z]+-[0-9]+)?\\\\.convex\\\\.cloud$`,\n ).test(url)\n )\n return Result.fail(new InvalidDeploymentTarget({ reason: \"deployment\" }));\n const key =\n /^(?:dev|prod|preview|custom):([a-z0-9]+(?:-[a-z0-9]+)*)\\|[a-zA-Z0-9+/=_-]+$/.exec(\n Redacted.value(props.deployKey),\n );\n if (!key || key[1] !== name)\n return Result.fail(new InvalidDeploymentTarget({ reason: \"deployKey\" }));\n return Result.succeed({\n _tag: \"Cloud\",\n deploymentName: name,\n deployKey: props.deployKey,\n });\n};\n\nconst localTarget = (\n props: CodeProps,\n): Result.Result<PushTarget, InvalidDeploymentTarget> => {\n const { name, url } = props.deployment;\n if (!deploymentName.test(name) || !Loopback.isOrigin(url))\n return Result.fail(new InvalidDeploymentTarget({ reason: \"deployment\" }));\n const key = /^([a-z0-9]+(?:-[a-z0-9]+)*)\\|[0-9a-f]+$/.exec(\n Redacted.value(props.deployKey),\n );\n if (!key || key[1] !== name)\n return Result.fail(new InvalidDeploymentTarget({ reason: \"deployKey\" }));\n return Result.succeed({\n _tag: \"SelfHosted\",\n deploymentName: name,\n url,\n adminKey: props.deployKey,\n });\n};\n\nconst targets = { live: cloudTarget, local: localTarget } satisfies Record<\n ProviderMode,\n (props: CodeProps) => Result.Result<PushTarget, InvalidDeploymentTarget>\n>;\n\nexport const deploy = Effect.fn(\"Code.deploy\")(function* (\n props: CodeProps,\n mode: ProviderMode = \"live\",\n) {\n const target = yield* Effect.fromResult(targets[mode](props));\n const runner = yield* CommandRunner;\n const lock = yield* PushLock;\n yield* lock.withLock(\n target.deploymentName,\n Effect.gen(function* () {\n if (props.prepare) yield* runner.prepare(props.prepare, props.cwd);\n yield* runner.deploy(target, props.cwd);\n }),\n );\n return { name: props.deployment.name, url: props.deployment.url };\n});\n"],"mappings":";;;;;;;;AAUA,IAAa,0BAAb,cAA6C,OAAO,YAAqC,CAAC,CACxF,2BACA,EAAE,QAAQ,OAAO,SAAS,CAAC,cAAc,WAAW,CAAC,EAAE,CACzD,CAAC,CAAC,CAAC;AAEH,MAAM,iBAAiB;AAEvB,MAAM,eACJ,UACuD;CACvD,MAAM,EAAE,MAAM,QAAQ,MAAM;CAC5B,IACE,CAAC,eAAe,KAAK,IAAI,KACzB,CAAC,IAAI,OACH,YAAY,KAAK,iDACnB,CAAC,CAAC,KAAK,GAAG,GAEV,OAAO,OAAO,KAAK,IAAI,wBAAwB,EAAE,QAAQ,aAAa,CAAC,CAAC;CAC1E,MAAM,MACJ,8EAA8E,KAC5E,SAAS,MAAM,MAAM,SAAS,CAChC;CACF,IAAI,CAAC,OAAO,IAAI,OAAO,MACrB,OAAO,OAAO,KAAK,IAAI,wBAAwB,EAAE,QAAQ,YAAY,CAAC,CAAC;CACzE,OAAO,OAAO,QAAQ;EACpB,MAAM;EACN,gBAAgB;EAChB,WAAW,MAAM;CACnB,CAAC;AACH;AAEA,MAAM,eACJ,UACuD;CACvD,MAAM,EAAE,MAAM,QAAQ,MAAM;CAC5B,IAAI,CAAC,eAAe,KAAK,IAAI,KAAK,CAACA,SAAkB,GAAG,GACtD,OAAO,OAAO,KAAK,IAAI,wBAAwB,EAAE,QAAQ,aAAa,CAAC,CAAC;CAC1E,MAAM,MAAM,0CAA0C,KACpD,SAAS,MAAM,MAAM,SAAS,CAChC;CACA,IAAI,CAAC,OAAO,IAAI,OAAO,MACrB,OAAO,OAAO,KAAK,IAAI,wBAAwB,EAAE,QAAQ,YAAY,CAAC,CAAC;CACzE,OAAO,OAAO,QAAQ;EACpB,MAAM;EACN,gBAAgB;EAChB;EACA,UAAU,MAAM;CAClB,CAAC;AACH;AAEA,MAAM,UAAU;CAAE,MAAM;CAAa,OAAO;AAAY;AAKxD,MAAa,SAAS,OAAO,GAAG,aAAa,CAAC,CAAC,WAC7C,OACA,OAAqB,QACrB;CACA,MAAM,SAAS,OAAO,OAAO,WAAW,QAAQ,KAAK,CAAC,KAAK,CAAC;CAC5D,MAAM,SAAS,OAAO;CAEtB,QAAO,OADa,SAAA,CACR,SACV,OAAO,gBACP,OAAO,IAAI,aAAa;EACtB,IAAI,MAAM,SAAS,OAAO,OAAO,QAAQ,MAAM,SAAS,MAAM,GAAG;EACjE,OAAO,OAAO,OAAO,QAAQ,MAAM,GAAG;CACxC,CAAC,CACH;CACA,OAAO;EAAE,MAAM,MAAM,WAAW;EAAM,KAAK,MAAM,WAAW;CAAI;AAClE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"LocalBackend.js","names":["Loopback.parsePortRange","FileLock.acquire","Loopback.origin"],"sources":["../../src/internal/LocalBackend.ts"],"sourcesContent":["import { createServer, type Server } from \"node:net\";\nimport { dotAlchemyDirectory } from \"alchemy/AlchemyContext\";\nimport { Stack } from \"alchemy/Stack\";\nimport * as Config from \"effect/Config\";\nimport * as Crypto from \"effect/Crypto\";\nimport * as Deferred from \"effect/Deferred\";\nimport * as Effect from \"effect/Effect\";\nimport * as Exit from \"effect/Exit\";\nimport * as FileSystem from \"effect/FileSystem\";\nimport * as Option from \"effect/Option\";\nimport * as Path from \"effect/Path\";\nimport * as Redacted from \"effect/Redacted\";\nimport * as Schedule from \"effect/Schedule\";\nimport * as Schema from \"effect/Schema\";\nimport * as Scope from \"effect/Scope\";\nimport * as Semaphore from \"effect/Semaphore\";\nimport * as Stream from \"effect/Stream\";\nimport * as HttpClient from \"effect/http/HttpClient\";\nimport { ChildProcess, ChildProcessSpawner } from \"effect/process\";\nimport { processEnvironment } from \"./CommandRunner\";\nimport * as FileLock from \"./FileLock\";\nimport * as Loopback from \"./Loopback\";\nimport { userCache } from \"./UserCache\";\nimport { extract } from \"./Zip\";\n\n/**\n * The backend release a new local deployment runs. An existing data directory\n * keeps running the release that created it, so upgrading this package never\n * opens a database with a different release.\n */\nexport const backendVersion = \"precompiled-2026-10-06-a3538c6\";\n\nexport class LocalBackendError extends Schema.TaggedError<LocalBackendError>()(\n \"LocalBackendError\",\n {\n deploymentName: Schema.String,\n reason: Schema.Literals([\n \"configuration\",\n \"filesystem\",\n \"install\",\n \"identity\",\n \"ports\",\n \"running\",\n \"spawn\",\n \"exit\",\n \"timeout\",\n ]),\n exitCode: Schema.optionalKey(Schema.Finite),\n },\n) {\n override get message() {\n const subject = `Local backend for ${this.deploymentName}`;\n switch (this.reason) {\n case \"configuration\":\n return `${subject} needs a home directory and, when set, CONFECT_LOCAL_BACKEND_PORTS as a range such as 3300-3399`;\n case \"filesystem\":\n return `${subject} could not read or write its data directory`;\n case \"install\":\n return `${subject} could not download or install the backend binary`;\n case \"identity\":\n return `${subject} could not read, create, or save its identity`;\n case \"ports\":\n return `${subject} could not get its ports; another process is using them`;\n case \"running\":\n return `${subject} is already running: stop the other alchemy dev session, or the backend process left over from one, that serves its data directory`;\n case \"spawn\":\n return `${subject} could not be started`;\n case \"exit\":\n return `${subject} exited${this.exitCode === undefined ? \"\" : ` with code ${this.exitCode}`} before it was ready`;\n case \"timeout\":\n return `${subject} did not become ready in time`;\n }\n }\n}\n\nexport interface LocalBackend {\n readonly url: string;\n readonly siteUrl: string;\n readonly adminKey: Redacted.Redacted<string>;\n /**\n * Completes when the backend process has exited and released its data\n * directory, so the deployment can be booted again.\n */\n readonly exited: Effect.Effect<void>;\n}\n\n// Ports are saved once a backend has answered on them, so a first start that\n// fails picks fresh ports next time instead of keeping ones that never worked.\nconst Identity = Schema.fromJsonString(\n Schema.Struct({\n name: Schema.String,\n version: Schema.String,\n instanceSecret: Schema.String,\n adminKey: Schema.String,\n ports: Schema.optionalKey(\n Schema.Struct({ port: Schema.Int, sitePort: Schema.Int }),\n ),\n }),\n);\ntype Identity = typeof Identity.Type;\n\n// The release archive per platform, as the Convex CLI maps it\n// (convex-js src/cli/lib/localDeployment/download.ts getDownloadPath).\nconst artifacts: Readonly<Record<string, string>> = {\n \"darwin-arm64\": \"convex-local-backend-aarch64-apple-darwin.zip\",\n \"darwin-x64\": \"convex-local-backend-x86_64-apple-darwin.zip\",\n \"linux-arm64\": \"convex-local-backend-aarch64-unknown-linux-gnu.zip\",\n \"linux-x64\": \"convex-local-backend-x86_64-unknown-linux-gnu.zip\",\n \"win32-arm64\": \"convex-local-backend-x86_64-pc-windows-msvc.zip\",\n \"win32-x64\": \"convex-local-backend-x86_64-pc-windows-msvc.zip\",\n};\nconst executable =\n process.platform === \"win32\"\n ? \"convex-local-backend.exe\"\n : \"convex-local-backend\";\n\nconst close = (server: Server) =>\n Effect.callback<void>((resume) => {\n server.close(() => resume(Effect.void));\n });\n\n// A server listening on `port`, or undefined when the port is taken, closed\n// with the scope. Listening is uninterruptible, so an interrupted probe never\n// leaves a server bound to the port.\nconst listen = (port: number) =>\n Effect.acquireRelease(\n Effect.callback<Server | undefined>((resume) => {\n const server = createServer();\n server.once(\"error\", () => resume(Effect.undefined));\n server.listen(port, \"127.0.0.1\", () => resume(Effect.succeed(server)));\n }),\n (server) => (server ? close(server) : Effect.void),\n );\n\nconst isFree = (port: number) =>\n listen(port).pipe(\n Effect.map((server) => server !== undefined),\n Effect.scoped,\n );\n\nconst portOf = (server: Server | undefined) => {\n const address = server?.address();\n return typeof address === \"object\" && address !== null\n ? address.port\n : undefined;\n};\n\n// Backends in one process start one at a time, so two deployments starting\n// together never probe and claim the same ports.\nconst startup = Semaphore.makeUnsafe(1);\n\n/**\n * Resolves the directory that holds one local deployment's identity, database,\n * and file storage: `.alchemy/convex/<stack>/<stage>/<deployment>`. Keyed by\n * the deployment name because a deploy key resource only knows that name.\n */\nexport const dataDirectories = Effect.gen(function* () {\n const path = yield* Path.Path;\n const stack = yield* Stack;\n const root = path.resolve(\n yield* dotAlchemyDirectory,\n \"convex\",\n stack.name,\n stack.stage,\n );\n return (deploymentName: string) => path.join(root, deploymentName);\n});\n\nconst readIdentity = Effect.fn(\"LocalBackend.readIdentity\")(function* (\n deploymentName: string,\n directory: string,\n) {\n const fs = yield* FileSystem.FileSystem;\n const path = yield* Path.Path;\n const file = path.join(directory, \"identity.json\");\n const invalid = () =>\n new LocalBackendError({ deploymentName, reason: \"identity\" });\n if (!(yield* fs.exists(file).pipe(Effect.mapError(invalid))))\n return Option.none<Identity>();\n const identity = yield* fs\n .readFileString(file)\n .pipe(\n Effect.flatMap(Schema.decodeEffect(Identity)),\n Effect.mapError(invalid),\n );\n if (identity.name !== deploymentName) return yield* invalid();\n return Option.some(identity);\n});\n\n/**\n * The admin key of a local deployment, for its deploy key resource.\n */\nexport const adminKey = Effect.fn(\"LocalBackend.adminKey\")(function* (\n deploymentName: string,\n directory: string,\n) {\n const identity = yield* readIdentity(deploymentName, directory);\n if (Option.isNone(identity))\n return yield* new LocalBackendError({ deploymentName, reason: \"identity\" });\n return Redacted.make(identity.value.adminKey);\n});\n\nexport const remove = Effect.fn(\"LocalBackend.remove\")(function* (\n deploymentName: string,\n directory: string,\n) {\n const fs = yield* FileSystem.FileSystem;\n yield* fs\n .remove(directory, { recursive: true, force: true })\n .pipe(\n Effect.mapError(\n () => new LocalBackendError({ deploymentName, reason: \"filesystem\" }),\n ),\n );\n});\n\n/**\n * Install a backend release into the Convex CLI's binary cache,\n * `<cache>/convex/binaries/<version>/`, unless it is already there.\n */\nconst install = Effect.fn(\"LocalBackend.install\")(function* (\n deploymentName: string,\n version: string,\n cache: string,\n) {\n const fs = yield* FileSystem.FileSystem;\n const path = yield* Path.Path;\n const http = yield* HttpClient.HttpClient;\n const failed = () =>\n new LocalBackendError({ deploymentName, reason: \"install\" });\n const binaries = path.join(cache, \"convex\", \"binaries\");\n const binary = path.join(binaries, version, executable);\n const artifact = artifacts[`${process.platform}-${process.arch}`];\n return yield* Effect.gen(function* () {\n if (yield* fs.exists(binary)) return binary;\n if (artifact === undefined) return yield* failed();\n yield* fs.makeDirectory(binaries, { recursive: true });\n const temp = yield* fs.makeTempDirectoryScoped({\n directory: binaries,\n prefix: \".download-\",\n });\n const archive = path.join(temp, artifact);\n const response = yield* http.get(\n `https://github.com/get-convex/convex-backend/releases/download/${version}/${artifact}`,\n );\n if (response.status !== 200) return yield* failed();\n yield* response.stream.pipe(Stream.run(fs.sink(archive)));\n const extracted = path.join(temp, executable);\n yield* extract(archive, executable, extracted);\n yield* fs.chmod(extracted, 0o755);\n yield* fs.makeDirectory(path.dirname(binary), { recursive: true });\n yield* fs.rename(extracted, binary);\n return binary;\n }).pipe(Effect.scoped, Effect.mapError(failed));\n});\n\n/**\n * Boot the local backend for one deployment and keep it running for the ambient\n * scope. The process and the data directory's `owner.lock` share a child scope\n * that closes when the boot fails or is interrupted and when the process exits,\n * so a deployment can be booted again in the same session. The first boot\n * installs the pinned release, generates an instance secret and admin key, and\n * picks two free loopback ports; later boots reuse all of them, so stored\n * credentials and URLs stay valid. A saved port that something else now holds\n * is an error rather than a move, because resources keep the URL.\n */\nexport const boot = Effect.fn(\"LocalBackend.boot\")(function* (\n deploymentName: string,\n directory: string,\n) {\n const path = yield* Path.Path;\n const fs = yield* FileSystem.FileSystem;\n const http = yield* HttpClient.HttpClient;\n const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;\n const crypto = yield* Crypto.Crypto;\n const fail = (reason: LocalBackendError[\"reason\"], exitCode?: number) =>\n new LocalBackendError({\n deploymentName,\n reason,\n ...(exitCode === undefined ? {} : { exitCode }),\n });\n const settings = yield* Config.all({\n environment: processEnvironment,\n ports: Config.String(\"CONFECT_LOCAL_BACKEND_PORTS\").pipe(Config.option),\n }).pipe(Effect.mapError(() => fail(\"configuration\")));\n const cache = yield* userCache.pipe(\n Effect.mapError(() => fail(\"configuration\")),\n );\n if (Option.isNone(cache)) return yield* fail(\"configuration\");\n const range = Option.map(settings.ports, Loopback.parsePortRange);\n if (Option.isSome(range) && Option.isNone(range.value))\n return yield* fail(\"configuration\");\n const env = {\n ...settings.environment,\n DISABLE_BEACON: \"1\",\n DO_NOT_TRACK: \"1\",\n };\n\n const answer = (url: string) =>\n http.get(`${url}/instance_name`).pipe(\n Effect.flatMap((response) =>\n response.status === 200 ? response.text : Effect.undefined,\n ),\n Effect.orElseSucceed(() => undefined),\n );\n\n const allocate = Effect.gen(function* () {\n if (Option.isNone(range) || Option.isNone(range.value)) {\n // A closed server no longer has an address.\n const [port, sitePort] = yield* Effect.all([listen(0), listen(0)]).pipe(\n Effect.map((servers) => servers.map(portOf)),\n Effect.scoped,\n );\n if (port === undefined || sitePort === undefined)\n return yield* fail(\"ports\");\n return { port, sitePort };\n }\n const free: number[] = [];\n const { from, to } = range.value.value;\n for (let port = from; port <= to && free.length < 2; port++) {\n if (yield* isFree(port)) free.push(port);\n }\n const [port, sitePort] = free;\n if (port === undefined || sitePort === undefined)\n return yield* fail(\"ports\");\n return { port, sitePort };\n });\n\n const generate = (binary: string) =>\n Effect.gen(function* () {\n const instanceSecret = Buffer.from(\n yield* crypto.randomBytes(32),\n ).toString(\"hex\");\n const output = yield* spawner.string(\n ChildProcess.make(\n binary,\n [\n \"keygen\",\n \"admin-key\",\n \"--instance-name\",\n deploymentName,\n \"--instance-secret\",\n instanceSecret,\n ],\n { env, extendEnv: false, stdin: \"ignore\", stderr: \"ignore\" },\n ),\n );\n const key = output.trim();\n if (!key.startsWith(`${deploymentName}|`)) return yield* fail(\"identity\");\n return { instanceSecret, adminKey: key };\n }).pipe(\n Effect.catchTag(\"PlatformError\", () => Effect.fail(fail(\"identity\"))),\n );\n\n const save = (identity: Identity) =>\n Effect.gen(function* () {\n const file = path.join(directory, \"identity.json\");\n const temp = `${file}.${process.pid}.tmp`;\n yield* fs.writeFileString(\n temp,\n yield* Schema.encodeEffect(Identity)(identity),\n { mode: 0o600 },\n );\n yield* fs.rename(temp, file);\n }).pipe(\n // Node cannot cancel a write or rename it has started; finishing it\n // keeps a pending rename from landing after owner.lock is released.\n Effect.uninterruptible,\n Effect.mapError(() => fail(\"identity\")),\n );\n\n const session = yield* Scope.Scope;\n const owned = yield* Scope.fork(session);\n const stopped = yield* Deferred.make<void>();\n // Registered first, so it runs after the process and owner.lock finalizers\n // however the scope closes.\n yield* Scope.addFinalizer(owned, Deferred.succeed(stopped, undefined));\n const start = Effect.gen(function* () {\n yield* FileLock.acquire(path.join(directory, \"owner.lock\")).pipe(\n Effect.mapError((error) =>\n fail(error.reason === \"held\" ? \"running\" : \"filesystem\"),\n ),\n );\n const saved = yield* readIdentity(deploymentName, directory);\n const version = Option.isSome(saved) ? saved.value.version : backendVersion;\n const binary = yield* install(deploymentName, version, cache.value);\n let identity: Identity;\n if (Option.isSome(saved)) {\n identity = saved.value;\n } else {\n identity = {\n name: deploymentName,\n version,\n ...(yield* generate(binary)),\n };\n yield* save(identity);\n }\n const ports = identity.ports ?? (yield* allocate);\n if (identity.ports !== undefined) {\n if (!(yield* isFree(ports.port)) || !(yield* isFree(ports.sitePort)))\n return yield* fail(\n (yield* answer(Loopback.origin(ports.port))) === deploymentName\n ? \"running\"\n : \"ports\",\n );\n }\n\n const url = Loopback.origin(ports.port);\n const siteUrl = Loopback.origin(ports.sitePort);\n const handle = yield* spawner\n .spawn(\n ChildProcess.make(\n binary,\n [\n \"--interface\",\n \"127.0.0.1\",\n \"--port\",\n String(ports.port),\n \"--site-proxy-port\",\n String(ports.sitePort),\n \"--instance-name\",\n deploymentName,\n \"--instance-secret\",\n identity.instanceSecret,\n \"--convex-origin\",\n url,\n \"--convex-site\",\n siteUrl,\n \"--local-storage\",\n path.join(directory, \"convex_local_storage\"),\n \"--disable-beacon\",\n path.join(directory, \"convex_local_backend.sqlite3\"),\n ],\n {\n cwd: directory,\n env,\n extendEnv: false,\n stdin: \"ignore\",\n stdout: \"ignore\",\n stderr: \"ignore\",\n forceKillAfter: \"3 seconds\",\n },\n ),\n )\n .pipe(Effect.mapError(() => fail(\"spawn\")));\n\n const ready = answer(url).pipe(\n Effect.flatMap((name) =>\n name === undefined || name === deploymentName\n ? Effect.succeed(name === deploymentName)\n : Effect.fail(fail(\"ports\")),\n ),\n Effect.repeat({\n until: (isReady) => isReady,\n schedule: Schedule.spaced(\"100 millis\"),\n }),\n );\n const exit = handle.exitCode.pipe(\n Effect.mapError(() => fail(\"exit\")),\n Effect.flatMap((code) => Effect.fail(fail(\"exit\", Number(code)))),\n );\n yield* Effect.raceFirst(ready, exit).pipe(\n Effect.timeoutOrElse({\n duration: \"60 seconds\",\n orElse: () => Effect.fail(fail(\"timeout\")),\n }),\n );\n if (identity.ports === undefined) yield* save({ ...identity, ports });\n // An exited backend releases the data directory before `exited`\n // completes, so the deployment can be booted again in this session.\n yield* handle.exitCode.pipe(\n Effect.ignore,\n Effect.andThen(Scope.close(owned, Exit.void)),\n Effect.forkIn(session),\n );\n return {\n url,\n siteUrl,\n adminKey: Redacted.make(identity.adminKey),\n exited: Deferred.await(stopped),\n } satisfies LocalBackend;\n });\n\n return yield* startup\n .withPermits(1)(start)\n .pipe(\n Scope.provide(owned),\n Effect.onExit((exit) =>\n Exit.isSuccess(exit) ? Effect.void : Scope.close(owned, exit),\n ),\n );\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"LocalBackend.js","names":["Loopback.parsePortRange","FileLock.acquire","Loopback.origin"],"sources":["../../src/internal/LocalBackend.ts"],"sourcesContent":["import { createServer, type Server } from \"node:net\";\nimport { dotAlchemyDirectory } from \"alchemy/AlchemyContext\";\nimport { Stack } from \"alchemy/Stack\";\nimport * as Config from \"effect/Config\";\nimport * as Crypto from \"effect/Crypto\";\nimport * as Deferred from \"effect/Deferred\";\nimport * as Effect from \"effect/Effect\";\nimport * as Exit from \"effect/Exit\";\nimport * as FileSystem from \"effect/FileSystem\";\nimport * as Option from \"effect/Option\";\nimport * as Path from \"effect/Path\";\nimport * as Redacted from \"effect/Redacted\";\nimport * as Schedule from \"effect/Schedule\";\nimport * as Schema from \"effect/Schema\";\nimport * as Scope from \"effect/Scope\";\nimport * as Semaphore from \"effect/Semaphore\";\nimport * as Stream from \"effect/Stream\";\nimport * as HttpClient from \"effect/http/HttpClient\";\nimport { ChildProcess, ChildProcessSpawner } from \"effect/process\";\nimport { processEnvironment } from \"./CommandRunner.js\";\nimport * as FileLock from \"./FileLock.js\";\nimport * as Loopback from \"./Loopback.js\";\nimport { userCache } from \"./UserCache.js\";\nimport { extract } from \"./Zip.js\";\n\n/**\n * The backend release a new local deployment runs. An existing data directory\n * keeps running the release that created it, so upgrading this package never\n * opens a database with a different release.\n */\nexport const backendVersion = \"precompiled-2026-10-06-a3538c6\";\n\nexport class LocalBackendError extends Schema.TaggedError<LocalBackendError>()(\n \"LocalBackendError\",\n {\n deploymentName: Schema.String,\n reason: Schema.Literals([\n \"configuration\",\n \"filesystem\",\n \"install\",\n \"identity\",\n \"ports\",\n \"running\",\n \"spawn\",\n \"exit\",\n \"timeout\",\n ]),\n exitCode: Schema.optionalKey(Schema.Finite),\n },\n) {\n override get message() {\n const subject = `Local backend for ${this.deploymentName}`;\n switch (this.reason) {\n case \"configuration\":\n return `${subject} needs a home directory and, when set, CONFECT_LOCAL_BACKEND_PORTS as a range such as 3300-3399`;\n case \"filesystem\":\n return `${subject} could not read or write its data directory`;\n case \"install\":\n return `${subject} could not download or install the backend binary`;\n case \"identity\":\n return `${subject} could not read, create, or save its identity`;\n case \"ports\":\n return `${subject} could not get its ports; another process is using them`;\n case \"running\":\n return `${subject} is already running: stop the other alchemy dev session, or the backend process left over from one, that serves its data directory`;\n case \"spawn\":\n return `${subject} could not be started`;\n case \"exit\":\n return `${subject} exited${this.exitCode === undefined ? \"\" : ` with code ${this.exitCode}`} before it was ready`;\n case \"timeout\":\n return `${subject} did not become ready in time`;\n }\n }\n}\n\nexport interface LocalBackend {\n readonly url: string;\n readonly siteUrl: string;\n readonly adminKey: Redacted.Redacted<string>;\n /**\n * Completes when the backend process has exited and released its data\n * directory, so the deployment can be booted again.\n */\n readonly exited: Effect.Effect<void>;\n}\n\n// Ports are saved once a backend has answered on them, so a first start that\n// fails picks fresh ports next time instead of keeping ones that never worked.\nconst Identity = Schema.fromJsonString(\n Schema.Struct({\n name: Schema.String,\n version: Schema.String,\n instanceSecret: Schema.String,\n adminKey: Schema.String,\n ports: Schema.optionalKey(\n Schema.Struct({ port: Schema.Int, sitePort: Schema.Int }),\n ),\n }),\n);\ntype Identity = typeof Identity.Type;\n\n// The release archive per platform, as the Convex CLI maps it\n// (convex-js src/cli/lib/localDeployment/download.ts getDownloadPath).\nconst artifacts: Readonly<Record<string, string>> = {\n \"darwin-arm64\": \"convex-local-backend-aarch64-apple-darwin.zip\",\n \"darwin-x64\": \"convex-local-backend-x86_64-apple-darwin.zip\",\n \"linux-arm64\": \"convex-local-backend-aarch64-unknown-linux-gnu.zip\",\n \"linux-x64\": \"convex-local-backend-x86_64-unknown-linux-gnu.zip\",\n \"win32-arm64\": \"convex-local-backend-x86_64-pc-windows-msvc.zip\",\n \"win32-x64\": \"convex-local-backend-x86_64-pc-windows-msvc.zip\",\n};\nconst executable =\n process.platform === \"win32\"\n ? \"convex-local-backend.exe\"\n : \"convex-local-backend\";\n\nconst close = (server: Server) =>\n Effect.callback<void>((resume) => {\n server.close(() => resume(Effect.void));\n });\n\n// A server listening on `port`, or undefined when the port is taken, closed\n// with the scope. Listening is uninterruptible, so an interrupted probe never\n// leaves a server bound to the port.\nconst listen = (port: number) =>\n Effect.acquireRelease(\n Effect.callback<Server | undefined>((resume) => {\n const server = createServer();\n server.once(\"error\", () => resume(Effect.undefined));\n server.listen(port, \"127.0.0.1\", () => resume(Effect.succeed(server)));\n }),\n (server) => (server ? close(server) : Effect.void),\n );\n\nconst isFree = (port: number) =>\n listen(port).pipe(\n Effect.map((server) => server !== undefined),\n Effect.scoped,\n );\n\nconst portOf = (server: Server | undefined) => {\n const address = server?.address();\n return typeof address === \"object\" && address !== null\n ? address.port\n : undefined;\n};\n\n// Backends in one process start one at a time, so two deployments starting\n// together never probe and claim the same ports.\nconst startup = Semaphore.makeUnsafe(1);\n\n/**\n * Resolves the directory that holds one local deployment's identity, database,\n * and file storage: `.alchemy/convex/<stack>/<stage>/<deployment>`. Keyed by\n * the deployment name because a deploy key resource only knows that name.\n */\nexport const dataDirectories = Effect.gen(function* () {\n const path = yield* Path.Path;\n const stack = yield* Stack;\n const root = path.resolve(\n yield* dotAlchemyDirectory,\n \"convex\",\n stack.name,\n stack.stage,\n );\n return (deploymentName: string) => path.join(root, deploymentName);\n});\n\nconst readIdentity = Effect.fn(\"LocalBackend.readIdentity\")(function* (\n deploymentName: string,\n directory: string,\n) {\n const fs = yield* FileSystem.FileSystem;\n const path = yield* Path.Path;\n const file = path.join(directory, \"identity.json\");\n const invalid = () =>\n new LocalBackendError({ deploymentName, reason: \"identity\" });\n if (!(yield* fs.exists(file).pipe(Effect.mapError(invalid))))\n return Option.none<Identity>();\n const identity = yield* fs\n .readFileString(file)\n .pipe(\n Effect.flatMap(Schema.decodeEffect(Identity)),\n Effect.mapError(invalid),\n );\n if (identity.name !== deploymentName) return yield* invalid();\n return Option.some(identity);\n});\n\n/**\n * The admin key of a local deployment, for its deploy key resource.\n */\nexport const adminKey = Effect.fn(\"LocalBackend.adminKey\")(function* (\n deploymentName: string,\n directory: string,\n) {\n const identity = yield* readIdentity(deploymentName, directory);\n if (Option.isNone(identity))\n return yield* new LocalBackendError({ deploymentName, reason: \"identity\" });\n return Redacted.make(identity.value.adminKey);\n});\n\nexport const remove = Effect.fn(\"LocalBackend.remove\")(function* (\n deploymentName: string,\n directory: string,\n) {\n const fs = yield* FileSystem.FileSystem;\n yield* fs\n .remove(directory, { recursive: true, force: true })\n .pipe(\n Effect.mapError(\n () => new LocalBackendError({ deploymentName, reason: \"filesystem\" }),\n ),\n );\n});\n\n/**\n * Install a backend release into the Convex CLI's binary cache,\n * `<cache>/convex/binaries/<version>/`, unless it is already there.\n */\nconst install = Effect.fn(\"LocalBackend.install\")(function* (\n deploymentName: string,\n version: string,\n cache: string,\n) {\n const fs = yield* FileSystem.FileSystem;\n const path = yield* Path.Path;\n const http = yield* HttpClient.HttpClient;\n const failed = () =>\n new LocalBackendError({ deploymentName, reason: \"install\" });\n const binaries = path.join(cache, \"convex\", \"binaries\");\n const binary = path.join(binaries, version, executable);\n const artifact = artifacts[`${process.platform}-${process.arch}`];\n return yield* Effect.gen(function* () {\n if (yield* fs.exists(binary)) return binary;\n if (artifact === undefined) return yield* failed();\n yield* fs.makeDirectory(binaries, { recursive: true });\n const temp = yield* fs.makeTempDirectoryScoped({\n directory: binaries,\n prefix: \".download-\",\n });\n const archive = path.join(temp, artifact);\n const response = yield* http.get(\n `https://github.com/get-convex/convex-backend/releases/download/${version}/${artifact}`,\n );\n if (response.status !== 200) return yield* failed();\n yield* response.stream.pipe(Stream.run(fs.sink(archive)));\n const extracted = path.join(temp, executable);\n yield* extract(archive, executable, extracted);\n yield* fs.chmod(extracted, 0o755);\n yield* fs.makeDirectory(path.dirname(binary), { recursive: true });\n yield* fs.rename(extracted, binary);\n return binary;\n }).pipe(Effect.scoped, Effect.mapError(failed));\n});\n\n/**\n * Boot the local backend for one deployment and keep it running for the ambient\n * scope. The process and the data directory's `owner.lock` share a child scope\n * that closes when the boot fails or is interrupted and when the process exits,\n * so a deployment can be booted again in the same session. The first boot\n * installs the pinned release, generates an instance secret and admin key, and\n * picks two free loopback ports; later boots reuse all of them, so stored\n * credentials and URLs stay valid. A saved port that something else now holds\n * is an error rather than a move, because resources keep the URL.\n */\nexport const boot = Effect.fn(\"LocalBackend.boot\")(function* (\n deploymentName: string,\n directory: string,\n) {\n const path = yield* Path.Path;\n const fs = yield* FileSystem.FileSystem;\n const http = yield* HttpClient.HttpClient;\n const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;\n const crypto = yield* Crypto.Crypto;\n const fail = (reason: LocalBackendError[\"reason\"], exitCode?: number) =>\n new LocalBackendError({\n deploymentName,\n reason,\n ...(exitCode === undefined ? {} : { exitCode }),\n });\n const settings = yield* Config.all({\n environment: processEnvironment,\n ports: Config.String(\"CONFECT_LOCAL_BACKEND_PORTS\").pipe(Config.option),\n }).pipe(Effect.mapError(() => fail(\"configuration\")));\n const cache = yield* userCache.pipe(\n Effect.mapError(() => fail(\"configuration\")),\n );\n if (Option.isNone(cache)) return yield* fail(\"configuration\");\n const range = Option.map(settings.ports, Loopback.parsePortRange);\n if (Option.isSome(range) && Option.isNone(range.value))\n return yield* fail(\"configuration\");\n const env = {\n ...settings.environment,\n DISABLE_BEACON: \"1\",\n DO_NOT_TRACK: \"1\",\n };\n\n const answer = (url: string) =>\n http.get(`${url}/instance_name`).pipe(\n Effect.flatMap((response) =>\n response.status === 200 ? response.text : Effect.undefined,\n ),\n Effect.orElseSucceed(() => undefined),\n );\n\n const allocate = Effect.gen(function* () {\n if (Option.isNone(range) || Option.isNone(range.value)) {\n // A closed server no longer has an address.\n const [port, sitePort] = yield* Effect.all([listen(0), listen(0)]).pipe(\n Effect.map((servers) => servers.map(portOf)),\n Effect.scoped,\n );\n if (port === undefined || sitePort === undefined)\n return yield* fail(\"ports\");\n return { port, sitePort };\n }\n const free: number[] = [];\n const { from, to } = range.value.value;\n for (let port = from; port <= to && free.length < 2; port++) {\n if (yield* isFree(port)) free.push(port);\n }\n const [port, sitePort] = free;\n if (port === undefined || sitePort === undefined)\n return yield* fail(\"ports\");\n return { port, sitePort };\n });\n\n const generate = (binary: string) =>\n Effect.gen(function* () {\n const instanceSecret = Buffer.from(\n yield* crypto.randomBytes(32),\n ).toString(\"hex\");\n const output = yield* spawner.string(\n ChildProcess.make(\n binary,\n [\n \"keygen\",\n \"admin-key\",\n \"--instance-name\",\n deploymentName,\n \"--instance-secret\",\n instanceSecret,\n ],\n { env, extendEnv: false, stdin: \"ignore\", stderr: \"ignore\" },\n ),\n );\n const key = output.trim();\n if (!key.startsWith(`${deploymentName}|`)) return yield* fail(\"identity\");\n return { instanceSecret, adminKey: key };\n }).pipe(\n Effect.catchTag(\"PlatformError\", () => Effect.fail(fail(\"identity\"))),\n );\n\n const save = (identity: Identity) =>\n Effect.gen(function* () {\n const file = path.join(directory, \"identity.json\");\n const temp = `${file}.${process.pid}.tmp`;\n yield* fs.writeFileString(\n temp,\n yield* Schema.encodeEffect(Identity)(identity),\n { mode: 0o600 },\n );\n yield* fs.rename(temp, file);\n }).pipe(\n // Node cannot cancel a write or rename it has started; finishing it\n // keeps a pending rename from landing after owner.lock is released.\n Effect.uninterruptible,\n Effect.mapError(() => fail(\"identity\")),\n );\n\n const session = yield* Scope.Scope;\n const owned = yield* Scope.fork(session);\n const stopped = yield* Deferred.make<void>();\n // Registered first, so it runs after the process and owner.lock finalizers\n // however the scope closes.\n yield* Scope.addFinalizer(owned, Deferred.succeed(stopped, undefined));\n const start = Effect.gen(function* () {\n yield* FileLock.acquire(path.join(directory, \"owner.lock\")).pipe(\n Effect.mapError((error) =>\n fail(error.reason === \"held\" ? \"running\" : \"filesystem\"),\n ),\n );\n const saved = yield* readIdentity(deploymentName, directory);\n const version = Option.isSome(saved) ? saved.value.version : backendVersion;\n const binary = yield* install(deploymentName, version, cache.value);\n let identity: Identity;\n if (Option.isSome(saved)) {\n identity = saved.value;\n } else {\n identity = {\n name: deploymentName,\n version,\n ...(yield* generate(binary)),\n };\n yield* save(identity);\n }\n const ports = identity.ports ?? (yield* allocate);\n if (identity.ports !== undefined) {\n if (!(yield* isFree(ports.port)) || !(yield* isFree(ports.sitePort)))\n return yield* fail(\n (yield* answer(Loopback.origin(ports.port))) === deploymentName\n ? \"running\"\n : \"ports\",\n );\n }\n\n const url = Loopback.origin(ports.port);\n const siteUrl = Loopback.origin(ports.sitePort);\n const handle = yield* spawner\n .spawn(\n ChildProcess.make(\n binary,\n [\n \"--interface\",\n \"127.0.0.1\",\n \"--port\",\n String(ports.port),\n \"--site-proxy-port\",\n String(ports.sitePort),\n \"--instance-name\",\n deploymentName,\n \"--instance-secret\",\n identity.instanceSecret,\n \"--convex-origin\",\n url,\n \"--convex-site\",\n siteUrl,\n \"--local-storage\",\n path.join(directory, \"convex_local_storage\"),\n \"--disable-beacon\",\n path.join(directory, \"convex_local_backend.sqlite3\"),\n ],\n {\n cwd: directory,\n env,\n extendEnv: false,\n stdin: \"ignore\",\n stdout: \"ignore\",\n stderr: \"ignore\",\n forceKillAfter: \"3 seconds\",\n },\n ),\n )\n .pipe(Effect.mapError(() => fail(\"spawn\")));\n\n const ready = answer(url).pipe(\n Effect.flatMap((name) =>\n name === undefined || name === deploymentName\n ? Effect.succeed(name === deploymentName)\n : Effect.fail(fail(\"ports\")),\n ),\n Effect.repeat({\n until: (isReady) => isReady,\n schedule: Schedule.spaced(\"100 millis\"),\n }),\n );\n const exit = handle.exitCode.pipe(\n Effect.mapError(() => fail(\"exit\")),\n Effect.flatMap((code) => Effect.fail(fail(\"exit\", Number(code)))),\n );\n yield* Effect.raceFirst(ready, exit).pipe(\n Effect.timeoutOrElse({\n duration: \"60 seconds\",\n orElse: () => Effect.fail(fail(\"timeout\")),\n }),\n );\n if (identity.ports === undefined) yield* save({ ...identity, ports });\n // An exited backend releases the data directory before `exited`\n // completes, so the deployment can be booted again in this session.\n yield* handle.exitCode.pipe(\n Effect.ignore,\n Effect.andThen(Scope.close(owned, Exit.void)),\n Effect.forkIn(session),\n );\n return {\n url,\n siteUrl,\n adminKey: Redacted.make(identity.adminKey),\n exited: Deferred.await(stopped),\n } satisfies LocalBackend;\n });\n\n return yield* startup\n .withPermits(1)(start)\n .pipe(\n Scope.provide(owned),\n Effect.onExit((exit) =>\n Exit.isSuccess(exit) ? Effect.void : Scope.close(owned, exit),\n ),\n );\n});\n"],"mappings":"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"}
@@ -1,3 +1,3 @@
1
- declare const _default: import("effect/Layer").Layer<import("alchemy/Provider").Provider<import("../Deployment").Deployment>, never, import("alchemy/AlchemyContext").AlchemyContext | import("alchemy/Artifacts").ArtifactStore | import("effect/process/ChildProcessSpawner").ChildProcessSpawner | import("effect/Crypto").Crypto | import("effect/FileSystem").FileSystem | import("effect/http/HttpClient").HttpClient | import("effect/Path").Path | import("alchemy/Stack").Stack>;
1
+ declare const _default: import("effect/Layer").Layer<import("alchemy/Provider").Provider<import("../Deployment.js").Deployment>, never, import("alchemy/AlchemyContext").AlchemyContext | import("alchemy/Artifacts").ArtifactStore | import("effect/process/ChildProcessSpawner").ChildProcessSpawner | import("effect/Crypto").Crypto | import("effect/FileSystem").FileSystem | import("effect/http/HttpClient").HttpClient | import("effect/Path").Path | import("alchemy/Stack").Stack>;
2
2
  export default _default;
3
3
  //# sourceMappingURL=LocalSidecar.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"LocalSidecar.js","names":[],"sources":["../../src/internal/LocalSidecar.ts"],"sourcesContent":["/**\n * The local Deployment provider served by Alchemy's dev sidecar, so a local\n * backend outlives reloads of the stack. Alchemy imports this module by URL and\n * builds its default export once per dev session.\n */\nimport type * as RpcServer from \"alchemy/Local/RpcServer\";\nimport { localLayer } from \"../Deployment\";\n\nexport default localLayer satisfies RpcServer.ProviderLayer;\n"],"mappings":";;AAQA,IAAA,uBAAe"}
1
+ {"version":3,"file":"LocalSidecar.js","names":[],"sources":["../../src/internal/LocalSidecar.ts"],"sourcesContent":["/**\n * The local Deployment provider served by Alchemy's dev sidecar, so a local\n * backend outlives reloads of the stack. Alchemy imports this module by URL and\n * builds its default export once per dev session.\n */\nimport type * as RpcServer from \"alchemy/Local/RpcServer\";\nimport { localLayer } from \"../Deployment.js\";\n\nexport default localLayer satisfies RpcServer.ProviderLayer;\n"],"mappings":";;AAQA,IAAA,uBAAe"}
@@ -1 +1 @@
1
- {"version":3,"file":"PushLock.js","names":["FileLock.acquire"],"sources":["../../src/internal/PushLock.ts"],"sourcesContent":["import * as Context from \"effect/Context\";\nimport * as Crypto from \"effect/Crypto\";\nimport * as Duration from \"effect/Duration\";\nimport * as Effect from \"effect/Effect\";\nimport * as FileSystem from \"effect/FileSystem\";\nimport * as Layer from \"effect/Layer\";\nimport * as Option from \"effect/Option\";\nimport * as Path from \"effect/Path\";\nimport * as Schema from \"effect/Schema\";\nimport * as Scope from \"effect/Scope\";\nimport * as FileLock from \"./FileLock\";\nimport { userCache } from \"./UserCache\";\n\nexport class PushLockError extends Schema.TaggedError<PushLockError>()(\n \"PushLockError\",\n {\n deploymentName: Schema.String,\n reason: Schema.Literals([\"configuration\", \"timeout\", \"filesystem\"]),\n },\n) {\n override get message() {\n switch (this.reason) {\n case \"configuration\":\n return `Push lock for ${this.deploymentName} needs a home directory to keep its lock file in`;\n case \"timeout\":\n return `Timed out waiting for another push to ${this.deploymentName} to release its push lock`;\n case \"filesystem\":\n return `Push lock for ${this.deploymentName} could not read or write its lock file`;\n }\n }\n}\n\n/**\n * Serialises pushes per deployment. Overlapping `convex deploy` runs against\n * one deployment race on `wait_for_schema`, so every push holds the lock for\n * its whole duration, whichever stack, checkout, or process it comes from.\n */\nexport class PushLock extends Context.Service<\n PushLock,\n {\n readonly withLock: <A, E, R>(\n deploymentName: string,\n effect: Effect.Effect<A, E, R>,\n ) => Effect.Effect<A, E | PushLockError, R>;\n }\n>()(\"@confect/alchemy/internal/PushLock\") {}\n\n/**\n * One lock file per deployment under the user's cache,\n * `confect/alchemy/locks/<deployment>.lock`, so every checkout on the machine\n * shares it. A lock left by a process that exited is taken over; a holder that\n * never releases ends in a typed timeout.\n */\nexport const layer = (options?: { readonly timeout?: Duration.Input }) =>\n Layer.effect(\n PushLock,\n Effect.gen(function* () {\n const fs = yield* FileSystem.FileSystem;\n const path = yield* Path.Path;\n const crypto = yield* Crypto.Crypto;\n const timeout = options?.timeout ?? Duration.minutes(10);\n const lock = Effect.fn(\"PushLock.lock\")(\n function* (deploymentName: string, scope: Scope.Scope) {\n const failed = (reason: PushLockError[\"reason\"]) =>\n new PushLockError({ deploymentName, reason });\n const cache = yield* userCache.pipe(\n Effect.mapError(() => failed(\"configuration\")),\n );\n if (Option.isNone(cache)) return yield* failed(\"configuration\");\n yield* FileLock.acquire(\n path.join(\n cache.value,\n \"confect\",\n \"alchemy\",\n \"locks\",\n `${deploymentName}.lock`,\n ),\n timeout,\n ).pipe(\n Scope.provide(scope),\n Effect.mapError((error) =>\n failed(error.reason === \"timeout\" ? \"timeout\" : \"filesystem\"),\n ),\n );\n },\n Effect.provideService(FileSystem.FileSystem, fs),\n Effect.provideService(Path.Path, path),\n Effect.provideService(Crypto.Crypto, crypto),\n );\n return PushLock.of({\n withLock: (deploymentName, effect) =>\n Effect.acquireUseRelease(\n Scope.make(),\n (scope) => lock(deploymentName, scope).pipe(Effect.andThen(effect)),\n (scope, exit) => Scope.close(scope, exit),\n ),\n });\n }),\n );\n"],"mappings":";;;;;;;;;;;;;AAaA,IAAa,gBAAb,cAAmC,OAAO,YAA2B,CAAC,CACpE,iBACA;CACE,gBAAgB,OAAO;CACvB,QAAQ,OAAO,SAAS;EAAC;EAAiB;EAAW;CAAY,CAAC;AACpE,CACF,CAAC,CAAC;CACA,IAAa,UAAU;EACrB,QAAQ,KAAK,QAAb;GACE,KAAK,iBACH,OAAO,iBAAiB,KAAK,eAAe;GAC9C,KAAK,WACH,OAAO,yCAAyC,KAAK,eAAe;GACtE,KAAK,cACH,OAAO,iBAAiB,KAAK,eAAe;EAChD;CACF;AACF;;;;;;AAOA,IAAa,WAAb,cAA8B,QAAQ,QAQpC,CAAC,CAAC,oCAAoC,CAAC,CAAC,CAAC;;;;;;;AAQ3C,MAAa,SAAS,YACpB,MAAM,OACJ,UACA,OAAO,IAAI,aAAa;CACtB,MAAM,KAAK,OAAO,WAAW;CAC7B,MAAM,OAAO,OAAO,KAAK;CACzB,MAAM,SAAS,OAAO,OAAO;CAC7B,MAAM,UAAU,SAAS,WAAW,SAAS,QAAQ,EAAE;CACvD,MAAM,OAAO,OAAO,GAAG,eAAe,CAAC,CACrC,WAAW,gBAAwB,OAAoB;EACrD,MAAM,UAAU,WACd,IAAI,cAAc;GAAE;GAAgB;EAAO,CAAC;EAC9C,MAAM,QAAQ,OAAO,UAAU,KAC7B,OAAO,eAAe,OAAO,eAAe,CAAC,CAC/C;EACA,IAAI,OAAO,OAAO,KAAK,GAAG,OAAO,OAAO,OAAO,eAAe;EAC9D,OAAOA,QACL,KAAK,KACH,MAAM,OACN,WACA,WACA,SACA,GAAG,eAAe,MACpB,GACA,OACF,CAAC,CAAC,KACA,MAAM,QAAQ,KAAK,GACnB,OAAO,UAAU,UACf,OAAO,MAAM,WAAW,YAAY,YAAY,YAAY,CAC9D,CACF;CACF,GACA,OAAO,eAAe,WAAW,YAAY,EAAE,GAC/C,OAAO,eAAe,KAAK,MAAM,IAAI,GACrC,OAAO,eAAe,OAAO,QAAQ,MAAM,CAC7C;CACA,OAAO,SAAS,GAAG,EACjB,WAAW,gBAAgB,WACzB,OAAO,kBACL,MAAM,KAAK,IACV,UAAU,KAAK,gBAAgB,KAAK,CAAC,CAAC,KAAK,OAAO,QAAQ,MAAM,CAAC,IACjE,OAAO,SAAS,MAAM,MAAM,OAAO,IAAI,CAC1C,EACJ,CAAC;AACH,CAAC,CACH"}
1
+ {"version":3,"file":"PushLock.js","names":["FileLock.acquire"],"sources":["../../src/internal/PushLock.ts"],"sourcesContent":["import * as Context from \"effect/Context\";\nimport * as Crypto from \"effect/Crypto\";\nimport * as Duration from \"effect/Duration\";\nimport * as Effect from \"effect/Effect\";\nimport * as FileSystem from \"effect/FileSystem\";\nimport * as Layer from \"effect/Layer\";\nimport * as Option from \"effect/Option\";\nimport * as Path from \"effect/Path\";\nimport * as Schema from \"effect/Schema\";\nimport * as Scope from \"effect/Scope\";\nimport * as FileLock from \"./FileLock.js\";\nimport { userCache } from \"./UserCache.js\";\n\nexport class PushLockError extends Schema.TaggedError<PushLockError>()(\n \"PushLockError\",\n {\n deploymentName: Schema.String,\n reason: Schema.Literals([\"configuration\", \"timeout\", \"filesystem\"]),\n },\n) {\n override get message() {\n switch (this.reason) {\n case \"configuration\":\n return `Push lock for ${this.deploymentName} needs a home directory to keep its lock file in`;\n case \"timeout\":\n return `Timed out waiting for another push to ${this.deploymentName} to release its push lock`;\n case \"filesystem\":\n return `Push lock for ${this.deploymentName} could not read or write its lock file`;\n }\n }\n}\n\n/**\n * Serialises pushes per deployment. Overlapping `convex deploy` runs against\n * one deployment race on `wait_for_schema`, so every push holds the lock for\n * its whole duration, whichever stack, checkout, or process it comes from.\n */\nexport class PushLock extends Context.Service<\n PushLock,\n {\n readonly withLock: <A, E, R>(\n deploymentName: string,\n effect: Effect.Effect<A, E, R>,\n ) => Effect.Effect<A, E | PushLockError, R>;\n }\n>()(\"@confect/alchemy/internal/PushLock\") {}\n\n/**\n * One lock file per deployment under the user's cache,\n * `confect/alchemy/locks/<deployment>.lock`, so every checkout on the machine\n * shares it. A lock left by a process that exited is taken over; a holder that\n * never releases ends in a typed timeout.\n */\nexport const layer = (options?: { readonly timeout?: Duration.Input }) =>\n Layer.effect(\n PushLock,\n Effect.gen(function* () {\n const fs = yield* FileSystem.FileSystem;\n const path = yield* Path.Path;\n const crypto = yield* Crypto.Crypto;\n const timeout = options?.timeout ?? Duration.minutes(10);\n const lock = Effect.fn(\"PushLock.lock\")(\n function* (deploymentName: string, scope: Scope.Scope) {\n const failed = (reason: PushLockError[\"reason\"]) =>\n new PushLockError({ deploymentName, reason });\n const cache = yield* userCache.pipe(\n Effect.mapError(() => failed(\"configuration\")),\n );\n if (Option.isNone(cache)) return yield* failed(\"configuration\");\n yield* FileLock.acquire(\n path.join(\n cache.value,\n \"confect\",\n \"alchemy\",\n \"locks\",\n `${deploymentName}.lock`,\n ),\n timeout,\n ).pipe(\n Scope.provide(scope),\n Effect.mapError((error) =>\n failed(error.reason === \"timeout\" ? \"timeout\" : \"filesystem\"),\n ),\n );\n },\n Effect.provideService(FileSystem.FileSystem, fs),\n Effect.provideService(Path.Path, path),\n Effect.provideService(Crypto.Crypto, crypto),\n );\n return PushLock.of({\n withLock: (deploymentName, effect) =>\n Effect.acquireUseRelease(\n Scope.make(),\n (scope) => lock(deploymentName, scope).pipe(Effect.andThen(effect)),\n (scope, exit) => Scope.close(scope, exit),\n ),\n });\n }),\n );\n"],"mappings":";;;;;;;;;;;;;AAaA,IAAa,gBAAb,cAAmC,OAAO,YAA2B,CAAC,CACpE,iBACA;CACE,gBAAgB,OAAO;CACvB,QAAQ,OAAO,SAAS;EAAC;EAAiB;EAAW;CAAY,CAAC;AACpE,CACF,CAAC,CAAC;CACA,IAAa,UAAU;EACrB,QAAQ,KAAK,QAAb;GACE,KAAK,iBACH,OAAO,iBAAiB,KAAK,eAAe;GAC9C,KAAK,WACH,OAAO,yCAAyC,KAAK,eAAe;GACtE,KAAK,cACH,OAAO,iBAAiB,KAAK,eAAe;EAChD;CACF;AACF;;;;;;AAOA,IAAa,WAAb,cAA8B,QAAQ,QAQpC,CAAC,CAAC,oCAAoC,CAAC,CAAC,CAAC;;;;;;;AAQ3C,MAAa,SAAS,YACpB,MAAM,OACJ,UACA,OAAO,IAAI,aAAa;CACtB,MAAM,KAAK,OAAO,WAAW;CAC7B,MAAM,OAAO,OAAO,KAAK;CACzB,MAAM,SAAS,OAAO,OAAO;CAC7B,MAAM,UAAU,SAAS,WAAW,SAAS,QAAQ,EAAE;CACvD,MAAM,OAAO,OAAO,GAAG,eAAe,CAAC,CACrC,WAAW,gBAAwB,OAAoB;EACrD,MAAM,UAAU,WACd,IAAI,cAAc;GAAE;GAAgB;EAAO,CAAC;EAC9C,MAAM,QAAQ,OAAO,UAAU,KAC7B,OAAO,eAAe,OAAO,eAAe,CAAC,CAC/C;EACA,IAAI,OAAO,OAAO,KAAK,GAAG,OAAO,OAAO,OAAO,eAAe;EAC9D,OAAOA,QACL,KAAK,KACH,MAAM,OACN,WACA,WACA,SACA,GAAG,eAAe,MACpB,GACA,OACF,CAAC,CAAC,KACA,MAAM,QAAQ,KAAK,GACnB,OAAO,UAAU,UACf,OAAO,MAAM,WAAW,YAAY,YAAY,YAAY,CAC9D,CACF;CACF,GACA,OAAO,eAAe,WAAW,YAAY,EAAE,GAC/C,OAAO,eAAe,KAAK,MAAM,IAAI,GACrC,OAAO,eAAe,OAAO,QAAQ,MAAM,CAC7C;CACA,OAAO,SAAS,GAAG,EACjB,WAAW,gBAAgB,WACzB,OAAO,kBACL,MAAM,KAAK,IACV,UAAU,KAAK,gBAAgB,KAAK,CAAC,CAAC,KAAK,OAAO,QAAQ,MAAM,CAAC,IACjE,OAAO,SAAS,MAAM,MAAM,OAAO,IAAI,CAC1C,EACJ,CAAC;AACH,CAAC,CACH"}
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@gaganref/confect-alchemy",
3
- "version": "10.3.1-fork.2",
3
+ "version": "10.3.1-fork.21",
4
4
  "dependencies": {
5
5
  "@convex-dev/platform": "^0.1.10"
6
6
  },
7
7
  "peerDependencies": {
8
- "@confect/cli": "npm:@gaganref/confect-cli@10.3.1-fork.2",
9
- "@confect/core": "npm:@gaganref/confect-core@10.3.1-fork.2",
8
+ "@confect/cli": "npm:@gaganref/confect-cli@10.3.1-fork.21",
9
+ "@confect/core": "npm:@gaganref/confect-core@10.3.1-fork.21",
10
10
  "alchemy": "2.0.0-beta.82",
11
11
  "convex": "^1.32.0",
12
12
  "effect": "^4.0.0"
package/src/Backend.ts CHANGED
@@ -4,8 +4,8 @@ import * as Namespace from "alchemy/Namespace";
4
4
  import * as Output from "alchemy/Output";
5
5
  import * as Effect from "effect/Effect";
6
6
  import type * as Redacted from "effect/Redacted";
7
- import { Code } from "./Code";
8
- import { EnvironmentVariables } from "./EnvironmentVariables";
7
+ import { Code } from "./Code.js";
8
+ import { EnvironmentVariables } from "./EnvironmentVariables.js";
9
9
 
10
10
  interface CommonProps {
11
11
  readonly deployment: {
package/src/Code.ts CHANGED
@@ -3,10 +3,13 @@ import type { ProviderMode } from "alchemy/ProviderMode";
3
3
  import { Resource } from "alchemy/Resource";
4
4
  import * as Effect from "effect/Effect";
5
5
  import type * as Redacted from "effect/Redacted";
6
- import type { Providers } from "./Providers";
7
- import { deploy } from "./internal/CodeDeployment";
8
- import { CommandRunner, type PrepareCommand } from "./internal/CommandRunner";
9
- import { PushLock } from "./internal/PushLock";
6
+ import type { Providers } from "./Providers.js";
7
+ import { deploy } from "./internal/CodeDeployment.js";
8
+ import {
9
+ CommandRunner,
10
+ type PrepareCommand,
11
+ } from "./internal/CommandRunner.js";
12
+ import { PushLock } from "./internal/PushLock.js";
10
13
 
11
14
  export interface CodeProps {
12
15
  readonly deployment: { readonly name: string; readonly url: string };
package/src/Confect.ts CHANGED
@@ -1 +1 @@
1
- export { Backend, type BackendProps } from "./Backend";
1
+ export { Backend, type BackendProps } from "./Backend.js";
package/src/Convex.ts CHANGED
@@ -1,18 +1,22 @@
1
- export { Project, type ProjectProps, type ProjectAttributes } from "./Project";
1
+ export {
2
+ Project,
3
+ type ProjectProps,
4
+ type ProjectAttributes,
5
+ } from "./Project.js";
2
6
  export {
3
7
  Deployment,
4
8
  type DeploymentProps,
5
9
  type DeploymentAttributes,
6
- } from "./Deployment";
10
+ } from "./Deployment.js";
7
11
  export {
8
12
  DeployKey,
9
13
  type DeployKeyProps,
10
14
  type DeployKeyAttributes,
11
- } from "./DeployKey";
15
+ } from "./DeployKey.js";
12
16
  export {
13
17
  EnvironmentVariables,
14
18
  type EnvironmentVariablesProps,
15
19
  type EnvironmentVariablesAttributes,
16
- } from "./EnvironmentVariables";
17
- export { Code, type CodeProps, type CodeAttributes } from "./Code";
18
- export { providers, Providers } from "./Providers";
20
+ } from "./EnvironmentVariables.js";
21
+ export { Code, type CodeProps, type CodeAttributes } from "./Code.js";
22
+ export { providers, Providers } from "./Providers.js";
@@ -11,7 +11,7 @@ import * as FetchHttpClient from "effect/http/FetchHttpClient";
11
11
  import * as HttpClient from "effect/http/HttpClient";
12
12
  import * as HttpClientRequest from "effect/http/HttpClientRequest";
13
13
  import type * as HttpClientResponse from "effect/http/HttpClientResponse";
14
- import * as Loopback from "./internal/Loopback";
14
+ import * as Loopback from "./internal/Loopback.js";
15
15
 
16
16
  export type Project = ManagementApi.ProjectResponse;
17
17
  export type CreatedProject = ManagementApi.PlatformCreateProjectResponse;
package/src/DeployKey.ts CHANGED
@@ -8,11 +8,11 @@ import * as Path from "effect/Path";
8
8
  import * as Redacted from "effect/Redacted";
9
9
  import * as Schema from "effect/Schema";
10
10
 
11
- import { ConvexClient } from "./ConvexClient";
12
- import type { Providers } from "./Providers";
13
- import { resourceName } from "./internal/ResourceIdentity";
14
- import { checkpointCreate } from "./internal/Lifecycle";
15
- import { adminKey, dataDirectories } from "./internal/LocalBackend";
11
+ import { ConvexClient } from "./ConvexClient.js";
12
+ import type { Providers } from "./Providers.js";
13
+ import { resourceName } from "./internal/ResourceIdentity.js";
14
+ import { checkpointCreate } from "./internal/Lifecycle.js";
15
+ import { adminKey, dataDirectories } from "./internal/LocalBackend.js";
16
16
 
17
17
  export interface DeployKeyProps {
18
18
  readonly deploymentName: string;
package/src/Deployment.ts CHANGED
@@ -13,11 +13,11 @@ import * as Effect from "effect/Effect";
13
13
  import * as FileSystem from "effect/FileSystem";
14
14
  import * as Schema from "effect/Schema";
15
15
 
16
- import { ConvexClient } from "./ConvexClient";
17
- import type { Providers } from "./Providers";
18
- import { resourceName } from "./internal/ResourceIdentity";
19
- import { checkpointCreate, shouldAdopt } from "./internal/Lifecycle";
20
- import { boot, dataDirectories, remove } from "./internal/LocalBackend";
16
+ import { ConvexClient } from "./ConvexClient.js";
17
+ import type { Providers } from "./Providers.js";
18
+ import { resourceName } from "./internal/ResourceIdentity.js";
19
+ import { checkpointCreate, shouldAdopt } from "./internal/Lifecycle.js";
20
+ import { boot, dataDirectories, remove } from "./internal/LocalBackend.js";
21
21
 
22
22
  export interface DeploymentProps {
23
23
  readonly projectId: number;
@@ -8,9 +8,9 @@ import * as FetchHttpClient from "effect/http/FetchHttpClient";
8
8
  import * as Redacted from "effect/Redacted";
9
9
  import * as Schema from "effect/Schema";
10
10
 
11
- import * as ConvexClient from "./ConvexClient";
12
- import type { Providers } from "./Providers";
13
- import { checkpointCreate, shouldAdopt } from "./internal/Lifecycle";
11
+ import * as ConvexClient from "./ConvexClient.js";
12
+ import type { Providers } from "./Providers.js";
13
+ import { checkpointCreate, shouldAdopt } from "./internal/Lifecycle.js";
14
14
 
15
15
  export interface EnvironmentVariablesProps {
16
16
  readonly url: string;