alchemy 2.0.0-beta.15 → 2.0.0-beta.16
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/bin/alchemy.js +1585 -707
- package/bin/alchemy.js.map +1 -1
- package/bin/alchemy.ts +2 -0
- package/bin/commands/login.ts +6 -3
- package/bin/commands/profile.ts +86 -0
- package/lib/Cloudflare/ApiToken/AccountApiToken.d.ts +2 -3
- package/lib/Cloudflare/ApiToken/AccountApiToken.d.ts.map +1 -1
- package/lib/Cloudflare/ApiToken/AccountApiToken.js +12 -8
- package/lib/Cloudflare/ApiToken/AccountApiToken.js.map +1 -1
- package/lib/Cloudflare/ApiToken/Common.d.ts +6 -1
- package/lib/Cloudflare/ApiToken/Common.d.ts.map +1 -1
- package/lib/Cloudflare/ApiToken/Common.js.map +1 -1
- package/lib/Cloudflare/ApiToken/UserApiToken.d.ts +2 -3
- package/lib/Cloudflare/ApiToken/UserApiToken.d.ts.map +1 -1
- package/lib/Cloudflare/ApiToken/UserApiToken.js +4 -4
- package/lib/Cloudflare/ApiToken/UserApiToken.js.map +1 -1
- package/lib/Cloudflare/Artifacts/Artifacts.d.ts +101 -0
- package/lib/Cloudflare/Artifacts/Artifacts.d.ts.map +1 -0
- package/lib/Cloudflare/Artifacts/Artifacts.js +92 -0
- package/lib/Cloudflare/Artifacts/Artifacts.js.map +1 -0
- package/lib/Cloudflare/Artifacts/ArtifactsBinding.d.ts +83 -0
- package/lib/Cloudflare/Artifacts/ArtifactsBinding.d.ts.map +1 -0
- package/lib/Cloudflare/Artifacts/ArtifactsBinding.js +65 -0
- package/lib/Cloudflare/Artifacts/ArtifactsBinding.js.map +1 -0
- package/lib/Cloudflare/Artifacts/index.d.ts +3 -0
- package/lib/Cloudflare/Artifacts/index.d.ts.map +1 -0
- package/lib/Cloudflare/Artifacts/index.js +3 -0
- package/lib/Cloudflare/Artifacts/index.js.map +1 -0
- package/lib/Cloudflare/Container/ContainerBinding.d.ts +1 -1
- package/lib/Cloudflare/Providers.d.ts.map +1 -1
- package/lib/Cloudflare/Providers.js +3 -1
- package/lib/Cloudflare/Providers.js.map +1 -1
- package/lib/Cloudflare/Workers/InferEnv.d.ts +1 -1
- package/lib/Cloudflare/Workers/InferEnv.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/InferEnv.js +0 -1
- package/lib/Cloudflare/Workers/InferEnv.js.map +1 -1
- package/lib/Cloudflare/Workers/Worker.d.ts +2 -1
- package/lib/Cloudflare/Workers/Worker.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/Worker.js +25 -18
- package/lib/Cloudflare/Workers/Worker.js.map +1 -1
- package/lib/Cloudflare/index.d.ts +1 -0
- package/lib/Cloudflare/index.d.ts.map +1 -1
- package/lib/Cloudflare/index.js +1 -0
- package/lib/Cloudflare/index.js.map +1 -1
- package/lib/GitHub/AuthProvider.d.ts +37 -0
- package/lib/GitHub/AuthProvider.d.ts.map +1 -0
- package/lib/GitHub/AuthProvider.js +154 -0
- package/lib/GitHub/AuthProvider.js.map +1 -0
- package/lib/GitHub/Credentials.d.ts +29 -0
- package/lib/GitHub/Credentials.d.ts.map +1 -0
- package/lib/GitHub/Credentials.js +54 -0
- package/lib/GitHub/Credentials.js.map +1 -0
- package/lib/GitHub/Providers.d.ts +12 -1
- package/lib/GitHub/Providers.d.ts.map +1 -1
- package/lib/GitHub/Providers.js +13 -3
- package/lib/GitHub/Providers.js.map +1 -1
- package/lib/GitHub/Secret.d.ts +8 -10
- package/lib/GitHub/Secret.d.ts.map +1 -1
- package/lib/GitHub/Secret.js +16 -14
- package/lib/GitHub/Secret.js.map +1 -1
- package/lib/GitHub/Variable.d.ts +8 -10
- package/lib/GitHub/Variable.d.ts.map +1 -1
- package/lib/GitHub/Variable.js +12 -13
- package/lib/GitHub/Variable.js.map +1 -1
- package/lib/GitHub/index.d.ts +2 -0
- package/lib/GitHub/index.d.ts.map +1 -1
- package/lib/GitHub/index.js +2 -0
- package/lib/GitHub/index.js.map +1 -1
- package/package.json +4 -4
- package/src/Cloudflare/ApiToken/AccountApiToken.ts +21 -11
- package/src/Cloudflare/ApiToken/Common.ts +6 -1
- package/src/Cloudflare/ApiToken/UserApiToken.ts +6 -8
- package/src/Cloudflare/Artifacts/Artifacts.ts +139 -0
- package/src/Cloudflare/Artifacts/ArtifactsBinding.ts +188 -0
- package/src/Cloudflare/Artifacts/index.ts +2 -0
- package/src/Cloudflare/Providers.ts +3 -0
- package/src/Cloudflare/Workers/InferEnv.ts +5 -4
- package/src/Cloudflare/Workers/Worker.ts +12 -1
- package/src/Cloudflare/index.ts +1 -0
- package/src/GitHub/AuthProvider.ts +309 -0
- package/src/GitHub/Credentials.ts +99 -0
- package/src/GitHub/Providers.ts +23 -3
- package/src/GitHub/Secret.ts +22 -24
- package/src/GitHub/Variable.ts +16 -23
- package/src/GitHub/index.ts +2 -0
package/lib/GitHub/Secret.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import * as Redacted from "effect/Redacted";
|
|
2
2
|
import * as Provider from "../Provider.ts";
|
|
3
3
|
import { Resource } from "../Resource.ts";
|
|
4
|
+
import { GitHubCredentials } from "./Credentials.ts";
|
|
5
|
+
import type { Providers } from "./Providers.ts";
|
|
4
6
|
export interface SecretProps {
|
|
5
7
|
/**
|
|
6
8
|
* Repository owner (user or organization).
|
|
@@ -24,18 +26,13 @@ export interface SecretProps {
|
|
|
24
26
|
* GitHub Actions environment instead of the whole repository.
|
|
25
27
|
*/
|
|
26
28
|
environment?: string;
|
|
27
|
-
/**
|
|
28
|
-
* GitHub API token. If not provided, falls back to
|
|
29
|
-
* `GITHUB_ACCESS_TOKEN` or `GITHUB_TOKEN` environment variables.
|
|
30
|
-
*/
|
|
31
|
-
token?: string;
|
|
32
29
|
}
|
|
33
30
|
export interface Secret extends Resource<"GitHub.Secret", SecretProps, {
|
|
34
31
|
/**
|
|
35
32
|
* ISO-8601 timestamp of the last update.
|
|
36
33
|
*/
|
|
37
34
|
updatedAt: string;
|
|
38
|
-
}> {
|
|
35
|
+
}, never, Providers> {
|
|
39
36
|
}
|
|
40
37
|
/**
|
|
41
38
|
* A GitHub Actions repository or environment secret.
|
|
@@ -45,9 +42,10 @@ export interface Secret extends Resource<"GitHub.Secret", SecretProps, {
|
|
|
45
42
|
* key via `libsodium` before being stored. The resource is idempotent —
|
|
46
43
|
* calling it with the same name will update the secret value in place.
|
|
47
44
|
*
|
|
48
|
-
* Authentication is resolved
|
|
49
|
-
* `
|
|
50
|
-
* `
|
|
45
|
+
* Authentication is resolved via the `GitHubCredentials` service supplied
|
|
46
|
+
* by `GitHub.providers()` (which uses the Alchemy AuthProvider — env,
|
|
47
|
+
* stored PAT, `gh` CLI, or OAuth). The token needs `repo` scope for
|
|
48
|
+
* private repositories or `public_repo` for public ones.
|
|
51
49
|
*
|
|
52
50
|
* @section Repository Secrets
|
|
53
51
|
* Store secrets accessible to all GitHub Actions workflows in the
|
|
@@ -116,5 +114,5 @@ export interface Secret extends Resource<"GitHub.Secret", SecretProps, {
|
|
|
116
114
|
* ```
|
|
117
115
|
*/
|
|
118
116
|
export declare const Secret: import("../Resource.ts").ResourceClass<Secret>;
|
|
119
|
-
export declare const SecretProvider: () => import("effect/Layer").Layer<Provider.Provider<Secret>, never,
|
|
117
|
+
export declare const SecretProvider: () => import("effect/Layer").Layer<Provider.Provider<Secret>, never, GitHubCredentials>;
|
|
120
118
|
//# sourceMappingURL=Secret.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Secret.d.ts","sourceRoot":"","sources":["../../src/GitHub/Secret.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,QAAQ,MAAM,iBAAiB,CAAC;AAC5C,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"Secret.d.ts","sourceRoot":"","sources":["../../src/GitHub/Secret.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,QAAQ,MAAM,iBAAiB,CAAC;AAC5C,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD,MAAM,WAAW,WAAW;IAC1B;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;;OAGG;IACH,KAAK,EAAE,QAAQ,CAAC,QAAQ,CAAC;IAEzB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,MAAO,SAAQ,QAAQ,CACtC,eAAe,EACf,WAAW,EACX;IACE;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;CACnB,EACD,KAAK,EACL,SAAS,CACV;CAAG;AAEJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8EG;AACH,eAAO,MAAM,MAAM,gDAAoC,CAAC;AAuBxD,eAAO,MAAM,cAAc,yFAyBvB,CAAC"}
|
package/lib/GitHub/Secret.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { Octokit } from "@octokit/rest";
|
|
2
1
|
import * as Effect from "effect/Effect";
|
|
3
2
|
import * as Redacted from "effect/Redacted";
|
|
4
3
|
import * as Provider from "../Provider.js";
|
|
5
4
|
import { Resource } from "../Resource.js";
|
|
5
|
+
import { GitHubCredentials } from "./Credentials.js";
|
|
6
6
|
/**
|
|
7
7
|
* A GitHub Actions repository or environment secret.
|
|
8
8
|
*
|
|
@@ -11,9 +11,10 @@ import { Resource } from "../Resource.js";
|
|
|
11
11
|
* key via `libsodium` before being stored. The resource is idempotent —
|
|
12
12
|
* calling it with the same name will update the secret value in place.
|
|
13
13
|
*
|
|
14
|
-
* Authentication is resolved
|
|
15
|
-
* `
|
|
16
|
-
* `
|
|
14
|
+
* Authentication is resolved via the `GitHubCredentials` service supplied
|
|
15
|
+
* by `GitHub.providers()` (which uses the Alchemy AuthProvider — env,
|
|
16
|
+
* stored PAT, `gh` CLI, or OAuth). The token needs `repo` scope for
|
|
17
|
+
* private repositories or `public_repo` for public ones.
|
|
17
18
|
*
|
|
18
19
|
* @section Repository Secrets
|
|
19
20
|
* Store secrets accessible to all GitHub Actions workflows in the
|
|
@@ -82,14 +83,15 @@ import { Resource } from "../Resource.js";
|
|
|
82
83
|
* ```
|
|
83
84
|
*/
|
|
84
85
|
export const Secret = Resource("GitHub.Secret");
|
|
85
|
-
function
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
return new Octokit({ auth: resolveToken(props) });
|
|
90
|
-
}
|
|
86
|
+
const getOctokit = Effect.gen(function* () {
|
|
87
|
+
const creds = yield* GitHubCredentials;
|
|
88
|
+
return creds.octokit();
|
|
89
|
+
});
|
|
91
90
|
async function encryptValue(plaintext, publicKey) {
|
|
92
|
-
const
|
|
91
|
+
const mod = await import("libsodium-wrappers");
|
|
92
|
+
// Bun/ESM interop: the actual sodium API lives on `.default` when the
|
|
93
|
+
// CJS module is wrapped, but is the module itself under other loaders.
|
|
94
|
+
const sodium = mod.default ?? mod;
|
|
93
95
|
await sodium.ready;
|
|
94
96
|
const binKey = sodium.from_base64(publicKey, sodium.base64_variants.ORIGINAL);
|
|
95
97
|
const binMessage = sodium.from_string(plaintext);
|
|
@@ -98,12 +100,12 @@ async function encryptValue(plaintext, publicKey) {
|
|
|
98
100
|
}
|
|
99
101
|
export const SecretProvider = () => Provider.succeed(Secret, {
|
|
100
102
|
create: Effect.fn(function* ({ news }) {
|
|
101
|
-
const octokit =
|
|
103
|
+
const octokit = yield* getOctokit;
|
|
102
104
|
yield* upsertSecret(octokit, news);
|
|
103
105
|
return { updatedAt: new Date().toISOString() };
|
|
104
106
|
}),
|
|
105
107
|
update: Effect.fn(function* ({ news, olds }) {
|
|
106
|
-
const octokit =
|
|
108
|
+
const octokit = yield* getOctokit;
|
|
107
109
|
const wasEnv = !!olds.environment;
|
|
108
110
|
const isEnv = !!news.environment;
|
|
109
111
|
if (wasEnv !== isEnv || olds.environment !== news.environment) {
|
|
@@ -113,7 +115,7 @@ export const SecretProvider = () => Provider.succeed(Secret, {
|
|
|
113
115
|
return { updatedAt: new Date().toISOString() };
|
|
114
116
|
}),
|
|
115
117
|
delete: Effect.fn(function* ({ olds }) {
|
|
116
|
-
const octokit =
|
|
118
|
+
const octokit = yield* getOctokit;
|
|
117
119
|
yield* deleteSecret(octokit, olds);
|
|
118
120
|
}),
|
|
119
121
|
});
|
package/lib/GitHub/Secret.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Secret.js","sourceRoot":"","sources":["../../src/GitHub/Secret.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Secret.js","sourceRoot":"","sources":["../../src/GitHub/Secret.ts"],"names":[],"mappings":"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"}
|
package/lib/GitHub/Variable.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import * as Provider from "../Provider.ts";
|
|
2
2
|
import { Resource } from "../Resource.ts";
|
|
3
|
+
import { GitHubCredentials } from "./Credentials.ts";
|
|
4
|
+
import type { Providers } from "./Providers.ts";
|
|
3
5
|
export interface VariableProps {
|
|
4
6
|
/**
|
|
5
7
|
* Repository owner (user or organization).
|
|
@@ -17,18 +19,13 @@ export interface VariableProps {
|
|
|
17
19
|
* Variable value.
|
|
18
20
|
*/
|
|
19
21
|
value: string;
|
|
20
|
-
/**
|
|
21
|
-
* GitHub API token. If not provided, falls back to
|
|
22
|
-
* `GITHUB_ACCESS_TOKEN` or `GITHUB_TOKEN` environment variables.
|
|
23
|
-
*/
|
|
24
|
-
token?: string;
|
|
25
22
|
}
|
|
26
23
|
export interface Variable extends Resource<"GitHub.Variable", VariableProps, {
|
|
27
24
|
/**
|
|
28
25
|
* ISO-8601 timestamp of the last update.
|
|
29
26
|
*/
|
|
30
27
|
updatedAt: string;
|
|
31
|
-
}> {
|
|
28
|
+
}, never, Providers> {
|
|
32
29
|
}
|
|
33
30
|
/**
|
|
34
31
|
* A GitHub Actions repository variable.
|
|
@@ -39,9 +36,10 @@ export interface Variable extends Resource<"GitHub.Variable", VariableProps, {
|
|
|
39
36
|
* labels, or feature flags. For sensitive values, use `GitHub.Secret`
|
|
40
37
|
* instead.
|
|
41
38
|
*
|
|
42
|
-
* Authentication is resolved
|
|
43
|
-
* `
|
|
44
|
-
* `
|
|
39
|
+
* Authentication is resolved via the `GitHubCredentials` service supplied
|
|
40
|
+
* by `GitHub.providers()` (which uses the Alchemy AuthProvider — env,
|
|
41
|
+
* stored PAT, `gh` CLI, or OAuth). The token needs `repo` scope for
|
|
42
|
+
* private repositories or `public_repo` for public ones.
|
|
45
43
|
*
|
|
46
44
|
* @section Repository Variables
|
|
47
45
|
* Store variables accessible to all GitHub Actions workflows in the
|
|
@@ -91,5 +89,5 @@ export interface Variable extends Resource<"GitHub.Variable", VariableProps, {
|
|
|
91
89
|
* ```
|
|
92
90
|
*/
|
|
93
91
|
export declare const Variable: import("../Resource.ts").ResourceClass<Variable>;
|
|
94
|
-
export declare const VariableProvider: () => import("effect/Layer").Layer<Provider.Provider<Variable>, never,
|
|
92
|
+
export declare const VariableProvider: () => import("effect/Layer").Layer<Provider.Provider<Variable>, never, GitHubCredentials>;
|
|
95
93
|
//# sourceMappingURL=Variable.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Variable.d.ts","sourceRoot":"","sources":["../../src/GitHub/Variable.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Variable.d.ts","sourceRoot":"","sources":["../../src/GitHub/Variable.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD,MAAM,WAAW,aAAa;IAC5B;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,QAAS,SAAQ,QAAQ,CACxC,iBAAiB,EACjB,aAAa,EACb;IACE;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;CACnB,EACD,KAAK,EACL,SAAS,CACV;CAAG;AAEJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4DG;AACH,eAAO,MAAM,QAAQ,kDAAwC,CAAC;AAO9D,eAAO,MAAM,gBAAgB,2FAiDzB,CAAC"}
|
package/lib/GitHub/Variable.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Octokit } from "@octokit/rest";
|
|
2
1
|
import * as Effect from "effect/Effect";
|
|
3
2
|
import * as Provider from "../Provider.js";
|
|
4
3
|
import { Resource } from "../Resource.js";
|
|
4
|
+
import { GitHubCredentials } from "./Credentials.js";
|
|
5
5
|
/**
|
|
6
6
|
* A GitHub Actions repository variable.
|
|
7
7
|
*
|
|
@@ -11,9 +11,10 @@ import { Resource } from "../Resource.js";
|
|
|
11
11
|
* labels, or feature flags. For sensitive values, use `GitHub.Secret`
|
|
12
12
|
* instead.
|
|
13
13
|
*
|
|
14
|
-
* Authentication is resolved
|
|
15
|
-
* `
|
|
16
|
-
* `
|
|
14
|
+
* Authentication is resolved via the `GitHubCredentials` service supplied
|
|
15
|
+
* by `GitHub.providers()` (which uses the Alchemy AuthProvider — env,
|
|
16
|
+
* stored PAT, `gh` CLI, or OAuth). The token needs `repo` scope for
|
|
17
|
+
* private repositories or `public_repo` for public ones.
|
|
17
18
|
*
|
|
18
19
|
* @section Repository Variables
|
|
19
20
|
* Store variables accessible to all GitHub Actions workflows in the
|
|
@@ -63,15 +64,13 @@ import { Resource } from "../Resource.js";
|
|
|
63
64
|
* ```
|
|
64
65
|
*/
|
|
65
66
|
export const Variable = Resource("GitHub.Variable");
|
|
66
|
-
function
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
return new Octokit({ auth: resolveToken(props) });
|
|
71
|
-
}
|
|
67
|
+
const getOctokit = Effect.gen(function* () {
|
|
68
|
+
const creds = yield* GitHubCredentials;
|
|
69
|
+
return creds.octokit();
|
|
70
|
+
});
|
|
72
71
|
export const VariableProvider = () => Provider.succeed(Variable, {
|
|
73
72
|
create: Effect.fn(function* ({ news }) {
|
|
74
|
-
const octokit =
|
|
73
|
+
const octokit = yield* getOctokit;
|
|
75
74
|
yield* Effect.tryPromise(() => octokit.rest.actions.createRepoVariable({
|
|
76
75
|
owner: news.owner,
|
|
77
76
|
repo: news.repository,
|
|
@@ -81,7 +80,7 @@ export const VariableProvider = () => Provider.succeed(Variable, {
|
|
|
81
80
|
return { updatedAt: new Date().toISOString() };
|
|
82
81
|
}),
|
|
83
82
|
update: Effect.fn(function* ({ news }) {
|
|
84
|
-
const octokit =
|
|
83
|
+
const octokit = yield* getOctokit;
|
|
85
84
|
yield* Effect.tryPromise(() => octokit.rest.actions.updateRepoVariable({
|
|
86
85
|
owner: news.owner,
|
|
87
86
|
repo: news.repository,
|
|
@@ -91,7 +90,7 @@ export const VariableProvider = () => Provider.succeed(Variable, {
|
|
|
91
90
|
return { updatedAt: new Date().toISOString() };
|
|
92
91
|
}),
|
|
93
92
|
delete: Effect.fn(function* ({ olds }) {
|
|
94
|
-
const octokit =
|
|
93
|
+
const octokit = yield* getOctokit;
|
|
95
94
|
yield* Effect.tryPromise(async () => {
|
|
96
95
|
try {
|
|
97
96
|
await octokit.rest.actions.deleteRepoVariable({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Variable.js","sourceRoot":"","sources":["../../src/GitHub/Variable.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"Variable.js","sourceRoot":"","sources":["../../src/GitHub/Variable.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAsCrD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4DG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,QAAQ,CAAW,iBAAiB,CAAC,CAAC;AAE9D,MAAM,UAAU,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IACrC,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,iBAAiB,CAAC;IACvC,OAAO,KAAK,CAAC,OAAO,EAAE,CAAC;AACzB,CAAC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAG,EAAE,CACnC,QAAQ,CAAC,OAAO,CAAC,QAAQ,EAAE;IACzB,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,EAAE,IAAI,EAAE;QACnC,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,UAAU,CAAC;QAElC,KAAK,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAC5B,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC;YACtC,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,IAAI,EAAE,IAAI,CAAC,UAAU;YACrB,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,KAAK,EAAE,IAAI,CAAC,KAAK;SAClB,CAAC,CACH,CAAC;QAEF,OAAO,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;IACjD,CAAC,CAAC;IAEF,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,EAAE,IAAI,EAAE;QACnC,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,UAAU,CAAC;QAElC,KAAK,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAC5B,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC;YACtC,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,IAAI,EAAE,IAAI,CAAC,UAAU;YACrB,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,KAAK,EAAE,IAAI,CAAC,KAAK;SAClB,CAAC,CACH,CAAC;QAEF,OAAO,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;IACjD,CAAC,CAAC;IAEF,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,EAAE,IAAI,EAAE;QACnC,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,UAAU,CAAC;QAElC,KAAK,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,IAAI,EAAE;YAClC,IAAI,CAAC;gBACH,MAAM,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC;oBAC5C,KAAK,EAAE,IAAI,CAAC,KAAK;oBACjB,IAAI,EAAE,IAAI,CAAC,UAAU;oBACrB,IAAI,EAAE,IAAI,CAAC,IAAI;iBAChB,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,KAAU,EAAE,CAAC;gBACpB,IAAI,KAAK,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;oBACzB,MAAM,KAAK,CAAC;gBACd,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;CACH,CAAC,CAAC"}
|
package/lib/GitHub/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/GitHub/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/GitHub/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,mBAAmB,CAAC;AAC1C,cAAc,cAAc,CAAC;AAC7B,OAAO,EAAE,iBAAiB,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACzE,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC"}
|
package/lib/GitHub/index.js
CHANGED
package/lib/GitHub/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/GitHub/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/GitHub/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,mBAAmB,CAAC;AAC1C,cAAc,cAAc,CAAC;AAC7B,OAAO,EAAE,iBAAiB,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACzE,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "alchemy",
|
|
3
|
-
"version": "2.0.0-beta.
|
|
3
|
+
"version": "2.0.0-beta.16",
|
|
4
4
|
"homepage": "https://alchemy.run",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Sam Goodwin <sam@alchemy.run>",
|
|
@@ -231,11 +231,11 @@
|
|
|
231
231
|
"@ai-sdk/provider": "^3.0.8",
|
|
232
232
|
"@aws-sdk/credential-providers": "^3.0.0",
|
|
233
233
|
"@clack/prompts": "^0.11.0",
|
|
234
|
-
"@distilled.cloud/aws": "^0.12.
|
|
235
|
-
"@distilled.cloud/cloudflare": "^0.12.
|
|
234
|
+
"@distilled.cloud/aws": "^0.12.5",
|
|
235
|
+
"@distilled.cloud/cloudflare": "^0.12.5",
|
|
236
236
|
"@distilled.cloud/cloudflare-rolldown-plugin": "0.3.0",
|
|
237
237
|
"@distilled.cloud/cloudflare-vite-plugin": "0.2.0",
|
|
238
|
-
"@distilled.cloud/core": "^0.12.
|
|
238
|
+
"@distilled.cloud/core": "^0.12.5",
|
|
239
239
|
"@effect/vitest": "4.0.0-beta.48",
|
|
240
240
|
"@libsql/client": "^0.17.0",
|
|
241
241
|
"@octokit/rest": "^22.0.1",
|
|
@@ -12,14 +12,12 @@ import {
|
|
|
12
12
|
conditionFingerprint,
|
|
13
13
|
policyFingerprint,
|
|
14
14
|
resolvePolicies,
|
|
15
|
-
type
|
|
15
|
+
type ApiTokenProps,
|
|
16
16
|
} from "./Common.ts";
|
|
17
17
|
|
|
18
|
-
export type AccountApiTokenProps = BaseApiTokenProps;
|
|
19
|
-
|
|
20
18
|
export type AccountApiToken = Resource<
|
|
21
19
|
"Cloudflare.AccountApiToken",
|
|
22
|
-
|
|
20
|
+
ApiTokenProps,
|
|
23
21
|
{
|
|
24
22
|
tokenId: string;
|
|
25
23
|
name: string;
|
|
@@ -87,7 +85,7 @@ export const AccountApiTokenProvider = () =>
|
|
|
87
85
|
Provider.effect(
|
|
88
86
|
AccountApiToken,
|
|
89
87
|
Effect.gen(function* () {
|
|
90
|
-
const { accountId } = yield* CloudflareEnvironment;
|
|
88
|
+
const { accountId: defaultAccountId } = yield* CloudflareEnvironment;
|
|
91
89
|
const createToken = yield* accounts.createToken;
|
|
92
90
|
const updateToken = yield* accounts.updateToken;
|
|
93
91
|
const deleteToken = yield* accounts.deleteToken;
|
|
@@ -100,6 +98,7 @@ export const AccountApiTokenProvider = () =>
|
|
|
100
98
|
status?: "active" | "disabled" | "expired" | null;
|
|
101
99
|
},
|
|
102
100
|
value: Redacted.Redacted<string>,
|
|
101
|
+
accountId: string,
|
|
103
102
|
): AccountApiTokenAttributes => ({
|
|
104
103
|
tokenId: tokenData.id ?? "",
|
|
105
104
|
name: tokenData.name ?? "",
|
|
@@ -112,16 +111,19 @@ export const AccountApiTokenProvider = () =>
|
|
|
112
111
|
stables: ["tokenId", "accountId"],
|
|
113
112
|
diff: Effect.fn(function* ({ id, olds, news, output }) {
|
|
114
113
|
if (!isResolved(news)) return undefined;
|
|
115
|
-
|
|
114
|
+
const newAccountId = news.accountId ?? defaultAccountId;
|
|
115
|
+
const oldAccountId =
|
|
116
|
+
output?.accountId ?? olds?.accountId ?? defaultAccountId;
|
|
117
|
+
if (oldAccountId !== newAccountId) {
|
|
116
118
|
return { action: "replace" } as const;
|
|
117
119
|
}
|
|
118
120
|
const oldName = output?.name ?? (yield* resolveName(id, olds?.name));
|
|
119
121
|
const newName = yield* resolveName(id, news.name);
|
|
120
122
|
const oldPolicyFp = policyFingerprint(
|
|
121
|
-
resolvePolicies(olds?.policies ?? [],
|
|
123
|
+
resolvePolicies(olds?.policies ?? [], oldAccountId),
|
|
122
124
|
);
|
|
123
125
|
const newPolicyFp = policyFingerprint(
|
|
124
|
-
resolvePolicies(news.policies,
|
|
126
|
+
resolvePolicies(news.policies, newAccountId),
|
|
125
127
|
);
|
|
126
128
|
const oldCondFp = conditionFingerprint(olds?.condition);
|
|
127
129
|
const newCondFp = conditionFingerprint(news.condition);
|
|
@@ -136,6 +138,7 @@ export const AccountApiTokenProvider = () =>
|
|
|
136
138
|
}
|
|
137
139
|
}),
|
|
138
140
|
create: Effect.fn(function* ({ id, news }) {
|
|
141
|
+
const accountId = news.accountId ?? defaultAccountId;
|
|
139
142
|
const name = yield* resolveName(id, news.name);
|
|
140
143
|
const policies = resolvePolicies(news.policies, accountId);
|
|
141
144
|
const result = yield* createToken({
|
|
@@ -151,9 +154,14 @@ export const AccountApiTokenProvider = () =>
|
|
|
151
154
|
`Cloudflare did not return a value for token "${name}".`,
|
|
152
155
|
);
|
|
153
156
|
}
|
|
154
|
-
return buildAttributes(
|
|
157
|
+
return buildAttributes(
|
|
158
|
+
result,
|
|
159
|
+
Redacted.make(result.value),
|
|
160
|
+
accountId,
|
|
161
|
+
);
|
|
155
162
|
}),
|
|
156
163
|
update: Effect.fn(function* ({ id, news, output }) {
|
|
164
|
+
const accountId = news.accountId ?? defaultAccountId;
|
|
157
165
|
const name = yield* resolveName(id, news.name);
|
|
158
166
|
const policies = resolvePolicies(news.policies, accountId);
|
|
159
167
|
const result = yield* updateToken({
|
|
@@ -167,7 +175,7 @@ export const AccountApiTokenProvider = () =>
|
|
|
167
175
|
});
|
|
168
176
|
// Cloudflare doesn't return the value on update; preserve the
|
|
169
177
|
// value captured at creation.
|
|
170
|
-
return buildAttributes(result, output.value);
|
|
178
|
+
return buildAttributes(result, output.value, accountId);
|
|
171
179
|
}),
|
|
172
180
|
delete: Effect.fn(function* ({ output }) {
|
|
173
181
|
yield* deleteToken({
|
|
@@ -187,7 +195,9 @@ export const AccountApiTokenProvider = () =>
|
|
|
187
195
|
accountId: output.accountId,
|
|
188
196
|
tokenId: output.tokenId,
|
|
189
197
|
}).pipe(
|
|
190
|
-
Effect.map((token) =>
|
|
198
|
+
Effect.map((token) =>
|
|
199
|
+
buildAttributes(token, output.value, output.accountId),
|
|
200
|
+
),
|
|
191
201
|
Effect.catchTag("InvalidRoute", () => Effect.succeed(undefined)),
|
|
192
202
|
Effect.catchTag("TokenNotFound", () => Effect.succeed(undefined)),
|
|
193
203
|
);
|
|
@@ -41,12 +41,17 @@ export interface ApiTokenCondition {
|
|
|
41
41
|
};
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
export type
|
|
44
|
+
export type ApiTokenProps = {
|
|
45
45
|
/**
|
|
46
46
|
* Token name. Defaults to a generated physical name based on the
|
|
47
47
|
* resource's logical id, app name, and stage.
|
|
48
48
|
*/
|
|
49
49
|
name?: string;
|
|
50
|
+
/**
|
|
51
|
+
* The Cloudflare account ID that owns this token. Defaults to the
|
|
52
|
+
* account ID resolved from the ambient {@link CloudflareEnvironment}.
|
|
53
|
+
*/
|
|
54
|
+
accountId?: string;
|
|
50
55
|
/**
|
|
51
56
|
* Access policies attached to the token. At least one policy is required
|
|
52
57
|
* by Cloudflare.
|
|
@@ -11,14 +11,12 @@ import {
|
|
|
11
11
|
conditionFingerprint,
|
|
12
12
|
policyFingerprint,
|
|
13
13
|
resolvePolicies,
|
|
14
|
-
type
|
|
14
|
+
type ApiTokenProps,
|
|
15
15
|
} from "./Common.ts";
|
|
16
16
|
|
|
17
|
-
export type UserApiTokenProps = BaseApiTokenProps;
|
|
18
|
-
|
|
19
17
|
export type UserApiToken = Resource<
|
|
20
18
|
"Cloudflare.UserApiToken",
|
|
21
|
-
|
|
19
|
+
ApiTokenProps,
|
|
22
20
|
{
|
|
23
21
|
tokenId: string;
|
|
24
22
|
name: string;
|
|
@@ -102,10 +100,10 @@ export const UserApiTokenProvider = () =>
|
|
|
102
100
|
const oldName = output?.name ?? (yield* resolveName(id, olds?.name));
|
|
103
101
|
const newName = yield* resolveName(id, news.name);
|
|
104
102
|
const oldPolicyFp = policyFingerprint(
|
|
105
|
-
resolvePolicies(olds?.policies ?? [],
|
|
103
|
+
resolvePolicies(olds?.policies ?? [], olds?.accountId),
|
|
106
104
|
);
|
|
107
105
|
const newPolicyFp = policyFingerprint(
|
|
108
|
-
resolvePolicies(news.policies,
|
|
106
|
+
resolvePolicies(news.policies, news.accountId),
|
|
109
107
|
);
|
|
110
108
|
const oldCondFp = conditionFingerprint(olds?.condition);
|
|
111
109
|
const newCondFp = conditionFingerprint(news.condition);
|
|
@@ -121,7 +119,7 @@ export const UserApiTokenProvider = () =>
|
|
|
121
119
|
}),
|
|
122
120
|
create: Effect.fn(function* ({ id, news }) {
|
|
123
121
|
const name = yield* resolveName(id, news.name);
|
|
124
|
-
const policies = resolvePolicies(news.policies,
|
|
122
|
+
const policies = resolvePolicies(news.policies, news.accountId);
|
|
125
123
|
const result = yield* createToken({
|
|
126
124
|
name,
|
|
127
125
|
policies,
|
|
@@ -138,7 +136,7 @@ export const UserApiTokenProvider = () =>
|
|
|
138
136
|
}),
|
|
139
137
|
update: Effect.fn(function* ({ id, news, output }) {
|
|
140
138
|
const name = yield* resolveName(id, news.name);
|
|
141
|
-
const policies = resolvePolicies(news.policies,
|
|
139
|
+
const policies = resolvePolicies(news.policies, news.accountId);
|
|
142
140
|
const result = yield* updateToken({
|
|
143
141
|
tokenId: output.tokenId,
|
|
144
142
|
name,
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect";
|
|
2
|
+
import { Stack } from "../../Stack.ts";
|
|
3
|
+
import { Stage } from "../../Stage.ts";
|
|
4
|
+
import { ArtifactsBinding } from "./ArtifactsBinding.ts";
|
|
5
|
+
|
|
6
|
+
type ArtifactsTypeId = typeof ArtifactsTypeId;
|
|
7
|
+
const ArtifactsTypeId = "Cloudflare.Artifacts" as const;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Cloudflare validation: 3–63 chars, lowercase alphanumeric and hyphens, must
|
|
11
|
+
* start and end with a lowercase alphanumeric character.
|
|
12
|
+
*/
|
|
13
|
+
const ARTIFACTS_NAMESPACE_REGEX = /^[a-z0-9](?:[a-z0-9-]{1,61}[a-z0-9])?$/;
|
|
14
|
+
|
|
15
|
+
export class InvalidArtifactsNamespaceError extends Error {
|
|
16
|
+
readonly _tag = "InvalidArtifactsNamespaceError" as const;
|
|
17
|
+
constructor(public readonly namespace: string) {
|
|
18
|
+
super(
|
|
19
|
+
`Invalid artifacts namespace name '${namespace}'. Must be 3-63 characters, start and end with a lowercase alphanumeric character, and contain only lowercase alphanumeric characters and hyphens.`,
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export type ArtifactsProps = {
|
|
25
|
+
/**
|
|
26
|
+
* Cloudflare namespace name. Namespaces are implicit on Cloudflare — the
|
|
27
|
+
* first repo created against this name conjures the namespace.
|
|
28
|
+
*
|
|
29
|
+
* Must be 3–63 lowercase alphanumeric characters or hyphens, and must start
|
|
30
|
+
* and end with a lowercase alphanumeric character. If omitted, a unique
|
|
31
|
+
* physical name is generated from the resource's logical id, app, and stage.
|
|
32
|
+
*/
|
|
33
|
+
namespace?: string;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Marker for a Cloudflare Artifacts namespace binding.
|
|
38
|
+
*
|
|
39
|
+
* Artifacts namespaces are implicit (created on first repo write) and require
|
|
40
|
+
* no deploy-time provisioning, so this is a pure binding marker rather than
|
|
41
|
+
* a full Resource. The Worker provider sees this object in `bindings: { ... }`
|
|
42
|
+
* and emits the corresponding `{ type: "artifacts", name, namespace }` binding
|
|
43
|
+
* to the script.
|
|
44
|
+
*/
|
|
45
|
+
export type Artifacts = {
|
|
46
|
+
kind: ArtifactsTypeId;
|
|
47
|
+
name: string;
|
|
48
|
+
namespace: string;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export const isArtifacts = (value: unknown): value is Artifacts =>
|
|
52
|
+
typeof value === "object" &&
|
|
53
|
+
value !== null &&
|
|
54
|
+
"kind" in value &&
|
|
55
|
+
(value as Artifacts).kind === ArtifactsTypeId;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* A Cloudflare Artifacts namespace — the top-level container for Git-compatible
|
|
59
|
+
* versioned repositories. See the
|
|
60
|
+
* {@link https://blog.cloudflare.com/artifacts-git-for-agents-beta/ | Artifacts launch post}
|
|
61
|
+
* and {@link https://developers.cloudflare.com/artifacts/concepts/namespaces/ | Namespaces docs}.
|
|
62
|
+
*
|
|
63
|
+
* Namespaces on Cloudflare are **implicit**: there is no `POST /namespaces`
|
|
64
|
+
* endpoint. The namespace is conjured the first time a repo is created against
|
|
65
|
+
* it (either via the REST API or the Worker binding). Because of that, the
|
|
66
|
+
* Alchemy "resource" is a thin binding marker — there is nothing to provision
|
|
67
|
+
* at deploy time. Repos themselves are typically created at runtime through
|
|
68
|
+
* the bound `Artifacts` API.
|
|
69
|
+
*
|
|
70
|
+
* @section Declaring a Namespace
|
|
71
|
+
* @example Default namespace (a unique physical name is generated)
|
|
72
|
+
* ```typescript
|
|
73
|
+
* const Repos = Cloudflare.Artifacts("Repos");
|
|
74
|
+
* ```
|
|
75
|
+
*
|
|
76
|
+
* @example Override the namespace name (must be lowercase, 3–63 chars)
|
|
77
|
+
* ```typescript
|
|
78
|
+
* const Repos = Cloudflare.Artifacts("Repos", { namespace: "starter-repos" });
|
|
79
|
+
* ```
|
|
80
|
+
*
|
|
81
|
+
* @section Binding to a Worker
|
|
82
|
+
* @example Wiring it into a Worker
|
|
83
|
+
* ```typescript
|
|
84
|
+
* export const Worker = Cloudflare.Worker("Worker", {
|
|
85
|
+
* main: "./src/worker.ts",
|
|
86
|
+
* bindings: { Repos },
|
|
87
|
+
* });
|
|
88
|
+
*
|
|
89
|
+
* export type WorkerEnv = Cloudflare.InferEnv<typeof Worker>;
|
|
90
|
+
* // { Repos: Artifacts }
|
|
91
|
+
* ```
|
|
92
|
+
*
|
|
93
|
+
* @example Async-style worker
|
|
94
|
+
* ```typescript
|
|
95
|
+
* export default {
|
|
96
|
+
* async fetch(request: Request, env: WorkerEnv) {
|
|
97
|
+
* const repo = await env.Repos.create("starter-repo");
|
|
98
|
+
* return Response.json({ remote: repo.remote, token: repo.token });
|
|
99
|
+
* },
|
|
100
|
+
* };
|
|
101
|
+
* ```
|
|
102
|
+
*
|
|
103
|
+
* @example Effect-style worker
|
|
104
|
+
* ```typescript
|
|
105
|
+
* const artifacts = yield* Cloudflare.Artifacts.bind(Repos);
|
|
106
|
+
* const repo = yield* artifacts.create("starter-repo", {
|
|
107
|
+
* setDefaultBranch: "main",
|
|
108
|
+
* });
|
|
109
|
+
* ```
|
|
110
|
+
*/
|
|
111
|
+
export const Artifacts: {
|
|
112
|
+
(
|
|
113
|
+
name: string,
|
|
114
|
+
props?: ArtifactsProps,
|
|
115
|
+
): Effect.Effect<Artifacts, never, Stack | Stage>;
|
|
116
|
+
/**
|
|
117
|
+
* Bind a Cloudflare Artifacts namespace to the surrounding Worker, returning
|
|
118
|
+
* an Effect-native client. See {@link ArtifactsBinding}.
|
|
119
|
+
*/
|
|
120
|
+
bind: typeof ArtifactsBinding.bind;
|
|
121
|
+
} = Object.assign(
|
|
122
|
+
Effect.fn(function* (name: string, props?: ArtifactsProps) {
|
|
123
|
+
const namespace = props?.namespace
|
|
124
|
+
? props.namespace
|
|
125
|
+
: name.toLocaleLowerCase();
|
|
126
|
+
if (!ARTIFACTS_NAMESPACE_REGEX.test(namespace)) {
|
|
127
|
+
return yield* Effect.die(new InvalidArtifactsNamespaceError(namespace));
|
|
128
|
+
}
|
|
129
|
+
return {
|
|
130
|
+
kind: ArtifactsTypeId,
|
|
131
|
+
name,
|
|
132
|
+
namespace,
|
|
133
|
+
} satisfies Artifacts;
|
|
134
|
+
}),
|
|
135
|
+
{
|
|
136
|
+
bind: (...args: Parameters<typeof ArtifactsBinding.bind>) =>
|
|
137
|
+
ArtifactsBinding.bind(...args),
|
|
138
|
+
},
|
|
139
|
+
);
|