@samebase/alchemy-convex 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +146 -0
  3. package/lib/Credentials.d.ts +39 -0
  4. package/lib/Credentials.d.ts.map +1 -0
  5. package/lib/Credentials.js +49 -0
  6. package/lib/Credentials.js.map +1 -0
  7. package/lib/DefaultEnvironmentVariable.d.ts +58 -0
  8. package/lib/DefaultEnvironmentVariable.d.ts.map +1 -0
  9. package/lib/DefaultEnvironmentVariable.js +93 -0
  10. package/lib/DefaultEnvironmentVariable.js.map +1 -0
  11. package/lib/Deploy.d.ts +62 -0
  12. package/lib/Deploy.d.ts.map +1 -0
  13. package/lib/Deploy.js +92 -0
  14. package/lib/Deploy.js.map +1 -0
  15. package/lib/DeployKey.d.ts +48 -0
  16. package/lib/DeployKey.d.ts.map +1 -0
  17. package/lib/DeployKey.js +104 -0
  18. package/lib/DeployKey.js.map +1 -0
  19. package/lib/EnvironmentVariable.d.ts +37 -0
  20. package/lib/EnvironmentVariable.d.ts.map +1 -0
  21. package/lib/EnvironmentVariable.js +65 -0
  22. package/lib/EnvironmentVariable.js.map +1 -0
  23. package/lib/ManagementApi.d.ts +50 -0
  24. package/lib/ManagementApi.d.ts.map +1 -0
  25. package/lib/ManagementApi.js +103 -0
  26. package/lib/ManagementApi.js.map +1 -0
  27. package/lib/PreviewDeployKey.d.ts +34 -0
  28. package/lib/PreviewDeployKey.d.ts.map +1 -0
  29. package/lib/PreviewDeployKey.js +78 -0
  30. package/lib/PreviewDeployKey.js.map +1 -0
  31. package/lib/Project.d.ts +29 -0
  32. package/lib/Project.d.ts.map +1 -0
  33. package/lib/Project.js +114 -0
  34. package/lib/Project.js.map +1 -0
  35. package/lib/Providers.d.ts +13 -0
  36. package/lib/Providers.d.ts.map +1 -0
  37. package/lib/Providers.js +30 -0
  38. package/lib/Providers.js.map +1 -0
  39. package/lib/index.d.ts +10 -0
  40. package/lib/index.d.ts.map +1 -0
  41. package/lib/index.js +11 -0
  42. package/lib/index.js.map +1 -0
  43. package/package.json +71 -0
  44. package/src/Credentials.ts +78 -0
  45. package/src/DefaultEnvironmentVariable.ts +165 -0
  46. package/src/Deploy.ts +171 -0
  47. package/src/DeployKey.ts +171 -0
  48. package/src/EnvironmentVariable.ts +129 -0
  49. package/src/ManagementApi.ts +193 -0
  50. package/src/PreviewDeployKey.ts +126 -0
  51. package/src/Project.ts +191 -0
  52. package/src/Providers.ts +51 -0
  53. package/src/index.ts +45 -0
