@gaganref/confect-alchemy 0.0.0-stage → 10.3.1-fork.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +7 -0
- package/README.md +22 -2
- package/dist/Backend.d.ts +45 -0
- package/dist/Backend.d.ts.map +1 -0
- package/dist/Backend.js +38 -0
- package/dist/Backend.js.map +1 -0
- package/dist/Code.d.ts +80 -0
- package/dist/Code.d.ts.map +1 -0
- package/dist/Code.js +29 -0
- package/dist/Code.js.map +1 -0
- package/dist/Confect.d.ts +2 -0
- package/dist/Confect.d.ts.map +1 -0
- package/dist/Confect.js +8 -0
- package/dist/Confect.js.map +1 -0
- package/dist/Convex.d.ts +7 -0
- package/dist/Convex.d.ts.map +1 -0
- package/dist/Convex.js +21 -0
- package/dist/Convex.js.map +1 -0
- package/dist/ConvexClient.d.ts +215 -0
- package/dist/ConvexClient.d.ts.map +1 -0
- package/dist/ConvexClient.js +224 -0
- package/dist/ConvexClient.js.map +1 -0
- package/dist/DeployKey.d.ts +120 -0
- package/dist/DeployKey.d.ts.map +1 -0
- package/dist/DeployKey.js +151 -0
- package/dist/DeployKey.js.map +1 -0
- package/dist/Deployment.d.ts +113 -0
- package/dist/Deployment.d.ts.map +1 -0
- package/dist/Deployment.js +160 -0
- package/dist/Deployment.js.map +1 -0
- package/dist/EnvironmentVariables.d.ts +155 -0
- package/dist/EnvironmentVariables.d.ts.map +1 -0
- package/dist/EnvironmentVariables.js +135 -0
- package/dist/EnvironmentVariables.js.map +1 -0
- package/dist/Project.d.ts +100 -0
- package/dist/Project.d.ts.map +1 -0
- package/dist/Project.js +123 -0
- package/dist/Project.js.map +1 -0
- package/dist/Providers.d.ts +17 -0
- package/dist/Providers.d.ts.map +1 -0
- package/dist/Providers.js +46 -0
- package/dist/Providers.js.map +1 -0
- package/dist/_virtual/_rolldown/runtime.js +13 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/internal/CodeDeployment.d.ts +17 -0
- package/dist/internal/CodeDeployment.d.ts.map +1 -0
- package/dist/internal/CodeDeployment.js +53 -0
- package/dist/internal/CodeDeployment.js.map +1 -0
- package/dist/internal/CommandRunner.d.ts +55 -0
- package/dist/internal/CommandRunner.d.ts.map +1 -0
- package/dist/internal/CommandRunner.js +126 -0
- package/dist/internal/CommandRunner.js.map +1 -0
- package/dist/internal/FileLock.d.ts +30 -0
- package/dist/internal/FileLock.d.ts.map +1 -0
- package/dist/internal/FileLock.js +83 -0
- package/dist/internal/FileLock.js.map +1 -0
- package/dist/internal/Lifecycle.d.ts +11 -0
- package/dist/internal/Lifecycle.d.ts.map +1 -0
- package/dist/internal/Lifecycle.js +45 -0
- package/dist/internal/Lifecycle.js.map +1 -0
- package/dist/internal/LocalBackend.d.ts +63 -0
- package/dist/internal/LocalBackend.d.ts.map +1 -0
- package/dist/internal/LocalBackend.js +333 -0
- package/dist/internal/LocalBackend.js.map +1 -0
- package/dist/internal/LocalSidecar.d.ts +3 -0
- package/dist/internal/LocalSidecar.d.ts.map +1 -0
- package/dist/internal/LocalSidecar.js +7 -0
- package/dist/internal/LocalSidecar.js.map +1 -0
- package/dist/internal/Loopback.d.ts +18 -0
- package/dist/internal/Loopback.d.ts.map +1 -0
- package/dist/internal/Loopback.js +31 -0
- package/dist/internal/Loopback.js.map +1 -0
- package/dist/internal/PushLock.d.ts +36 -0
- package/dist/internal/PushLock.d.ts.map +1 -0
- package/dist/internal/PushLock.js +61 -0
- package/dist/internal/PushLock.js.map +1 -0
- package/dist/internal/ResourceIdentity.d.ts +3 -0
- package/dist/internal/ResourceIdentity.d.ts.map +1 -0
- package/dist/internal/ResourceIdentity.js +10 -0
- package/dist/internal/ResourceIdentity.js.map +1 -0
- package/dist/internal/UserCache.d.ts +12 -0
- package/dist/internal/UserCache.d.ts.map +1 -0
- package/dist/internal/UserCache.js +25 -0
- package/dist/internal/UserCache.js.map +1 -0
- package/dist/internal/Zip.d.ts +15 -0
- package/dist/internal/Zip.d.ts.map +1 -0
- package/dist/internal/Zip.js +65 -0
- package/dist/internal/Zip.js.map +1 -0
- package/package.json +65 -3
- package/src/Backend.ts +101 -0
- package/src/Code.ts +55 -0
- package/src/Confect.ts +1 -0
- package/src/Convex.ts +18 -0
- package/src/ConvexClient.ts +544 -0
- package/src/DeployKey.ts +256 -0
- package/src/Deployment.ts +277 -0
- package/src/EnvironmentVariables.ts +254 -0
- package/src/Project.ts +205 -0
- package/src/Providers.ts +67 -0
- package/src/index.ts +2 -0
- package/src/internal/CodeDeployment.ts +81 -0
- package/src/internal/CommandRunner.ts +251 -0
- package/src/internal/FileLock.ts +136 -0
- package/src/internal/Lifecycle.ts +49 -0
- package/src/internal/LocalBackend.ts +492 -0
- package/src/internal/LocalSidecar.ts +9 -0
- package/src/internal/Loopback.ts +34 -0
- package/src/internal/PushLock.ts +99 -0
- package/src/internal/ResourceIdentity.ts +20 -0
- package/src/internal/UserCache.ts +25 -0
- package/src/internal/Zip.ts +108 -0
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
import { isOrigin } from "./internal/Loopback.js";
|
|
2
|
+
import * as Effect from "effect/Effect";
|
|
3
|
+
import * as Redacted from "effect/Redacted";
|
|
4
|
+
import * as Schema from "effect/Schema";
|
|
5
|
+
import * as Config from "effect/Config";
|
|
6
|
+
import * as Context from "effect/Context";
|
|
7
|
+
import * as Layer from "effect/Layer";
|
|
8
|
+
import * as FetchHttpClient from "effect/http/FetchHttpClient";
|
|
9
|
+
import * as HttpClient from "effect/http/HttpClient";
|
|
10
|
+
import * as HttpClientRequest from "effect/http/HttpClientRequest";
|
|
11
|
+
//#region src/ConvexClient.ts
|
|
12
|
+
const errorFields = {
|
|
13
|
+
operation: Schema.String,
|
|
14
|
+
status: Schema.optionalKey(Schema.Finite),
|
|
15
|
+
code: Schema.Literals([
|
|
16
|
+
"HttpError",
|
|
17
|
+
"TransportError",
|
|
18
|
+
"InvalidResponse",
|
|
19
|
+
"InvalidRequest",
|
|
20
|
+
"InvalidPagination",
|
|
21
|
+
"InvalidConfiguration"
|
|
22
|
+
])
|
|
23
|
+
};
|
|
24
|
+
var ConvexApiError = class extends Schema.TaggedError()("ConvexApiError", errorFields) {};
|
|
25
|
+
var ConvexNotFound = class extends Schema.TaggedError()("ConvexNotFound", errorFields) {};
|
|
26
|
+
var ConvexConflict = class extends Schema.TaggedError()("ConvexConflict", errorFields) {};
|
|
27
|
+
const ProjectSchema = Schema.Struct({
|
|
28
|
+
id: Schema.Finite,
|
|
29
|
+
name: Schema.String,
|
|
30
|
+
slug: Schema.String,
|
|
31
|
+
teamId: Schema.Finite,
|
|
32
|
+
teamSlug: Schema.String,
|
|
33
|
+
createTime: Schema.Finite,
|
|
34
|
+
prodDeploymentName: Schema.optionalKey(Schema.NullOr(Schema.String)),
|
|
35
|
+
devDeploymentName: Schema.optionalKey(Schema.NullOr(Schema.String))
|
|
36
|
+
});
|
|
37
|
+
const CreatedProjectSchema = Schema.Struct({
|
|
38
|
+
id: Schema.Finite,
|
|
39
|
+
projectId: Schema.Finite,
|
|
40
|
+
slug: Schema.String,
|
|
41
|
+
deploymentName: Schema.optionalKey(Schema.NullOr(Schema.String)),
|
|
42
|
+
deploymentUrl: Schema.optionalKey(Schema.NullOr(Schema.String))
|
|
43
|
+
});
|
|
44
|
+
const deploymentFields = {
|
|
45
|
+
name: Schema.String,
|
|
46
|
+
createTime: Schema.Finite,
|
|
47
|
+
deploymentType: Schema.Literals([
|
|
48
|
+
"dev",
|
|
49
|
+
"prod",
|
|
50
|
+
"preview",
|
|
51
|
+
"custom"
|
|
52
|
+
]),
|
|
53
|
+
projectId: Schema.Finite,
|
|
54
|
+
previewIdentifier: Schema.optionalKey(Schema.NullOr(Schema.String))
|
|
55
|
+
};
|
|
56
|
+
const DeploymentSchema = Schema.Union([Schema.Struct({
|
|
57
|
+
...deploymentFields,
|
|
58
|
+
kind: Schema.Literal("cloud"),
|
|
59
|
+
id: Schema.Finite,
|
|
60
|
+
lastDeployTime: Schema.optionalKey(Schema.NullOr(Schema.Finite)),
|
|
61
|
+
creator: Schema.optionalKey(Schema.NullOr(Schema.Finite)),
|
|
62
|
+
region: Schema.Literals([
|
|
63
|
+
"aws-us-east-1",
|
|
64
|
+
"aws-eu-west-1",
|
|
65
|
+
"aws-ap-southeast-2",
|
|
66
|
+
"aws-ca-central-1"
|
|
67
|
+
]),
|
|
68
|
+
isDefault: Schema.Boolean,
|
|
69
|
+
reference: Schema.String,
|
|
70
|
+
dashboardEditConfirmation: Schema.optionalKey(Schema.NullOr(Schema.Boolean)),
|
|
71
|
+
deploymentUrl: Schema.String,
|
|
72
|
+
expiresAt: Schema.optionalKey(Schema.NullOr(Schema.Finite)),
|
|
73
|
+
class: Schema.String,
|
|
74
|
+
sendLogsToClient: Schema.optionalKey(Schema.NullOr(Schema.Boolean))
|
|
75
|
+
}), Schema.Struct({
|
|
76
|
+
...deploymentFields,
|
|
77
|
+
kind: Schema.Literal("local"),
|
|
78
|
+
creator: Schema.Finite,
|
|
79
|
+
port: Schema.Finite,
|
|
80
|
+
deviceName: Schema.String,
|
|
81
|
+
isActive: Schema.Boolean
|
|
82
|
+
})]);
|
|
83
|
+
const DeployKeySchema = Schema.Struct({
|
|
84
|
+
id: Schema.Finite,
|
|
85
|
+
name: Schema.String,
|
|
86
|
+
creationTime: Schema.Finite,
|
|
87
|
+
lastUsedTime: Schema.optionalKey(Schema.NullOr(Schema.Finite)),
|
|
88
|
+
expiresAt: Schema.optionalKey(Schema.NullOr(Schema.Finite)),
|
|
89
|
+
creator: Schema.optionalKey(Schema.NullOr(Schema.Finite)),
|
|
90
|
+
managedBy: Schema.optionalKey(Schema.NullOr(Schema.Union([Schema.Literal("vercel"), Schema.Struct({ oauthApp: Schema.String })]))),
|
|
91
|
+
allowedActions: Schema.Array(Schema.String)
|
|
92
|
+
});
|
|
93
|
+
const ProjectsPageSchema = Schema.Struct({
|
|
94
|
+
items: Schema.Array(ProjectSchema),
|
|
95
|
+
pagination: Schema.Struct({
|
|
96
|
+
hasMore: Schema.Boolean,
|
|
97
|
+
nextCursor: Schema.optionalKey(Schema.NullOr(Schema.String))
|
|
98
|
+
})
|
|
99
|
+
});
|
|
100
|
+
const make = Effect.fn("ConvexClient.make")(function* (options) {
|
|
101
|
+
const http = yield* HttpClient.HttpClient;
|
|
102
|
+
const managementAuthorization = Effect.gen(function* () {
|
|
103
|
+
const token = options?.token ?? (yield* Config.Redacted("CONVEX_ACCESS_TOKEN").pipe(Effect.mapError(() => new ConvexApiError({
|
|
104
|
+
operation: "configure",
|
|
105
|
+
code: "InvalidConfiguration"
|
|
106
|
+
}))));
|
|
107
|
+
return Redacted.make(`Bearer ${Redacted.value(token)}`);
|
|
108
|
+
});
|
|
109
|
+
const baseUrl = "https://api.convex.dev/v1";
|
|
110
|
+
const send = Effect.fn("ConvexClient.request")(function* (operation, method, url, authorization, body) {
|
|
111
|
+
let request = HttpClientRequest.make(method)(url).pipe(HttpClientRequest.setHeader("authorization", Redacted.value(authorization)), HttpClientRequest.acceptJson);
|
|
112
|
+
if (body !== void 0) request = yield* HttpClientRequest.bodyJson(request, body).pipe(Effect.mapError(() => new ConvexApiError({
|
|
113
|
+
operation,
|
|
114
|
+
code: "InvalidRequest"
|
|
115
|
+
})));
|
|
116
|
+
const response = yield* http.execute(request).pipe(Effect.provideService(FetchHttpClient.RequestInit, { redirect: "manual" }), Effect.mapError(() => new ConvexApiError({
|
|
117
|
+
operation,
|
|
118
|
+
code: "TransportError"
|
|
119
|
+
})));
|
|
120
|
+
if (response.status === 404) return yield* new ConvexNotFound({
|
|
121
|
+
operation,
|
|
122
|
+
status: 404,
|
|
123
|
+
code: "HttpError"
|
|
124
|
+
});
|
|
125
|
+
if (response.status === 409) return yield* new ConvexConflict({
|
|
126
|
+
operation,
|
|
127
|
+
status: 409,
|
|
128
|
+
code: "HttpError"
|
|
129
|
+
});
|
|
130
|
+
if (response.status < 200 || response.status >= 300) return yield* new ConvexApiError({
|
|
131
|
+
operation,
|
|
132
|
+
status: response.status,
|
|
133
|
+
code: "HttpError"
|
|
134
|
+
});
|
|
135
|
+
return response;
|
|
136
|
+
});
|
|
137
|
+
const decode = Effect.fn("ConvexClient.decode")(function* (operation, response, schema) {
|
|
138
|
+
const invalidResponse = () => new ConvexApiError({
|
|
139
|
+
operation,
|
|
140
|
+
status: response.status,
|
|
141
|
+
code: "InvalidResponse"
|
|
142
|
+
});
|
|
143
|
+
const body = yield* response.json.pipe(Effect.mapError(invalidResponse));
|
|
144
|
+
return yield* Schema.decodeEffect(schema)(body).pipe(Effect.mapError(invalidResponse));
|
|
145
|
+
});
|
|
146
|
+
const management = Effect.fn("ConvexClient.management")(function* (operation, method, path, schema, body) {
|
|
147
|
+
const response = yield* send(operation, method, `${baseUrl}${path}`, yield* managementAuthorization, body);
|
|
148
|
+
return yield* decode(operation, response, schema);
|
|
149
|
+
});
|
|
150
|
+
const managementVoid = Effect.fn("ConvexClient.managementVoid")(function* (operation, method, path, body) {
|
|
151
|
+
yield* send(operation, method, `${baseUrl}${path}`, yield* managementAuthorization, body);
|
|
152
|
+
});
|
|
153
|
+
const deploymentUrl = Effect.fn("ConvexClient.deploymentUrl")(function* (operation, url) {
|
|
154
|
+
const invalidUrl = () => new ConvexApiError({
|
|
155
|
+
operation,
|
|
156
|
+
code: "InvalidRequest"
|
|
157
|
+
});
|
|
158
|
+
if (options?.mode === "local") {
|
|
159
|
+
if (!isOrigin(url)) return yield* invalidUrl();
|
|
160
|
+
return `${url}/api/v1`;
|
|
161
|
+
}
|
|
162
|
+
const parsed = yield* Effect.try({
|
|
163
|
+
try: () => new URL(url),
|
|
164
|
+
catch: invalidUrl
|
|
165
|
+
});
|
|
166
|
+
if (parsed.protocol !== "https:" || parsed.username !== "" || parsed.password !== "" || parsed.port !== "" || parsed.search !== "" || parsed.hash !== "" || parsed.pathname !== "/" || !/^[a-z0-9-]+(?:\.(?:eu-west-1|ap-southeast-2|ca-central-1))?\.convex\.cloud$/.test(parsed.hostname) || url.replace(/\/$/, "") !== parsed.origin) return yield* invalidUrl();
|
|
167
|
+
return `${parsed.origin}/api/v1`;
|
|
168
|
+
});
|
|
169
|
+
return {
|
|
170
|
+
listProjects: Effect.fn("ConvexClient.listProjects")(function* (teamId) {
|
|
171
|
+
const projects = [];
|
|
172
|
+
const seenCursors = /* @__PURE__ */ new Set();
|
|
173
|
+
let cursor;
|
|
174
|
+
while (true) {
|
|
175
|
+
const page = yield* management("listProjects", "GET", `/teams/${teamId}/projects${cursor === void 0 ? "" : `?cursor=${encodeURIComponent(cursor)}`}`, ProjectsPageSchema);
|
|
176
|
+
projects.push(...page.items);
|
|
177
|
+
if (!page.pagination.hasMore) return projects;
|
|
178
|
+
const nextCursor = page.pagination.nextCursor;
|
|
179
|
+
if (!nextCursor || seenCursors.has(nextCursor)) return yield* new ConvexApiError({
|
|
180
|
+
operation: "listProjects",
|
|
181
|
+
code: "InvalidPagination"
|
|
182
|
+
});
|
|
183
|
+
seenCursors.add(nextCursor);
|
|
184
|
+
cursor = nextCursor;
|
|
185
|
+
}
|
|
186
|
+
}),
|
|
187
|
+
getProject: Effect.fn("ConvexClient.getProject")((projectId) => management("getProject", "GET", `/projects/${projectId}`, ProjectSchema)),
|
|
188
|
+
createProject: Effect.fn("ConvexClient.createProject")((teamId, input) => management("createProject", "POST", `/teams/${teamId}/create_project`, CreatedProjectSchema, input)),
|
|
189
|
+
updateProject: Effect.fn("ConvexClient.updateProject")((projectId, input) => management("updateProject", "PATCH", `/projects/${projectId}`, ProjectSchema, input)),
|
|
190
|
+
deleteProject: Effect.fn("ConvexClient.deleteProject")((projectId) => managementVoid("deleteProject", "POST", `/projects/${projectId}/delete`)),
|
|
191
|
+
listDeployments: Effect.fn("ConvexClient.listDeployments")((projectId) => management("listDeployments", "GET", `/projects/${projectId}/list_deployments`, Schema.Array(DeploymentSchema))),
|
|
192
|
+
getDeployment: Effect.fn("ConvexClient.getDeployment")((name) => management("getDeployment", "GET", `/deployments/${encodeURIComponent(name)}`, DeploymentSchema)),
|
|
193
|
+
createDeployment: Effect.fn("ConvexClient.createDeployment")((projectId, input) => management("createDeployment", "POST", `/projects/${projectId}/create_deployment`, DeploymentSchema, input)),
|
|
194
|
+
updateDeployment: Effect.fn("ConvexClient.updateDeployment")((name, input) => managementVoid("updateDeployment", "PATCH", `/deployments/${encodeURIComponent(name)}`, input)),
|
|
195
|
+
deleteDeployment: Effect.fn("ConvexClient.deleteDeployment")((name) => managementVoid("deleteDeployment", "POST", `/deployments/${encodeURIComponent(name)}/delete`)),
|
|
196
|
+
createDeployKey: Effect.fn("ConvexClient.createDeployKey")(function* (name, input) {
|
|
197
|
+
const response = yield* management("createDeployKey", "POST", `/deployments/${encodeURIComponent(name)}/create_deploy_key`, Schema.Struct({ deployKey: Schema.String }), input);
|
|
198
|
+
return { deployKey: Redacted.make(response.deployKey) };
|
|
199
|
+
}),
|
|
200
|
+
listDeployKeys: Effect.fn("ConvexClient.listDeployKeys")((name) => management("listDeployKeys", "GET", `/deployments/${encodeURIComponent(name)}/list_deploy_keys`, Schema.Array(DeployKeySchema))),
|
|
201
|
+
deleteDeployKey: Effect.fn("ConvexClient.deleteDeployKey")((name, id) => managementVoid("deleteDeployKey", "POST", `/deployments/${encodeURIComponent(name)}/delete_deploy_key`, { id: Redacted.isRedacted(id) ? Redacted.value(id) : id })),
|
|
202
|
+
listEnvironmentVariables: Effect.fn("ConvexClient.listEnvironmentVariables")(function* (url, key) {
|
|
203
|
+
const response = yield* send("listEnvironmentVariables", "GET", `${yield* deploymentUrl("listEnvironmentVariables", url)}/list_environment_variables`, Redacted.make(`Convex ${Redacted.value(key)}`));
|
|
204
|
+
const result = yield* decode("listEnvironmentVariables", response, Schema.Struct({ environmentVariables: Schema.Record(Schema.String, Schema.String) }));
|
|
205
|
+
return Object.fromEntries(Object.entries(result.environmentVariables).map(([name, value]) => [name, Redacted.make(value)]));
|
|
206
|
+
}),
|
|
207
|
+
updateEnvironmentVariables: Effect.fn("ConvexClient.updateEnvironmentVariables")(function* (url, key, changes) {
|
|
208
|
+
yield* send("updateEnvironmentVariables", "POST", `${yield* deploymentUrl("updateEnvironmentVariables", url)}/update_environment_variables`, Redacted.make(`Convex ${Redacted.value(key)}`), { changes: changes.map(({ name, value }) => ({
|
|
209
|
+
name,
|
|
210
|
+
...value === void 0 ? {} : { value: Redacted.isRedacted(value) ? Redacted.value(value) : value }
|
|
211
|
+
})) });
|
|
212
|
+
})
|
|
213
|
+
};
|
|
214
|
+
});
|
|
215
|
+
var ConvexClient = class extends Context.Service()("@confect/alchemy/ConvexClient") {};
|
|
216
|
+
/**
|
|
217
|
+
* `mode: "local"` sends deployment requests only to a loopback backend over
|
|
218
|
+
* HTTP; the default accepts only Convex cloud HTTPS origins.
|
|
219
|
+
*/
|
|
220
|
+
const layer = (options) => Layer.effect(ConvexClient, make(options).pipe(Effect.map(ConvexClient.of)));
|
|
221
|
+
//#endregion
|
|
222
|
+
export { ConvexApiError, ConvexClient, ConvexConflict, ConvexNotFound, layer };
|
|
223
|
+
|
|
224
|
+
//# sourceMappingURL=ConvexClient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConvexClient.js","names":["Loopback.isOrigin"],"sources":["../src/ConvexClient.ts"],"sourcesContent":["import type * as DeploymentApi from \"@convex-dev/platform/deploymentApi\";\nimport type * as ManagementApi from \"@convex-dev/platform/managementApi\";\nimport type { ProviderMode } from \"alchemy/ProviderMode\";\nimport * as Config from \"effect/Config\";\nimport * as Context from \"effect/Context\";\nimport * as Effect from \"effect/Effect\";\nimport * as Layer from \"effect/Layer\";\nimport * as Redacted from \"effect/Redacted\";\nimport * as Schema from \"effect/Schema\";\nimport * as FetchHttpClient from \"effect/http/FetchHttpClient\";\nimport * as HttpClient from \"effect/http/HttpClient\";\nimport * as HttpClientRequest from \"effect/http/HttpClientRequest\";\nimport type * as HttpClientResponse from \"effect/http/HttpClientResponse\";\nimport * as Loopback from \"./internal/Loopback\";\n\nexport type Project = ManagementApi.ProjectResponse;\nexport type CreatedProject = ManagementApi.PlatformCreateProjectResponse;\nexport type Deployment = ManagementApi.PlatformDeploymentResponse;\nexport type DeployKey = Omit<\n ManagementApi.PlatformDeployKeyResponse,\n \"allowedActions\"\n> & {\n readonly allowedActions: readonly string[];\n};\nexport type CreateProjectInput = Pick<\n ManagementApi.PlatformCreateProjectArgs,\n \"projectName\"\n>;\nexport type UpdateProjectInput = Pick<\n ManagementApi.PlatformUpdateProjectArgs,\n \"name\"\n>;\nexport type CreateDeploymentInput = Pick<\n ManagementApi.PlatformCreateDeploymentArgs,\n \"type\" | \"region\" | \"class\"\n> & { readonly reference: string };\nexport type UpdateDeploymentInput = Pick<\n ManagementApi.PlatformUpdateDeploymentArgs,\n \"reference\" | \"expiresAt\" | \"sendLogsToClient\"\n>;\nexport type CreateDeployKeyInput = ManagementApi.PlatformCreateDeployKeyArgs;\nexport type CreatedDeployKey = {\n readonly deployKey: Redacted.Redacted<\n ManagementApi.PlatformCreateDeployKeyResponse[\"deployKey\"]\n >;\n};\nexport type EnvironmentVariableChange = Omit<\n DeploymentApi.UpdateEnvVarRequest,\n \"value\"\n> & {\n readonly value?:\n | Exclude<DeploymentApi.UpdateEnvVarRequest[\"value\"], undefined>\n | Redacted.Redacted<string>;\n};\nexport type EnvironmentVariables = Readonly<\n Record<\n string,\n Redacted.Redacted<\n DeploymentApi.ListEnvVarsResponse[\"environmentVariables\"][string]\n >\n >\n>;\n\nconst errorFields = {\n operation: Schema.String,\n status: Schema.optionalKey(Schema.Finite),\n code: Schema.Literals([\n \"HttpError\",\n \"TransportError\",\n \"InvalidResponse\",\n \"InvalidRequest\",\n \"InvalidPagination\",\n \"InvalidConfiguration\",\n ]),\n};\n\nexport class ConvexApiError extends Schema.TaggedError<ConvexApiError>()(\n \"ConvexApiError\",\n errorFields,\n) {}\n\nexport class ConvexNotFound extends Schema.TaggedError<ConvexNotFound>()(\n \"ConvexNotFound\",\n errorFields,\n) {}\n\nexport class ConvexConflict extends Schema.TaggedError<ConvexConflict>()(\n \"ConvexConflict\",\n errorFields,\n) {}\n\nexport type ConvexClientError =\n | ConvexApiError\n | ConvexNotFound\n | ConvexConflict;\n\nconst ProjectSchema = Schema.Struct({\n id: Schema.Finite,\n name: Schema.String,\n slug: Schema.String,\n teamId: Schema.Finite,\n teamSlug: Schema.String,\n createTime: Schema.Finite,\n prodDeploymentName: Schema.optionalKey(Schema.NullOr(Schema.String)),\n devDeploymentName: Schema.optionalKey(Schema.NullOr(Schema.String)),\n}) satisfies Schema.Schema<Project>;\n\nconst CreatedProjectSchema = Schema.Struct({\n id: Schema.Finite,\n projectId: Schema.Finite,\n slug: Schema.String,\n deploymentName: Schema.optionalKey(Schema.NullOr(Schema.String)),\n deploymentUrl: Schema.optionalKey(Schema.NullOr(Schema.String)),\n}) satisfies Schema.Schema<CreatedProject>;\n\nconst deploymentFields = {\n name: Schema.String,\n createTime: Schema.Finite,\n deploymentType: Schema.Literals([\"dev\", \"prod\", \"preview\", \"custom\"]),\n projectId: Schema.Finite,\n previewIdentifier: Schema.optionalKey(Schema.NullOr(Schema.String)),\n};\n\nconst DeploymentSchema = Schema.Union([\n Schema.Struct({\n ...deploymentFields,\n kind: Schema.Literal(\"cloud\"),\n id: Schema.Finite,\n lastDeployTime: Schema.optionalKey(Schema.NullOr(Schema.Finite)),\n creator: Schema.optionalKey(Schema.NullOr(Schema.Finite)),\n region: Schema.Literals([\n \"aws-us-east-1\",\n \"aws-eu-west-1\",\n \"aws-ap-southeast-2\",\n \"aws-ca-central-1\",\n ]),\n isDefault: Schema.Boolean,\n reference: Schema.String,\n dashboardEditConfirmation: Schema.optionalKey(\n Schema.NullOr(Schema.Boolean),\n ),\n deploymentUrl: Schema.String,\n expiresAt: Schema.optionalKey(Schema.NullOr(Schema.Finite)),\n class: Schema.String,\n sendLogsToClient: Schema.optionalKey(Schema.NullOr(Schema.Boolean)),\n }),\n Schema.Struct({\n ...deploymentFields,\n kind: Schema.Literal(\"local\"),\n creator: Schema.Finite,\n port: Schema.Finite,\n deviceName: Schema.String,\n isActive: Schema.Boolean,\n }),\n]) satisfies Schema.Schema<Deployment>;\n\nconst DeployKeySchema = Schema.Struct({\n id: Schema.Finite,\n name: Schema.String,\n creationTime: Schema.Finite,\n lastUsedTime: Schema.optionalKey(Schema.NullOr(Schema.Finite)),\n expiresAt: Schema.optionalKey(Schema.NullOr(Schema.Finite)),\n creator: Schema.optionalKey(Schema.NullOr(Schema.Finite)),\n managedBy: Schema.optionalKey(\n Schema.NullOr(\n Schema.Union([\n Schema.Literal(\"vercel\"),\n Schema.Struct({ oauthApp: Schema.String }),\n ]),\n ),\n ),\n allowedActions: Schema.Array(Schema.String),\n}) satisfies Schema.Schema<DeployKey>;\n\nconst ProjectsPageSchema = Schema.Struct({\n items: Schema.Array(ProjectSchema),\n pagination: Schema.Struct({\n hasMore: Schema.Boolean,\n nextCursor: Schema.optionalKey(Schema.NullOr(Schema.String)),\n }),\n});\n\nconst make = Effect.fn(\"ConvexClient.make\")(function* (options?: {\n readonly token?: Redacted.Redacted<string>;\n readonly mode?: ProviderMode;\n}) {\n const http = yield* HttpClient.HttpClient;\n const managementAuthorization = Effect.gen(function* () {\n const token =\n options?.token ??\n (yield* Config.Redacted(\"CONVEX_ACCESS_TOKEN\").pipe(\n Effect.mapError(\n () =>\n new ConvexApiError({\n operation: \"configure\",\n code: \"InvalidConfiguration\",\n }),\n ),\n ));\n return Redacted.make(`Bearer ${Redacted.value(token)}`);\n });\n const baseUrl = \"https://api.convex.dev/v1\";\n\n const send = Effect.fn(\"ConvexClient.request\")(function* (\n operation: string,\n method: \"GET\" | \"POST\" | \"PATCH\",\n url: string,\n authorization: Redacted.Redacted<string>,\n body?: unknown,\n ) {\n let request = HttpClientRequest.make(method)(url).pipe(\n HttpClientRequest.setHeader(\n \"authorization\",\n Redacted.value(authorization),\n ),\n HttpClientRequest.acceptJson,\n );\n if (body !== undefined) {\n request = yield* HttpClientRequest.bodyJson(request, body).pipe(\n Effect.mapError(\n () => new ConvexApiError({ operation, code: \"InvalidRequest\" }),\n ),\n );\n }\n const response = yield* http.execute(request).pipe(\n Effect.provideService(FetchHttpClient.RequestInit, {\n redirect: \"manual\",\n }),\n Effect.mapError(\n () => new ConvexApiError({ operation, code: \"TransportError\" }),\n ),\n );\n if (response.status === 404) {\n return yield* new ConvexNotFound({\n operation,\n status: 404,\n code: \"HttpError\",\n });\n }\n if (response.status === 409) {\n return yield* new ConvexConflict({\n operation,\n status: 409,\n code: \"HttpError\",\n });\n }\n if (response.status < 200 || response.status >= 300) {\n return yield* new ConvexApiError({\n operation,\n status: response.status,\n code: \"HttpError\",\n });\n }\n return response;\n });\n\n const decode = Effect.fn(\"ConvexClient.decode\")(function* <A>(\n operation: string,\n response: HttpClientResponse.HttpClientResponse,\n schema: Schema.Decoder<A>,\n ) {\n const invalidResponse = () =>\n new ConvexApiError({\n operation,\n status: response.status,\n code: \"InvalidResponse\",\n });\n const body = yield* response.json.pipe(Effect.mapError(invalidResponse));\n return yield* Schema.decodeEffect(schema)(body).pipe(\n Effect.mapError(invalidResponse),\n );\n });\n\n const management = Effect.fn(\"ConvexClient.management\")(function* <A>(\n operation: string,\n method: \"GET\" | \"POST\" | \"PATCH\",\n path: string,\n schema: Schema.Decoder<A>,\n body?: unknown,\n ) {\n const response = yield* send(\n operation,\n method,\n `${baseUrl}${path}`,\n yield* managementAuthorization,\n body,\n );\n return yield* decode(operation, response, schema);\n });\n\n const managementVoid = Effect.fn(\"ConvexClient.managementVoid\")(function* (\n operation: string,\n method: \"POST\" | \"PATCH\",\n path: string,\n body?: unknown,\n ) {\n yield* send(\n operation,\n method,\n `${baseUrl}${path}`,\n yield* managementAuthorization,\n body,\n );\n });\n\n const deploymentUrl = Effect.fn(\"ConvexClient.deploymentUrl\")(function* (\n operation: string,\n url: string,\n ) {\n const invalidUrl = () =>\n new ConvexApiError({ operation, code: \"InvalidRequest\" });\n if (options?.mode === \"local\") {\n if (!Loopback.isOrigin(url)) return yield* invalidUrl();\n return `${url}/api/v1`;\n }\n const parsed = yield* Effect.try({\n try: () => new URL(url),\n catch: invalidUrl,\n });\n if (\n parsed.protocol !== \"https:\" ||\n parsed.username !== \"\" ||\n parsed.password !== \"\" ||\n parsed.port !== \"\" ||\n parsed.search !== \"\" ||\n parsed.hash !== \"\" ||\n parsed.pathname !== \"/\" ||\n !/^[a-z0-9-]+(?:\\.(?:eu-west-1|ap-southeast-2|ca-central-1))?\\.convex\\.cloud$/.test(\n parsed.hostname,\n ) ||\n url.replace(/\\/$/, \"\") !== parsed.origin\n ) {\n return yield* invalidUrl();\n }\n return `${parsed.origin}/api/v1`;\n });\n\n return {\n listProjects: Effect.fn(\"ConvexClient.listProjects\")(function* (\n teamId: number,\n ) {\n const projects: Project[] = [];\n const seenCursors = new Set<string>();\n let cursor: string | undefined;\n while (true) {\n const page = yield* management(\n \"listProjects\",\n \"GET\",\n `/teams/${teamId}/projects${cursor === undefined ? \"\" : `?cursor=${encodeURIComponent(cursor)}`}`,\n ProjectsPageSchema,\n );\n projects.push(...page.items);\n if (!page.pagination.hasMore) return projects;\n const nextCursor = page.pagination.nextCursor;\n if (!nextCursor || seenCursors.has(nextCursor)) {\n return yield* new ConvexApiError({\n operation: \"listProjects\",\n code: \"InvalidPagination\",\n });\n }\n seenCursors.add(nextCursor);\n cursor = nextCursor;\n }\n }),\n getProject: Effect.fn(\"ConvexClient.getProject\")((projectId: number) =>\n management(\"getProject\", \"GET\", `/projects/${projectId}`, ProjectSchema),\n ),\n createProject: Effect.fn(\"ConvexClient.createProject\")(\n (teamId: number, input: CreateProjectInput) =>\n management(\n \"createProject\",\n \"POST\",\n `/teams/${teamId}/create_project`,\n CreatedProjectSchema,\n input,\n ),\n ),\n updateProject: Effect.fn(\"ConvexClient.updateProject\")(\n (projectId: number, input: UpdateProjectInput) =>\n management(\n \"updateProject\",\n \"PATCH\",\n `/projects/${projectId}`,\n ProjectSchema,\n input,\n ),\n ),\n deleteProject: Effect.fn(\"ConvexClient.deleteProject\")(\n (projectId: number) =>\n managementVoid(\n \"deleteProject\",\n \"POST\",\n `/projects/${projectId}/delete`,\n ),\n ),\n listDeployments: Effect.fn(\"ConvexClient.listDeployments\")(\n (projectId: number) =>\n management(\n \"listDeployments\",\n \"GET\",\n `/projects/${projectId}/list_deployments`,\n Schema.Array(DeploymentSchema),\n ),\n ),\n getDeployment: Effect.fn(\"ConvexClient.getDeployment\")((name: string) =>\n management(\n \"getDeployment\",\n \"GET\",\n `/deployments/${encodeURIComponent(name)}`,\n DeploymentSchema,\n ),\n ),\n createDeployment: Effect.fn(\"ConvexClient.createDeployment\")(\n (projectId: number, input: CreateDeploymentInput) =>\n management(\n \"createDeployment\",\n \"POST\",\n `/projects/${projectId}/create_deployment`,\n DeploymentSchema,\n input,\n ),\n ),\n updateDeployment: Effect.fn(\"ConvexClient.updateDeployment\")(\n (name: string, input: UpdateDeploymentInput) =>\n managementVoid(\n \"updateDeployment\",\n \"PATCH\",\n `/deployments/${encodeURIComponent(name)}`,\n input,\n ),\n ),\n deleteDeployment: Effect.fn(\"ConvexClient.deleteDeployment\")(\n (name: string) =>\n managementVoid(\n \"deleteDeployment\",\n \"POST\",\n `/deployments/${encodeURIComponent(name)}/delete`,\n ),\n ),\n createDeployKey: Effect.fn(\"ConvexClient.createDeployKey\")(function* (\n name: string,\n input: CreateDeployKeyInput,\n ): Effect.fn.Return<CreatedDeployKey, ConvexClientError> {\n const response = yield* management(\n \"createDeployKey\",\n \"POST\",\n `/deployments/${encodeURIComponent(name)}/create_deploy_key`,\n Schema.Struct({ deployKey: Schema.String }),\n input,\n );\n return { deployKey: Redacted.make(response.deployKey) };\n }),\n listDeployKeys: Effect.fn(\"ConvexClient.listDeployKeys\")((name: string) =>\n management(\n \"listDeployKeys\",\n \"GET\",\n `/deployments/${encodeURIComponent(name)}/list_deploy_keys`,\n Schema.Array(DeployKeySchema),\n ),\n ),\n deleteDeployKey: Effect.fn(\"ConvexClient.deleteDeployKey\")(\n (name: string, id: string | Redacted.Redacted<string>) =>\n managementVoid(\n \"deleteDeployKey\",\n \"POST\",\n `/deployments/${encodeURIComponent(name)}/delete_deploy_key`,\n {\n id: Redacted.isRedacted(id) ? Redacted.value(id) : id,\n } satisfies ManagementApi.PlatformDeleteDeployKeyArgs,\n ),\n ),\n listEnvironmentVariables: Effect.fn(\n \"ConvexClient.listEnvironmentVariables\",\n )(function* (\n url: string,\n key: Redacted.Redacted<string>,\n ): Effect.fn.Return<EnvironmentVariables, ConvexClientError> {\n const response = yield* send(\n \"listEnvironmentVariables\",\n \"GET\",\n `${yield* deploymentUrl(\"listEnvironmentVariables\", url)}/list_environment_variables`,\n Redacted.make(`Convex ${Redacted.value(key)}`),\n );\n const result = yield* decode(\n \"listEnvironmentVariables\",\n response,\n Schema.Struct({\n environmentVariables: Schema.Record(Schema.String, Schema.String),\n }),\n );\n return Object.fromEntries(\n Object.entries(result.environmentVariables).map(([name, value]) => [\n name,\n Redacted.make(value),\n ]),\n );\n }),\n updateEnvironmentVariables: Effect.fn(\n \"ConvexClient.updateEnvironmentVariables\",\n )(function* (\n url: string,\n key: Redacted.Redacted<string>,\n changes: readonly EnvironmentVariableChange[],\n ) {\n yield* send(\n \"updateEnvironmentVariables\",\n \"POST\",\n `${yield* deploymentUrl(\"updateEnvironmentVariables\", url)}/update_environment_variables`,\n Redacted.make(`Convex ${Redacted.value(key)}`),\n {\n changes: changes.map(({ name, value }) => ({\n name,\n ...(value === undefined\n ? {}\n : {\n value: Redacted.isRedacted(value)\n ? Redacted.value(value)\n : value,\n }),\n })),\n } satisfies {\n readonly changes: Readonly<\n DeploymentApi.UpdateEnvVarsRequest[\"changes\"]\n >;\n },\n );\n }),\n };\n});\n\nexport class ConvexClient extends Context.Service<\n ConvexClient,\n Effect.Success<ReturnType<typeof make>>\n>()(\"@confect/alchemy/ConvexClient\") {}\n\n/**\n * `mode: \"local\"` sends deployment requests only to a loopback backend over\n * HTTP; the default accepts only Convex cloud HTTPS origins.\n */\nexport const layer = (options?: {\n readonly token?: Redacted.Redacted<string>;\n readonly mode?: ProviderMode;\n}) =>\n Layer.effect(ConvexClient, make(options).pipe(Effect.map(ConvexClient.of)));\n"],"mappings":"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"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import type { PlatformCreateDeployKeyArgs } from "@convex-dev/platform/managementApi";
|
|
2
|
+
import * as Provider from "alchemy/Provider";
|
|
3
|
+
import { Resource } from "alchemy/Resource";
|
|
4
|
+
import * as Effect from "effect/Effect";
|
|
5
|
+
import * as FileSystem from "effect/FileSystem";
|
|
6
|
+
import * as Path from "effect/Path";
|
|
7
|
+
import * as Redacted from "effect/Redacted";
|
|
8
|
+
import * as Schema from "effect/Schema";
|
|
9
|
+
import { ConvexClient } from "./ConvexClient";
|
|
10
|
+
import type { Providers } from "./Providers";
|
|
11
|
+
export interface DeployKeyProps {
|
|
12
|
+
readonly deploymentName: string;
|
|
13
|
+
readonly name?: string;
|
|
14
|
+
readonly allowedActions?: ReadonlyArray<NonNullable<PlatformCreateDeployKeyArgs["allowedActions"]>[number]>;
|
|
15
|
+
}
|
|
16
|
+
export interface DeployKeyAttributes {
|
|
17
|
+
readonly deploymentName: string;
|
|
18
|
+
readonly keyId: number;
|
|
19
|
+
readonly name: string;
|
|
20
|
+
readonly deployKey: Redacted.Redacted<string>;
|
|
21
|
+
readonly allowedActions: ReadonlyArray<string>;
|
|
22
|
+
}
|
|
23
|
+
export type DeployKey = Resource<"Convex.DeployKey", DeployKeyProps, DeployKeyAttributes, never, Providers>;
|
|
24
|
+
export declare const DeployKey: import("alchemy/Resource").ResourceClass<DeployKey>;
|
|
25
|
+
declare const DeployKeyRecoveryRequired_base: Schema.Class<DeployKeyRecoveryRequired, Schema.TaggedStruct<"DeployKeyRecoveryRequired", {
|
|
26
|
+
readonly deploymentName: Schema.String;
|
|
27
|
+
readonly name: Schema.String;
|
|
28
|
+
readonly keyIds: Schema.$Array<Schema.Finite>;
|
|
29
|
+
}>, import("effect/Cause").YieldableError>;
|
|
30
|
+
export declare class DeployKeyRecoveryRequired extends DeployKeyRecoveryRequired_base {
|
|
31
|
+
}
|
|
32
|
+
declare const DeployKeyChangeRequiresNewResource_base: Schema.Class<DeployKeyChangeRequiresNewResource, Schema.TaggedStruct<"DeployKeyChangeRequiresNewResource", {
|
|
33
|
+
readonly deploymentName: Schema.String;
|
|
34
|
+
readonly keyId: Schema.Finite;
|
|
35
|
+
readonly field: Schema.String;
|
|
36
|
+
}>, import("effect/Cause").YieldableError>;
|
|
37
|
+
export declare class DeployKeyChangeRequiresNewResource extends DeployKeyChangeRequiresNewResource_base {
|
|
38
|
+
}
|
|
39
|
+
export declare const provider: Effect.Effect<{
|
|
40
|
+
diff: (args_0: {
|
|
41
|
+
id: string;
|
|
42
|
+
fqn: string;
|
|
43
|
+
instanceId: string;
|
|
44
|
+
olds: DeployKeyProps;
|
|
45
|
+
news: import("alchemy/Input").Input<DeployKeyProps>;
|
|
46
|
+
oldBindings: import("alchemy/Resource").ResourceBinding<never>[];
|
|
47
|
+
newBindings: import("alchemy/Input").Input<import("alchemy/Resource").ResourceBinding<never>[]>;
|
|
48
|
+
output: DeployKeyAttributes | undefined;
|
|
49
|
+
}) => Effect.Effect<undefined, import("./ConvexClient").ConvexApiError | import("./ConvexClient").ConvexConflict | import("./ConvexClient").ConvexNotFound | DeployKeyChangeRequiresNewResource | DeployKeyRecoveryRequired, never>;
|
|
50
|
+
read: (args_0: {
|
|
51
|
+
id: string;
|
|
52
|
+
fqn: string;
|
|
53
|
+
instanceId: string;
|
|
54
|
+
olds: DeployKeyProps;
|
|
55
|
+
output: DeployKeyAttributes | undefined;
|
|
56
|
+
}) => Effect.Effect<{
|
|
57
|
+
deploymentName: string;
|
|
58
|
+
keyId: number;
|
|
59
|
+
name: string;
|
|
60
|
+
deployKey: Redacted.Redacted<string>;
|
|
61
|
+
allowedActions: readonly string[];
|
|
62
|
+
} | undefined, import("./ConvexClient").ConvexApiError | import("./ConvexClient").ConvexConflict | import("./ConvexClient").ConvexNotFound | DeployKeyRecoveryRequired, never>;
|
|
63
|
+
reconcile: (args_0: {
|
|
64
|
+
id: string;
|
|
65
|
+
fqn: string;
|
|
66
|
+
instanceId: string;
|
|
67
|
+
news: DeployKeyProps;
|
|
68
|
+
olds: DeployKeyProps | undefined;
|
|
69
|
+
output: DeployKeyAttributes | undefined;
|
|
70
|
+
session: import("alchemy/Report").ScopedPlanStatusSession;
|
|
71
|
+
bindings: import("alchemy/Resource").ResourceBinding<never>[];
|
|
72
|
+
}) => Effect.Effect<{
|
|
73
|
+
deploymentName: string;
|
|
74
|
+
keyId: number;
|
|
75
|
+
name: string;
|
|
76
|
+
deployKey: Redacted.Redacted<string>;
|
|
77
|
+
allowedActions: readonly string[];
|
|
78
|
+
}, DeployKeyChangeRequiresNewResource | DeployKeyRecoveryRequired | import("./internal/Lifecycle").LifecycleStateError | import("alchemy/State/State").StateStoreError | import("./ConvexClient").ConvexClientError, never>;
|
|
79
|
+
delete: (args_0: {
|
|
80
|
+
id: string;
|
|
81
|
+
fqn: string;
|
|
82
|
+
instanceId: string;
|
|
83
|
+
olds: DeployKeyProps;
|
|
84
|
+
output: DeployKeyAttributes;
|
|
85
|
+
session: import("alchemy/Report").ScopedPlanStatusSession;
|
|
86
|
+
bindings: import("alchemy/Resource").ResourceBinding<never>[];
|
|
87
|
+
force?: boolean;
|
|
88
|
+
}) => Effect.Effect<void, import("./ConvexClient").ConvexApiError | import("./ConvexClient").ConvexConflict, never>;
|
|
89
|
+
}, never, ConvexClient>;
|
|
90
|
+
/**
|
|
91
|
+
* Under `alchemy dev` the deploy key is the admin key the local deployment
|
|
92
|
+
* generated. It is read on every apply, so a recreated backend's new key
|
|
93
|
+
* replaces the old one.
|
|
94
|
+
*/
|
|
95
|
+
export declare const localProvider: Effect.Effect<{
|
|
96
|
+
diff: () => Effect.Effect<{
|
|
97
|
+
action: "update";
|
|
98
|
+
}, never, never>;
|
|
99
|
+
reconcile: (args_0: {
|
|
100
|
+
id: string;
|
|
101
|
+
fqn: string;
|
|
102
|
+
instanceId: string;
|
|
103
|
+
news: DeployKeyProps;
|
|
104
|
+
olds: DeployKeyProps | undefined;
|
|
105
|
+
output: DeployKeyAttributes | undefined;
|
|
106
|
+
session: import("alchemy/Report").ScopedPlanStatusSession;
|
|
107
|
+
bindings: import("alchemy/Resource").ResourceBinding<never>[];
|
|
108
|
+
}) => Effect.Effect<{
|
|
109
|
+
deploymentName: string;
|
|
110
|
+
keyId: number;
|
|
111
|
+
name: string;
|
|
112
|
+
deployKey: Redacted.Redacted<string>;
|
|
113
|
+
allowedActions: readonly ("deployment:aiGateway:use" | "deployment:auditLog:view" | "deployment:backups:create" | "deployment:backups:delete" | "deployment:backups:download" | "deployment:backups:import" | "deployment:backups:view" | "deployment:data:view" | "deployment:data:write" | "deployment:deploy" | "deployment:env:view" | "deployment:env:write" | "deployment:functions:actAsUser" | "deployment:functions:runInternalActions" | "deployment:functions:runInternalMutations" | "deployment:functions:runInternalQueries" | "deployment:functions:runTestQuery" | "deployment:integrations:view" | "deployment:integrations:write" | "deployment:logs:view" | "deployment:metrics:view" | "deployment:pause" | "deployment:unpause" | "deployment:usage:view" | "deployment:usageLimits:view" | "deployment:usageLimits:write")[];
|
|
114
|
+
}, import("./internal/LocalBackend").LocalBackendError, never>;
|
|
115
|
+
delete: () => Effect.Effect<void, never, never>;
|
|
116
|
+
}, never, FileSystem.FileSystem | Path.Path | import("alchemy/Stack").Stack>;
|
|
117
|
+
export declare const layer: import("effect/Layer").Layer<Provider.Provider<DeployKey>, never, ConvexClient>;
|
|
118
|
+
export declare const localLayer: import("effect/Layer").Layer<Provider.Provider<DeployKey>, never, FileSystem.FileSystem | Path.Path | import("alchemy/Stack").Stack>;
|
|
119
|
+
export {};
|
|
120
|
+
//# sourceMappingURL=DeployKey.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DeployKey.d.ts","sourceRoot":"","sources":["../src/DeployKey.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,oCAAoC,CAAC;AAEtF,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,UAAU,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,IAAI,MAAM,aAAa,CAAC;AACpC,OAAO,KAAK,QAAQ,MAAM,iBAAiB,CAAC;AAC5C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAExC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAK7C,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,cAAc,CAAC,EAAE,aAAa,CACrC,WAAW,CAAC,2BAA2B,CAAC,gBAAgB,CAAC,CAAC,CAAC,MAAM,CAAC,CACnE,CAAC;CACH;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC9C,QAAQ,CAAC,cAAc,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;CAChD;AAED,MAAM,MAAM,SAAS,GAAG,QAAQ,CAC9B,kBAAkB,EAClB,cAAc,EACd,mBAAmB,EACnB,KAAK,EACL,SAAS,CACV,CAAC;AACF,eAAO,MAAM,SAAS,qDAA0C,CAAC;;;;;;AAEjE,qBAAa,yBAA0B,SAAQ,8BAO9C;CAAG;;;;;;AAEJ,qBAAa,kCAAmC,SAAQ,uCAGvD;CAAG;AAEJ,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;wBA9BM,MAAM;eACf,MAAM;cACP,MAAM;mBACD,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC;;;;;;;;;;;;;wBAHpB,MAAM;eACf,MAAM;cACP,MAAM;mBACD,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC;;;;;;;;;;;;;uBA4L7C,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;4EA6BxB,CAAC;AAEH,eAAO,MAAM,KAAK,iFAAuC,CAAC;AAC1D,eAAO,MAAM,UAAU,sIAA4C,CAAC"}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { ConvexClient } from "./ConvexClient.js";
|
|
2
|
+
import { checkpointCreate } from "./internal/Lifecycle.js";
|
|
3
|
+
import { resourceName } from "./internal/ResourceIdentity.js";
|
|
4
|
+
import { adminKey, dataDirectories } from "./internal/LocalBackend.js";
|
|
5
|
+
import * as Effect from "effect/Effect";
|
|
6
|
+
import * as Provider from "alchemy/Provider";
|
|
7
|
+
import { Resource } from "alchemy/Resource";
|
|
8
|
+
import * as Redacted from "effect/Redacted";
|
|
9
|
+
import * as Schema from "effect/Schema";
|
|
10
|
+
import * as FileSystem from "effect/FileSystem";
|
|
11
|
+
import * as Path from "effect/Path";
|
|
12
|
+
import { isResolved } from "alchemy/Diff";
|
|
13
|
+
//#region src/DeployKey.ts
|
|
14
|
+
const DeployKey = Resource("Convex.DeployKey");
|
|
15
|
+
var DeployKeyRecoveryRequired = class extends Schema.TaggedError()("DeployKeyRecoveryRequired", {
|
|
16
|
+
deploymentName: Schema.String,
|
|
17
|
+
name: Schema.String,
|
|
18
|
+
keyIds: Schema.Array(Schema.Finite)
|
|
19
|
+
}) {};
|
|
20
|
+
var DeployKeyChangeRequiresNewResource = class extends Schema.TaggedError()("DeployKeyChangeRequiresNewResource", {
|
|
21
|
+
deploymentName: Schema.String,
|
|
22
|
+
keyId: Schema.Finite,
|
|
23
|
+
field: Schema.String
|
|
24
|
+
}) {};
|
|
25
|
+
const provider = Effect.gen(function* () {
|
|
26
|
+
const client = yield* ConvexClient;
|
|
27
|
+
const hasName = (keyName, name) => keyName === name || keyName.startsWith(`${name} (`) && /^[0-9a-f]{8}\)$/.test(keyName.slice(name.length + 2));
|
|
28
|
+
const recover = (deploymentName, name, keyIds) => new DeployKeyRecoveryRequired({
|
|
29
|
+
deploymentName,
|
|
30
|
+
name,
|
|
31
|
+
keyIds
|
|
32
|
+
});
|
|
33
|
+
return {
|
|
34
|
+
diff: Effect.fn("DeployKey.diff")(function* ({ news, output }) {
|
|
35
|
+
if (!isResolved(news) || !output) return;
|
|
36
|
+
for (const field of ["deploymentName", "name"]) if (news[field] !== void 0 && news[field] !== output[field]) return yield* new DeployKeyChangeRequiresNewResource({
|
|
37
|
+
deploymentName: output.deploymentName,
|
|
38
|
+
keyId: output.keyId,
|
|
39
|
+
field
|
|
40
|
+
});
|
|
41
|
+
const key = (yield* client.listDeployKeys(output.deploymentName)).find((candidate) => candidate.id === output.keyId);
|
|
42
|
+
if (!key || !Redacted.isRedacted(output.deployKey)) return yield* recover(output.deploymentName, output.name, [output.keyId]);
|
|
43
|
+
if (!hasName(key.name, news.name ?? output.name)) return yield* new DeployKeyChangeRequiresNewResource({
|
|
44
|
+
deploymentName: output.deploymentName,
|
|
45
|
+
keyId: output.keyId,
|
|
46
|
+
field: "name"
|
|
47
|
+
});
|
|
48
|
+
const allowedActions = news.allowedActions ?? output.allowedActions;
|
|
49
|
+
if (new Set(allowedActions).size !== new Set(key.allowedActions).size || allowedActions.some((action) => !key.allowedActions.includes(action))) return yield* new DeployKeyChangeRequiresNewResource({
|
|
50
|
+
deploymentName: output.deploymentName,
|
|
51
|
+
keyId: output.keyId,
|
|
52
|
+
field: "allowedActions"
|
|
53
|
+
});
|
|
54
|
+
}),
|
|
55
|
+
read: Effect.fn("DeployKey.read")(function* ({ fqn, instanceId, olds, output }) {
|
|
56
|
+
const deploymentName = output?.deploymentName ?? olds.deploymentName;
|
|
57
|
+
if (deploymentName === void 0) return;
|
|
58
|
+
const name = output?.name ?? olds.name ?? (yield* resourceName("key", fqn, instanceId));
|
|
59
|
+
const keys = yield* client.listDeployKeys(deploymentName);
|
|
60
|
+
if (output) {
|
|
61
|
+
const key = keys.find((candidate) => candidate.id === output.keyId);
|
|
62
|
+
if (!key) return yield* recover(deploymentName, name, [output.keyId]);
|
|
63
|
+
if (!Redacted.isRedacted(output.deployKey)) return yield* recover(deploymentName, name, [key.id]);
|
|
64
|
+
return {
|
|
65
|
+
...output,
|
|
66
|
+
allowedActions: key.allowedActions
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
const matches = keys.filter((key) => hasName(key.name, name));
|
|
70
|
+
if (matches.length > 0) return yield* recover(deploymentName, name, matches.map((candidate) => candidate.id));
|
|
71
|
+
}),
|
|
72
|
+
reconcile: Effect.fn("DeployKey.reconcile")(function* ({ fqn, instanceId, news, output }) {
|
|
73
|
+
if (!output) yield* checkpointCreate(fqn, instanceId, news);
|
|
74
|
+
const name = news.name ?? output?.name ?? (yield* resourceName("key", fqn, instanceId));
|
|
75
|
+
if (output) {
|
|
76
|
+
for (const field of ["deploymentName", "name"]) if (news[field] !== void 0 && news[field] !== output[field]) return yield* new DeployKeyChangeRequiresNewResource({
|
|
77
|
+
deploymentName: output.deploymentName,
|
|
78
|
+
keyId: output.keyId,
|
|
79
|
+
field
|
|
80
|
+
});
|
|
81
|
+
const key = (yield* client.listDeployKeys(output.deploymentName)).find((candidate) => candidate.id === output.keyId);
|
|
82
|
+
if (!key || !Redacted.isRedacted(output.deployKey)) return yield* recover(output.deploymentName, name, [output.keyId]);
|
|
83
|
+
if (!hasName(key.name, name)) return yield* new DeployKeyChangeRequiresNewResource({
|
|
84
|
+
deploymentName: output.deploymentName,
|
|
85
|
+
keyId: output.keyId,
|
|
86
|
+
field: "name"
|
|
87
|
+
});
|
|
88
|
+
const allowedActions = news.allowedActions ?? output.allowedActions;
|
|
89
|
+
if (new Set(allowedActions).size !== new Set(key.allowedActions).size || allowedActions.some((action) => !key.allowedActions.includes(action))) return yield* new DeployKeyChangeRequiresNewResource({
|
|
90
|
+
deploymentName: output.deploymentName,
|
|
91
|
+
keyId: output.keyId,
|
|
92
|
+
field: "allowedActions"
|
|
93
|
+
});
|
|
94
|
+
return {
|
|
95
|
+
...output,
|
|
96
|
+
allowedActions: key.allowedActions
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
const existing = (yield* client.listDeployKeys(news.deploymentName)).filter((key) => hasName(key.name, name));
|
|
100
|
+
if (existing.length > 0) return yield* recover(news.deploymentName, name, existing.map((key) => key.id));
|
|
101
|
+
const created = yield* client.createDeployKey(news.deploymentName, {
|
|
102
|
+
name,
|
|
103
|
+
...news.allowedActions === void 0 ? {} : { allowedActions: [...news.allowedActions] }
|
|
104
|
+
});
|
|
105
|
+
const matches = (yield* client.listDeployKeys(news.deploymentName)).filter((key) => hasName(key.name, name));
|
|
106
|
+
const key = matches[0];
|
|
107
|
+
if (matches.length !== 1 || !key) return yield* recover(news.deploymentName, name, matches.map((candidate) => candidate.id));
|
|
108
|
+
return {
|
|
109
|
+
deploymentName: news.deploymentName,
|
|
110
|
+
keyId: key.id,
|
|
111
|
+
name,
|
|
112
|
+
deployKey: created.deployKey,
|
|
113
|
+
allowedActions: key.allowedActions
|
|
114
|
+
};
|
|
115
|
+
}),
|
|
116
|
+
delete: Effect.fn("DeployKey.delete")(function* ({ output }) {
|
|
117
|
+
yield* client.deleteDeployKey(output.deploymentName, output.deployKey).pipe(Effect.catchTag("ConvexNotFound", () => Effect.void));
|
|
118
|
+
})
|
|
119
|
+
};
|
|
120
|
+
});
|
|
121
|
+
/**
|
|
122
|
+
* Under `alchemy dev` the deploy key is the admin key the local deployment
|
|
123
|
+
* generated. It is read on every apply, so a recreated backend's new key
|
|
124
|
+
* replaces the old one.
|
|
125
|
+
*/
|
|
126
|
+
const localProvider = Effect.gen(function* () {
|
|
127
|
+
const fs = yield* FileSystem.FileSystem;
|
|
128
|
+
const path = yield* Path.Path;
|
|
129
|
+
const directory = yield* dataDirectories;
|
|
130
|
+
return {
|
|
131
|
+
diff: () => Effect.succeed({ action: "update" }),
|
|
132
|
+
reconcile: Effect.fn("DeployKey.localReconcile")(function* ({ fqn, instanceId, news }) {
|
|
133
|
+
const name = news.name ?? (yield* resourceName("key", fqn, instanceId));
|
|
134
|
+
const deployKey = yield* adminKey(news.deploymentName, directory(news.deploymentName)).pipe(Effect.provideService(FileSystem.FileSystem, fs), Effect.provideService(Path.Path, path));
|
|
135
|
+
return {
|
|
136
|
+
deploymentName: news.deploymentName,
|
|
137
|
+
keyId: 0,
|
|
138
|
+
name,
|
|
139
|
+
deployKey,
|
|
140
|
+
allowedActions: news.allowedActions ?? []
|
|
141
|
+
};
|
|
142
|
+
}),
|
|
143
|
+
delete: () => Effect.void
|
|
144
|
+
};
|
|
145
|
+
});
|
|
146
|
+
const layer = Provider.effect(DeployKey, provider);
|
|
147
|
+
const localLayer = Provider.effect(DeployKey, localProvider);
|
|
148
|
+
//#endregion
|
|
149
|
+
export { DeployKey, DeployKeyChangeRequiresNewResource, DeployKeyRecoveryRequired, layer, localLayer, localProvider, provider };
|
|
150
|
+
|
|
151
|
+
//# sourceMappingURL=DeployKey.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DeployKey.js","names":[],"sources":["../src/DeployKey.ts"],"sourcesContent":["import type { PlatformCreateDeployKeyArgs } from \"@convex-dev/platform/managementApi\";\nimport { isResolved } from \"alchemy/Diff\";\nimport * as Provider from \"alchemy/Provider\";\nimport { Resource } from \"alchemy/Resource\";\nimport * as Effect from \"effect/Effect\";\nimport * as FileSystem from \"effect/FileSystem\";\nimport * as Path from \"effect/Path\";\nimport * as Redacted from \"effect/Redacted\";\nimport * as Schema from \"effect/Schema\";\n\nimport { ConvexClient } from \"./ConvexClient\";\nimport type { Providers } from \"./Providers\";\nimport { resourceName } from \"./internal/ResourceIdentity\";\nimport { checkpointCreate } from \"./internal/Lifecycle\";\nimport { adminKey, dataDirectories } from \"./internal/LocalBackend\";\n\nexport interface DeployKeyProps {\n readonly deploymentName: string;\n readonly name?: string;\n readonly allowedActions?: ReadonlyArray<\n NonNullable<PlatformCreateDeployKeyArgs[\"allowedActions\"]>[number]\n >;\n}\n\nexport interface DeployKeyAttributes {\n readonly deploymentName: string;\n readonly keyId: number;\n readonly name: string;\n readonly deployKey: Redacted.Redacted<string>;\n readonly allowedActions: ReadonlyArray<string>;\n}\n\nexport type DeployKey = Resource<\n \"Convex.DeployKey\",\n DeployKeyProps,\n DeployKeyAttributes,\n never,\n Providers\n>;\nexport const DeployKey = Resource<DeployKey>(\"Convex.DeployKey\");\n\nexport class DeployKeyRecoveryRequired extends Schema.TaggedError<DeployKeyRecoveryRequired>()(\n \"DeployKeyRecoveryRequired\",\n {\n deploymentName: Schema.String,\n name: Schema.String,\n keyIds: Schema.Array(Schema.Finite),\n },\n) {}\n\nexport class DeployKeyChangeRequiresNewResource extends Schema.TaggedError<DeployKeyChangeRequiresNewResource>()(\n \"DeployKeyChangeRequiresNewResource\",\n { deploymentName: Schema.String, keyId: Schema.Finite, field: Schema.String },\n) {}\n\nexport const provider = Effect.gen(function* () {\n const client = yield* ConvexClient;\n const hasName = (keyName: string, name: string) =>\n keyName === name ||\n (keyName.startsWith(`${name} (`) &&\n /^[0-9a-f]{8}\\)$/.test(keyName.slice(name.length + 2)));\n const recover = (\n deploymentName: string,\n name: string,\n keyIds: ReadonlyArray<number>,\n ) => new DeployKeyRecoveryRequired({ deploymentName, name, keyIds });\n return {\n diff: Effect.fn(\"DeployKey.diff\")(function* ({ news, output }) {\n if (!isResolved(news) || !output) return;\n for (const field of [\"deploymentName\", \"name\"] as const) {\n if (news[field] !== undefined && news[field] !== output[field])\n return yield* new DeployKeyChangeRequiresNewResource({\n deploymentName: output.deploymentName,\n keyId: output.keyId,\n field,\n });\n }\n const keys = yield* client.listDeployKeys(output.deploymentName);\n const key = keys.find((candidate) => candidate.id === output.keyId);\n if (!key || !Redacted.isRedacted(output.deployKey))\n return yield* recover(output.deploymentName, output.name, [\n output.keyId,\n ]);\n if (!hasName(key.name, news.name ?? output.name))\n return yield* new DeployKeyChangeRequiresNewResource({\n deploymentName: output.deploymentName,\n keyId: output.keyId,\n field: \"name\",\n });\n const allowedActions = news.allowedActions ?? output.allowedActions;\n if (\n new Set(allowedActions).size !== new Set(key.allowedActions).size ||\n allowedActions.some((action) => !key.allowedActions.includes(action))\n )\n return yield* new DeployKeyChangeRequiresNewResource({\n deploymentName: output.deploymentName,\n keyId: output.keyId,\n field: \"allowedActions\",\n });\n }),\n read: Effect.fn(\"DeployKey.read\")(function* ({\n fqn,\n instanceId,\n olds,\n output,\n }) {\n const deploymentName = output?.deploymentName ?? olds.deploymentName;\n if (deploymentName === undefined) return;\n const name =\n output?.name ??\n olds.name ??\n (yield* resourceName(\"key\", fqn, instanceId));\n const keys = yield* client.listDeployKeys(deploymentName);\n if (output) {\n const key = keys.find((candidate) => candidate.id === output.keyId);\n if (!key) return yield* recover(deploymentName, name, [output.keyId]);\n if (!Redacted.isRedacted(output.deployKey))\n return yield* recover(deploymentName, name, [key.id]);\n return {\n ...output,\n allowedActions: key.allowedActions,\n };\n }\n const matches = keys.filter((key) => hasName(key.name, name));\n if (matches.length > 0)\n return yield* recover(\n deploymentName,\n name,\n matches.map((candidate) => candidate.id),\n );\n return undefined;\n }),\n reconcile: Effect.fn(\"DeployKey.reconcile\")(function* ({\n fqn,\n instanceId,\n news,\n output,\n }) {\n if (!output) yield* checkpointCreate(fqn, instanceId, news);\n const name =\n news.name ??\n output?.name ??\n (yield* resourceName(\"key\", fqn, instanceId));\n if (output) {\n for (const field of [\"deploymentName\", \"name\"] as const) {\n if (news[field] !== undefined && news[field] !== output[field])\n return yield* new DeployKeyChangeRequiresNewResource({\n deploymentName: output.deploymentName,\n keyId: output.keyId,\n field,\n });\n }\n const keys = yield* client.listDeployKeys(output.deploymentName);\n const key = keys.find((candidate) => candidate.id === output.keyId);\n if (!key || !Redacted.isRedacted(output.deployKey))\n return yield* recover(output.deploymentName, name, [output.keyId]);\n if (!hasName(key.name, name))\n return yield* new DeployKeyChangeRequiresNewResource({\n deploymentName: output.deploymentName,\n keyId: output.keyId,\n field: \"name\",\n });\n const allowedActions = news.allowedActions ?? output.allowedActions;\n if (\n new Set(allowedActions).size !== new Set(key.allowedActions).size ||\n allowedActions.some((action) => !key.allowedActions.includes(action))\n )\n return yield* new DeployKeyChangeRequiresNewResource({\n deploymentName: output.deploymentName,\n keyId: output.keyId,\n field: \"allowedActions\",\n });\n return {\n ...output,\n allowedActions: key.allowedActions,\n };\n }\n const existing = (yield* client.listDeployKeys(\n news.deploymentName,\n )).filter((key) => hasName(key.name, name));\n if (existing.length > 0)\n return yield* recover(\n news.deploymentName,\n name,\n existing.map((key) => key.id),\n );\n const created = yield* client.createDeployKey(news.deploymentName, {\n name,\n ...(news.allowedActions === undefined\n ? {}\n : { allowedActions: [...news.allowedActions] }),\n });\n const matches = (yield* client.listDeployKeys(\n news.deploymentName,\n )).filter((key) => hasName(key.name, name));\n const key = matches[0];\n if (matches.length !== 1 || !key)\n return yield* recover(\n news.deploymentName,\n name,\n matches.map((candidate) => candidate.id),\n );\n return {\n deploymentName: news.deploymentName,\n keyId: key.id,\n name,\n deployKey: created.deployKey,\n allowedActions: key.allowedActions,\n };\n }),\n delete: Effect.fn(\"DeployKey.delete\")(function* ({ output }) {\n yield* client\n .deleteDeployKey(output.deploymentName, output.deployKey)\n .pipe(Effect.catchTag(\"ConvexNotFound\", () => Effect.void));\n }),\n } satisfies Provider.ProviderServiceInput<DeployKey>;\n});\n\n/**\n * Under `alchemy dev` the deploy key is the admin key the local deployment\n * generated. It is read on every apply, so a recreated backend's new key\n * replaces the old one.\n */\nexport const localProvider = Effect.gen(function* () {\n const fs = yield* FileSystem.FileSystem;\n const path = yield* Path.Path;\n const directory = yield* dataDirectories;\n return {\n diff: () => Effect.succeed({ action: \"update\" }),\n reconcile: Effect.fn(\"DeployKey.localReconcile\")(function* ({\n fqn,\n instanceId,\n news,\n }) {\n const name = news.name ?? (yield* resourceName(\"key\", fqn, instanceId));\n const deployKey = yield* adminKey(\n news.deploymentName,\n directory(news.deploymentName),\n ).pipe(\n Effect.provideService(FileSystem.FileSystem, fs),\n Effect.provideService(Path.Path, path),\n );\n return {\n deploymentName: news.deploymentName,\n keyId: 0,\n name,\n deployKey,\n allowedActions: news.allowedActions ?? [],\n } satisfies DeployKeyAttributes;\n }),\n delete: () => Effect.void,\n } satisfies Provider.ProviderServiceInput<DeployKey>;\n});\n\nexport const layer = Provider.effect(DeployKey, provider);\nexport const localLayer = Provider.effect(DeployKey, localProvider);\n"],"mappings":"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"}
|