alchemy 0.12.21 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/ai/client.d.ts.map +1 -1
- package/lib/ai/client.js +3 -5
- package/lib/ai/client.js.map +1 -1
- package/lib/alchemy.d.ts +2 -1
- package/lib/alchemy.d.ts.map +1 -1
- package/lib/alchemy.js +87 -92
- package/lib/alchemy.js.map +1 -1
- package/lib/apply.d.ts.map +1 -1
- package/lib/apply.js +6 -0
- package/lib/apply.js.map +1 -1
- package/lib/aws/bucket.d.ts.map +1 -1
- package/lib/aws/bucket.js +55 -57
- package/lib/aws/bucket.js.map +1 -1
- package/lib/aws/function.d.ts.map +1 -1
- package/lib/aws/function.js +250 -252
- package/lib/aws/function.js.map +1 -1
- package/lib/aws/policy-attachment.d.ts.map +1 -1
- package/lib/aws/policy-attachment.js +4 -6
- package/lib/aws/policy-attachment.js.map +1 -1
- package/lib/aws/policy.d.ts.map +1 -1
- package/lib/aws/policy.js +63 -65
- package/lib/aws/policy.js.map +1 -1
- package/lib/aws/queue.js +88 -90
- package/lib/aws/queue.js.map +1 -1
- package/lib/aws/table.d.ts.map +1 -1
- package/lib/aws/table.js +95 -99
- package/lib/aws/table.js.map +1 -1
- package/lib/cloudflare/account-api-token.d.ts +1 -1
- package/lib/cloudflare/account-api-token.d.ts.map +1 -1
- package/lib/cloudflare/account-api-token.js +0 -1
- package/lib/cloudflare/account-api-token.js.map +1 -1
- package/lib/cloudflare/ai-gateway.js.map +1 -1
- package/lib/cloudflare/ai.d.ts +1 -1
- package/lib/cloudflare/ai.d.ts.map +1 -1
- package/lib/cloudflare/ai.js.map +1 -1
- package/lib/cloudflare/api.js +1 -5
- package/lib/cloudflare/api.js.map +1 -1
- package/lib/cloudflare/bucket.d.ts +2 -2
- package/lib/cloudflare/bucket.d.ts.map +1 -1
- package/lib/cloudflare/bucket.js +22 -24
- package/lib/cloudflare/bucket.js.map +1 -1
- package/lib/cloudflare/bundle/hybrid-nodejs-compat.d.ts +0 -3
- package/lib/cloudflare/bundle/hybrid-nodejs-compat.d.ts.map +1 -1
- package/lib/cloudflare/bundle/hybrid-nodejs-compat.js +3 -4
- package/lib/cloudflare/bundle/hybrid-nodejs-compat.js.map +1 -1
- package/lib/cloudflare/custom-domain.d.ts.map +1 -1
- package/lib/cloudflare/custom-domain.js +3 -5
- package/lib/cloudflare/custom-domain.js.map +1 -1
- package/lib/cloudflare/d1-database.d.ts +1 -1
- package/lib/cloudflare/d1-database.d.ts.map +1 -1
- package/lib/cloudflare/d1-database.js +70 -72
- package/lib/cloudflare/d1-database.js.map +1 -1
- package/lib/cloudflare/d1-migrations.d.ts +1 -1
- package/lib/cloudflare/d1-migrations.d.ts.map +1 -1
- package/lib/cloudflare/d1-migrations.js +2 -3
- package/lib/cloudflare/d1-migrations.js.map +1 -1
- package/lib/cloudflare/dns-records.d.ts.map +1 -1
- package/lib/cloudflare/dns-records.js +2 -4
- package/lib/cloudflare/dns-records.js.map +1 -1
- package/lib/cloudflare/kv-namespace.d.ts +1 -1
- package/lib/cloudflare/kv-namespace.d.ts.map +1 -1
- package/lib/cloudflare/kv-namespace.js +24 -27
- package/lib/cloudflare/kv-namespace.js.map +1 -1
- package/lib/cloudflare/pipeline.d.ts +1 -1
- package/lib/cloudflare/pipeline.d.ts.map +1 -1
- package/lib/cloudflare/pipeline.js +32 -34
- package/lib/cloudflare/pipeline.js.map +1 -1
- package/lib/cloudflare/queue-consumer.d.ts +1 -1
- package/lib/cloudflare/queue-consumer.d.ts.map +1 -1
- package/lib/cloudflare/queue-consumer.js +31 -33
- package/lib/cloudflare/queue-consumer.js.map +1 -1
- package/lib/cloudflare/queue.d.ts +1 -1
- package/lib/cloudflare/queue.d.ts.map +1 -1
- package/lib/cloudflare/queue.js +36 -38
- package/lib/cloudflare/queue.js.map +1 -1
- package/lib/cloudflare/r2-rest-state-store.js +4 -8
- package/lib/cloudflare/r2-rest-state-store.js.map +1 -1
- package/lib/cloudflare/types.d.ts.map +1 -1
- package/lib/cloudflare/types.js +1 -3
- package/lib/cloudflare/types.js.map +1 -1
- package/lib/cloudflare/vectorize-index.d.ts.map +1 -1
- package/lib/cloudflare/vectorize-index.js +37 -39
- package/lib/cloudflare/vectorize-index.js.map +1 -1
- package/lib/cloudflare/vectorize-metadata-index.d.ts +1 -1
- package/lib/cloudflare/vectorize-metadata-index.d.ts.map +1 -1
- package/lib/cloudflare/vectorize-metadata-index.js +10 -13
- package/lib/cloudflare/vectorize-metadata-index.js.map +1 -1
- package/lib/cloudflare/worker.js +6 -12
- package/lib/cloudflare/worker.js.map +1 -1
- package/lib/cloudflare/workflow.d.ts +1 -1
- package/lib/cloudflare/workflow.d.ts.map +1 -1
- package/lib/cloudflare/workflow.js.map +1 -1
- package/lib/cloudflare/zone.d.ts.map +1 -1
- package/lib/cloudflare/zone.js +48 -50
- package/lib/cloudflare/zone.js.map +1 -1
- package/lib/dns/godaddy.js +1 -1
- package/lib/dns/import-dns.js +1 -1
- package/lib/dns/import-dns.js.map +1 -1
- package/lib/env.js +7 -9
- package/lib/env.js.map +1 -1
- package/lib/esbuild/bundle.js +8 -10
- package/lib/esbuild/bundle.js.map +1 -1
- package/lib/fs/copy-file.d.ts.map +1 -1
- package/lib/fs/copy-file.js +27 -29
- package/lib/fs/copy-file.js.map +1 -1
- package/lib/fs/file.d.ts +1 -1
- package/lib/fs/file.d.ts.map +1 -1
- package/lib/fs/file.js +1 -1
- package/lib/fs/file.js.map +1 -1
- package/lib/fs/folder.d.ts.map +1 -1
- package/lib/fs/folder.js +1 -3
- package/lib/fs/folder.js.map +1 -1
- package/lib/github/client.d.ts.map +1 -1
- package/lib/github/client.js +3 -5
- package/lib/github/client.js.map +1 -1
- package/lib/github/repository-environment.d.ts.map +1 -1
- package/lib/github/repository-environment.js +173 -176
- package/lib/github/repository-environment.js.map +1 -1
- package/lib/github/secret.d.ts.map +1 -1
- package/lib/github/secret.js +97 -99
- package/lib/github/secret.js.map +1 -1
- package/lib/internal/docs/providers.d.ts.map +1 -1
- package/lib/internal/docs/providers.js +5 -7
- package/lib/internal/docs/providers.js.map +1 -1
- package/lib/neon/api.js +1 -2
- package/lib/neon/api.js.map +1 -1
- package/lib/neon/project.js +2 -2
- package/lib/neon/project.js.map +1 -1
- package/lib/os/exec.d.ts +5 -0
- package/lib/os/exec.d.ts.map +1 -1
- package/lib/os/exec.js +88 -56
- package/lib/os/exec.js.map +1 -1
- package/lib/scope.d.ts +3 -0
- package/lib/scope.d.ts.map +1 -1
- package/lib/scope.js +10 -3
- package/lib/scope.js.map +1 -1
- package/lib/secret.d.ts.map +1 -1
- package/lib/secret.js +1 -3
- package/lib/secret.js.map +1 -1
- package/lib/serde.d.ts.map +1 -1
- package/lib/serde.js +13 -15
- package/lib/serde.js.map +1 -1
- package/lib/stripe/price.d.ts.map +1 -1
- package/lib/stripe/price.js +69 -73
- package/lib/stripe/price.js.map +1 -1
- package/lib/stripe/product.d.ts.map +1 -1
- package/lib/stripe/product.js +50 -52
- package/lib/stripe/product.js.map +1 -1
- package/lib/stripe/webhook.d.ts.map +1 -1
- package/lib/stripe/webhook.js +51 -53
- package/lib/stripe/webhook.js.map +1 -1
- package/lib/test/bun.d.ts +1 -1
- package/lib/test/bun.d.ts.map +1 -1
- package/lib/test/bun.js +1 -0
- package/lib/test/bun.js.map +1 -1
- package/lib/test/prune.d.ts.map +1 -1
- package/lib/test/prune.js.map +1 -1
- package/lib/util/dedent.js +4 -4
- package/lib/util/dedent.js.map +1 -1
- package/lib/web/astro.js +1 -1
- package/lib/web/shadcn.js +4 -4
- package/lib/web/shadcn.js.map +1 -1
- package/lib/web/tailwind.d.ts.map +1 -1
- package/lib/web/tailwind.js +0 -1
- package/lib/web/tailwind.js.map +1 -1
- package/lib/web/vite.js +3 -3
- package/lib/web/vitepress/home-page.d.ts.map +1 -1
- package/lib/web/vitepress/home-page.js +6 -8
- package/lib/web/vitepress/home-page.js.map +1 -1
- package/lib/web/vitepress/process-front-matter-files.js +1 -1
- package/lib/web/vitepress/process-front-matter-files.js.map +1 -1
- package/lib/web/vitepress/vitepress.js +2 -2
- package/lib/web/vitepress/vitepress.js.map +1 -1
- package/package.json +1 -1
- package/src/ai/astro-file.ts +4 -4
- package/src/ai/client.ts +4 -5
- package/src/ai/css-file.ts +4 -4
- package/src/ai/document.ts +3 -3
- package/src/ai/html-file.ts +4 -4
- package/src/ai/json-file.ts +1 -1
- package/src/ai/typescript-file.ts +4 -4
- package/src/ai/vue-file.ts +4 -4
- package/src/ai/yaml-file.ts +1 -1
- package/src/alchemy.ts +111 -104
- package/src/apply.ts +13 -5
- package/src/aws/bucket.ts +72 -75
- package/src/aws/function.ts +296 -297
- package/src/aws/oidc/github-oidc-provider.ts +1 -1
- package/src/aws/oidc/oidc-provider.ts +15 -15
- package/src/aws/policy-attachment.ts +10 -11
- package/src/aws/policy.ts +91 -94
- package/src/aws/queue.ts +111 -111
- package/src/aws/role.ts +24 -24
- package/src/aws/ses.ts +17 -17
- package/src/aws/table.ts +114 -115
- package/src/cloudflare/account-api-token.ts +11 -11
- package/src/cloudflare/account-id.ts +1 -1
- package/src/cloudflare/ai-gateway.ts +4 -4
- package/src/cloudflare/ai.ts +1 -1
- package/src/cloudflare/api-error.ts +1 -1
- package/src/cloudflare/api.ts +7 -11
- package/src/cloudflare/assets.ts +4 -4
- package/src/cloudflare/auth.ts +13 -13
- package/src/cloudflare/bucket.ts +62 -63
- package/src/cloudflare/bundle/hybrid-nodejs-compat.ts +13 -14
- package/src/cloudflare/custom-domain.ts +27 -28
- package/src/cloudflare/d1-database.ts +101 -102
- package/src/cloudflare/d1-migrations.ts +10 -10
- package/src/cloudflare/dns-records.ts +23 -24
- package/src/cloudflare/durable-object-namespace.ts +1 -1
- package/src/cloudflare/event-source.ts +1 -1
- package/src/cloudflare/hyperdrive.ts +3 -3
- package/src/cloudflare/kv-namespace.ts +36 -37
- package/src/cloudflare/nuxt.ts +1 -1
- package/src/cloudflare/permission-groups.ts +7 -7
- package/src/cloudflare/pipeline.ts +55 -56
- package/src/cloudflare/queue-consumer.ts +53 -54
- package/src/cloudflare/queue.ts +56 -57
- package/src/cloudflare/r2-rest-state-store.ts +11 -11
- package/src/cloudflare/redwood.ts +1 -1
- package/src/cloudflare/tanstack-start.ts +1 -1
- package/src/cloudflare/types.ts +1 -2
- package/src/cloudflare/vectorize-index.ts +60 -61
- package/src/cloudflare/vectorize-metadata-index.ts +25 -25
- package/src/cloudflare/vite.ts +1 -1
- package/src/cloudflare/website.ts +3 -3
- package/src/cloudflare/worker.ts +61 -61
- package/src/cloudflare/workflow.ts +4 -4
- package/src/cloudflare/wrangler.json.ts +4 -4
- package/src/cloudflare/zone.ts +69 -70
- package/src/destroy.ts +4 -4
- package/src/dns/godaddy.ts +1 -1
- package/src/dns/import-dns.ts +5 -5
- package/src/encrypt.ts +6 -6
- package/src/env.ts +10 -10
- package/src/esbuild/bundle.ts +14 -14
- package/src/fs/copy-file.ts +35 -36
- package/src/fs/file-system-state-store.ts +4 -4
- package/src/fs/file.ts +9 -8
- package/src/fs/folder.ts +6 -7
- package/src/github/client.ts +15 -14
- package/src/github/repository-environment.ts +206 -210
- package/src/github/secret.ts +111 -116
- package/src/internal/docs/providers.ts +16 -17
- package/src/neon/api-error.ts +1 -1
- package/src/neon/api.ts +6 -6
- package/src/neon/project.ts +18 -17
- package/src/os/exec.ts +107 -66
- package/src/resource.ts +3 -3
- package/src/scope.ts +14 -4
- package/src/secret.ts +2 -3
- package/src/serde.ts +30 -22
- package/src/stripe/price.ts +74 -77
- package/src/stripe/product.ts +55 -56
- package/src/stripe/webhook.ts +56 -57
- package/src/test/bun.ts +7 -6
- package/src/test/prune.ts +4 -4
- package/src/util/dedent.ts +4 -4
- package/src/web/astro.ts +10 -10
- package/src/web/shadcn-component.ts +4 -4
- package/src/web/shadcn.ts +10 -10
- package/src/web/tailwind.ts +2 -3
- package/src/web/vite.ts +11 -11
- package/src/web/vitepress/config.ts +2 -2
- package/src/web/vitepress/custom-theme.ts +7 -7
- package/src/web/vitepress/dependencies.ts +4 -4
- package/src/web/vitepress/home-page.ts +8 -9
- package/src/web/vitepress/process-front-matter-files.ts +5 -5
- package/src/web/vitepress/vitepress.ts +7 -7
package/src/github/secret.ts
CHANGED
|
@@ -135,7 +135,7 @@ export const GitHubSecret = Resource(
|
|
|
135
135
|
async function (
|
|
136
136
|
this: Context<GitHubSecretOutput>,
|
|
137
137
|
id: string,
|
|
138
|
-
props: GitHubSecretProps
|
|
138
|
+
props: GitHubSecretProps,
|
|
139
139
|
): Promise<GitHubSecretOutput> {
|
|
140
140
|
// Create authenticated Octokit client - will automatically handle token resolution
|
|
141
141
|
/// TODO: use fetch
|
|
@@ -181,133 +181,128 @@ export const GitHubSecret = Resource(
|
|
|
181
181
|
|
|
182
182
|
// Return void (a deleted resource has no content)
|
|
183
183
|
return this.destroy();
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
isEnvironmentSecret !== wasEnvironmentSecret;
|
|
184
|
+
}
|
|
185
|
+
try {
|
|
186
|
+
// Check if we're transitioning between secret types (repo <-> environment)
|
|
187
|
+
if (this.phase === "update") {
|
|
188
|
+
const wasEnvironmentSecret = !!this.output.environment;
|
|
189
|
+
const secretTypeChanged = isEnvironmentSecret !== wasEnvironmentSecret;
|
|
191
190
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
191
|
+
// If secret type changed, we need to delete the old one first
|
|
192
|
+
if (secretTypeChanged) {
|
|
193
|
+
console.log(
|
|
194
|
+
`Secret type changed from ${wasEnvironmentSecret ? "environment" : "repository"} to ${isEnvironmentSecret ? "environment" : "repository"} secret. Deleting the old secret first.`,
|
|
195
|
+
);
|
|
197
196
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
}
|
|
197
|
+
try {
|
|
198
|
+
if (wasEnvironmentSecret) {
|
|
199
|
+
// Delete the old environment secret
|
|
200
|
+
await octokit.rest.actions.deleteEnvironmentSecret({
|
|
201
|
+
owner: this.output.owner,
|
|
202
|
+
repo: this.output.repository,
|
|
203
|
+
environment_name: this.output.environment!,
|
|
204
|
+
secret_name: this.output.name,
|
|
205
|
+
});
|
|
206
|
+
} else {
|
|
207
|
+
// Delete the old repository secret
|
|
208
|
+
await octokit.rest.actions.deleteRepoSecret({
|
|
209
|
+
owner: this.output.owner,
|
|
210
|
+
repo: this.output.repository,
|
|
211
|
+
secret_name: this.output.name,
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
} catch (error: any) {
|
|
215
|
+
// Log but don't fail if the old secret doesn't exist or can't be deleted
|
|
216
|
+
if (error.status === 404) {
|
|
217
|
+
console.log(
|
|
218
|
+
"Old secret not found, continuing with creation of new secret",
|
|
219
|
+
);
|
|
220
|
+
} else {
|
|
221
|
+
throw error;
|
|
224
222
|
}
|
|
225
223
|
}
|
|
226
224
|
}
|
|
225
|
+
}
|
|
227
226
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
// Get the appropriate public key for encrypting secrets
|
|
231
|
-
if (isEnvironmentSecret) {
|
|
232
|
-
// Get the environment's public key
|
|
233
|
-
const { data } = await octokit.rest.actions.getEnvironmentPublicKey({
|
|
234
|
-
owner: props.owner,
|
|
235
|
-
repo: props.repository,
|
|
236
|
-
environment_name: props.environment!,
|
|
237
|
-
});
|
|
238
|
-
publicKey = data;
|
|
239
|
-
} else {
|
|
240
|
-
// Get the repository's public key
|
|
241
|
-
const { data } = await octokit.rest.actions.getRepoPublicKey({
|
|
242
|
-
owner: props.owner,
|
|
243
|
-
repo: props.repository,
|
|
244
|
-
});
|
|
245
|
-
publicKey = data;
|
|
246
|
-
}
|
|
227
|
+
let publicKey;
|
|
247
228
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
229
|
+
// Get the appropriate public key for encrypting secrets
|
|
230
|
+
if (isEnvironmentSecret) {
|
|
231
|
+
// Get the environment's public key
|
|
232
|
+
const { data } = await octokit.rest.actions.getEnvironmentPublicKey({
|
|
233
|
+
owner: props.owner,
|
|
234
|
+
repo: props.repository,
|
|
235
|
+
environment_name: props.environment!,
|
|
236
|
+
});
|
|
237
|
+
publicKey = data;
|
|
238
|
+
} else {
|
|
239
|
+
// Get the repository's public key
|
|
240
|
+
const { data } = await octokit.rest.actions.getRepoPublicKey({
|
|
241
|
+
owner: props.owner,
|
|
242
|
+
repo: props.repository,
|
|
243
|
+
});
|
|
244
|
+
publicKey = data;
|
|
245
|
+
}
|
|
253
246
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
environment_name: props.environment!,
|
|
260
|
-
secret_name: props.name,
|
|
261
|
-
encrypted_value: encryptedValue,
|
|
262
|
-
key_id: publicKey.key_id,
|
|
263
|
-
});
|
|
264
|
-
} else {
|
|
265
|
-
await octokit.rest.actions.createOrUpdateRepoSecret({
|
|
266
|
-
owner: props.owner,
|
|
267
|
-
repo: props.repository,
|
|
268
|
-
secret_name: props.name,
|
|
269
|
-
encrypted_value: encryptedValue,
|
|
270
|
-
key_id: publicKey.key_id,
|
|
271
|
-
});
|
|
272
|
-
}
|
|
247
|
+
// Encrypt the secret value using libsodium
|
|
248
|
+
const encryptedValue = await encryptString(
|
|
249
|
+
props.value.unencrypted,
|
|
250
|
+
publicKey.key,
|
|
251
|
+
);
|
|
273
252
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
idParts.push(props.environment!);
|
|
278
|
-
}
|
|
279
|
-
idParts.push(props.name);
|
|
280
|
-
|
|
281
|
-
return this({
|
|
282
|
-
id: idParts.join("/"),
|
|
253
|
+
// Create or update the secret with the encrypted value and key_id
|
|
254
|
+
if (isEnvironmentSecret) {
|
|
255
|
+
await octokit.rest.actions.createOrUpdateEnvironmentSecret({
|
|
283
256
|
owner: props.owner,
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
257
|
+
repo: props.repository,
|
|
258
|
+
environment_name: props.environment!,
|
|
259
|
+
secret_name: props.name,
|
|
260
|
+
encrypted_value: encryptedValue,
|
|
261
|
+
key_id: publicKey.key_id,
|
|
289
262
|
});
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
263
|
+
} else {
|
|
264
|
+
await octokit.rest.actions.createOrUpdateRepoSecret({
|
|
265
|
+
owner: props.owner,
|
|
266
|
+
repo: props.repository,
|
|
267
|
+
secret_name: props.name,
|
|
268
|
+
encrypted_value: encryptedValue,
|
|
269
|
+
key_id: publicKey.key_id,
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
// GitHub doesn't return the secret details on create/update, so we need to construct it
|
|
274
|
+
const idParts = [props.owner, props.repository];
|
|
275
|
+
if (isEnvironmentSecret) {
|
|
276
|
+
idParts.push(props.environment!);
|
|
277
|
+
}
|
|
278
|
+
idParts.push(props.name);
|
|
279
|
+
|
|
280
|
+
return this({
|
|
281
|
+
id: idParts.join("/"),
|
|
282
|
+
owner: props.owner,
|
|
283
|
+
repository: props.repository,
|
|
284
|
+
name: props.name,
|
|
285
|
+
environment: props.environment,
|
|
286
|
+
token: props.token,
|
|
287
|
+
updatedAt: new Date().toISOString(),
|
|
288
|
+
});
|
|
289
|
+
} catch (error: any) {
|
|
290
|
+
if (
|
|
291
|
+
error.status === 403 &&
|
|
292
|
+
error.message?.includes("Must have admin rights")
|
|
293
|
+
) {
|
|
294
|
+
console.error(
|
|
295
|
+
"\n⚠️ Error creating/updating GitHub secret: You must have admin rights to the repository.",
|
|
296
|
+
);
|
|
297
|
+
console.error(
|
|
298
|
+
"Make sure your GitHub token has the required permissions (repo scope for private repos).\n",
|
|
299
|
+
);
|
|
300
|
+
} else {
|
|
301
|
+
console.error("Error creating/updating GitHub secret:", error.message);
|
|
308
302
|
}
|
|
303
|
+
throw error;
|
|
309
304
|
}
|
|
310
|
-
}
|
|
305
|
+
},
|
|
311
306
|
);
|
|
312
307
|
|
|
313
308
|
/**
|
|
@@ -320,7 +315,7 @@ export const GitHubSecret = Resource(
|
|
|
320
315
|
*/
|
|
321
316
|
async function encryptString(
|
|
322
317
|
value: string,
|
|
323
|
-
publicKey: string
|
|
318
|
+
publicKey: string,
|
|
324
319
|
): Promise<string> {
|
|
325
320
|
// Initialize libsodium
|
|
326
321
|
await sodium.ready;
|
|
@@ -60,7 +60,7 @@ export async function Providers({
|
|
|
60
60
|
];
|
|
61
61
|
|
|
62
62
|
// Get all folders in the alchemy/src directory
|
|
63
|
-
|
|
63
|
+
const providers = (
|
|
64
64
|
await fs.readdir(srcDir, {
|
|
65
65
|
withFileTypes: true,
|
|
66
66
|
})
|
|
@@ -71,18 +71,17 @@ export async function Providers({
|
|
|
71
71
|
if (parallel) {
|
|
72
72
|
return await Promise.all(
|
|
73
73
|
providers.map((provider) =>
|
|
74
|
-
generateProviderDocs({ provider, outDir, parallel })
|
|
75
|
-
)
|
|
74
|
+
generateProviderDocs({ provider, outDir, parallel }),
|
|
75
|
+
),
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
const generatedProviders = [];
|
|
79
|
+
for (const provider of providers) {
|
|
80
|
+
generatedProviders.push(
|
|
81
|
+
await generateProviderDocs({ provider, outDir, parallel }),
|
|
76
82
|
);
|
|
77
|
-
} else {
|
|
78
|
-
const generatedProviders = [];
|
|
79
|
-
for (const provider of providers) {
|
|
80
|
-
generatedProviders.push(
|
|
81
|
-
await generateProviderDocs({ provider, outDir, parallel })
|
|
82
|
-
);
|
|
83
|
-
}
|
|
84
|
-
return generatedProviders;
|
|
85
83
|
}
|
|
84
|
+
return generatedProviders;
|
|
86
85
|
}
|
|
87
86
|
|
|
88
87
|
async function generateProviderDocs({
|
|
@@ -102,7 +101,7 @@ async function generateProviderDocs({
|
|
|
102
101
|
)
|
|
103
102
|
.filter((dirent) => dirent.isFile())
|
|
104
103
|
.map((dirent) =>
|
|
105
|
-
path.relative(process.cwd(), path.resolve(provider, dirent.name))
|
|
104
|
+
path.relative(process.cwd(), path.resolve(provider, dirent.name)),
|
|
106
105
|
)
|
|
107
106
|
.filter((file) => file.endsWith(".ts") && !file.endsWith("index.ts"));
|
|
108
107
|
|
|
@@ -123,13 +122,13 @@ async function generateProviderDocs({
|
|
|
123
122
|
schema: type({
|
|
124
123
|
groups: type({
|
|
125
124
|
identifier: type("string").describe(
|
|
126
|
-
"The identifier of the file's primary exported Resource/Function/Type, e.g. Bucket or StaticSite, AstroFile, TypeScriptFile"
|
|
125
|
+
"The identifier of the file's primary exported Resource/Function/Type, e.g. Bucket or StaticSite, AstroFile, TypeScriptFile",
|
|
127
126
|
),
|
|
128
127
|
filename: type("string").describe(
|
|
129
|
-
"The filename of the Resource's Document, e.g. bucket.md or static-site.md"
|
|
128
|
+
"The filename of the Resource's Document, e.g. bucket.md or static-site.md",
|
|
130
129
|
),
|
|
131
130
|
category: type("'Resource'|'Client'|'Utility'|'Types'").describe(
|
|
132
|
-
"The classification of the Resource's Document, one of: Resource, Client, Utility, or Types."
|
|
131
|
+
"The classification of the Resource's Document, one of: Resource, Client, Utility, or Types.",
|
|
133
132
|
),
|
|
134
133
|
}).array(),
|
|
135
134
|
}),
|
|
@@ -163,7 +162,7 @@ async function generateProviderDocs({
|
|
|
163
162
|
let documents: Document[] = [];
|
|
164
163
|
if (parallel) {
|
|
165
164
|
documents = await Promise.all(
|
|
166
|
-
groups.filter((g) => g.category === "Resource").map(generateDocument)
|
|
165
|
+
groups.filter((g) => g.category === "Resource").map(generateDocument),
|
|
167
166
|
);
|
|
168
167
|
} else {
|
|
169
168
|
for (const g of groups.filter((g) => g.category === "Resource")) {
|
|
@@ -176,7 +175,7 @@ async function generateProviderDocs({
|
|
|
176
175
|
title: g.identifier,
|
|
177
176
|
path: path.join(
|
|
178
177
|
providerDocsDir,
|
|
179
|
-
`${g.filename.replace(".ts", "").replace(".md", "")}.md
|
|
178
|
+
`${g.filename.replace(".ts", "").replace(".md", "")}.md`,
|
|
180
179
|
),
|
|
181
180
|
freeze: false,
|
|
182
181
|
model: {
|
package/src/neon/api-error.ts
CHANGED
|
@@ -46,7 +46,7 @@ export async function handleApiError(
|
|
|
46
46
|
response: Response,
|
|
47
47
|
action: "get" | "create" | "update" | "delete" | "list",
|
|
48
48
|
resourceType: string,
|
|
49
|
-
resourceId?: string
|
|
49
|
+
resourceId?: string,
|
|
50
50
|
): Promise<never> {
|
|
51
51
|
const resourceDisplay = resourceId ? `'${resourceId}'` : "";
|
|
52
52
|
let errorData: any;
|
package/src/neon/api.ts
CHANGED
|
@@ -35,13 +35,13 @@ export function createNeonApi(options: Partial<NeonApiOptions> = {}): NeonApi {
|
|
|
35
35
|
* @returns Headers for authentication
|
|
36
36
|
*/
|
|
37
37
|
export async function getNeonAuthHeaders(
|
|
38
|
-
options: Partial<NeonApiOptions
|
|
38
|
+
options: Partial<NeonApiOptions>,
|
|
39
39
|
): Promise<Record<string, string>> {
|
|
40
40
|
const apiKey = options.apiKey?.unencrypted ?? process.env.NEON_API_KEY;
|
|
41
41
|
|
|
42
42
|
if (!apiKey) {
|
|
43
43
|
throw new Error(
|
|
44
|
-
"Neon API key is required. Set NEON_API_KEY environment variable or provide apiKey option."
|
|
44
|
+
"Neon API key is required. Set NEON_API_KEY environment variable or provide apiKey option.",
|
|
45
45
|
);
|
|
46
46
|
}
|
|
47
47
|
|
|
@@ -114,7 +114,7 @@ export class NeonApi {
|
|
|
114
114
|
return isNetworkError || error?.status?.toString().startsWith("5");
|
|
115
115
|
},
|
|
116
116
|
5, // Maximum 5 attempts (1 initial + 4 retries)
|
|
117
|
-
1000 // Start with 1s delay, will exponentially increase
|
|
117
|
+
1000, // Start with 1s delay, will exponentially increase
|
|
118
118
|
);
|
|
119
119
|
}
|
|
120
120
|
|
|
@@ -131,7 +131,7 @@ export class NeonApi {
|
|
|
131
131
|
async post(
|
|
132
132
|
path: string,
|
|
133
133
|
body: any,
|
|
134
|
-
init: RequestInit = {}
|
|
134
|
+
init: RequestInit = {},
|
|
135
135
|
): Promise<Response> {
|
|
136
136
|
const requestBody =
|
|
137
137
|
body instanceof FormData
|
|
@@ -148,7 +148,7 @@ export class NeonApi {
|
|
|
148
148
|
async put(
|
|
149
149
|
path: string,
|
|
150
150
|
body: any,
|
|
151
|
-
init: RequestInit = {}
|
|
151
|
+
init: RequestInit = {},
|
|
152
152
|
): Promise<Response> {
|
|
153
153
|
const requestBody = body instanceof FormData ? body : JSON.stringify(body);
|
|
154
154
|
return this.fetch(path, { ...init, method: "PUT", body: requestBody });
|
|
@@ -160,7 +160,7 @@ export class NeonApi {
|
|
|
160
160
|
async patch(
|
|
161
161
|
path: string,
|
|
162
162
|
body: any,
|
|
163
|
-
init: RequestInit = {}
|
|
163
|
+
init: RequestInit = {},
|
|
164
164
|
): Promise<Response> {
|
|
165
165
|
return this.fetch(path, {
|
|
166
166
|
...init,
|
package/src/neon/project.ts
CHANGED
|
@@ -510,7 +510,7 @@ export const NeonProject = Resource(
|
|
|
510
510
|
async function (
|
|
511
511
|
this: Context<NeonProject>,
|
|
512
512
|
id: string,
|
|
513
|
-
props: NeonProjectProps
|
|
513
|
+
props: NeonProjectProps,
|
|
514
514
|
): Promise<NeonProject> {
|
|
515
515
|
const api = createNeonApi(props);
|
|
516
516
|
const projectId = props.existing_project_id || this.output?.id;
|
|
@@ -553,7 +553,7 @@ export const NeonProject = Resource(
|
|
|
553
553
|
response = await getProject(
|
|
554
554
|
api,
|
|
555
555
|
projectId,
|
|
556
|
-
initialData as Partial<NeonApiResponse
|
|
556
|
+
initialData as Partial<NeonApiResponse>,
|
|
557
557
|
);
|
|
558
558
|
} else {
|
|
559
559
|
// Check if a project with this ID already exists
|
|
@@ -576,7 +576,7 @@ export const NeonProject = Resource(
|
|
|
576
576
|
response = await getProject(
|
|
577
577
|
api,
|
|
578
578
|
projectId,
|
|
579
|
-
initialData as Partial<NeonApiResponse
|
|
579
|
+
initialData as Partial<NeonApiResponse>,
|
|
580
580
|
);
|
|
581
581
|
} else if (getResponse.status !== 404) {
|
|
582
582
|
// Unexpected error during GET check
|
|
@@ -631,7 +631,7 @@ export const NeonProject = Resource(
|
|
|
631
631
|
console.error(`Error ${this.phase} Neon project '${id}':`, error);
|
|
632
632
|
throw error;
|
|
633
633
|
}
|
|
634
|
-
}
|
|
634
|
+
},
|
|
635
635
|
);
|
|
636
636
|
|
|
637
637
|
/**
|
|
@@ -639,7 +639,7 @@ export const NeonProject = Resource(
|
|
|
639
639
|
*/
|
|
640
640
|
async function createNewProject(
|
|
641
641
|
api: any,
|
|
642
|
-
props: NeonProjectProps
|
|
642
|
+
props: NeonProjectProps,
|
|
643
643
|
): Promise<NeonApiResponse> {
|
|
644
644
|
const defaultEndpoint = props.default_endpoint ?? true;
|
|
645
645
|
const projectResponse = await api.post("/projects", {
|
|
@@ -672,13 +672,13 @@ async function createNewProject(
|
|
|
672
672
|
async function getProject(
|
|
673
673
|
api: any,
|
|
674
674
|
projectId: string,
|
|
675
|
-
initialData: Partial<NeonApiResponse> = {}
|
|
675
|
+
initialData: Partial<NeonApiResponse> = {},
|
|
676
676
|
): Promise<NeonApiResponse> {
|
|
677
677
|
// Get the latest project details
|
|
678
678
|
const updatedData = await getProjectDetails(api, projectId);
|
|
679
679
|
|
|
680
680
|
// Start with a copy of the initial data
|
|
681
|
-
|
|
681
|
+
const responseData = { ...initialData };
|
|
682
682
|
|
|
683
683
|
// Check if we have a branch ID from the initial data
|
|
684
684
|
const branchId = initialData.branch?.id;
|
|
@@ -736,10 +736,10 @@ async function waitForOperations(
|
|
|
736
736
|
project_id: string;
|
|
737
737
|
status: string;
|
|
738
738
|
action: string;
|
|
739
|
-
}
|
|
739
|
+
}>,
|
|
740
740
|
): Promise<void> {
|
|
741
741
|
const pendingOperations = operations.filter(
|
|
742
|
-
(op) => op.status !== "finished" && op.status !== "failed"
|
|
742
|
+
(op) => op.status !== "finished" && op.status !== "failed",
|
|
743
743
|
);
|
|
744
744
|
|
|
745
745
|
if (pendingOperations.length === 0) {
|
|
@@ -774,7 +774,7 @@ async function waitForOperations(
|
|
|
774
774
|
|
|
775
775
|
// Check operation status
|
|
776
776
|
const operationResponse = await api.get(
|
|
777
|
-
`/projects/${operation.project_id}/operations/${operation.id}
|
|
777
|
+
`/projects/${operation.project_id}/operations/${operation.id}`,
|
|
778
778
|
);
|
|
779
779
|
|
|
780
780
|
if (operationResponse.ok) {
|
|
@@ -782,16 +782,17 @@ async function waitForOperations(
|
|
|
782
782
|
operationStatus = operationData.operation?.status;
|
|
783
783
|
} else {
|
|
784
784
|
throw new Error(
|
|
785
|
-
`Failed to check operation ${operation.id} status: HTTP ${operationResponse.status}
|
|
785
|
+
`Failed to check operation ${operation.id} status: HTTP ${operationResponse.status}`,
|
|
786
786
|
);
|
|
787
787
|
}
|
|
788
788
|
}
|
|
789
789
|
|
|
790
790
|
if (operationStatus === "failed") {
|
|
791
791
|
throw new Error(`Operation ${operation.id} (${operation.action}) failed`);
|
|
792
|
-
}
|
|
792
|
+
}
|
|
793
|
+
if (totalWaitTime >= maxWaitTime) {
|
|
793
794
|
throw new Error(
|
|
794
|
-
`Timeout waiting for operation ${operation.id} (${operation.action}) to complete
|
|
795
|
+
`Timeout waiting for operation ${operation.id} (${operation.action}) to complete`,
|
|
795
796
|
);
|
|
796
797
|
}
|
|
797
798
|
}
|
|
@@ -810,7 +811,7 @@ async function waitForOperations(
|
|
|
810
811
|
*/
|
|
811
812
|
async function getProjectDetails(
|
|
812
813
|
api: any,
|
|
813
|
-
projectId: string
|
|
814
|
+
projectId: string,
|
|
814
815
|
): Promise<NeonApiResponse> {
|
|
815
816
|
const response = await api.get(`/projects/${projectId}`);
|
|
816
817
|
|
|
@@ -833,7 +834,7 @@ async function getProjectDetails(
|
|
|
833
834
|
async function getBranchDetails(
|
|
834
835
|
api: any,
|
|
835
836
|
projectId: string,
|
|
836
|
-
branchId: string
|
|
837
|
+
branchId: string,
|
|
837
838
|
): Promise<{ branch: NeonBranch }> {
|
|
838
839
|
const response = await api.get(`/projects/${projectId}/branches/${branchId}`);
|
|
839
840
|
|
|
@@ -856,10 +857,10 @@ async function getBranchDetails(
|
|
|
856
857
|
async function getEndpointDetails(
|
|
857
858
|
api: any,
|
|
858
859
|
projectId: string,
|
|
859
|
-
branchId: string
|
|
860
|
+
branchId: string,
|
|
860
861
|
): Promise<{ endpoints: NeonEndpoint[] }> {
|
|
861
862
|
const response = await api.get(
|
|
862
|
-
`/projects/${projectId}/branches/${branchId}/endpoints
|
|
863
|
+
`/projects/${projectId}/branches/${branchId}/endpoints`,
|
|
863
864
|
);
|
|
864
865
|
|
|
865
866
|
if (!response.ok) {
|