@@ -0,0 +1,62 @@
1
+ import { Resource } from "alchemy";
2
+ import { CommandExecutor, type CommandRunProps } from "alchemy/Command";
3
+ import { type MemoOptions } from "alchemy/Command/Memo";
4
+ import * as Provider from "alchemy/Provider";
5
+ import type * as Redacted from "effect/Redacted";
6
+ import type { Providers } from "./Providers.ts";
7
+ export interface DeployProps extends Pick<CommandRunProps, "cwd" | "env" | "timeout"> {
8
+ /**
9
+ * Deploy key that selects the target deployment: a production, development,
10
+ * project, or preview deploy key. The CLI receives it as `CONVEX_DEPLOY_KEY`,
11
+ * and Alchemy removes its value from the logged output.
12
+ */
13
+ readonly deployKey: Redacted.Redacted<string>;
14
+ /**
15
+ * Preview deployment name for a preview deploy key. The CLI reuses an
16
+ * existing preview deployment with this name.
17
+ */
18
+ readonly previewName?: string;
19
+ /**
20
+ * Like {@link previewName}, but the CLI deletes and recreates an existing
21
+ * preview deployment with this name, so every run gets a new URL.
22
+ */
23
+ readonly previewCreate?: string;
24
+ /**
25
+ * Function to run after the push, such as `init:seed`. The CLI runs it only
26
+ * when the push created a new preview deployment.
27
+ */
28
+ readonly previewRun?: string;
29
+ /**
30
+ * More `convex deploy` flags, added after the preview flags. Alchemy splits
31
+ * the command on whitespace, so an argument cannot contain whitespace: use
32
+ * `--typecheck=disable`, not `--typecheck disable` as one argument.
33
+ */
34
+ readonly extraArgs?: readonly string[];
35
+ /**
36
+ * Files hashed to skip an unchanged push. By default every non-gitignored
37
+ * file under `cwd` and the nearest lockfile. Use
38
+ * `{ include: ["convex/**"], lockfile: true }` to ignore frontend changes,
39
+ * or `false` to push on every deploy.
40
+ * @default true
41
+ */
42
+ readonly memo?: MemoOptions | boolean;
43
+ }
44
+ export interface DeployAttributes {
45
+ /** Client URL of the deployment that received the push, such as `https://happy-otter-123.convex.cloud`. */
46
+ readonly url: string;
47
+ /** First label of the URL host, such as `happy-otter-123`. */
48
+ readonly deploymentName: string;
49
+ /** Hash of the memoized input files after the push, or `undefined` when `memo` is `false`. */
50
+ readonly hash: string | undefined;
51
+ }
52
+ export type Deploy = Resource<"Convex.Deploy", DeployProps, DeployAttributes, never, Providers>;
53
+ export declare const Deploy: import("alchemy").ResourceClass<Deploy>;
54
+ /** Reads the deployment URL from `convex deploy` output. ANSI escape codes are removed first. */
55
+ export declare const parseDeployOutput: (text: string) => {
56
+ url: string;
57
+ deploymentName: string;
58
+ } | undefined;
59
+ /** The `convex deploy` argv, starting with `npx`. */
60
+ export declare const deployArgs: (props: Pick<DeployProps, "previewName" | "previewCreate" | "previewRun" | "extraArgs">) => readonly string[];
61
+ export declare const DeployProvider: () => import("effect/Layer").Layer<Provider.Provider<Deploy>, never, import("effect/FileSystem").FileSystem | import("effect/Path").Path | CommandExecutor>;
62
+ //# sourceMappingURL=Deploy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Deploy.d.ts","sourceRoot":"","sources":["../src/Deploy.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,eAAe,EAAE,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACxE,OAAO,EAAiB,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEvE,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAE7C,OAAO,KAAK,KAAK,QAAQ,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD,MAAM,WAAW,WAAY,SAAQ,IAAI,CAAC,eAAe,EAAE,KAAK,GAAG,KAAK,GAAG,SAAS,CAAC;IACnF;;;;OAIG;IACH,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC9C;;;OAGG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B;;;OAGG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC;;;OAGG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B;;;;OAIG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC;;;;;;OAMG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC;CACvC;AAED,MAAM,WAAW,gBAAgB;IAC/B,2GAA2G;IAC3G,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,8DAA8D;IAC9D,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,8FAA8F;IAC9F,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;CACnC;AAED,MAAM,MAAM,MAAM,GAAG,QAAQ,CAAC,eAAe,EAAE,WAAW,EAAE,gBAAgB,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;AAChG,eAAO,MAAM,MAAM,yCAAoC,CAAC;AAWxD,iGAAiG;AACjG,eAAO,MAAM,iBAAiB,GAC5B,MAAM,MAAM,KACX;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAE,GAAG,SAK5C,CAAC;AAEF,qDAAqD;AACrD,eAAO,MAAM,UAAU,GACrB,OAAO,IAAI,CAAC,WAAW,EAAE,aAAa,GAAG,eAAe,GAAG,YAAY,GAAG,WAAW,CAAC,KACrF,SAAS,MAAM,EAQjB,CAAC;AAKF,eAAO,MAAM,cAAc,6JAqExB,CAAC"}
package/lib/Deploy.js ADDED
@@ -0,0 +1,92 @@
1
+ // Convex.Deploy: pushes the functions in a `convex/` directory with
2
+ // `npx convex deploy` and exposes the deployment URL for a frontend build.
3
+ //
4
+ // The deployment itself belongs to the project, so delete leaves the last
5
+ // pushed functions running. The URL comes from the CLI's own output because
6
+ // the deploy key, not this resource, decides which deployment receives the push.
7
+ import { stripVTControlCharacters } from "node:util";
8
+ import { Resource } from "alchemy";
9
+ import { CommandExecutor } from "alchemy/Command";
10
+ import { hashDirectory } from "alchemy/Command/Memo";
11
+ import { havePropsChanged, isResolved } from "alchemy/Diff";
12
+ import * as Provider from "alchemy/Provider";
13
+ import * as Effect from "effect/Effect";
14
+ export const Deploy = Resource("Convex.Deploy");
15
+ /**
16
+ * The CLI prints this line with `logFinishedStep` after the push succeeds, to
17
+ * stderr (convex 1.45 `cli/lib/deploy2.js` for existing deployments,
18
+ * `cli/deploy.js` for preview deployments). The host is
19
+ * `<deployment>.convex.cloud` or `<deployment>.<region>.convex.cloud`.
20
+ */
21
+ const DEPLOYED_LINE = /Deployed Convex functions to (https:\/\/([a-z0-9]+(?:-[a-z0-9]+)*)(?:\.[a-z0-9]+(?:-[a-z0-9]+)*)?\.convex\.cloud)\/?(?=\s|$)/m;
22
+ /** Reads the deployment URL from `convex deploy` output. ANSI escape codes are removed first. */
23
+ export const parseDeployOutput = (text) => {
24
+ const match = DEPLOYED_LINE.exec(stripVTControlCharacters(text));
25
+ const url = match?.[1];
26
+ const deploymentName = match?.[2];
27
+ return url === undefined || deploymentName === undefined ? undefined : { url, deploymentName };
28
+ };
29
+ /** The `convex deploy` argv, starting with `npx`. */
30
+ export const deployArgs = (props) => [
31
+ "npx",
32
+ "convex",
33
+ "deploy",
34
+ ...(props.previewName === undefined ? [] : ["--preview-name", props.previewName]),
35
+ ...(props.previewCreate === undefined ? [] : ["--preview-create", props.previewCreate]),
36
+ ...(props.previewRun === undefined ? [] : ["--preview-run", props.previewRun]),
37
+ ...(props.extraArgs ?? []),
38
+ ];
39
+ /** Number of output lines quoted when the CLI exits 0 without the deployed line. */
40
+ const OUTPUT_TAIL_LINES = 20;
41
+ export const DeployProvider = () => Provider.effect(Deploy, Effect.gen(function* () {
42
+ const { run } = yield* CommandExecutor;
43
+ const hashOf = (props) => props.memo === false
44
+ ? Effect.succeed(undefined)
45
+ : hashDirectory({
46
+ ...(props.cwd === undefined ? {} : { cwd: props.cwd }),
47
+ memo: props.memo === true || props.memo === undefined ? {} : props.memo,
48
+ });
49
+ return {
50
+ // No `stables`: the same deploy key can push to a different URL. A
51
+ // project deploy key follows the project's default production
52
+ // deployment, and a preview deployment can expire or be recreated
53
+ // under the same name.
54
+ diff: Effect.fn(function* ({ olds, news, output }) {
55
+ if (!isResolved(news))
56
+ return undefined;
57
+ if (output === undefined || output.hash === undefined || havePropsChanged(olds, news)) {
58
+ return { action: "update" };
59
+ }
60
+ return { action: (yield* hashOf(news)) === output.hash ? "noop" : "update" };
61
+ }),
62
+ reconcile: Effect.fn(function* ({ news, session }) {
63
+ const args = deployArgs(news);
64
+ const spaced = args.find((arg) => /\s/.test(arg));
65
+ if (spaced !== undefined) {
66
+ return yield* Effect.die(new Error(`Convex.Deploy argument "${spaced}" contains whitespace; Alchemy splits commands on whitespace`));
67
+ }
68
+ // A push is idempotent: the CLI uploads the full function set every time.
69
+ const { stdout, stderr } = yield* run({
70
+ command: args.join(" "),
71
+ ...(news.cwd === undefined ? {} : { cwd: news.cwd }),
72
+ ...(news.timeout === undefined ? {} : { timeout: news.timeout }),
73
+ env: { ...news.env, CONVEX_DEPLOY_KEY: news.deployKey },
74
+ }, session);
75
+ // `run` returns output with the deploy key already replaced.
76
+ const output = `${stdout}\n${stderr}`;
77
+ const deployed = parseDeployOutput(output);
78
+ if (deployed === undefined) {
79
+ const tail = stripVTControlCharacters(output)
80
+ .split(/\r?\n|\r/)
81
+ .filter((line) => line.trim() !== "")
82
+ .slice(-OUTPUT_TAIL_LINES)
83
+ .join("\n");
84
+ return yield* Effect.die(new Error(`npx convex deploy exited 0 but printed no "Deployed Convex functions to <url>" line. Last output:\n${tail}`));
85
+ }
86
+ return { ...deployed, hash: yield* hashOf(news) };
87
+ }),
88
+ // The deployment belongs to the project; its functions stay deployed.
89
+ delete: () => Effect.void,
90
+ };
91
+ }));
92
+ //# sourceMappingURL=Deploy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Deploy.js","sourceRoot":"","sources":["../src/Deploy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ import { Resource } from "alchemy";
2
+ import * as Provider from "alchemy/Provider";
3
+ import * as Redacted from "effect/Redacted";
4
+ import * as Schema from "effect/Schema";
5
+ import type { components } from "@convex-dev/platform/managementApi";
6
+ import { ManagementApi } from "./ManagementApi.ts";
7
+ import type { Providers } from "./Providers.ts";
8
+ /** Actions a deploy key can be limited to, from the generated schema. */
9
+ export type DeployKeyAction = NonNullable<components["schemas"]["PlatformCreateDeployKeyArgs"]["allowedActions"]>[number];
10
+ /**
11
+ * The listed key that a create call for `name` just made. The newest match
12
+ * wins: an earlier attempt that failed before Alchemy saved state can leave
13
+ * another key with the same requested name, and its secret is lost.
14
+ */
15
+ export declare const selectCreatedKey: (entries: ReadonlyArray<typeof ListedKey.Type>, name: string) => typeof ListedKey.Type | undefined;
16
+ /** One row of list_deploy_keys and list_preview_deploy_keys. Only the fields the providers use. */
17
+ export declare const ListedKey: Schema.Struct<{
18
+ readonly name: Schema.String;
19
+ readonly creationTime: Schema.Number;
20
+ }>;
21
+ /** GET /deployments/{deployment_name}/list_deploy_keys */
22
+ export declare const DeployKeyList: Schema.$Array<Schema.Struct<{
23
+ readonly name: Schema.String;
24
+ readonly creationTime: Schema.Number;
25
+ }>>;
26
+ /** POST /deployments/{deployment_name}/create_deploy_key */
27
+ export declare const CreatedDeployKey: Schema.Struct<{
28
+ readonly deployKey: Schema.String;
29
+ }>;
30
+ export interface DeployKeyProps {
31
+ /** Deployment name, such as `project.prodDeploymentName`. */
32
+ readonly deployment: string;
33
+ /** Requested key name. Convex appends a short id to make it unique. */
34
+ readonly name: string;
35
+ /** Limits the key to these actions. Convex grants every deployment action when omitted. */
36
+ readonly allowedActions?: readonly DeployKeyAction[];
37
+ }
38
+ export interface DeployKeyAttributes {
39
+ /** The name Convex lists the key under, such as "my-key (0e71106d)". */
40
+ readonly uniqueName: string;
41
+ readonly deployment: string;
42
+ /** The secret, such as `prod:<deployment>|<token>`. Convex returns it only at creation. */
43
+ readonly deployKey: Redacted.Redacted<string>;
44
+ }
45
+ export type DeployKey = Resource<"Convex.DeployKey", DeployKeyProps, DeployKeyAttributes, never, Providers>;
46
+ export declare const DeployKey: import("alchemy").ResourceClass<DeployKey>;
47
+ export declare const DeployKeyProvider: () => import("effect/Layer").Layer<Provider.Provider<DeployKey>, never, ManagementApi>;
48
+ //# sourceMappingURL=DeployKey.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DeployKey.d.ts","sourceRoot":"","sources":["../src/DeployKey.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEnC,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAE7C,OAAO,KAAK,QAAQ,MAAM,iBAAiB,CAAC;AAC5C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oCAAoC,CAAC;AACrE,OAAO,EAAqB,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACtE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD,yEAAyE;AACzE,MAAM,MAAM,eAAe,GAAG,WAAW,CACvC,UAAU,CAAC,SAAS,CAAC,CAAC,6BAA6B,CAAC,CAAC,gBAAgB,CAAC,CACvE,CAAC,MAAM,CAAC,CAAC;AAYV;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,GAC3B,SAAS,aAAa,CAAC,OAAO,SAAS,CAAC,IAAI,CAAC,EAC7C,MAAM,MAAM,KACX,OAAO,SAAS,CAAC,IAAI,GAAG,SAOtB,CAAC;AAEN,mGAAmG;AACnG,eAAO,MAAM,SAAS;;;EAGpB,CAAC;AAEH,0DAA0D;AAC1D,eAAO,MAAM,aAAa;;;GAA0B,CAAC;AAErD,4DAA4D;AAC5D,eAAO,MAAM,gBAAgB;;EAA8C,CAAC;AAE5E,MAAM,WAAW,cAAc;IAC7B,6DAA6D;IAC7D,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,uEAAuE;IACvE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,2FAA2F;IAC3F,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,eAAe,EAAE,CAAC;CACtD;AAED,MAAM,WAAW,mBAAmB;IAClC,wEAAwE;IACxE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,2FAA2F;IAC3F,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;CAC/C;AAED,MAAM,MAAM,SAAS,GAAG,QAAQ,CAC9B,kBAAkB,EAClB,cAAc,EACd,mBAAmB,EACnB,KAAK,EACL,SAAS,CACV,CAAC;AACF,eAAO,MAAM,SAAS,4CAA0C,CAAC;AAEjE,eAAO,MAAM,iBAAiB,wFAkF3B,CAAC"}
@@ -0,0 +1,104 @@
1
+ // Convex.DeployKey: a deploy key for one deployment, such as the key
2
+ // `npx convex deploy` reads from CONVEX_DEPLOY_KEY.
3
+ //
4
+ // Convex returns the secret only once, from create_deploy_key. The listing
5
+ // shows each key under a unique name, the requested name plus a short id
6
+ // suffix such as "my-key (0e71106d)", and delete_deploy_key accepts that
7
+ // unique name. A key cannot be changed after creation, so every property
8
+ // change is a replacement.
9
+ import { Resource } from "alchemy";
10
+ import { havePropsChanged, isResolved } from "alchemy/Diff";
11
+ import * as Provider from "alchemy/Provider";
12
+ import * as Effect from "effect/Effect";
13
+ import * as Redacted from "effect/Redacted";
14
+ import * as Schema from "effect/Schema";
15
+ import { absentAsUndefined, ManagementApi } from "./ManagementApi.js";
16
+ /**
17
+ * True when `listedName` is how Convex lists a key created as `name`: the
18
+ * requested name, a space, and one parenthesized id without spaces. The id
19
+ * check keeps `my-key` from matching a key created as `my-key (old)`.
20
+ */
21
+ const isListedAs = (listedName, name) => {
22
+ const prefix = `${name} (`;
23
+ return listedName.startsWith(prefix) && /^[^\s()]+\)$/.test(listedName.slice(prefix.length));
24
+ };
25
+ /**
26
+ * The listed key that a create call for `name` just made. The newest match
27
+ * wins: an earlier attempt that failed before Alchemy saved state can leave
28
+ * another key with the same requested name, and its secret is lost.
29
+ */
30
+ export const selectCreatedKey = (entries, name) => entries
31
+ .filter((entry) => isListedAs(entry.name, name))
32
+ .reduce((newest, entry) => newest === undefined || entry.creationTime > newest.creationTime ? entry : newest, undefined);
33
+ /** One row of list_deploy_keys and list_preview_deploy_keys. Only the fields the providers use. */
34
+ export const ListedKey = Schema.Struct({
35
+ name: Schema.String,
36
+ creationTime: Schema.Number,
37
+ });
38
+ /** GET /deployments/{deployment_name}/list_deploy_keys */
39
+ export const DeployKeyList = Schema.Array(ListedKey);
40
+ /** POST /deployments/{deployment_name}/create_deploy_key */
41
+ export const CreatedDeployKey = Schema.Struct({ deployKey: Schema.String });
42
+ export const DeployKey = Resource("Convex.DeployKey");
43
+ export const DeployKeyProvider = () => Provider.effect(DeployKey, Effect.gen(function* () {
44
+ const api = yield* ManagementApi;
45
+ const listKeys = (deployment) => api
46
+ .request("list deploy keys", (client) => client.GET("/deployments/{deployment_name}/list_deploy_keys", {
47
+ params: { path: { deployment_name: deployment } },
48
+ }))
49
+ .pipe(Effect.map((body) => Schema.decodeUnknownSync(DeployKeyList)(body)));
50
+ return {
51
+ stables: ["uniqueName", "deployment"],
52
+ diff: ({ olds, news, output }) => {
53
+ if (!isResolved(news))
54
+ return Effect.succeed(undefined);
55
+ // State written without the secret cannot hand a key to dependents,
56
+ // and Convex cannot return it again, so only a new key helps.
57
+ return Effect.succeed((output !== undefined && output.deployKey === undefined) || havePropsChanged(olds, news)
58
+ ? { action: "replace" }
59
+ : { action: "noop" });
60
+ },
61
+ read: Effect.fn(function* ({ output }) {
62
+ // A key that is not in state has no known secret, so it is never adopted.
63
+ if (output === undefined)
64
+ return undefined;
65
+ const entries = yield* absentAsUndefined(listKeys(output.deployment));
66
+ return entries?.some((entry) => entry.name === output.uniqueName) ? output : undefined;
67
+ }),
68
+ reconcile: Effect.fn(function* ({ news, output }) {
69
+ if (output !== undefined) {
70
+ // The secret cannot be read back. A key that still exists keeps the one in state.
71
+ const entries = yield* listKeys(news.deployment);
72
+ if (entries.some((entry) => entry.name === output.uniqueName))
73
+ return output;
74
+ }
75
+ const created = yield* api.request("create deploy key", (client) => client.POST("/deployments/{deployment_name}/create_deploy_key", {
76
+ params: { path: { deployment_name: news.deployment } },
77
+ body: {
78
+ name: news.name,
79
+ ...(news.allowedActions === undefined
80
+ ? {}
81
+ : { allowedActions: [...news.allowedActions] }),
82
+ },
83
+ }));
84
+ const { deployKey } = Schema.decodeUnknownSync(CreatedDeployKey)(created);
85
+ const listed = selectCreatedKey(yield* listKeys(news.deployment), news.name);
86
+ if (listed === undefined) {
87
+ return yield* Effect.die(new Error(`Convex created deploy key "${news.name}" on ${news.deployment} but does not list it`));
88
+ }
89
+ return {
90
+ uniqueName: listed.name,
91
+ deployment: news.deployment,
92
+ deployKey: Redacted.make(deployKey),
93
+ };
94
+ }),
95
+ delete: Effect.fn(function* ({ output }) {
96
+ // 404 DeployKeyNotFound: an earlier attempt or someone else deleted it.
97
+ yield* absentAsUndefined(api.requestVoid("delete deploy key", (client) => client.POST("/deployments/{deployment_name}/delete_deploy_key", {
98
+ params: { path: { deployment_name: output.deployment } },
99
+ body: { id: output.uniqueName },
100
+ })));
101
+ }),
102
+ };
103
+ }));
104
+ //# sourceMappingURL=DeployKey.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DeployKey.js","sourceRoot":"","sources":["../src/DeployKey.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ import { Resource } from "alchemy";
2
+ import * as Provider from "alchemy/Provider";
3
+ import * as Effect from "effect/Effect";
4
+ import * as Redacted from "effect/Redacted";
5
+ import * as Schema from "effect/Schema";
6
+ import { ManagementApi } from "./ManagementApi.ts";
7
+ import type { Providers } from "./Providers.ts";
8
+ /**
9
+ * Attributes when the listing has `name`. Own keys only: a valid variable
10
+ * name such as `toString` must not match the object prototype.
11
+ */
12
+ export declare const findVariable: (list: typeof EnvironmentVariableList.Type, deployment: string, name: string) => EnvironmentVariableAttributes | undefined;
13
+ /**
14
+ * Sets one variable, or removes it when `value` is null. The deployment
15
+ * answers 200 with an empty body, so this reads no response data.
16
+ */
17
+ export declare const updateVariable: (deployment: string, deployKey: Redacted.Redacted<string>, name: string, value: string | Redacted.Redacted<string> | null) => Effect.Effect<void, import("./ManagementApi.ts").ConvexApiError, never>;
18
+ /** GET https://<deployment>.convex.cloud/api/v1/list_environment_variables */
19
+ export declare const EnvironmentVariableList: Schema.Struct<{
20
+ readonly environmentVariables: Schema.$Record<Schema.String, Schema.String>;
21
+ }>;
22
+ export interface EnvironmentVariableProps {
23
+ /** Deployment name, or its URL for deployments outside US East. */
24
+ readonly deployment: string;
25
+ /** Deploy key for `deployment`, such as `deployKey.deployKey`. */
26
+ readonly deployKey: Redacted.Redacted<string>;
27
+ readonly name: string;
28
+ readonly value: string | Redacted.Redacted<string>;
29
+ }
30
+ export interface EnvironmentVariableAttributes {
31
+ readonly deployment: string;
32
+ readonly name: string;
33
+ }
34
+ export type EnvironmentVariable = Resource<"Convex.EnvironmentVariable", EnvironmentVariableProps, EnvironmentVariableAttributes, never, Providers>;
35
+ export declare const EnvironmentVariable: import("alchemy").ResourceClass<EnvironmentVariable>;
36
+ export declare const EnvironmentVariableProvider: () => import("effect/Layer").Layer<Provider.Provider<EnvironmentVariable>, never, ManagementApi>;
37
+ //# sourceMappingURL=EnvironmentVariable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EnvironmentVariable.d.ts","sourceRoot":"","sources":["../src/EnvironmentVariable.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEnC,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAC7C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,QAAQ,MAAM,iBAAiB,CAAC;AAC5C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,EAAqB,aAAa,EAAc,MAAM,oBAAoB,CAAC;AAClF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD;;;GAGG;AACH,eAAO,MAAM,YAAY,GACvB,MAAM,OAAO,uBAAuB,CAAC,IAAI,EACzC,YAAY,MAAM,EAClB,MAAM,MAAM,KACX,6BAA6B,GAAG,SACgD,CAAC;AAEpF;;;GAGG;AACH,eAAO,MAAM,cAAc,GACzB,YAAY,MAAM,EAClB,WAAW,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,EACpC,MAAM,MAAM,EACZ,OAAO,MAAM,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,IAAI,4EAW/C,CAAC;AAEJ,8EAA8E;AAC9E,eAAO,MAAM,uBAAuB;;EAElC,CAAC;AAEH,MAAM,WAAW,wBAAwB;IACvC,mEAAmE;IACnE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,kEAAkE;IAClE,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC9C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;CACpD;AAED,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CACxC,4BAA4B,EAC5B,wBAAwB,EACxB,6BAA6B,EAC7B,KAAK,EACL,SAAS,CACV,CAAC;AACF,eAAO,MAAM,mBAAmB,sDAA8D,CAAC;AAE/F,eAAO,MAAM,2BAA2B,kGAmDrC,CAAC"}
@@ -0,0 +1,65 @@
1
+ // Convex.EnvironmentVariable: one environment variable on one deployment.
2
+ //
3
+ // Environment variables live on the deployment API
4
+ // (https://<deployment>.convex.cloud/api/v1), which authenticates with a
5
+ // deploy key, not with the Management API token. Setting a variable and
6
+ // removing it are the same call: update_environment_variables with
7
+ // `value: null` removes the variable.
8
+ import { createDeploymentClient } from "@convex-dev/platform";
9
+ import { Resource } from "alchemy";
10
+ import { isResolved } from "alchemy/Diff";
11
+ import * as Provider from "alchemy/Provider";
12
+ import * as Effect from "effect/Effect";
13
+ import * as Redacted from "effect/Redacted";
14
+ import * as Schema from "effect/Schema";
15
+ import { absentAsUndefined, ManagementApi, settleVoid } from "./ManagementApi.js";
16
+ /**
17
+ * Attributes when the listing has `name`. Own keys only: a valid variable
18
+ * name such as `toString` must not match the object prototype.
19
+ */
20
+ export const findVariable = (list, deployment, name) => Object.hasOwn(list.environmentVariables, name) ? { deployment, name } : undefined;
21
+ /**
22
+ * Sets one variable, or removes it when `value` is null. The deployment
23
+ * answers 200 with an empty body, so this reads no response data.
24
+ */
25
+ export const updateVariable = (deployment, deployKey, name, value) => settleVoid("update environment variables", () => createDeploymentClient(deployment, Redacted.value(deployKey)).POST("/update_environment_variables", {
26
+ body: {
27
+ changes: [{ name, value: Redacted.isRedacted(value) ? Redacted.value(value) : value }],
28
+ },
29
+ }));
30
+ /** GET https://<deployment>.convex.cloud/api/v1/list_environment_variables */
31
+ export const EnvironmentVariableList = Schema.Struct({
32
+ environmentVariables: Schema.Record(Schema.String, Schema.String),
33
+ });
34
+ export const EnvironmentVariable = Resource("Convex.EnvironmentVariable");
35
+ export const EnvironmentVariableProvider = () => Provider.effect(EnvironmentVariable, Effect.gen(function* () {
36
+ const api = yield* ManagementApi;
37
+ return {
38
+ stables: ["deployment", "name"],
39
+ diff: ({ olds, news }) => {
40
+ if (!isResolved(news))
41
+ return Effect.succeed(undefined);
42
+ // Otherwise undefined: the engine updates when any prop changed and
43
+ // compares Redacted values, such as the value and the deploy key, by content.
44
+ return Effect.succeed(olds.deployment !== news.deployment || olds.name !== news.name
45
+ ? { action: "replace" }
46
+ : undefined);
47
+ },
48
+ read: Effect.fn(function* ({ olds }) {
49
+ // 404: the deployment no longer exists, so neither does the variable.
50
+ const body = yield* absentAsUndefined(api.deploymentRequest("list environment variables", olds.deployment, olds.deployKey, (client) => client.GET("/list_environment_variables")));
51
+ if (body === undefined)
52
+ return undefined;
53
+ return findVariable(Schema.decodeUnknownSync(EnvironmentVariableList)(body), olds.deployment, olds.name);
54
+ }),
55
+ reconcile: Effect.fn(function* ({ news }) {
56
+ yield* updateVariable(news.deployment, news.deployKey, news.name, news.value);
57
+ return { deployment: news.deployment, name: news.name };
58
+ }),
59
+ delete: Effect.fn(function* ({ olds, output }) {
60
+ // Removing an absent variable succeeds; 404 means the deployment is gone.
61
+ yield* absentAsUndefined(updateVariable(output.deployment, olds.deployKey, output.name, null));
62
+ }),
63
+ };
64
+ }));
65
+ //# sourceMappingURL=EnvironmentVariable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EnvironmentVariable.js","sourceRoot":"","sources":["../src/EnvironmentVariable.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ import { createDeploymentClient, createManagementClient } from "@convex-dev/platform";
2
+ import * as Context from "effect/Context";
3
+ import * as Effect from "effect/Effect";
4
+ import * as Layer from "effect/Layer";
5
+ import * as Redacted from "effect/Redacted";
6
+ import * as Schema from "effect/Schema";
7
+ import { Credentials } from "./Credentials.ts";
8
+ export type ManagementClient = ReturnType<typeof createManagementClient>;
9
+ export type DeploymentClient = ReturnType<typeof createDeploymentClient>;
10
+ /** Shape of every openapi-fetch result we consume. */
11
+ export interface FetchResult<T> {
12
+ readonly data?: T;
13
+ readonly error?: unknown;
14
+ readonly response: Response;
15
+ }
16
+ declare const ConvexApiError_base: Schema.Class<ConvexApiError, Schema.TaggedStruct<"ConvexApiError", {
17
+ readonly operation: Schema.String;
18
+ readonly status: Schema.Number;
19
+ readonly code: Schema.optionalKey<Schema.String>;
20
+ readonly message: Schema.String;
21
+ }>, import("effect/Cause").YieldableError>;
22
+ /**
23
+ * One error for every control-plane and deployment call. Resources branch on
24
+ * `status` (404 means absent for read and delete), so the class is load
25
+ * bearing, not decorative.
26
+ */
27
+ export declare class ConvexApiError extends ConvexApiError_base {
28
+ }
29
+ export interface ManagementApiService {
30
+ /** Run one management call with the resolved credentials. */
31
+ readonly request: <T>(operation: string, run: (client: ManagementClient) => Promise<FetchResult<T>>) => Effect.Effect<T, ConvexApiError>;
32
+ /** Run one management call whose success response has no body. */
33
+ readonly requestVoid: (operation: string, run: (client: ManagementClient) => Promise<FetchResult<unknown>>) => Effect.Effect<void, ConvexApiError>;
34
+ /** Run one deployment-scoped call authenticated with a deploy key. */
35
+ readonly deploymentRequest: <T>(operation: string, deploymentUrlOrName: string, deployKey: Redacted.Redacted<string>, run: (client: DeploymentClient) => Promise<FetchResult<T>>) => Effect.Effect<T, ConvexApiError>;
36
+ /** Team id for a slug or numeric id. */
37
+ readonly resolveTeamId: (team: string | number) => Effect.Effect<number, ConvexApiError>;
38
+ }
39
+ declare const ManagementApi_base: Context.ServiceClass<ManagementApi, "@samebase/alchemy-convex/ManagementApi", ManagementApiService>;
40
+ export declare class ManagementApi extends ManagementApi_base {
41
+ }
42
+ /** Reads `data` or fails with the HTTP status and the API's own code and message. */
43
+ export declare const settle: <T>(operation: string, run: () => Promise<FetchResult<T>>) => Effect.Effect<T, ConvexApiError>;
44
+ /** For endpoints that answer with an empty body, such as delete calls. */
45
+ export declare const settleVoid: (operation: string, run: () => Promise<FetchResult<unknown>>) => Effect.Effect<void, ConvexApiError>;
46
+ /** Turns a 404 into `undefined` so read and delete stay idempotent. */
47
+ export declare const absentAsUndefined: <A, R>(effect: Effect.Effect<A, ConvexApiError, R>) => Effect.Effect<A | undefined, ConvexApiError, R>;
48
+ export declare const ManagementApiLive: () => Layer.Layer<ManagementApi, never, Credentials>;
49
+ export {};
50
+ //# sourceMappingURL=ManagementApi.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ManagementApi.d.ts","sourceRoot":"","sources":["../src/ManagementApi.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,103 @@
1
+ // Effect wrapper around the official Convex platform client.
2
+ //
3
+ // `@convex-dev/platform` is an openapi-fetch client: every call resolves to
4
+ // `{ data, error, response }`. This service turns that into an Effect with one
5
+ // typed error, resolves credentials lazily, and validates the fields the
6
+ // provider relies on at runtime.
7
+ import { createDeploymentClient, createManagementClient } from "@convex-dev/platform";
8
+ import * as Context from "effect/Context";
9
+ import * as Effect from "effect/Effect";
10
+ import * as Layer from "effect/Layer";
11
+ import * as Redacted from "effect/Redacted";
12
+ import * as Schema from "effect/Schema";
13
+ import { Credentials } from "./Credentials.js";
14
+ /**
15
+ * One error for every control-plane and deployment call. Resources branch on
16
+ * `status` (404 means absent for read and delete), so the class is load
17
+ * bearing, not decorative.
18
+ */
19
+ export class ConvexApiError extends Schema.TaggedError()("ConvexApiError", {
20
+ operation: Schema.String,
21
+ status: Schema.Number,
22
+ code: Schema.optionalKey(Schema.String),
23
+ message: Schema.String,
24
+ }) {
25
+ }
26
+ const ErrorBody = Schema.Struct({
27
+ code: Schema.optionalKey(Schema.String),
28
+ message: Schema.optionalKey(Schema.String),
29
+ });
30
+ const toApiError = (operation, result) => {
31
+ const body = Schema.decodeUnknownSync(Schema.NullishOr(ErrorBody))(result.error ?? null);
32
+ const code = body?.code;
33
+ return new ConvexApiError({
34
+ operation,
35
+ status: result.response.status,
36
+ ...(code === undefined ? {} : { code }),
37
+ message: body?.message ?? `${operation} failed with HTTP ${result.response.status}`,
38
+ });
39
+ };
40
+ export class ManagementApi extends Context.Service()("@samebase/alchemy-convex/ManagementApi") {
41
+ }
42
+ const attempt = (operation, run) => Effect.tryPromise({
43
+ try: run,
44
+ catch: (cause) => new ConvexApiError({
45
+ operation,
46
+ status: 0,
47
+ message: cause instanceof Error ? cause.message : String(cause),
48
+ }),
49
+ });
50
+ /** Reads `data` or fails with the HTTP status and the API's own code and message. */
51
+ export const settle = (operation, run) => attempt(operation, run).pipe(Effect.flatMap((result) => result.response.ok && result.data !== undefined
52
+ ? Effect.succeed(result.data)
53
+ : Effect.fail(toApiError(operation, result))));
54
+ /** For endpoints that answer with an empty body, such as delete calls. */
55
+ export const settleVoid = (operation, run) => attempt(operation, run).pipe(Effect.flatMap((result) => result.response.ok ? Effect.void : Effect.fail(toApiError(operation, result))));
56
+ /** Turns a 404 into `undefined` so read and delete stay idempotent. */
57
+ export const absentAsUndefined = (effect) => effect.pipe(Effect.catchIf((error) => error.status === 404, () => Effect.succeed(undefined)));
58
+ const TeamRow = Schema.Struct({ id: Schema.Number, slug: Schema.String });
59
+ const TeamRows = Schema.Array(TeamRow);
60
+ export const ManagementApiLive = () => Layer.effect(ManagementApi, Effect.gen(function* () {
61
+ const credentials = yield* Credentials;
62
+ const client = Effect.cached(credentials.pipe(Effect.map((resolved) => createManagementClient(Redacted.value(resolved.accessToken))))).pipe(Effect.flatten);
63
+ const request = (operation, run) => client.pipe(Effect.flatMap((c) => settle(operation, () => run(c))));
64
+ const requestVoid = (operation, run) => client.pipe(Effect.flatMap((c) => settleVoid(operation, () => run(c))));
65
+ const deploymentRequest = (operation, deploymentUrlOrName, deployKey, run) => settle(operation, () => run(createDeploymentClient(deploymentUrlOrName, Redacted.value(deployKey))));
66
+ // The Management API addresses teams by numeric id. The only slug lookup
67
+ // it offers is per project, so a slug falls back to the dashboard's team
68
+ // list, which is unofficial. Pass the numeric team id to skip this.
69
+ const resolveTeamId = (team) => Effect.gen(function* () {
70
+ if (typeof team === "number")
71
+ return team;
72
+ if (/^\d+$/.test(team))
73
+ return Number(team);
74
+ const resolved = yield* credentials;
75
+ const rows = yield* Effect.tryPromise({
76
+ try: async () => {
77
+ const response = await fetch("https://api.convex.dev/api/dashboard/teams", {
78
+ headers: { Authorization: `Bearer ${Redacted.value(resolved.accessToken)}` },
79
+ });
80
+ if (!response.ok) {
81
+ throw new Error(`team lookup for "${team}" failed with HTTP ${response.status}`);
82
+ }
83
+ return Schema.decodeUnknownSync(TeamRows)(await response.json());
84
+ },
85
+ catch: (cause) => new ConvexApiError({
86
+ operation: "resolve team",
87
+ status: 0,
88
+ message: cause instanceof Error ? cause.message : String(cause),
89
+ }),
90
+ });
91
+ const match = rows.find((row) => row.slug === team);
92
+ if (match === undefined) {
93
+ return yield* new ConvexApiError({
94
+ operation: "resolve team",
95
+ status: 404,
96
+ message: `no team with slug "${team}" for this token`,
97
+ });
98
+ }
99
+ return match.id;
100
+ });
101
+ return { request, requestVoid, deploymentRequest, resolveTeamId };
102
+ }));
103
+ //# sourceMappingURL=ManagementApi.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ManagementApi.js","sourceRoot":"","sources":["../src/ManagementApi.ts"],"names":[],"mappings":"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"}