effect-cf 0.26.0 → 0.28.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/CHANGELOG.md +16 -0
- package/README.md +8 -6
- package/dist/{Artifacts-DcoXcRP5.d.mts → Artifacts-DnHQA-Ax.d.mts} +42 -25
- package/dist/Artifacts-rq3hUKQE.mjs +257 -0
- package/dist/{Binding-COCtoJXa.d.mts → Binding-xJJJPmiD.d.mts} +6 -5
- package/dist/ComputerArtifacts.d.mts +55 -0
- package/dist/ComputerArtifacts.mjs +95 -0
- package/dist/ComputerWorkspace.d.mts +279 -0
- package/dist/ComputerWorkspace.mjs +577 -0
- package/dist/ComputerWorkspaceHost.d.mts +1 -1
- package/dist/ComputerWorkspaceHost.mjs +18 -16
- package/dist/{WorkflowBinding-D5iWzCUa.d.mts → DurableObjectState-B3uFY1eM.d.mts} +90 -141
- package/dist/{DurableObjectState-CEh0DVw7.mjs → DurableObjectState-BjkK2kwH.mjs} +4 -49
- package/dist/ErrorMessage-BM0K-Nik.mjs +46 -0
- package/dist/{Hyperdrive-6p59yyVk.d.mts → Hyperdrive-z-9fFz15.d.mts} +2 -2
- package/dist/HyperdrivePg.d.mts +2 -2
- package/dist/Vitest.d.mts +6 -4
- package/dist/Vitest.mjs +2 -1
- package/dist/WorkflowBinding-wZ-yGHow.d.mts +74 -0
- package/dist/index.d.mts +92 -398
- package/dist/index.mjs +323 -1105
- package/package.json +12 -1
- package/src/AiGateway.ts +62 -7
- package/src/AnalyticsEngine.ts +17 -13
- package/src/Artifacts.ts +111 -47
- package/src/Binding.ts +34 -23
- package/src/BrowserRendering.ts +72 -33
- package/src/CloudflareOtlp.ts +8 -5
- package/src/ComputerArtifacts.ts +17 -9
- package/src/ComputerWorkspace.ts +202 -98
- package/src/ComputerWorkspaceHost.ts +55 -27
- package/src/ContainerNamespace.ts +8 -9
- package/src/D1.ts +8 -14
- package/src/DurableObject.ts +27 -11
- package/src/DurableObjectAlarm.ts +17 -5
- package/src/DurableObjectDefinition.ts +89 -72
- package/src/DurableObjectNamespace.ts +26 -12
- package/src/DurableObjectRpcWebSocket.ts +9 -10
- package/src/DurableObjectState.ts +1 -0
- package/src/DurableObjectStorage.ts +5 -2
- package/src/DurableObjectWebSocket.ts +4 -1
- package/src/Email.ts +26 -25
- package/src/Hyperdrive.ts +4 -10
- package/src/Images.ts +12 -14
- package/src/Kv.ts +15 -17
- package/src/Queue.ts +2 -1
- package/src/QueueBinding.ts +7 -12
- package/src/QueueDefinition.ts +7 -2
- package/src/R2.ts +33 -24
- package/src/Rpc.ts +15 -21
- package/src/RpcDefinition.ts +33 -38
- package/src/ServiceBinding.ts +26 -8
- package/src/Vectorize.ts +45 -18
- package/src/Vitest.ts +9 -3
- package/src/WebTransport.ts +11 -5
- package/src/Worker.ts +91 -21
- package/src/WorkerDefinition.ts +143 -63
- package/src/WorkersAi.ts +50 -28
- package/src/Workflow.ts +66 -13
- package/src/WorkflowBinding.ts +18 -25
- package/src/WorkflowDefinition.ts +4 -2
- package/src/index.ts +0 -2
- package/src/internal/Entrypoint.ts +29 -13
- package/src/internal/ErrorMessage.ts +7 -6
- package/src/internal/RpcInvocation.ts +34 -11
- package/src/internal/Runtime.ts +33 -22
- package/src/internal/WorkerContext.ts +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# effect-cf
|
|
2
2
|
|
|
3
|
+
## 0.28.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#104](https://github.com/danieljvdm/effect-cf/pull/104) [`4aadbd0`](https://github.com/danieljvdm/effect-cf/commit/4aadbd0b6e76449bac190dbc5abb4c20486c8761) Thanks [@danieljvdm](https://github.com/danieljvdm)! - Allow workflow step Effects to fail terminally with `WorkflowStepNonRetryableError`, which is rethrown to Cloudflare as its native `NonRetryableError`.
|
|
8
|
+
|
|
9
|
+
- [#104](https://github.com/danieljvdm/effect-cf/pull/104) [`4aadbd0`](https://github.com/danieljvdm/effect-cf/commit/4aadbd0b6e76449bac190dbc5abb4c20486c8761) Thanks [@danieljvdm](https://github.com/danieljvdm)! - Support method-only remote Artifacts repository bindings with a typed `info()` client operation and live commit history shapes.
|
|
10
|
+
|
|
11
|
+
- [#102](https://github.com/danieljvdm/effect-cf/pull/102) [`1b32c54`](https://github.com/danieljvdm/effect-cf/commit/1b32c54757bf404c2454389b0386e0996974cdc6) Thanks [@danieljvdm](https://github.com/danieljvdm)! - Harden Cloudflare and WebTransport runtime boundaries with receiver-safe invocation, truthful return types, validated external data, and stricter event-layer requirements.
|
|
12
|
+
|
|
13
|
+
## 0.27.0
|
|
14
|
+
|
|
15
|
+
### Minor Changes
|
|
16
|
+
|
|
17
|
+
- [#99](https://github.com/danieljvdm/effect-cf/pull/99) [`5195812`](https://github.com/danieljvdm/effect-cf/commit/519581205c3d3b63e977515f2a33db989a5c9875) Thanks [@danieljvdm](https://github.com/danieljvdm)! - Keep the optional `@cloudflare/computer` integration out of the root bundle so Durable Object and other unrelated consumers can bundle `effect-cf` without installing or externalizing that peer. The synchronous root namespaces could not be preserved without making esbuild resolve the optional dependency before tree-shaking, so update `ComputerWorkspace` imports to `effect-cf/computer-workspace` and `ComputerArtifacts` imports to `effect-cf/computer-artifacts`; `effect-cf/computer-workspace-host` remains unchanged.
|
|
18
|
+
|
|
3
19
|
## 0.26.0
|
|
4
20
|
|
|
5
21
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -19,8 +19,8 @@ npm install effect-cf "effect@^4.0.0-beta.105"
|
|
|
19
19
|
```
|
|
20
20
|
|
|
21
21
|
The Computer workspace integration is an optional peer. Install it only in
|
|
22
|
-
applications that import `
|
|
23
|
-
`effect-cf/computer-workspace-host`:
|
|
22
|
+
applications that import `effect-cf/computer-workspace`,
|
|
23
|
+
`effect-cf/computer-artifacts`, or `effect-cf/computer-workspace-host`:
|
|
24
24
|
|
|
25
25
|
```bash
|
|
26
26
|
bun add "@cloudflare/computer@^0.2.0"
|
|
@@ -51,8 +51,8 @@ Runtime creation belongs at Cloudflare entrypoints, not inside binding helpers.
|
|
|
51
51
|
- `D1` - typed D1 database binding helper with an `@effect/sql-d1` backed SQL layer
|
|
52
52
|
- `R2` - typed R2 bucket binding helper with Effect-wrapped object and multipart operations
|
|
53
53
|
- `Artifacts` - typed Cloudflare Artifacts namespace and repository helpers, including repository lifecycle, tokens, and Git object reads
|
|
54
|
-
- `
|
|
55
|
-
- `
|
|
54
|
+
- `effect-cf/computer-workspace` - scoped Effect wrappers for the complete Cloudflare Computer filesystem, Git, runtime, Assets, Artifacts, and Think-compatible client surfaces
|
|
55
|
+
- `effect-cf/computer-artifacts` - session-isolated Artifacts repositories backed by `@cloudflare/computer/artifacts`
|
|
56
56
|
- `effect-cf/computer-workspace-host` - optional Durable Object host mixin, worker-shell backend wiring, and `WorkspaceServiceProxy`
|
|
57
57
|
- `Hyperdrive` - typed Hyperdrive binding helper for connection strings and optional Postgres SQL integration
|
|
58
58
|
- `Images` - typed Cloudflare Images binding helper with transformation APIs and optional hosted image operations
|
|
@@ -473,7 +473,8 @@ scope closes. The host mixin is a separate optional-dependency entrypoint:
|
|
|
473
473
|
```ts
|
|
474
474
|
import shellCurl from "@cloudflare/computer/shell/curl";
|
|
475
475
|
import { Effect, Schema as S } from "effect";
|
|
476
|
-
import {
|
|
476
|
+
import { DurableObjectDefinition } from "effect-cf";
|
|
477
|
+
import * as ComputerWorkspace from "effect-cf/computer-workspace";
|
|
477
478
|
import { withComputerWorkspace, WorkspaceServiceProxy } from "effect-cf/computer-workspace-host";
|
|
478
479
|
|
|
479
480
|
export { WorkspaceServiceProxy };
|
|
@@ -561,7 +562,8 @@ Workers can use that session isolation without a Durable Object or workspace:
|
|
|
561
562
|
|
|
562
563
|
```ts
|
|
563
564
|
import { Effect } from "effect";
|
|
564
|
-
import { Artifacts
|
|
565
|
+
import { Artifacts } from "effect-cf";
|
|
566
|
+
import * as ComputerArtifacts from "effect-cf/computer-artifacts";
|
|
565
567
|
|
|
566
568
|
export const createSessionRepo = (binding: Artifacts.ArtifactsBinding, sessionId: string) =>
|
|
567
569
|
Effect.gen(function* () {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { c as WorkerEnvironment, r as BindingValidationError, t as BindingNotFoundError } from "./Binding-
|
|
1
|
+
import { c as WorkerEnvironment, r as BindingValidationError, t as BindingNotFoundError } from "./Binding-xJJJPmiD.mjs";
|
|
2
2
|
import { Context, Effect, Layer } from "effect";
|
|
3
3
|
declare namespace Artifacts_d_exports {
|
|
4
|
-
export { ArtifactsBinding, ArtifactsClient, ArtifactsCommit, ArtifactsCreateOptions, ArtifactsCreateRepoResult, ArtifactsCreateTokenResult, ArtifactsDefinition, ArtifactsErrorCode, ArtifactsForkOptions, ArtifactsImportParams, ArtifactsImportSource, ArtifactsImportTarget, ArtifactsImportTargetOptions, ArtifactsListOptions, ArtifactsLogOptions, ArtifactsLogResult, ArtifactsOperation, ArtifactsOperationError, ArtifactsRepoBinding, ArtifactsRepoClient, ArtifactsRepoInfo, ArtifactsRepoListEntry, ArtifactsRepoListResult, ArtifactsRepoStatus, ArtifactsService, ArtifactsTokenInfo, ArtifactsTokenListResult, ArtifactsTokenScope, ArtifactsTokenState, ArtifactsTree, Cursor, LayerOptions, RepoName, Tag, TagClass, artifactsErrorCodes, artifactsErrorNumericCodes, isArtifactsBinding, isArtifactsRepoBinding, layer, make, makeClient };
|
|
4
|
+
export { ArtifactsBinding, ArtifactsClient, ArtifactsCommit, ArtifactsCommitIdentity, ArtifactsCreateOptions, ArtifactsCreateRepoResult, ArtifactsCreateTokenResult, ArtifactsDefinition, ArtifactsErrorCode, ArtifactsForkOptions, ArtifactsImportParams, ArtifactsImportSource, ArtifactsImportTarget, ArtifactsImportTargetOptions, ArtifactsListOptions, ArtifactsLogOptions, ArtifactsLogResult, ArtifactsOperation, ArtifactsOperationError, ArtifactsRepoBinding, ArtifactsRepoClient, ArtifactsRepoInfo, ArtifactsRepoListEntry, ArtifactsRepoListResult, ArtifactsRepoStatus, ArtifactsService, ArtifactsTokenInfo, ArtifactsTokenListResult, ArtifactsTokenScope, ArtifactsTokenState, ArtifactsTree, Cursor, LayerOptions, RepoName, Tag, TagClass, artifactsErrorCodes, artifactsErrorNumericCodes, isArtifactsBinding, isArtifactsRepoBinding, layer, make, makeClient };
|
|
5
5
|
}
|
|
6
6
|
/** Artifacts operation represented by {@link ArtifactsOperationError}. */
|
|
7
|
-
type ArtifactsOperation = "createClient" | "create" | "get" | "import" | "list" | "delete" | "createToken" | "listTokens" | "getToken" | "revokeToken" | "fork" | "log" | "readCommit" | "readTree" | "cli";
|
|
7
|
+
type ArtifactsOperation = "createClient" | "create" | "get" | "import" | "list" | "delete" | "createToken" | "listTokens" | "getToken" | "revokeToken" | "fork" | "info" | "log" | "readCommit" | "readTree" | "cli";
|
|
8
8
|
/** Documented string error codes returned by Cloudflare Artifacts. */
|
|
9
9
|
declare const artifactsErrorCodes: readonly ["ALREADY_EXISTS", "NOT_FOUND", "IMPORT_IN_PROGRESS", "FORK_IN_PROGRESS", "INVALID_INPUT", "INVALID_REPO_NAME", "INVALID_TTL", "INVALID_URL", "REMOTE_AUTH_REQUIRED", "UPSTREAM_UNAVAILABLE", "MEMORY_LIMIT", "INTERNAL_ERROR"];
|
|
10
10
|
/** Documented numeric error codes returned by Cloudflare Artifacts. */
|
|
@@ -74,32 +74,34 @@ type ArtifactsCreateTokenResult = CloudflareArtifactsCreateTokenResult;
|
|
|
74
74
|
type ArtifactsTokenInfo = CloudflareArtifactsTokenInfo;
|
|
75
75
|
/** Repository token list result. */
|
|
76
76
|
type ArtifactsTokenListResult = CloudflareArtifactsTokenListResult;
|
|
77
|
-
/**
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
* publish its fields in the binding reference or Workers type declarations.
|
|
82
|
-
*/
|
|
83
|
-
interface ArtifactsLogResult {
|
|
84
|
-
readonly [field: string]: unknown;
|
|
77
|
+
/** Identity recorded for a Git commit author or committer. */
|
|
78
|
+
interface ArtifactsCommitIdentity {
|
|
79
|
+
readonly name: string;
|
|
80
|
+
readonly email: string;
|
|
85
81
|
}
|
|
86
|
-
/**
|
|
87
|
-
* Parsed Git commit returned by `readCommit()`.
|
|
88
|
-
*
|
|
89
|
-
* Cloudflare currently documents this generated type by name but does not
|
|
90
|
-
* publish its fields in the binding reference or Workers type declarations.
|
|
91
|
-
*/
|
|
82
|
+
/** Parsed Git commit returned by `readCommit()` and `log()`. */
|
|
92
83
|
interface ArtifactsCommit {
|
|
93
|
-
readonly
|
|
94
|
-
|
|
84
|
+
readonly hash: string;
|
|
85
|
+
readonly treeHash: string;
|
|
86
|
+
readonly message: string;
|
|
87
|
+
readonly author: ArtifactsCommitIdentity;
|
|
88
|
+
readonly committer: ArtifactsCommitIdentity;
|
|
89
|
+
readonly parents: ReadonlyArray<string>;
|
|
90
|
+
/** Unix timestamp in seconds. */
|
|
91
|
+
readonly authoredAt: number;
|
|
92
|
+
/** Unix timestamp in seconds. */
|
|
93
|
+
readonly committedAt: number;
|
|
94
|
+
}
|
|
95
|
+
/** Bare commit array returned by `log()`. */
|
|
96
|
+
type ArtifactsLogResult = ReadonlyArray<ArtifactsCommit>;
|
|
95
97
|
/**
|
|
96
98
|
* Parsed Git tree returned by `readTree()`.
|
|
97
99
|
*
|
|
98
100
|
* Cloudflare currently documents this generated type by name but does not
|
|
99
101
|
* publish its fields in the binding reference or Workers type declarations.
|
|
100
102
|
*/
|
|
101
|
-
interface ArtifactsTree {
|
|
102
|
-
readonly [field: string]:
|
|
103
|
+
interface ArtifactsTree<Field = unknown> {
|
|
104
|
+
readonly [field: string]: Field;
|
|
103
105
|
}
|
|
104
106
|
/** Options for `Artifacts.create()`. */
|
|
105
107
|
interface ArtifactsCreateOptions {
|
|
@@ -155,7 +157,15 @@ interface ArtifactsLogOptions {
|
|
|
155
157
|
readonly offset?: number;
|
|
156
158
|
}
|
|
157
159
|
/** Runtime repository handle, including methods absent from current shipped Workers types. */
|
|
158
|
-
interface ArtifactsRepoBinding extends ArtifactsRepoInfo {
|
|
160
|
+
interface ArtifactsRepoBinding extends Partial<ArtifactsRepoInfo> {
|
|
161
|
+
/**
|
|
162
|
+
* Read repository metadata.
|
|
163
|
+
*
|
|
164
|
+
* Remote bindings expose method-only RPC handles and provide metadata only
|
|
165
|
+
* through this method. It is optional solely for compatibility with older
|
|
166
|
+
* local handles that expose metadata as data properties.
|
|
167
|
+
*/
|
|
168
|
+
readonly info?: () => Promise<ArtifactsRepoInfo>;
|
|
159
169
|
/**
|
|
160
170
|
* Create a Git token for the repository.
|
|
161
171
|
*
|
|
@@ -178,8 +188,15 @@ interface ArtifactsBinding {
|
|
|
178
188
|
readonly list: (options?: ArtifactsListOptions) => Promise<ArtifactsRepoListResult>;
|
|
179
189
|
readonly delete: (name: RepoName) => Promise<boolean>;
|
|
180
190
|
}
|
|
181
|
-
/**
|
|
191
|
+
/**
|
|
192
|
+
* Effect wrapper around a repository handle returned by `Artifacts.get()`.
|
|
193
|
+
*
|
|
194
|
+
* The inherited metadata is the snapshot read while resolving the client.
|
|
195
|
+
* Use `info()` to refresh it from the repository handle.
|
|
196
|
+
*/
|
|
182
197
|
interface ArtifactsRepoClient extends ArtifactsRepoInfo {
|
|
198
|
+
/** Read and validate the repository's current metadata. */
|
|
199
|
+
readonly info: () => Effect.Effect<ArtifactsRepoInfo, ArtifactsOperationError>;
|
|
183
200
|
/**
|
|
184
201
|
* Create a Git token for the repository.
|
|
185
202
|
*
|
|
@@ -220,9 +237,9 @@ interface TagClass<Self, Id extends string> extends Context.ServiceClass<Self, I
|
|
|
220
237
|
readonly layer: (options: LayerOptions) => Layer.Layer<Self, BindingNotFoundError | BindingValidationError, WorkerEnvironment>;
|
|
221
238
|
}
|
|
222
239
|
/** Tests whether a value exposes the complete documented Artifacts repo handle API. */
|
|
223
|
-
declare const isArtifactsRepoBinding: (value:
|
|
240
|
+
declare const isArtifactsRepoBinding: <Candidate>(value: Candidate) => value is Candidate & ArtifactsRepoBinding;
|
|
224
241
|
/** Tests whether a value exposes the complete documented Artifacts namespace API. */
|
|
225
|
-
declare const isArtifactsBinding: (value:
|
|
242
|
+
declare const isArtifactsBinding: <Candidate>(value: Candidate) => value is Candidate & ArtifactsBinding;
|
|
226
243
|
declare const makeClient: (definition: ArtifactsDefinition) => (artifacts: ArtifactsBinding) => ArtifactsClient;
|
|
227
244
|
declare const layer: <Self>(tag: Context.Service<Self, ArtifactsClient>, definition: ArtifactsDefinition) => Layer.Layer<Self, BindingNotFoundError | BindingValidationError, WorkerEnvironment>;
|
|
228
245
|
declare const make: <Id extends string>(id: Id) => TagClass<ArtifactsService<Id>, Id>;
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
|
|
2
|
+
import { a as WorkerEnvironment, t as causeMessage } from "./ErrorMessage-BM0K-Nik.mjs";
|
|
3
|
+
import { Context, Data, Effect, Layer, Predicate, Schema } from "effect";
|
|
4
|
+
//#region src/Binding.ts
|
|
5
|
+
var Binding_exports = /* @__PURE__ */ __exportAll({
|
|
6
|
+
BindingNotFoundError: () => BindingNotFoundError,
|
|
7
|
+
BindingValidationError: () => BindingValidationError,
|
|
8
|
+
Service: () => Service,
|
|
9
|
+
TypeId: () => TypeId,
|
|
10
|
+
layer: () => layer$1
|
|
11
|
+
});
|
|
12
|
+
/** Internal type id marker used by binding helper services. */
|
|
13
|
+
const TypeId = "~effect-cf/Binding";
|
|
14
|
+
/** Error raised when a configured binding does not exist on `env`. */
|
|
15
|
+
var BindingNotFoundError = class extends Data.TaggedError("BindingNotFoundError") {};
|
|
16
|
+
/** Error raised when a binding exists but does not match the expected shape. */
|
|
17
|
+
var BindingValidationError = class extends Data.TaggedError("BindingValidationError") {};
|
|
18
|
+
const defaultExpected = "Cloudflare binding resource";
|
|
19
|
+
const isPropertyTarget = (value) => Predicate.isObjectOrArray(value) || Predicate.isFunction(value);
|
|
20
|
+
const getObjectName = (value) => {
|
|
21
|
+
const tag = (() => {
|
|
22
|
+
try {
|
|
23
|
+
return Object.prototype.toString.call(value).slice(8, -1);
|
|
24
|
+
} catch {
|
|
25
|
+
return Predicate.isFunction(value) ? "function" : "object";
|
|
26
|
+
}
|
|
27
|
+
})();
|
|
28
|
+
const constructorName = (() => {
|
|
29
|
+
try {
|
|
30
|
+
return "constructor" in value && Predicate.isFunction(value.constructor) && Predicate.isString(value.constructor.name) ? value.constructor.name : void 0;
|
|
31
|
+
} catch {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
})();
|
|
35
|
+
if (tag !== "Object") return tag;
|
|
36
|
+
if (constructorName !== void 0 && constructorName !== "" && constructorName !== "Object") return constructorName;
|
|
37
|
+
return tag;
|
|
38
|
+
};
|
|
39
|
+
const propertyNames = (value) => {
|
|
40
|
+
const names = /* @__PURE__ */ new Set();
|
|
41
|
+
for (const target of [value, Object.getPrototypeOf(value)]) {
|
|
42
|
+
if (target === null || target === Object.prototype || target === Function.prototype) continue;
|
|
43
|
+
try {
|
|
44
|
+
for (const name of Object.getOwnPropertyNames(target)) names.add(name);
|
|
45
|
+
} catch {
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return [...names].filter((name) => name !== "constructor").sort();
|
|
50
|
+
};
|
|
51
|
+
const isMethod = (value, name) => {
|
|
52
|
+
try {
|
|
53
|
+
return Predicate.hasProperty(value, name) && Predicate.isFunction(value[name]);
|
|
54
|
+
} catch {
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
const describeActual = (value) => {
|
|
59
|
+
if (value === null) return "null";
|
|
60
|
+
if (!isPropertyTarget(value)) {
|
|
61
|
+
if (Predicate.isString(value)) return "string";
|
|
62
|
+
if (Predicate.isNumber(value)) return "number";
|
|
63
|
+
if (Predicate.isBoolean(value)) return "boolean";
|
|
64
|
+
if (Predicate.isBigInt(value)) return "bigint";
|
|
65
|
+
if (Predicate.isSymbol(value)) return "symbol";
|
|
66
|
+
return "undefined";
|
|
67
|
+
}
|
|
68
|
+
const names = propertyNames(value);
|
|
69
|
+
const methods = names.filter((name) => isMethod(value, name));
|
|
70
|
+
const properties = names.filter((name) => !methods.includes(name));
|
|
71
|
+
const details = [methods.length > 0 ? `methods ${methods.join(", ")}` : void 0, properties.length > 0 ? `properties ${properties.join(", ")}` : void 0].filter((detail) => detail !== void 0);
|
|
72
|
+
if (details.length === 0) return getObjectName(value);
|
|
73
|
+
return `${getObjectName(value)} with ${details.join("; ")}`;
|
|
74
|
+
};
|
|
75
|
+
const getBinding = (env, binding, isResource, options) => Effect.gen(function* () {
|
|
76
|
+
if (!isPropertyTarget(env)) {
|
|
77
|
+
const actual = describeActual(env);
|
|
78
|
+
return yield* Effect.fail(new BindingValidationError({
|
|
79
|
+
binding,
|
|
80
|
+
expected: "WorkerEnvironment object",
|
|
81
|
+
actual,
|
|
82
|
+
message: `Cloudflare binding "${binding}" failed validation. Expected WorkerEnvironment object; got ${actual}`
|
|
83
|
+
}));
|
|
84
|
+
}
|
|
85
|
+
const resource = Predicate.hasProperty(env, binding) ? env[binding] : void 0;
|
|
86
|
+
if (resource === void 0) return yield* Effect.fail(new BindingNotFoundError({
|
|
87
|
+
binding,
|
|
88
|
+
message: `Cloudflare binding "${binding}" was not found in WorkerEnvironment`
|
|
89
|
+
}));
|
|
90
|
+
if (!isResource(resource)) {
|
|
91
|
+
const expected = options?.expected ?? defaultExpected;
|
|
92
|
+
const actual = describeActual(resource);
|
|
93
|
+
return yield* Effect.fail(new BindingValidationError({
|
|
94
|
+
binding,
|
|
95
|
+
expected,
|
|
96
|
+
actual,
|
|
97
|
+
message: `Cloudflare binding "${binding}" failed validation. Expected ${expected}; got ${actual}`
|
|
98
|
+
}));
|
|
99
|
+
}
|
|
100
|
+
return resource;
|
|
101
|
+
});
|
|
102
|
+
/**
|
|
103
|
+
* The overloads on {@link layer} and {@link Service} guarantee that
|
|
104
|
+
* `Service = Resource` whenever `wrap` is absent, making the fallback cast
|
|
105
|
+
* safe.
|
|
106
|
+
*/
|
|
107
|
+
const makeBindingLayer = (tag, binding, isResource, wrap, options) => Layer.effect(tag, Effect.gen(function* () {
|
|
108
|
+
const env = yield* WorkerEnvironment;
|
|
109
|
+
const resource = yield* getBinding(env, binding, isResource, options);
|
|
110
|
+
return wrap === void 0 ? resource : wrap(resource);
|
|
111
|
+
}));
|
|
112
|
+
function layer$1(tag, binding, isResource, wrap, options) {
|
|
113
|
+
return makeBindingLayer(tag, binding, isResource, wrap, options);
|
|
114
|
+
}
|
|
115
|
+
const Service = () => {
|
|
116
|
+
function makeService(id, binding, isResource, wrap, options) {
|
|
117
|
+
const tag = Context.Service()(`effect-cf/Binding/${id}`);
|
|
118
|
+
const serviceLayer = makeBindingLayer(tag, binding, isResource, wrap, options);
|
|
119
|
+
return Object.assign(tag, {
|
|
120
|
+
[TypeId]: TypeId,
|
|
121
|
+
id,
|
|
122
|
+
binding,
|
|
123
|
+
layer: serviceLayer
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
return makeService;
|
|
127
|
+
};
|
|
128
|
+
//#endregion
|
|
129
|
+
//#region src/Artifacts.ts
|
|
130
|
+
var Artifacts_exports = /* @__PURE__ */ __exportAll({
|
|
131
|
+
ArtifactsOperationError: () => ArtifactsOperationError,
|
|
132
|
+
Tag: () => Tag,
|
|
133
|
+
artifactsErrorCodes: () => artifactsErrorCodes,
|
|
134
|
+
artifactsErrorNumericCodes: () => artifactsErrorNumericCodes,
|
|
135
|
+
isArtifactsBinding: () => isArtifactsBinding,
|
|
136
|
+
isArtifactsRepoBinding: () => isArtifactsRepoBinding,
|
|
137
|
+
layer: () => layer,
|
|
138
|
+
make: () => make,
|
|
139
|
+
makeClient: () => makeClient
|
|
140
|
+
});
|
|
141
|
+
const expectedArtifactsBinding = "Artifacts binding with create(), get(), import(), list(), and delete()";
|
|
142
|
+
const expectedArtifactsRepo = "Artifacts repo handle with createToken(), listTokens(), revokeToken(), fork(), log(), readCommit(), and readTree()";
|
|
143
|
+
/** Documented string error codes returned by Cloudflare Artifacts. */
|
|
144
|
+
const artifactsErrorCodes = [
|
|
145
|
+
"ALREADY_EXISTS",
|
|
146
|
+
"NOT_FOUND",
|
|
147
|
+
"IMPORT_IN_PROGRESS",
|
|
148
|
+
"FORK_IN_PROGRESS",
|
|
149
|
+
"INVALID_INPUT",
|
|
150
|
+
"INVALID_REPO_NAME",
|
|
151
|
+
"INVALID_TTL",
|
|
152
|
+
"INVALID_URL",
|
|
153
|
+
"REMOTE_AUTH_REQUIRED",
|
|
154
|
+
"UPSTREAM_UNAVAILABLE",
|
|
155
|
+
"MEMORY_LIMIT",
|
|
156
|
+
"INTERNAL_ERROR"
|
|
157
|
+
];
|
|
158
|
+
/** Documented numeric error codes returned by Cloudflare Artifacts. */
|
|
159
|
+
const artifactsErrorNumericCodes = {
|
|
160
|
+
ALREADY_EXISTS: 10201,
|
|
161
|
+
NOT_FOUND: 10200,
|
|
162
|
+
IMPORT_IN_PROGRESS: 10302,
|
|
163
|
+
FORK_IN_PROGRESS: 10303,
|
|
164
|
+
INVALID_INPUT: 10100,
|
|
165
|
+
INVALID_REPO_NAME: 10101,
|
|
166
|
+
INVALID_TTL: 10103,
|
|
167
|
+
INVALID_URL: 10104,
|
|
168
|
+
REMOTE_AUTH_REQUIRED: 10106,
|
|
169
|
+
UPSTREAM_UNAVAILABLE: 10401,
|
|
170
|
+
MEMORY_LIMIT: 10402,
|
|
171
|
+
INTERNAL_ERROR: 10400
|
|
172
|
+
};
|
|
173
|
+
/** Error raised when a Cloudflare Artifacts operation fails. */
|
|
174
|
+
var ArtifactsOperationError = class extends Data.TaggedError("ArtifactsOperationError") {
|
|
175
|
+
get message() {
|
|
176
|
+
const code = this.code === void 0 ? "" : ` (${this.code})`;
|
|
177
|
+
return `Artifacts ${this.operation} failed for binding "${this.binding}"${code}: ${causeMessage(this.cause)}`;
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
const artifactsErrorDetails = (cause) => {
|
|
181
|
+
if (!Predicate.isObject(cause)) return {};
|
|
182
|
+
const code = Predicate.hasProperty(cause, "code") ? cause.code : void 0;
|
|
183
|
+
const numericCode = Predicate.hasProperty(cause, "numericCode") ? cause.numericCode : void 0;
|
|
184
|
+
const details = {};
|
|
185
|
+
if (Predicate.isString(code)) details.code = code;
|
|
186
|
+
if (Predicate.isNumber(numericCode)) details.numericCode = numericCode;
|
|
187
|
+
return details;
|
|
188
|
+
};
|
|
189
|
+
const artifactsError = (binding, operation, cause) => new ArtifactsOperationError({
|
|
190
|
+
binding,
|
|
191
|
+
operation,
|
|
192
|
+
cause,
|
|
193
|
+
...artifactsErrorDetails(cause)
|
|
194
|
+
});
|
|
195
|
+
const tryArtifactsPromise = (binding, operation, evaluate) => Effect.tryPromise({
|
|
196
|
+
try: evaluate,
|
|
197
|
+
catch: (cause) => artifactsError(binding, operation, cause)
|
|
198
|
+
});
|
|
199
|
+
const spanOptions = (binding, operation) => ({ attributes: {
|
|
200
|
+
binding,
|
|
201
|
+
operation
|
|
202
|
+
} });
|
|
203
|
+
const hasFunction = (value, key) => Predicate.hasProperty(value, key) && Predicate.isFunction(value[key]);
|
|
204
|
+
const ArtifactsRepoInfoSchema = Schema.Struct({
|
|
205
|
+
id: Schema.String,
|
|
206
|
+
name: Schema.String,
|
|
207
|
+
description: Schema.NullOr(Schema.String),
|
|
208
|
+
defaultBranch: Schema.String,
|
|
209
|
+
createdAt: Schema.String,
|
|
210
|
+
updatedAt: Schema.String,
|
|
211
|
+
lastPushAt: Schema.NullOr(Schema.String),
|
|
212
|
+
source: Schema.NullOr(Schema.String),
|
|
213
|
+
readOnly: Schema.Boolean,
|
|
214
|
+
remote: Schema.String
|
|
215
|
+
});
|
|
216
|
+
const decodeRepoInfo = (binding, value) => Schema.decodeUnknownEffect(ArtifactsRepoInfoSchema)(value).pipe(Effect.mapError((cause) => artifactsError(binding, "info", cause)));
|
|
217
|
+
const readRepoInfo = (binding, repo) => {
|
|
218
|
+
if (hasFunction(repo, "info")) return tryArtifactsPromise(binding, "info", () => repo.info()).pipe(Effect.flatMap((info) => decodeRepoInfo(binding, info)), Effect.withSpan("Artifacts.info", spanOptions(binding, "info")));
|
|
219
|
+
return decodeRepoInfo(binding, repo).pipe(Effect.withSpan("Artifacts.info", spanOptions(binding, "info")));
|
|
220
|
+
};
|
|
221
|
+
/** Tests whether a value exposes the complete documented Artifacts repo handle API. */
|
|
222
|
+
const isArtifactsRepoBinding = (value) => hasFunction(value, "createToken") && hasFunction(value, "listTokens") && hasFunction(value, "revokeToken") && hasFunction(value, "fork") && hasFunction(value, "log") && hasFunction(value, "readCommit") && hasFunction(value, "readTree");
|
|
223
|
+
/** Tests whether a value exposes the complete documented Artifacts namespace API. */
|
|
224
|
+
const isArtifactsBinding = (value) => hasFunction(value, "create") && hasFunction(value, "get") && hasFunction(value, "import") && hasFunction(value, "list") && hasFunction(value, "delete");
|
|
225
|
+
const wrapRepo = (binding, repo, info) => ({
|
|
226
|
+
...info,
|
|
227
|
+
info: () => readRepoInfo(binding, repo),
|
|
228
|
+
createToken: Effect.fn("Artifacts.createToken", spanOptions(binding, "createToken"))((scope, ttl) => tryArtifactsPromise(binding, "createToken", () => repo.createToken(scope, ttl))),
|
|
229
|
+
listTokens: tryArtifactsPromise(binding, "listTokens", () => repo.listTokens()).pipe(Effect.withSpan("Artifacts.listTokens", spanOptions(binding, "listTokens"))),
|
|
230
|
+
revokeToken: Effect.fn("Artifacts.revokeToken", spanOptions(binding, "revokeToken"))((tokenOrId) => tryArtifactsPromise(binding, "revokeToken", () => repo.revokeToken(tokenOrId))),
|
|
231
|
+
fork: Effect.fn("Artifacts.fork", spanOptions(binding, "fork"))((name, options) => tryArtifactsPromise(binding, "fork", () => repo.fork(name, options))),
|
|
232
|
+
log: Effect.fn("Artifacts.log", spanOptions(binding, "log"))((options) => tryArtifactsPromise(binding, "log", () => repo.log(options))),
|
|
233
|
+
readCommit: Effect.fn("Artifacts.readCommit", spanOptions(binding, "readCommit"))((hash) => tryArtifactsPromise(binding, "readCommit", () => repo.readCommit(hash))),
|
|
234
|
+
readTree: Effect.fn("Artifacts.readTree", spanOptions(binding, "readTree"))((hash) => tryArtifactsPromise(binding, "readTree", () => repo.readTree(hash))),
|
|
235
|
+
raw: repo
|
|
236
|
+
});
|
|
237
|
+
const makeClient = (definition) => (artifacts) => ({
|
|
238
|
+
definition,
|
|
239
|
+
create: Effect.fn("Artifacts.create", spanOptions(definition.binding, "create"))((name, options) => tryArtifactsPromise(definition.binding, "create", () => artifacts.create(name, options))),
|
|
240
|
+
get: Effect.fn("Artifacts.get", spanOptions(definition.binding, "get"))((name) => tryArtifactsPromise(definition.binding, "get", () => artifacts.get(name)).pipe(Effect.flatMap((repo) => isArtifactsRepoBinding(repo) ? readRepoInfo(definition.binding, repo).pipe(Effect.map((info) => wrapRepo(definition.binding, repo, info))) : Effect.fail(artifactsError(definition.binding, "get", /* @__PURE__ */ new TypeError(`Expected ${expectedArtifactsRepo}`)))))),
|
|
241
|
+
import: Effect.fn("Artifacts.import", spanOptions(definition.binding, "import"))((params) => tryArtifactsPromise(definition.binding, "import", () => artifacts.import(params))),
|
|
242
|
+
list: Effect.fn("Artifacts.list", spanOptions(definition.binding, "list"))((options) => tryArtifactsPromise(definition.binding, "list", () => artifacts.list(options))),
|
|
243
|
+
delete: Effect.fn("Artifacts.delete", spanOptions(definition.binding, "delete"))((name) => tryArtifactsPromise(definition.binding, "delete", () => artifacts.delete(name))),
|
|
244
|
+
rawUnsafe: Effect.succeed(artifacts)
|
|
245
|
+
});
|
|
246
|
+
const layer = (tag, definition) => layer$1(tag, definition.binding, isArtifactsBinding, makeClient(definition), { expected: expectedArtifactsBinding });
|
|
247
|
+
const make = (id) => Tag()(id);
|
|
248
|
+
const Tag = () => (id) => {
|
|
249
|
+
const tag = Context.Service()(id);
|
|
250
|
+
const makeLayer = (definition) => layer(tag, definition);
|
|
251
|
+
return Object.assign(tag, {
|
|
252
|
+
id,
|
|
253
|
+
layer: makeLayer
|
|
254
|
+
});
|
|
255
|
+
};
|
|
256
|
+
//#endregion
|
|
257
|
+
export { layer$1 as a, Service as i, Artifacts_exports as n, Binding_exports as r, ArtifactsOperationError as t };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Config, ConfigProvider, Context, Effect, Layer } from "effect";
|
|
1
|
+
import { Config, ConfigProvider, Context, Effect, Layer, Predicate } from "effect";
|
|
2
2
|
declare namespace Environment_d_exports {
|
|
3
3
|
export { WorkerConfig, WorkerEnv, WorkerEnvironment };
|
|
4
4
|
}
|
|
@@ -116,6 +116,7 @@ declare class BindingValidationError extends BindingValidationError_base<{
|
|
|
116
116
|
interface ValidationOptions {
|
|
117
117
|
readonly expected?: string;
|
|
118
118
|
}
|
|
119
|
+
type BindingCandidate = Parameters<typeof Predicate.isUnknown>[0];
|
|
119
120
|
/**
|
|
120
121
|
* Creates a Context tag + layer for reading and validating a Cloudflare binding.
|
|
121
122
|
*
|
|
@@ -128,11 +129,11 @@ interface BindingService<Self, Id extends string, Service> extends Context.Servi
|
|
|
128
129
|
readonly binding: string;
|
|
129
130
|
readonly layer: Layer.Layer<Self, BindingNotFoundError | BindingValidationError, WorkerEnvironment>;
|
|
130
131
|
}
|
|
131
|
-
declare function layer<Self, Resource>(tag: Context.Service<Self, Resource>, binding: string, isResource: (value:
|
|
132
|
-
declare function layer<Self, Resource, Service>(tag: Context.Service<Self, Service>, binding: string, isResource: (value:
|
|
132
|
+
declare function layer<Self, Resource>(tag: Context.Service<Self, Resource>, binding: string, isResource: (value: BindingCandidate) => value is Resource, wrap?: undefined, options?: ValidationOptions): Layer.Layer<Self, BindingNotFoundError | BindingValidationError, WorkerEnvironment>;
|
|
133
|
+
declare function layer<Self, Resource, Service>(tag: Context.Service<Self, Service>, binding: string, isResource: (value: BindingCandidate) => value is Resource, wrap: (resource: Resource) => Service, options?: ValidationOptions): Layer.Layer<Self, BindingNotFoundError | BindingValidationError, WorkerEnvironment>;
|
|
133
134
|
declare const Service: <Self>() => {
|
|
134
|
-
<Id extends string, Resource>(id: Id, binding: string, isResource: (value:
|
|
135
|
-
<Id extends string, Resource, Service>(id: Id, binding: string, isResource: (value:
|
|
135
|
+
<Id extends string, Resource>(id: Id, binding: string, isResource: (value: BindingCandidate) => value is Resource, wrap?: undefined, options?: ValidationOptions): BindingService<Self, Id, Resource>;
|
|
136
|
+
<Id extends string, Resource, Service>(id: Id, binding: string, isResource: (value: BindingCandidate) => value is Resource, wrap: (resource: Resource) => Service, options?: ValidationOptions): BindingService<Self, Id, Service>;
|
|
136
137
|
};
|
|
137
138
|
//#endregion
|
|
138
139
|
export { Environment_d_exports as a, WorkerEnvironment as c, Binding_d_exports as i, BindingService as n, WorkerConfig as o, BindingValidationError as r, WorkerEnv as s, BindingNotFoundError as t };
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { a as ArtifactsOperationError, c as ArtifactsTokenListResult, i as ArtifactsCreateTokenResult, n as ArtifactsCreateOptions, o as ArtifactsRepoInfo, r as ArtifactsCreateRepoResult, s as ArtifactsTokenInfo, t as ArtifactsBinding, u as RepoName } from "./Artifacts-DnHQA-Ax.mjs";
|
|
2
|
+
import { Effect } from "effect";
|
|
3
|
+
import { ArtifactClient, ArtifactImportOptions, ArtifactImportSource, ArtifactRepoSummary, ArtifactScope, ArtifactsCLIInput, ArtifactsCLIResult, RemoteAddFn } from "@cloudflare/computer/artifacts";
|
|
4
|
+
//#region src/ComputerArtifacts.d.ts
|
|
5
|
+
/** External Git source accepted by a session-scoped repository import. */
|
|
6
|
+
type ComputerArtifactImportSource = Readonly<ArtifactImportSource>;
|
|
7
|
+
/** Target options accepted by a session-scoped repository import. */
|
|
8
|
+
type ComputerArtifactImportOptions = Readonly<ArtifactImportOptions>;
|
|
9
|
+
/** Repository metadata returned by a session-scoped list operation. */
|
|
10
|
+
type ComputerArtifactRepoSummary = Readonly<ArtifactRepoSummary>;
|
|
11
|
+
/** Token scope accepted by the upstream session facade. */
|
|
12
|
+
type ComputerArtifactScope = ArtifactScope;
|
|
13
|
+
/** Optional Git remote-registration seam accepted by the argv API. */
|
|
14
|
+
type ComputerArtifactsRemoteAdd = RemoteAddFn;
|
|
15
|
+
/** Input to the session-scoped `artifacts` argv API. */
|
|
16
|
+
type ComputerArtifactsCliInput = ArtifactsCLIInput;
|
|
17
|
+
/** Result from the session-scoped `artifacts` argv API. */
|
|
18
|
+
type ComputerArtifactsCliResult = Readonly<ArtifactsCLIResult>;
|
|
19
|
+
/** Options used when wrapping a session-scoped Artifacts client. */
|
|
20
|
+
interface ComputerArtifactsClientOptions {
|
|
21
|
+
/** Binding name attached to errors and tracing spans. Defaults to `ARTIFACTS`. */
|
|
22
|
+
readonly binding?: string;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Effect-native facade over `@cloudflare/computer/artifacts`.
|
|
26
|
+
*
|
|
27
|
+
* Repository names are local to {@link sessionId}. Prefixing and filtering are
|
|
28
|
+
* intentionally delegated to the upstream `createArtifact` implementation so
|
|
29
|
+
* this client and the worker-shell `artifacts` command always use the same
|
|
30
|
+
* namespace convention.
|
|
31
|
+
*/
|
|
32
|
+
interface ComputerArtifactsClient {
|
|
33
|
+
readonly sessionId: string;
|
|
34
|
+
readonly create: (name: RepoName, options?: ArtifactsCreateOptions) => Effect.Effect<ArtifactsCreateRepoResult, ArtifactsOperationError>;
|
|
35
|
+
readonly get: (name: RepoName) => Effect.Effect<ArtifactsRepoInfo, ArtifactsOperationError>;
|
|
36
|
+
readonly list: Effect.Effect<ReadonlyArray<ComputerArtifactRepoSummary>, ArtifactsOperationError>;
|
|
37
|
+
readonly import: (name: RepoName, source: ComputerArtifactImportSource, options?: ComputerArtifactImportOptions) => Effect.Effect<ArtifactsCreateRepoResult, ArtifactsOperationError>;
|
|
38
|
+
readonly delete: (name: RepoName) => Effect.Effect<boolean, ArtifactsOperationError>;
|
|
39
|
+
readonly createToken: (name: RepoName, scope?: ComputerArtifactScope, ttl?: number) => Effect.Effect<ArtifactsCreateTokenResult, ArtifactsOperationError>;
|
|
40
|
+
readonly listTokens: (name: RepoName) => Effect.Effect<ArtifactsTokenListResult, ArtifactsOperationError>;
|
|
41
|
+
readonly getToken: (name: RepoName, id: string) => Effect.Effect<ArtifactsTokenInfo, ArtifactsOperationError>;
|
|
42
|
+
readonly revokeToken: (name: RepoName, tokenOrId: string) => Effect.Effect<boolean, ArtifactsOperationError>;
|
|
43
|
+
readonly cli: (input: ComputerArtifactsCliInput) => Effect.Effect<ComputerArtifactsCliResult, ArtifactsOperationError>;
|
|
44
|
+
readonly rawUnsafe: Effect.Effect<ArtifactClient>;
|
|
45
|
+
}
|
|
46
|
+
/** Wraps an already-created upstream session client. */
|
|
47
|
+
declare const fromClient: (client: ArtifactClient, options?: ComputerArtifactsClientOptions) => ComputerArtifactsClient;
|
|
48
|
+
/**
|
|
49
|
+
* Creates an Effect-native session client directly from a Worker Artifacts
|
|
50
|
+
* binding. `@cloudflare/computer` is loaded only when this Effect runs, keeping
|
|
51
|
+
* the optional peer out of applications that do not use this integration.
|
|
52
|
+
*/
|
|
53
|
+
declare const makeClient: (bindingValue: ArtifactsBinding, sessionId: string, options?: ComputerArtifactsClientOptions | undefined) => Effect.Effect<ComputerArtifactsClient, ArtifactsOperationError, never>;
|
|
54
|
+
//#endregion
|
|
55
|
+
export { ComputerArtifactImportOptions, ComputerArtifactImportSource, ComputerArtifactRepoSummary, ComputerArtifactScope, ComputerArtifactsCliInput, ComputerArtifactsCliResult, ComputerArtifactsClient, ComputerArtifactsClientOptions, ComputerArtifactsRemoteAdd, fromClient, makeClient };
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { t as ArtifactsOperationError } from "./Artifacts-rq3hUKQE.mjs";
|
|
2
|
+
import { Effect, Predicate } from "effect";
|
|
3
|
+
//#region src/ComputerArtifacts.ts
|
|
4
|
+
const artifactsErrorDetails = (cause) => {
|
|
5
|
+
if (!Predicate.isObject(cause)) return {};
|
|
6
|
+
const code = Predicate.hasProperty(cause, "code") ? cause.code : void 0;
|
|
7
|
+
const numericCode = Predicate.hasProperty(cause, "numericCode") ? cause.numericCode : void 0;
|
|
8
|
+
const details = {};
|
|
9
|
+
if (Predicate.isString(code)) details.code = code;
|
|
10
|
+
if (Predicate.isNumber(numericCode)) details.numericCode = numericCode;
|
|
11
|
+
return details;
|
|
12
|
+
};
|
|
13
|
+
const operationError = (binding, operation, cause) => new ArtifactsOperationError({
|
|
14
|
+
binding,
|
|
15
|
+
operation,
|
|
16
|
+
cause,
|
|
17
|
+
...artifactsErrorDetails(cause)
|
|
18
|
+
});
|
|
19
|
+
const tryOperation = (binding, operation, evaluate) => Effect.tryPromise({
|
|
20
|
+
try: evaluate,
|
|
21
|
+
catch: (cause) => operationError(binding, operation, cause)
|
|
22
|
+
});
|
|
23
|
+
const spanOptions = (binding, sessionId, operation) => ({ attributes: {
|
|
24
|
+
binding,
|
|
25
|
+
sessionId,
|
|
26
|
+
operation
|
|
27
|
+
} });
|
|
28
|
+
/** Wraps an already-created upstream session client. */
|
|
29
|
+
const fromClient = (client, options = {}) => {
|
|
30
|
+
const binding = options.binding ?? "ARTIFACTS";
|
|
31
|
+
const { sessionId } = client;
|
|
32
|
+
return {
|
|
33
|
+
sessionId,
|
|
34
|
+
create: Effect.fn("ComputerArtifacts.create", spanOptions(binding, sessionId, "create"))(function* (name, createOptions) {
|
|
35
|
+
yield* Effect.annotateCurrentSpan("repo", name);
|
|
36
|
+
return yield* tryOperation(binding, "create", () => client.create(name, createOptions));
|
|
37
|
+
}),
|
|
38
|
+
get: Effect.fn("ComputerArtifacts.get", spanOptions(binding, sessionId, "get"))(function* (name) {
|
|
39
|
+
yield* Effect.annotateCurrentSpan("repo", name);
|
|
40
|
+
return yield* tryOperation(binding, "get", () => client.get(name));
|
|
41
|
+
}),
|
|
42
|
+
list: tryOperation(binding, "list", () => client.list()).pipe(Effect.withSpan("ComputerArtifacts.list", spanOptions(binding, sessionId, "list"))),
|
|
43
|
+
import: Effect.fn("ComputerArtifacts.import", spanOptions(binding, sessionId, "import"))(function* (name, source, importOptions) {
|
|
44
|
+
yield* Effect.annotateCurrentSpan("repo", name);
|
|
45
|
+
return yield* tryOperation(binding, "import", () => client.import(name, source, importOptions));
|
|
46
|
+
}),
|
|
47
|
+
delete: Effect.fn("ComputerArtifacts.delete", spanOptions(binding, sessionId, "delete"))(function* (name) {
|
|
48
|
+
yield* Effect.annotateCurrentSpan("repo", name);
|
|
49
|
+
return yield* tryOperation(binding, "delete", () => client.delete(name));
|
|
50
|
+
}),
|
|
51
|
+
createToken: Effect.fn("ComputerArtifacts.createToken", spanOptions(binding, sessionId, "createToken"))(function* (name, scope, ttl) {
|
|
52
|
+
yield* Effect.annotateCurrentSpan("repo", name);
|
|
53
|
+
return yield* tryOperation(binding, "createToken", () => client.createToken(name, scope, ttl));
|
|
54
|
+
}),
|
|
55
|
+
listTokens: Effect.fn("ComputerArtifacts.listTokens", spanOptions(binding, sessionId, "listTokens"))(function* (name) {
|
|
56
|
+
yield* Effect.annotateCurrentSpan("repo", name);
|
|
57
|
+
return yield* tryOperation(binding, "listTokens", () => client.listTokens(name));
|
|
58
|
+
}),
|
|
59
|
+
getToken: Effect.fn("ComputerArtifacts.getToken", spanOptions(binding, sessionId, "getToken"))(function* (name, id) {
|
|
60
|
+
yield* Effect.annotateCurrentSpan({
|
|
61
|
+
repo: name,
|
|
62
|
+
tokenId: id
|
|
63
|
+
});
|
|
64
|
+
return yield* tryOperation(binding, "getToken", () => client.getToken(name, id));
|
|
65
|
+
}),
|
|
66
|
+
revokeToken: Effect.fn("ComputerArtifacts.revokeToken", spanOptions(binding, sessionId, "revokeToken"))(function* (name, tokenOrId) {
|
|
67
|
+
yield* Effect.annotateCurrentSpan("repo", name);
|
|
68
|
+
return yield* tryOperation(binding, "revokeToken", () => client.revokeToken(name, tokenOrId));
|
|
69
|
+
}),
|
|
70
|
+
cli: Effect.fn("ComputerArtifacts.cli", spanOptions(binding, sessionId, "cli"))(function* (input) {
|
|
71
|
+
yield* Effect.annotateCurrentSpan("argv", input.argv.join(" "));
|
|
72
|
+
return yield* tryOperation(binding, "cli", () => client.cli(input));
|
|
73
|
+
}),
|
|
74
|
+
rawUnsafe: Effect.succeed(client)
|
|
75
|
+
};
|
|
76
|
+
};
|
|
77
|
+
/**
|
|
78
|
+
* Creates an Effect-native session client directly from a Worker Artifacts
|
|
79
|
+
* binding. `@cloudflare/computer` is loaded only when this Effect runs, keeping
|
|
80
|
+
* the optional peer out of applications that do not use this integration.
|
|
81
|
+
*/
|
|
82
|
+
const makeClient = Effect.fn("ComputerArtifacts.makeClient")(function* (bindingValue, sessionId, options = {}) {
|
|
83
|
+
const binding = options.binding ?? "ARTIFACTS";
|
|
84
|
+
const computerArtifacts = yield* Effect.tryPromise({
|
|
85
|
+
try: () => import("@cloudflare/computer/artifacts"),
|
|
86
|
+
catch: (cause) => operationError(binding, "createClient", cause)
|
|
87
|
+
});
|
|
88
|
+
const client = yield* Effect.try({
|
|
89
|
+
try: () => computerArtifacts.createArtifact(bindingValue, sessionId),
|
|
90
|
+
catch: (cause) => operationError(binding, "createClient", cause)
|
|
91
|
+
});
|
|
92
|
+
return fromClient(client, { binding });
|
|
93
|
+
});
|
|
94
|
+
//#endregion
|
|
95
|
+
export { fromClient, makeClient };
|