effect-cf 0.30.0 → 0.31.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 +10 -0
- package/README.md +25 -8
- package/dist/ComputerWorkspace.d.mts +1 -1
- package/dist/ComputerWorkspace.mjs +1 -1
- package/dist/{DurableObjectState-CepagPkX.mjs → DurableObjectState-CxS5Y2hf.mjs} +2 -1
- package/dist/{DurableObjectState-D3k-WRnd.d.mts → DurableObjectState-DVIgf0sA.d.mts} +2 -0
- package/dist/Vitest.d.mts +9 -9
- package/dist/Vitest.mjs +5 -5
- package/dist/{WorkflowBinding-CtrmxfdT.d.mts → WorkflowBinding-C9KRmfDU.d.mts} +6 -3
- package/dist/index.d.mts +19 -6
- package/dist/index.mjs +13 -5
- package/package.json +5 -5
- package/src/Images.ts +60 -9
- package/src/Vitest.ts +9 -9
- package/src/Worker.ts +2 -0
- package/src/WorkflowBinding.ts +10 -2
- package/src/internal/WorkerContext.ts +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# effect-cf
|
|
2
2
|
|
|
3
|
+
## 0.31.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#116](https://github.com/danieljvdm/effect-cf/pull/116) [`98d343b`](https://github.com/danieljvdm/effect-cf/commit/98d343ba7d5a427789ec8e7fc030668987eab1ea) Thanks [@danieljvdm](https://github.com/danieljvdm)! - Move the optional `effect-cf/vitest` peer from `@cloudflare/vitest-pool-workers` to `@cloudflare/vitest-plugin` `^1.0.0`. The package API is unchanged: keep using `cloudflareTest()` and `cloudflare:test`.
|
|
8
|
+
|
|
9
|
+
- [#118](https://github.com/danieljvdm/effect-cf/pull/118) [`80730a8`](https://github.com/danieljvdm/effect-cf/commit/80730a82b26728e824ba6e4ed8bdbe290428baa6) Thanks [@danieljvdm](https://github.com/danieljvdm)! - Pin the Cloudflare Workers runtime stack to workerd `1.20260820.1` (`@cloudflare/workers-types@^5.20260820.1`, wrangler `4.125.0`, recommended `compatibility_date` `2026-08-20`).
|
|
10
|
+
|
|
11
|
+
Images gains text rasterization (`text` / `process` text input), hosted `createDirectUpload` and `signedUrl`, and `response(options?)` for extra headers. Workflow instances gain `delete`, optional `terminate({ rollback })`, and `create`/`createBatch` `locationHint` via the updated types. `Worker.WorkerContext` now wraps the non-experimental `ExecutionContext.abort`.
|
|
12
|
+
|
|
3
13
|
## 0.30.0
|
|
4
14
|
|
|
5
15
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -4,7 +4,8 @@ Effect-native Cloudflare primitives for Workers, Durable Objects, Containers, bi
|
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
7
|
-
`effect-cf` targets Effect `^4.0.0-beta.105
|
|
7
|
+
`effect-cf` targets Effect `^4.0.0-beta.105` and Cloudflare workerd `1.20260820.1`
|
|
8
|
+
(`@cloudflare/workers-types@5.20260820.1`, recommended `compatibility_date` `2026-08-20`).
|
|
8
9
|
|
|
9
10
|
```bash
|
|
10
11
|
bun add effect-cf "effect@^4.0.0-beta.105"
|
|
@@ -72,12 +73,12 @@ Runtime creation belongs at Cloudflare entrypoints, not inside binding helpers.
|
|
|
72
73
|
- `Rpc` - Cloudflare RPC type helpers and scoped disposal utilities
|
|
73
74
|
- `WebTransport` - truthful WebTransport/HTTP-3 boundary: typed runtime capabilities and decoded inbound protocol metadata
|
|
74
75
|
- `WorkerConfig` - Effect `Config` helpers backed by Cloudflare `env`
|
|
75
|
-
- `effect-cf/vitest` - Effect-native runners and scoped test helpers for Cloudflare's Vitest
|
|
76
|
+
- `effect-cf/vitest` - Effect-native runners and scoped test helpers for Cloudflare's Workers Vitest plugin
|
|
76
77
|
|
|
77
|
-
## Vitest Workers
|
|
78
|
+
## Vitest Workers Plugin
|
|
78
79
|
|
|
79
|
-
Install and configure a `^0.
|
|
80
|
-
[`@cloudflare/vitest-
|
|
80
|
+
Install and configure a `^1.0.0` release of
|
|
81
|
+
[`@cloudflare/vitest-plugin`](https://github.com/cloudflare/workers-sdk/tree/main/packages/vitest-plugin#readme),
|
|
81
82
|
then import the test-only helpers from `effect-cf/vitest`. The `fetch` runner
|
|
82
83
|
constructs the Worker with the current test environment and waits for all
|
|
83
84
|
`waitUntil` work before completing the Effect.
|
|
@@ -109,7 +110,7 @@ it.effect("reads Wrangler vars", () =>
|
|
|
109
110
|
```
|
|
110
111
|
|
|
111
112
|
Queue consumers can be invoked with typed message bodies while retaining the
|
|
112
|
-
|
|
113
|
+
plugin's acknowledgement and retry result:
|
|
113
114
|
|
|
114
115
|
```ts
|
|
115
116
|
it.effect("acknowledges a job", () =>
|
|
@@ -130,7 +131,7 @@ it.effect("acknowledges a job", () =>
|
|
|
130
131
|
|
|
131
132
|
Scheduled handlers and Pages Functions use the same lifecycle behavior: their
|
|
132
133
|
Effects complete only after the event's `waitUntil` work has settled. Pages
|
|
133
|
-
tests must configure the `ASSETS` binding required by
|
|
134
|
+
tests must configure the `ASSETS` binding required by the Workers Vitest plugin.
|
|
134
135
|
|
|
135
136
|
```ts
|
|
136
137
|
it.effect("runs the cron handler", () =>
|
|
@@ -719,10 +720,26 @@ export const resizeAvatar = (image: Images.ImageInputValue) =>
|
|
|
719
720
|
},
|
|
720
721
|
);
|
|
721
722
|
|
|
722
|
-
return yield* result.response;
|
|
723
|
+
return yield* result.response();
|
|
723
724
|
});
|
|
724
725
|
```
|
|
725
726
|
|
|
727
|
+
## Cloudflare runtime pin
|
|
728
|
+
|
|
729
|
+
`effect-cf` develops and tests against a fixed Cloudflare Workers runtime stack. Keep consumer
|
|
730
|
+
`compatibility_date` and optional `@cloudflare/workers-types` peers at or above this pin:
|
|
731
|
+
|
|
732
|
+
| Pin | Version |
|
|
733
|
+
| ------------------------------------------- | -------------- |
|
|
734
|
+
| workerd | `1.20260820.1` |
|
|
735
|
+
| `@cloudflare/workers-types` (optional peer) | `5.20260820.1` |
|
|
736
|
+
| wrangler (repo catalog / examples) | `4.125.0` |
|
|
737
|
+
| Recommended `compatibility_date` | `2026-08-20` |
|
|
738
|
+
|
|
739
|
+
The date in the `workerd` / `@cloudflare/workers-types` version is the API surface this package wraps.
|
|
740
|
+
Repo catalog pins live in the root `package.json` `catalog` field (`@cloudflare/workers-types`, `wrangler`).
|
|
741
|
+
`wrangler@4.125.0` pulls `workerd@1.20260820.1` and peers `@cloudflare/workers-types@^5.20260820.1`.
|
|
742
|
+
|
|
726
743
|
## Email Example
|
|
727
744
|
|
|
728
745
|
Email tags expose Cloudflare Email Service `send_email` bindings as Effect-wrapped `send(...)` operations. Structured messages are validated against documented Email Sending limits before reaching the binding, and Cloudflare's `E_*` error codes are surfaced on `EmailOperationError.code`.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ComputerArtifactsClient } from "./ComputerArtifacts.mjs";
|
|
2
|
-
import { t as DurableObjectState } from "./DurableObjectState-
|
|
2
|
+
import { t as DurableObjectState } from "./DurableObjectState-DVIgf0sA.mjs";
|
|
3
3
|
import { Context, Effect, Layer, Schema, Scope, Stream } from "effect";
|
|
4
4
|
import { CommitView, GitClient, GitCloneOptions, GitCommitOptions, GitDiffOptions, GitFetchOptions, GitLogOptions, GitUpdateRefOptions } from "@cloudflare/computer/git";
|
|
5
5
|
import { ExecSyncResult, RuntimeExecOptions, RuntimeGetOptions, RuntimeKillOptions, ShellValue, SkippedEntry, ThinkWorkspaceCompatibility, WorkspaceClient, WorkspaceRuntimeResult, WorkspaceRuntimeValue as WorkspaceRuntimeValue$1 } from "@cloudflare/computer";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as DurableObjectState } from "./DurableObjectState-
|
|
1
|
+
import { t as DurableObjectState } from "./DurableObjectState-CxS5Y2hf.mjs";
|
|
2
2
|
import { fromClient } from "./ComputerArtifacts.mjs";
|
|
3
3
|
import { t as lookup } from "./ComputerWorkspaceHostRegistry-CY5Fv4Ng.mjs";
|
|
4
4
|
import { Context, Effect, Layer, Predicate, Schema, Stream } from "effect";
|
|
@@ -308,7 +308,8 @@ const fromExecutionContext = (ctx, runPromiseExit = (effect) => Effect.runPromis
|
|
|
308
308
|
raw: ctx,
|
|
309
309
|
waitUntil: (effect, options) => schedule(effect, options, options?.mode ?? "observe"),
|
|
310
310
|
waitUntilPropagating: (effect, options) => schedule(effect, options, "propagate"),
|
|
311
|
-
passThroughOnException: Effect.sync(() => ctx.passThroughOnException())
|
|
311
|
+
passThroughOnException: Effect.sync(() => ctx.passThroughOnException()),
|
|
312
|
+
abort: (reason) => Effect.sync(() => ctx.abort(reason))
|
|
312
313
|
};
|
|
313
314
|
};
|
|
314
315
|
//#endregion
|
|
@@ -834,6 +834,8 @@ interface WorkerContextService {
|
|
|
834
834
|
waitUntil<A, E, R, R2 = never>(effect: Effect.Effect<A, E, R>, options?: WorkerContextWaitUntilOptions<E, R2>): Effect.Effect<void, never, R | R2>;
|
|
835
835
|
waitUntilPropagating<A, E, R, R2 = never>(effect: Effect.Effect<A, E, R>, options?: Omit<WorkerContextWaitUntilOptions<E, R2>, "mode">): Effect.Effect<void, never, R | R2>;
|
|
836
836
|
readonly passThroughOnException: Effect.Effect<void>;
|
|
837
|
+
/** Abort the current stateless Worker invocation (`ExecutionContext.abort`). */
|
|
838
|
+
abort(reason?: string): Effect.Effect<void>;
|
|
837
839
|
}
|
|
838
840
|
declare const WorkerContext_base: Context.ServiceClass<WorkerContext, "effect-cf/WorkerContext", WorkerContextService>;
|
|
839
841
|
/**
|
package/dist/Vitest.d.mts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { c as WorkerEnvironment, s as WorkerEnv } from "./Binding-xJJJPmiD.mjs";
|
|
2
|
-
import { n as DurableObjectStateService, t as DurableObjectState } from "./DurableObjectState-
|
|
3
|
-
import { o as WorkflowInstanceStatusName } from "./WorkflowBinding-
|
|
2
|
+
import { n as DurableObjectStateService, t as DurableObjectState } from "./DurableObjectState-DVIgf0sA.mjs";
|
|
3
|
+
import { o as WorkflowInstanceStatusName } from "./WorkflowBinding-C9KRmfDU.mjs";
|
|
4
4
|
import { Effect, Layer, Schema } from "effect";
|
|
5
5
|
import { DurableObject } from "cloudflare:workers";
|
|
6
6
|
import { adminSecretsStore as adminSecretsStore$1, getQueueResult, introspectWorkflow as introspectWorkflow$1, introspectWorkflowInstance as introspectWorkflowInstance$1 } from "cloudflare:test";
|
|
7
7
|
//#region src/Vitest.d.ts
|
|
8
8
|
/**
|
|
9
|
-
* Provides the Workers
|
|
9
|
+
* Provides the Workers test environment as both {@link WorkerEnvironment} and
|
|
10
10
|
* the active Effect `ConfigProvider`.
|
|
11
11
|
*/
|
|
12
12
|
declare const layer: Layer.Layer<WorkerEnvironment>;
|
|
@@ -54,7 +54,7 @@ type PagesEventContextInitData<Context> = Context extends globalThis.EventContex
|
|
|
54
54
|
} : {
|
|
55
55
|
readonly data: Data;
|
|
56
56
|
} : never;
|
|
57
|
-
/** Initialization accepted by
|
|
57
|
+
/** Initialization accepted by the Workers Vitest plugin for a Pages Function. */
|
|
58
58
|
type PagesEventContextInit<Function extends AnyPagesFunction> = PagesEventContextInitBase & PagesEventContextInitParams<Parameters<Function>[0]> & PagesEventContextInitData<Parameters<Function>[0]>;
|
|
59
59
|
/**
|
|
60
60
|
* Invokes a Pages Function with a typed event context and drains its
|
|
@@ -64,7 +64,7 @@ declare const pages: <Function extends AnyPagesFunction>(handler: Function, init
|
|
|
64
64
|
interface QueueWorker {
|
|
65
65
|
queue(batch: globalThis.MessageBatch): Promise<void>;
|
|
66
66
|
}
|
|
67
|
-
/** Input message accepted by
|
|
67
|
+
/** Input message accepted by the Workers Vitest plugin's `createMessageBatch` helper. */
|
|
68
68
|
type QueueMessage<Body> = {
|
|
69
69
|
readonly id: string;
|
|
70
70
|
readonly timestamp: Date;
|
|
@@ -74,7 +74,7 @@ type QueueMessage<Body> = {
|
|
|
74
74
|
} | {
|
|
75
75
|
readonly serializedBody: ArrayBuffer | ArrayBufferView;
|
|
76
76
|
});
|
|
77
|
-
/** Acknowledgement and retry result returned by
|
|
77
|
+
/** Acknowledgement and retry result returned by the Workers Vitest plugin. */
|
|
78
78
|
type QueueResult = Awaited<ReturnType<typeof getQueueResult>>;
|
|
79
79
|
/** Result of invoking a queue consumer through {@link queue}. */
|
|
80
80
|
interface QueueRunResult<Body> {
|
|
@@ -83,7 +83,7 @@ interface QueueRunResult<Body> {
|
|
|
83
83
|
}
|
|
84
84
|
/**
|
|
85
85
|
* Invokes an Effect-backed queue consumer, drains its `waitUntil` work, and
|
|
86
|
-
* returns
|
|
86
|
+
* returns the Workers Vitest plugin's acknowledgement and retry result.
|
|
87
87
|
*/
|
|
88
88
|
declare const queue: <Body, Instance extends QueueWorker>(Worker: WorkerConstructor<Instance>, queueName: string, messages: readonly QueueMessage<Body>[], workerEnv?: Cloudflare.Env | undefined) => Effect.Effect<QueueRunResult<Body>, never, never>;
|
|
89
89
|
/**
|
|
@@ -110,7 +110,7 @@ declare const reset: () => Effect.Effect<void, never, never>;
|
|
|
110
110
|
declare const abortAllDurableObjects: () => Effect.Effect<void, never, never>;
|
|
111
111
|
/** Gracefully evicts all running Durable Objects while preserving durable storage. */
|
|
112
112
|
declare const evictAllDurableObjects: (options?: DurableObjectEvictionOptions | undefined) => Effect.Effect<void, never, never>;
|
|
113
|
-
/** A D1 migration accepted by
|
|
113
|
+
/** A D1 migration accepted by the Workers Vitest plugin. */
|
|
114
114
|
interface D1Migration {
|
|
115
115
|
readonly name: string;
|
|
116
116
|
readonly queries: ReadonlyArray<string>;
|
|
@@ -125,7 +125,7 @@ interface SecretsStoreSecret {
|
|
|
125
125
|
readonly uuid: string;
|
|
126
126
|
};
|
|
127
127
|
}
|
|
128
|
-
/** Effect-native wrapper around
|
|
128
|
+
/** Effect-native wrapper around the Workers Vitest plugin's Secrets Store admin API. */
|
|
129
129
|
interface SecretsStoreAdmin {
|
|
130
130
|
readonly raw: NativeSecretsStoreAdmin;
|
|
131
131
|
readonly create: (value: string) => Effect.Effect<string>;
|
package/dist/Vitest.mjs
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { a as WorkerEnvironment, i as WorkerConfig } from "./ErrorMessage-BM0K-Nik.mjs";
|
|
2
|
-
import { r as fromDurableObjectState, t as DurableObjectState } from "./DurableObjectState-
|
|
2
|
+
import { r as fromDurableObjectState, t as DurableObjectState } from "./DurableObjectState-CxS5Y2hf.mjs";
|
|
3
3
|
import { ConfigProvider, Effect, Exit, Layer } from "effect";
|
|
4
4
|
import { env } from "cloudflare:workers";
|
|
5
5
|
import { abortAllDurableObjects as abortAllDurableObjects$1, adminSecretsStore as adminSecretsStore$1, applyD1Migrations as applyD1Migrations$1, createExecutionContext, createMessageBatch, createPagesEventContext, createScheduledController, evictAllDurableObjects as evictAllDurableObjects$1, evictDurableObject as evictDurableObject$1, getQueueResult, introspectWorkflow as introspectWorkflow$1, introspectWorkflowInstance as introspectWorkflowInstance$1, listDurableObjectIds as listDurableObjectIds$1, reset as reset$1, runDurableObjectAlarm as runDurableObjectAlarm$1, runInDurableObject as runInDurableObject$1, waitOnExecutionContext } from "cloudflare:test";
|
|
6
6
|
//#region src/Vitest.ts
|
|
7
7
|
/**
|
|
8
|
-
* Effect-native helpers for tests running in Cloudflare's Vitest
|
|
8
|
+
* Effect-native helpers for tests running in Cloudflare's Workers Vitest plugin.
|
|
9
9
|
*
|
|
10
10
|
* Import this module through the `effect-cf/vitest` subpath. It is intended to
|
|
11
11
|
* run inside the Workers test runtime, where `cloudflare:test` is available.
|
|
12
12
|
*/
|
|
13
13
|
const currentEnv = env;
|
|
14
14
|
/**
|
|
15
|
-
* Provides the Workers
|
|
15
|
+
* Provides the Workers test environment as both {@link WorkerEnvironment} and
|
|
16
16
|
* the active Effect `ConfigProvider`.
|
|
17
17
|
*/
|
|
18
18
|
const layer = Layer.mergeAll(Layer.succeed(WorkerEnvironment, currentEnv), ConfigProvider.layer(WorkerConfig.providerFromEnv(currentEnv)));
|
|
@@ -50,7 +50,7 @@ const pages = Effect.fn("effect-cf/vitest/pages")(function* (handler, init) {
|
|
|
50
50
|
});
|
|
51
51
|
/**
|
|
52
52
|
* Invokes an Effect-backed queue consumer, drains its `waitUntil` work, and
|
|
53
|
-
* returns
|
|
53
|
+
* returns the Workers Vitest plugin's acknowledgement and retry result.
|
|
54
54
|
*/
|
|
55
55
|
const queue = Effect.fn("effect-cf/vitest/queue")(function* (Worker, queueName, messages, workerEnv = currentEnv) {
|
|
56
56
|
return yield* withExecutionContext(Effect.fnUntraced(function* (context) {
|
|
@@ -146,7 +146,7 @@ const runWorkflowModifier = Effect.fnUntraced(function* (register, use) {
|
|
|
146
146
|
if (callbackExit !== void 0 && Exit.isFailure(callbackExit)) return callbackExit;
|
|
147
147
|
throw cause;
|
|
148
148
|
}
|
|
149
|
-
if (callbackExit === void 0) throw new Error("
|
|
149
|
+
if (callbackExit === void 0) throw new Error("The Workers Vitest plugin did not invoke the Workflow modifier callback");
|
|
150
150
|
return callbackExit;
|
|
151
151
|
});
|
|
152
152
|
});
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import { c as WorkerEnvironment, r as BindingValidationError, t as BindingNotFoundError } from "./Binding-xJJJPmiD.mjs";
|
|
2
|
-
import { x as ServiceFreeSchema } from "./DurableObjectState-
|
|
2
|
+
import { x as ServiceFreeSchema } from "./DurableObjectState-DVIgf0sA.mjs";
|
|
3
3
|
import { Context, Effect, Option, Schema } from "effect";
|
|
4
4
|
declare namespace WorkflowBinding_d_exports {
|
|
5
|
-
export { WorkflowBindingClient, WorkflowBindingDefinition, WorkflowInstance, WorkflowInstanceCreateBatchOptions, WorkflowInstanceCreateOptions, WorkflowInstanceEvent, WorkflowInstanceRestartOptions, WorkflowInstanceStatus, WorkflowInstanceStatusName, WorkflowOperationError, WorkflowResultDecodeError, isWorkflow, layer, makeClient };
|
|
5
|
+
export { WorkflowBindingClient, WorkflowBindingDefinition, WorkflowInstance, WorkflowInstanceCreateBatchOptions, WorkflowInstanceCreateOptions, WorkflowInstanceEvent, WorkflowInstanceLocationHint, WorkflowInstanceRestartOptions, WorkflowInstanceStatus, WorkflowInstanceStatusName, WorkflowInstanceTerminateOptions, WorkflowOperationError, WorkflowResultDecodeError, isWorkflow, layer, makeClient };
|
|
6
6
|
}
|
|
7
7
|
type WorkflowInstanceCreateOptions<Payload> = Omit<CloudflareWorkflowInstanceCreateOptions<Payload>, "params">;
|
|
8
8
|
type WorkflowInstanceCreateBatchOptions<Payload, EncodedPayload = unknown> = ReadonlyArray<{
|
|
9
9
|
readonly payload: Payload;
|
|
10
10
|
} & WorkflowInstanceCreateOptions<EncodedPayload>>;
|
|
11
11
|
type WorkflowInstanceRestartOptions = CloudflareWorkflowInstanceRestartOptions;
|
|
12
|
+
type WorkflowInstanceTerminateOptions = CloudflareWorkflowInstanceTerminateOptions;
|
|
13
|
+
type WorkflowInstanceLocationHint = CloudflareWorkflowInstanceLocationHint;
|
|
12
14
|
type WorkflowInstanceStatusName = CloudflareInstanceStatus["status"];
|
|
13
15
|
interface WorkflowInstanceStatus<Result> {
|
|
14
16
|
readonly status: WorkflowInstanceStatusName;
|
|
@@ -23,8 +25,9 @@ interface WorkflowInstance<Result> {
|
|
|
23
25
|
readonly id: string;
|
|
24
26
|
readonly pause: Effect.Effect<void, WorkflowOperationError>;
|
|
25
27
|
readonly resume: Effect.Effect<void, WorkflowOperationError>;
|
|
26
|
-
readonly terminate: Effect.Effect<void, WorkflowOperationError>;
|
|
28
|
+
readonly terminate: (options?: WorkflowInstanceTerminateOptions) => Effect.Effect<void, WorkflowOperationError>;
|
|
27
29
|
readonly restart: (options?: WorkflowInstanceRestartOptions) => Effect.Effect<void, WorkflowOperationError>;
|
|
30
|
+
readonly delete: Effect.Effect<void, WorkflowOperationError>;
|
|
28
31
|
readonly status: Effect.Effect<WorkflowInstanceStatus<Result>, WorkflowOperationError | WorkflowResultDecodeError>;
|
|
29
32
|
readonly sendEvent: (event: WorkflowInstanceEvent) => Effect.Effect<void, WorkflowOperationError>;
|
|
30
33
|
}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { a as Environment_d_exports, c as WorkerEnvironment, i as Binding_d_exports, n as BindingService, o as WorkerConfig, r as BindingValidationError, s as WorkerEnv, t as BindingNotFoundError } from "./Binding-xJJJPmiD.mjs";
|
|
2
2
|
import { l as Artifacts_d_exports } from "./Artifacts-DnHQA-Ax.mjs";
|
|
3
|
-
import { C as Rpc_d_exports, D as StorageOperationError, E as DurableObjectStorage_d_exports, S as Provider, T as DurableWebSocket, _ as Definition$4, a as NativeRequest, b as RpcDefinition_d_exports, c as WorkerDefinition_d_exports, d as AsyncMethodCloudflareReturn, f as AsyncMethodKey, g as QueueBinding_d_exports, h as QueueDefinition_d_exports, i as ExecutionContext, l as ServiceBinding_d_exports, m as Queue_d_exports, o as WorkerContext, p as AsyncMethodSuccess, r as DurableObjectState_d_exports, s as Worker_d_exports, t as DurableObjectState, u as AsyncMethodArgs, v as Method$2, w as DurableObjectWebSocket_d_exports, x as ServiceFreeSchema$1, y as ReservedMethodName$2 } from "./DurableObjectState-
|
|
3
|
+
import { C as Rpc_d_exports, D as StorageOperationError, E as DurableObjectStorage_d_exports, S as Provider, T as DurableWebSocket, _ as Definition$4, a as NativeRequest, b as RpcDefinition_d_exports, c as WorkerDefinition_d_exports, d as AsyncMethodCloudflareReturn, f as AsyncMethodKey, g as QueueBinding_d_exports, h as QueueDefinition_d_exports, i as ExecutionContext, l as ServiceBinding_d_exports, m as Queue_d_exports, o as WorkerContext, p as AsyncMethodSuccess, r as DurableObjectState_d_exports, s as Worker_d_exports, t as DurableObjectState, u as AsyncMethodArgs, v as Method$2, w as DurableObjectWebSocket_d_exports, x as ServiceFreeSchema$1, y as ReservedMethodName$2 } from "./DurableObjectState-DVIgf0sA.mjs";
|
|
4
4
|
import { t as Hyperdrive_d_exports } from "./Hyperdrive-z-9fFz15.mjs";
|
|
5
5
|
import { t as ContainerNamespace_d_exports } from "./ContainerNamespace-CFjiLw8b.mjs";
|
|
6
|
-
import { a as WorkflowInstanceCreateOptions, i as WorkflowInstanceCreateBatchOptions, n as WorkflowBinding_d_exports, r as WorkflowInstance, s as WorkflowOperationError, t as WorkflowBindingClient } from "./WorkflowBinding-
|
|
6
|
+
import { a as WorkflowInstanceCreateOptions, i as WorkflowInstanceCreateBatchOptions, n as WorkflowBinding_d_exports, r as WorkflowInstance, s as WorkflowOperationError, t as WorkflowBindingClient } from "./WorkflowBinding-C9KRmfDU.mjs";
|
|
7
7
|
import { Cause, Config, Context, Data, DateTime, Duration, Effect, Layer, Option, Predicate, Redacted, Schema, Scope } from "effect";
|
|
8
8
|
import { Headers as Headers$1, HttpClient, HttpClientResponse } from "effect/unstable/http";
|
|
9
9
|
import { OtlpExporter, OtlpResource } from "effect/unstable/observability";
|
|
@@ -1491,7 +1491,7 @@ declare const layer$4: <Self>(tag: Context.Service<Self, EmailClient>, definitio
|
|
|
1491
1491
|
declare const make$5: <Id extends string>(id: Id) => TagClass$6<EmailService<Id>, Id>;
|
|
1492
1492
|
declare const Tag$7: <Self>() => <Id extends string>(id: Id) => TagClass$6<Self, Id>;
|
|
1493
1493
|
declare namespace Images_d_exports {
|
|
1494
|
-
export { DrawStepOptions, HostedImagesClient, ImageDrawOptions, ImageHandleClient, ImageInfoResponse, ImageInputOptions, ImageInputValue, ImageList, ImageListOptions, ImageMetadata, ImageOutputOptions, ImageTransform, ImageTransformationOutputOptions, ImageTransformationResult, ImageUpdateOptions, ImageUploadOptions, ImageUploadValue, ImagesClient, ImagesDefinition, ImagesOperationError, ImagesRuntimeBinding, ImagesService, ImagesTransformationResultClient, LayerOptions$5 as LayerOptions, ProcessOptions, Step, Steps, Tag$6 as Tag, TagClass$5 as TagClass, TypeId, draw, empty, isImagesBinding, layer$3 as layer, make$4 as make, makeClient$3 as makeClient, transform };
|
|
1494
|
+
export { DrawStepOptions, HostedImagesClient, ImageDirectUploadOptions, ImageDirectUploadResult, ImageDrawOptions, ImageHandleClient, ImageInfoResponse, ImageInputOptions, ImageInputValue, ImageList, ImageListOptions, ImageMetadata, ImageOutputOptions, ImageSignedUrlOptions, ImageTransform, ImageTransformationOutputOptions, ImageTransformationResponseOptions, ImageTransformationResult, ImageUpdateOptions, ImageUploadOptions, ImageUploadValue, ImagesClient, ImagesDefinition, ImagesOperationError, ImagesRuntimeBinding, ImagesService, ImagesTransformationResultClient, LayerOptions$5 as LayerOptions, ProcessOptions, Step, Steps, Tag$6 as Tag, TagClass$5 as TagClass, TextOptions, TypeId, draw, empty, isImagesBinding, layer$3 as layer, make$4 as make, makeClient$3 as makeClient, transform };
|
|
1495
1495
|
}
|
|
1496
1496
|
declare const TypeId: "~effect-cf/Images/Steps";
|
|
1497
1497
|
type TypeId = typeof TypeId;
|
|
@@ -1517,12 +1517,17 @@ type ImageDrawOptions = CloudflareImageDrawOptions;
|
|
|
1517
1517
|
type ImageInputOptions = CloudflareImageInputOptions;
|
|
1518
1518
|
type ImageOutputOptions = CloudflareImageOutputOptions;
|
|
1519
1519
|
type ImageTransformationOutputOptions = CloudflareImageTransformationOutputOptions;
|
|
1520
|
+
type ImageTransformationResponseOptions = CloudflareImageTransformationResponseOptions;
|
|
1520
1521
|
type ImageTransformationResult = CloudflareImageTransformationResult;
|
|
1521
1522
|
type ImageUploadOptions = CloudflareImageUploadOptions;
|
|
1522
1523
|
type ImageUpdateOptions = CloudflareImageUpdateOptions;
|
|
1523
1524
|
type ImageListOptions = CloudflareImageListOptions;
|
|
1524
1525
|
type ImageList = CloudflareImageList;
|
|
1525
1526
|
type ImageMetadata = CloudflareImageMetadata;
|
|
1527
|
+
type ImageSignedUrlOptions = CloudflareImageSignedUrlOptions;
|
|
1528
|
+
type ImageDirectUploadOptions = CloudflareImageDirectUploadOptions;
|
|
1529
|
+
type ImageDirectUploadResult = CloudflareImageDirectUploadResult;
|
|
1530
|
+
type TextOptions = CloudflareTextOptions;
|
|
1526
1531
|
type ImageInputValue = ReadableStream<Uint8Array> | ArrayBuffer;
|
|
1527
1532
|
type ImageUploadValue = ReadableStream<Uint8Array> | ArrayBuffer;
|
|
1528
1533
|
interface DrawStepOptions {
|
|
@@ -1598,14 +1603,18 @@ interface Steps {
|
|
|
1598
1603
|
readonly [TypeId]: typeof TypeId;
|
|
1599
1604
|
readonly steps: ReadonlyArray<Step>;
|
|
1600
1605
|
}
|
|
1601
|
-
|
|
1606
|
+
type ProcessOptions = {
|
|
1602
1607
|
readonly stream: ImageInputValue;
|
|
1603
1608
|
readonly inputOptions?: ImageInputOptions;
|
|
1604
1609
|
readonly outputOptions: ImageOutputOptions;
|
|
1605
|
-
}
|
|
1610
|
+
} | {
|
|
1611
|
+
readonly text: string;
|
|
1612
|
+
readonly textOptions: TextOptions;
|
|
1613
|
+
readonly outputOptions: ImageOutputOptions;
|
|
1614
|
+
};
|
|
1606
1615
|
interface ImagesTransformationResultClient {
|
|
1607
1616
|
readonly raw: CloudflareImageTransformationResult;
|
|
1608
|
-
readonly response: Effect.Effect<CloudflareResponse, ImagesOperationError>;
|
|
1617
|
+
readonly response: (options?: ImageTransformationResponseOptions) => Effect.Effect<CloudflareResponse, ImagesOperationError>;
|
|
1609
1618
|
readonly contentType: Effect.Effect<string, ImagesOperationError>;
|
|
1610
1619
|
readonly image: (options?: ImageTransformationOutputOptions) => Effect.Effect<ReadableStream<Uint8Array>, ImagesOperationError>;
|
|
1611
1620
|
}
|
|
@@ -1613,6 +1622,7 @@ interface ImageHandleClient {
|
|
|
1613
1622
|
readonly raw: CloudflareImageHandle;
|
|
1614
1623
|
readonly details: Effect.Effect<Option.Option<ImageMetadata>, ImagesOperationError>;
|
|
1615
1624
|
readonly bytes: Effect.Effect<Option.Option<ReadableStream<Uint8Array>>, ImagesOperationError>;
|
|
1625
|
+
readonly signedUrl: (options: ImageSignedUrlOptions) => Effect.Effect<string, ImagesOperationError>;
|
|
1616
1626
|
readonly update: (options: ImageUpdateOptions) => Effect.Effect<ImageMetadata, ImagesOperationError>;
|
|
1617
1627
|
readonly delete: Effect.Effect<boolean, ImagesOperationError>;
|
|
1618
1628
|
}
|
|
@@ -1620,16 +1630,19 @@ interface HostedImagesClient {
|
|
|
1620
1630
|
readonly image: (imageId: string) => ImageHandleClient;
|
|
1621
1631
|
readonly upload: (image: ImageUploadValue, options?: ImageUploadOptions) => Effect.Effect<ImageMetadata, ImagesOperationError>;
|
|
1622
1632
|
readonly list: (options?: ImageListOptions) => Effect.Effect<ImageList, ImagesOperationError>;
|
|
1633
|
+
readonly createDirectUpload: (options?: ImageDirectUploadOptions) => Effect.Effect<ImageDirectUploadResult, ImagesOperationError>;
|
|
1623
1634
|
readonly rawUnsafe: Effect.Effect<CloudflareHostedImagesBinding>;
|
|
1624
1635
|
}
|
|
1625
1636
|
interface ImagesRuntimeBinding {
|
|
1626
1637
|
readonly info: (image: ImageInputValue, options?: ImageInputOptions) => Promise<ImageInfoResponse>;
|
|
1627
1638
|
readonly input: (image: ImageInputValue, options?: ImageInputOptions) => CloudflareImageTransformer;
|
|
1639
|
+
readonly text?: (content: string, options: TextOptions) => CloudflareImageTransformer;
|
|
1628
1640
|
readonly hosted?: CloudflareHostedImagesBinding;
|
|
1629
1641
|
}
|
|
1630
1642
|
interface ImagesClient {
|
|
1631
1643
|
readonly info: (image: ImageInputValue, options?: ImageInputOptions) => Effect.Effect<ImageInfoResponse, ImagesOperationError>;
|
|
1632
1644
|
readonly input: (image: ImageInputValue, options?: ImageInputOptions) => Effect.Effect<CloudflareImageTransformer, ImagesOperationError>;
|
|
1645
|
+
readonly text: (content: string, options: TextOptions) => Effect.Effect<CloudflareImageTransformer, ImagesOperationError>;
|
|
1633
1646
|
readonly process: (steps: Steps, options: ProcessOptions) => Effect.Effect<ImagesTransformationResultClient, ImagesOperationError>;
|
|
1634
1647
|
readonly hosted: Option.Option<HostedImagesClient>;
|
|
1635
1648
|
readonly rawUnsafe: Effect.Effect<ImagesRuntimeBinding>;
|
package/dist/index.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
|
|
|
2
2
|
import { a as WorkerEnvironment, i as WorkerConfig, n as violationsMessage, r as Environment_exports, t as causeMessage } from "./ErrorMessage-BM0K-Nik.mjs";
|
|
3
3
|
import { n as Service$2, r as layer$19, t as Binding_exports } from "./Binding-pfilNJmP.mjs";
|
|
4
4
|
import { n as Artifacts_exports } from "./Artifacts-CSIk1Oml.mjs";
|
|
5
|
-
import { a as DurableObjectWebSocket_exports, i as fromExecutionContext, n as DurableObjectState_exports, o as fromWebSocket, r as fromDurableObjectState, s as DurableObjectStorage_exports, t as DurableObjectState } from "./DurableObjectState-
|
|
5
|
+
import { a as DurableObjectWebSocket_exports, i as fromExecutionContext, n as DurableObjectState_exports, o as fromWebSocket, r as fromDurableObjectState, s as DurableObjectStorage_exports, t as DurableObjectState } from "./DurableObjectState-CxS5Y2hf.mjs";
|
|
6
6
|
import { Cause, Clock, Config, ConfigProvider, Context, Data, DateTime, Duration, Effect, Exit, Function as Function$1, Layer, ManagedRuntime, Option, Predicate, Queue, Result, Schema } from "effect";
|
|
7
7
|
import { FetchHttpClient, HttpClient, HttpClientRequest, HttpEffect, HttpServerRequest, HttpServerResponse } from "effect/unstable/http";
|
|
8
8
|
import { OtlpExporter, OtlpLogger, OtlpMetrics, OtlpSerialization, OtlpTracer } from "effect/unstable/observability";
|
|
@@ -2918,11 +2918,11 @@ const tryImagesSync = (binding, operation, evaluate) => Effect.try({
|
|
|
2918
2918
|
});
|
|
2919
2919
|
const maybe = (value) => value === null ? Option.none() : Option.some(value);
|
|
2920
2920
|
const hasFunction = (value, key) => Predicate.hasProperty(value, key) && Predicate.isFunction(value[key]);
|
|
2921
|
-
const isHostedImagesBinding = (value) => hasFunction(value, "image") && hasFunction(value, "upload") && hasFunction(value, "list");
|
|
2921
|
+
const isHostedImagesBinding = (value) => hasFunction(value, "image") && hasFunction(value, "upload") && hasFunction(value, "list") && hasFunction(value, "createDirectUpload");
|
|
2922
2922
|
const isImagesBinding = (value) => hasFunction(value, "info") && hasFunction(value, "input");
|
|
2923
2923
|
const wrapResult = (binding, result) => ({
|
|
2924
2924
|
raw: result,
|
|
2925
|
-
response: tryImagesSync(binding, "response", () => result.response()),
|
|
2925
|
+
response: (options) => tryImagesSync(binding, "response", () => result.response(options)),
|
|
2926
2926
|
contentType: tryImagesSync(binding, "contentType", () => result.contentType()),
|
|
2927
2927
|
image: (options) => tryImagesSync(binding, "image", () => result.image(options))
|
|
2928
2928
|
});
|
|
@@ -2930,6 +2930,7 @@ const wrapHandle = (binding, handle) => ({
|
|
|
2930
2930
|
raw: handle,
|
|
2931
2931
|
details: tryImagesPromise(binding, "details", () => handle.details()).pipe(Effect.map(maybe), Effect.withSpan("Images.details")),
|
|
2932
2932
|
bytes: tryImagesPromise(binding, "bytes", () => handle.bytes()).pipe(Effect.map(maybe), Effect.withSpan("Images.bytes")),
|
|
2933
|
+
signedUrl: Effect.fn("Images.signedUrl")((options) => tryImagesPromise(binding, "signedUrl", () => handle.signedUrl(options))),
|
|
2933
2934
|
update: Effect.fn("Images.update")((options) => tryImagesPromise(binding, "update", () => handle.update(options))),
|
|
2934
2935
|
delete: tryImagesPromise(binding, "delete", () => handle.delete()).pipe(Effect.withSpan("Images.delete"))
|
|
2935
2936
|
});
|
|
@@ -2937,12 +2938,17 @@ const wrapHosted = (binding, hosted) => ({
|
|
|
2937
2938
|
image: (imageId) => wrapHandle(binding, hosted.image(imageId)),
|
|
2938
2939
|
upload: Effect.fn("Images.upload")((image, options) => tryImagesPromise(binding, "upload", () => hosted.upload(image, options))),
|
|
2939
2940
|
list: Effect.fn("Images.list")((options) => tryImagesPromise(binding, "list", () => hosted.list(options))),
|
|
2941
|
+
createDirectUpload: Effect.fn("Images.createDirectUpload")((options) => tryImagesPromise(binding, "createDirectUpload", () => hosted.createDirectUpload(options))),
|
|
2940
2942
|
rawUnsafe: Effect.succeed(hosted)
|
|
2941
2943
|
});
|
|
2942
2944
|
const makeClient$4 = (definition) => (images) => {
|
|
2943
2945
|
const input = (image, options) => tryImagesSync(definition.binding, "input", () => images.input(image, options));
|
|
2946
|
+
const text = (content, options) => tryImagesSync(definition.binding, "text", () => {
|
|
2947
|
+
if (!hasFunction(images, "text")) throw new Error("Images binding is missing text()");
|
|
2948
|
+
return images.text(content, options);
|
|
2949
|
+
});
|
|
2944
2950
|
const process = Effect.fn("Images.process")(function* (steps, options) {
|
|
2945
|
-
let transformer = yield* input(options.stream, options.inputOptions);
|
|
2951
|
+
let transformer = "text" in options ? yield* text(options.text, options.textOptions) : yield* input(options.stream, options.inputOptions);
|
|
2946
2952
|
for (const step of steps.steps) transformer = yield* Step.$match(step, {
|
|
2947
2953
|
Draw: (drawStep) => tryImagesSync(definition.binding, "draw", () => transformer.draw(drawStep.image, drawStep.options)),
|
|
2948
2954
|
Transform: (transformStep) => tryImagesSync(definition.binding, "transform", () => transformer.transform(transformStep.transform))
|
|
@@ -2954,6 +2960,7 @@ const makeClient$4 = (definition) => (images) => {
|
|
|
2954
2960
|
definition,
|
|
2955
2961
|
info: Effect.fn("Images.info")((image, options) => tryImagesPromise(definition.binding, "info", () => images.info(image, options))),
|
|
2956
2962
|
input,
|
|
2963
|
+
text,
|
|
2957
2964
|
process,
|
|
2958
2965
|
hosted: isHostedImagesBinding(images.hosted) ? Option.some(wrapHosted(definition.binding, images.hosted)) : Option.none(),
|
|
2959
2966
|
rawUnsafe: Effect.succeed(images)
|
|
@@ -3377,8 +3384,9 @@ const makeClient = (definition) => {
|
|
|
3377
3384
|
id: raw.id,
|
|
3378
3385
|
pause: operation("pause", () => raw.pause()),
|
|
3379
3386
|
resume: operation("resume", () => raw.resume()),
|
|
3380
|
-
terminate: operation("terminate", () => raw.terminate()),
|
|
3387
|
+
terminate: (options) => operation("terminate", () => raw.terminate(options)),
|
|
3381
3388
|
restart: (options) => operation("restart", () => raw.restart(options)),
|
|
3389
|
+
delete: operation("delete", () => raw.delete()),
|
|
3382
3390
|
status: operation("status", () => raw.status()).pipe(Effect.flatMap((status) => Effect.gen(function* () {
|
|
3383
3391
|
const output = status.output === void 0 || status.output === null && status.status !== "complete" ? Option.none() : Option.some(yield* decodeResult(status.output).pipe(Effect.mapError((cause) => new WorkflowResultDecodeError({
|
|
3384
3392
|
binding: definition.binding,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "effect-cf",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.31.0",
|
|
4
4
|
"description": "Effect-native primitives for Cloudflare Workers and bindings.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
"@cloudflare/computer": "0.2.0",
|
|
69
69
|
"@cloudflare/containers": "catalog:",
|
|
70
70
|
"@cloudflare/sandbox": "0.13.0-next.738.2",
|
|
71
|
-
"@cloudflare/vitest-
|
|
71
|
+
"@cloudflare/vitest-plugin": "catalog:",
|
|
72
72
|
"@cloudflare/workers-types": "catalog:",
|
|
73
73
|
"@effect/platform-node": "^4.0.0-rc.110",
|
|
74
74
|
"@effect/sql-d1": "catalog:",
|
|
@@ -84,8 +84,8 @@
|
|
|
84
84
|
"peerDependencies": {
|
|
85
85
|
"@cloudflare/computer": "^0.2.0",
|
|
86
86
|
"@cloudflare/sandbox": "^0.13.0-next.738.2",
|
|
87
|
-
"@cloudflare/vitest-
|
|
88
|
-
"@cloudflare/workers-types": "^
|
|
87
|
+
"@cloudflare/vitest-plugin": "^1.0.0",
|
|
88
|
+
"@cloudflare/workers-types": "^5.20260820.1",
|
|
89
89
|
"@effect/sql-d1": "^4.0.0-rc.110",
|
|
90
90
|
"@effect/sql-pg": "^4.0.0-rc.110",
|
|
91
91
|
"@effect/sql-sqlite-do": "^4.0.0-rc.110",
|
|
@@ -98,7 +98,7 @@
|
|
|
98
98
|
"@cloudflare/sandbox": {
|
|
99
99
|
"optional": true
|
|
100
100
|
},
|
|
101
|
-
"@cloudflare/vitest-
|
|
101
|
+
"@cloudflare/vitest-plugin": {
|
|
102
102
|
"optional": true
|
|
103
103
|
},
|
|
104
104
|
"@cloudflare/workers-types": {
|
package/src/Images.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
HostedImagesBinding as CloudflareHostedImagesBinding,
|
|
3
|
+
ImageDirectUploadOptions as CloudflareImageDirectUploadOptions,
|
|
4
|
+
ImageDirectUploadResult as CloudflareImageDirectUploadResult,
|
|
3
5
|
ImageDrawOptions as CloudflareImageDrawOptions,
|
|
4
6
|
ImageHandle as CloudflareImageHandle,
|
|
5
7
|
ImageInfoResponse as CloudflareImageInfoResponse,
|
|
@@ -8,13 +10,16 @@ import type {
|
|
|
8
10
|
ImageListOptions as CloudflareImageListOptions,
|
|
9
11
|
ImageMetadata as CloudflareImageMetadata,
|
|
10
12
|
ImageOutputOptions as CloudflareImageOutputOptions,
|
|
13
|
+
ImageSignedUrlOptions as CloudflareImageSignedUrlOptions,
|
|
11
14
|
ImageTransform as CloudflareImageTransform,
|
|
12
15
|
ImageTransformationOutputOptions as CloudflareImageTransformationOutputOptions,
|
|
16
|
+
ImageTransformationResponseOptions as CloudflareImageTransformationResponseOptions,
|
|
13
17
|
ImageTransformationResult as CloudflareImageTransformationResult,
|
|
14
18
|
ImageTransformer as CloudflareImageTransformer,
|
|
15
19
|
ImageUpdateOptions as CloudflareImageUpdateOptions,
|
|
16
20
|
ImageUploadOptions as CloudflareImageUploadOptions,
|
|
17
21
|
Response as CloudflareResponse,
|
|
22
|
+
TextOptions as CloudflareTextOptions,
|
|
18
23
|
} from "@cloudflare/workers-types";
|
|
19
24
|
import { Context, Data, Effect, Function, Option, Predicate, type Layer } from "effect";
|
|
20
25
|
|
|
@@ -51,12 +56,17 @@ export type ImageDrawOptions = CloudflareImageDrawOptions;
|
|
|
51
56
|
export type ImageInputOptions = CloudflareImageInputOptions;
|
|
52
57
|
export type ImageOutputOptions = CloudflareImageOutputOptions;
|
|
53
58
|
export type ImageTransformationOutputOptions = CloudflareImageTransformationOutputOptions;
|
|
59
|
+
export type ImageTransformationResponseOptions = CloudflareImageTransformationResponseOptions;
|
|
54
60
|
export type ImageTransformationResult = CloudflareImageTransformationResult;
|
|
55
61
|
export type ImageUploadOptions = CloudflareImageUploadOptions;
|
|
56
62
|
export type ImageUpdateOptions = CloudflareImageUpdateOptions;
|
|
57
63
|
export type ImageListOptions = CloudflareImageListOptions;
|
|
58
64
|
export type ImageList = CloudflareImageList;
|
|
59
65
|
export type ImageMetadata = CloudflareImageMetadata;
|
|
66
|
+
export type ImageSignedUrlOptions = CloudflareImageSignedUrlOptions;
|
|
67
|
+
export type ImageDirectUploadOptions = CloudflareImageDirectUploadOptions;
|
|
68
|
+
export type ImageDirectUploadResult = CloudflareImageDirectUploadResult;
|
|
69
|
+
export type TextOptions = CloudflareTextOptions;
|
|
60
70
|
export type ImageInputValue = ReadableStream<Uint8Array> | ArrayBuffer;
|
|
61
71
|
export type ImageUploadValue = ReadableStream<Uint8Array> | ArrayBuffer;
|
|
62
72
|
|
|
@@ -79,15 +89,23 @@ export interface Steps {
|
|
|
79
89
|
readonly steps: ReadonlyArray<Step>;
|
|
80
90
|
}
|
|
81
91
|
|
|
82
|
-
export
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
92
|
+
export type ProcessOptions =
|
|
93
|
+
| {
|
|
94
|
+
readonly stream: ImageInputValue;
|
|
95
|
+
readonly inputOptions?: ImageInputOptions;
|
|
96
|
+
readonly outputOptions: ImageOutputOptions;
|
|
97
|
+
}
|
|
98
|
+
| {
|
|
99
|
+
readonly text: string;
|
|
100
|
+
readonly textOptions: TextOptions;
|
|
101
|
+
readonly outputOptions: ImageOutputOptions;
|
|
102
|
+
};
|
|
87
103
|
|
|
88
104
|
export interface ImagesTransformationResultClient {
|
|
89
105
|
readonly raw: CloudflareImageTransformationResult;
|
|
90
|
-
readonly response:
|
|
106
|
+
readonly response: (
|
|
107
|
+
options?: ImageTransformationResponseOptions,
|
|
108
|
+
) => Effect.Effect<CloudflareResponse, ImagesOperationError>;
|
|
91
109
|
readonly contentType: Effect.Effect<string, ImagesOperationError>;
|
|
92
110
|
readonly image: (
|
|
93
111
|
options?: ImageTransformationOutputOptions,
|
|
@@ -98,6 +116,9 @@ export interface ImageHandleClient {
|
|
|
98
116
|
readonly raw: CloudflareImageHandle;
|
|
99
117
|
readonly details: Effect.Effect<Option.Option<ImageMetadata>, ImagesOperationError>;
|
|
100
118
|
readonly bytes: Effect.Effect<Option.Option<ReadableStream<Uint8Array>>, ImagesOperationError>;
|
|
119
|
+
readonly signedUrl: (
|
|
120
|
+
options: ImageSignedUrlOptions,
|
|
121
|
+
) => Effect.Effect<string, ImagesOperationError>;
|
|
101
122
|
readonly update: (
|
|
102
123
|
options: ImageUpdateOptions,
|
|
103
124
|
) => Effect.Effect<ImageMetadata, ImagesOperationError>;
|
|
@@ -111,6 +132,9 @@ export interface HostedImagesClient {
|
|
|
111
132
|
options?: ImageUploadOptions,
|
|
112
133
|
) => Effect.Effect<ImageMetadata, ImagesOperationError>;
|
|
113
134
|
readonly list: (options?: ImageListOptions) => Effect.Effect<ImageList, ImagesOperationError>;
|
|
135
|
+
readonly createDirectUpload: (
|
|
136
|
+
options?: ImageDirectUploadOptions,
|
|
137
|
+
) => Effect.Effect<ImageDirectUploadResult, ImagesOperationError>;
|
|
114
138
|
readonly rawUnsafe: Effect.Effect<CloudflareHostedImagesBinding>;
|
|
115
139
|
}
|
|
116
140
|
|
|
@@ -123,6 +147,7 @@ export interface ImagesRuntimeBinding {
|
|
|
123
147
|
image: ImageInputValue,
|
|
124
148
|
options?: ImageInputOptions,
|
|
125
149
|
) => CloudflareImageTransformer;
|
|
150
|
+
readonly text?: (content: string, options: TextOptions) => CloudflareImageTransformer;
|
|
126
151
|
readonly hosted?: CloudflareHostedImagesBinding;
|
|
127
152
|
}
|
|
128
153
|
|
|
@@ -135,6 +160,10 @@ export interface ImagesClient {
|
|
|
135
160
|
image: ImageInputValue,
|
|
136
161
|
options?: ImageInputOptions,
|
|
137
162
|
) => Effect.Effect<CloudflareImageTransformer, ImagesOperationError>;
|
|
163
|
+
readonly text: (
|
|
164
|
+
content: string,
|
|
165
|
+
options: TextOptions,
|
|
166
|
+
) => Effect.Effect<CloudflareImageTransformer, ImagesOperationError>;
|
|
138
167
|
readonly process: (
|
|
139
168
|
steps: Steps,
|
|
140
169
|
options: ProcessOptions,
|
|
@@ -230,7 +259,10 @@ const hasFunction = <Candidate>(value: Candidate, key: string): boolean =>
|
|
|
230
259
|
const isHostedImagesBinding = <Candidate>(
|
|
231
260
|
value: Candidate,
|
|
232
261
|
): value is Candidate & CloudflareHostedImagesBinding =>
|
|
233
|
-
hasFunction(value, "image") &&
|
|
262
|
+
hasFunction(value, "image") &&
|
|
263
|
+
hasFunction(value, "upload") &&
|
|
264
|
+
hasFunction(value, "list") &&
|
|
265
|
+
hasFunction(value, "createDirectUpload");
|
|
234
266
|
|
|
235
267
|
export const isImagesBinding = <Candidate>(
|
|
236
268
|
value: Candidate,
|
|
@@ -242,7 +274,7 @@ const wrapResult = (
|
|
|
242
274
|
result: CloudflareImageTransformationResult,
|
|
243
275
|
): ImagesTransformationResultClient => ({
|
|
244
276
|
raw: result,
|
|
245
|
-
response: tryImagesSync(binding, "response", () => result.response()),
|
|
277
|
+
response: (options) => tryImagesSync(binding, "response", () => result.response(options)),
|
|
246
278
|
contentType: tryImagesSync(binding, "contentType", () => result.contentType()),
|
|
247
279
|
image: (options) => tryImagesSync(binding, "image", () => result.image(options)),
|
|
248
280
|
});
|
|
@@ -257,6 +289,9 @@ const wrapHandle = (binding: string, handle: CloudflareImageHandle): ImageHandle
|
|
|
257
289
|
Effect.map(maybe),
|
|
258
290
|
Effect.withSpan("Images.bytes"),
|
|
259
291
|
),
|
|
292
|
+
signedUrl: Effect.fn("Images.signedUrl")((options: ImageSignedUrlOptions) =>
|
|
293
|
+
tryImagesPromise(binding, "signedUrl", () => handle.signedUrl(options)),
|
|
294
|
+
),
|
|
260
295
|
update: Effect.fn("Images.update")((options: ImageUpdateOptions) =>
|
|
261
296
|
tryImagesPromise(binding, "update", () => handle.update(options)),
|
|
262
297
|
),
|
|
@@ -276,6 +311,9 @@ const wrapHosted = (
|
|
|
276
311
|
list: Effect.fn("Images.list")((options?: ImageListOptions) =>
|
|
277
312
|
tryImagesPromise(binding, "list", () => hosted.list(options)),
|
|
278
313
|
),
|
|
314
|
+
createDirectUpload: Effect.fn("Images.createDirectUpload")((options?: ImageDirectUploadOptions) =>
|
|
315
|
+
tryImagesPromise(binding, "createDirectUpload", () => hosted.createDirectUpload(options)),
|
|
316
|
+
),
|
|
279
317
|
rawUnsafe: Effect.succeed(hosted),
|
|
280
318
|
});
|
|
281
319
|
|
|
@@ -285,8 +323,20 @@ export const makeClient =
|
|
|
285
323
|
const input = (image: ImageInputValue, options?: ImageInputOptions) =>
|
|
286
324
|
tryImagesSync(definition.binding, "input", () => images.input(image, options));
|
|
287
325
|
|
|
326
|
+
const text = (content: string, options: TextOptions) =>
|
|
327
|
+
tryImagesSync(definition.binding, "text", () => {
|
|
328
|
+
if (!hasFunction(images, "text")) {
|
|
329
|
+
throw new Error("Images binding is missing text()");
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
return images.text!(content, options);
|
|
333
|
+
});
|
|
334
|
+
|
|
288
335
|
const process = Effect.fn("Images.process")(function* (steps: Steps, options: ProcessOptions) {
|
|
289
|
-
let transformer =
|
|
336
|
+
let transformer =
|
|
337
|
+
"text" in options
|
|
338
|
+
? yield* text(options.text, options.textOptions)
|
|
339
|
+
: yield* input(options.stream, options.inputOptions);
|
|
290
340
|
|
|
291
341
|
for (const step of steps.steps) {
|
|
292
342
|
transformer = yield* Step.$match(step, {
|
|
@@ -314,6 +364,7 @@ export const makeClient =
|
|
|
314
364
|
tryImagesPromise(definition.binding, "info", () => images.info(image, options)),
|
|
315
365
|
),
|
|
316
366
|
input,
|
|
367
|
+
text,
|
|
317
368
|
process,
|
|
318
369
|
hosted: isHostedImagesBinding(images.hosted)
|
|
319
370
|
? Option.some(wrapHosted(definition.binding, images.hosted))
|
package/src/Vitest.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Effect-native helpers for tests running in Cloudflare's Vitest
|
|
2
|
+
* Effect-native helpers for tests running in Cloudflare's Workers Vitest plugin.
|
|
3
3
|
*
|
|
4
4
|
* Import this module through the `effect-cf/vitest` subpath. It is intended to
|
|
5
5
|
* run inside the Workers test runtime, where `cloudflare:test` is available.
|
|
@@ -37,7 +37,7 @@ import type { WorkflowInstanceStatusName } from "./WorkflowBinding";
|
|
|
37
37
|
const currentEnv: WorkerEnv = env;
|
|
38
38
|
|
|
39
39
|
/**
|
|
40
|
-
* Provides the Workers
|
|
40
|
+
* Provides the Workers test environment as both {@link WorkerEnvironment} and
|
|
41
41
|
* the active Effect `ConfigProvider`.
|
|
42
42
|
*/
|
|
43
43
|
export const layer: Layer.Layer<WorkerEnvironment> = Layer.mergeAll(
|
|
@@ -134,7 +134,7 @@ type PagesEventContextInitData<Context> =
|
|
|
134
134
|
: { readonly data: Data }
|
|
135
135
|
: never;
|
|
136
136
|
|
|
137
|
-
/** Initialization accepted by
|
|
137
|
+
/** Initialization accepted by the Workers Vitest plugin for a Pages Function. */
|
|
138
138
|
export type PagesEventContextInit<Function extends AnyPagesFunction> = PagesEventContextInitBase &
|
|
139
139
|
PagesEventContextInitParams<Parameters<Function>[0]> &
|
|
140
140
|
PagesEventContextInitData<Parameters<Function>[0]>;
|
|
@@ -162,14 +162,14 @@ interface QueueWorker {
|
|
|
162
162
|
queue(batch: globalThis.MessageBatch): Promise<void>;
|
|
163
163
|
}
|
|
164
164
|
|
|
165
|
-
/** Input message accepted by
|
|
165
|
+
/** Input message accepted by the Workers Vitest plugin's `createMessageBatch` helper. */
|
|
166
166
|
export type QueueMessage<Body> = {
|
|
167
167
|
readonly id: string;
|
|
168
168
|
readonly timestamp: Date;
|
|
169
169
|
readonly attempts: number;
|
|
170
170
|
} & ({ readonly body: Body } | { readonly serializedBody: ArrayBuffer | ArrayBufferView });
|
|
171
171
|
|
|
172
|
-
/** Acknowledgement and retry result returned by
|
|
172
|
+
/** Acknowledgement and retry result returned by the Workers Vitest plugin. */
|
|
173
173
|
export type QueueResult = Awaited<ReturnType<typeof getQueueResult>>;
|
|
174
174
|
|
|
175
175
|
/** Result of invoking a queue consumer through {@link queue}. */
|
|
@@ -180,7 +180,7 @@ export interface QueueRunResult<Body> {
|
|
|
180
180
|
|
|
181
181
|
/**
|
|
182
182
|
* Invokes an Effect-backed queue consumer, drains its `waitUntil` work, and
|
|
183
|
-
* returns
|
|
183
|
+
* returns the Workers Vitest plugin's acknowledgement and retry result.
|
|
184
184
|
*/
|
|
185
185
|
export const queue = Effect.fn("effect-cf/vitest/queue")(function* <
|
|
186
186
|
Body,
|
|
@@ -280,7 +280,7 @@ export const evictAllDurableObjects = Effect.fn("effect-cf/vitest/evictAllDurabl
|
|
|
280
280
|
},
|
|
281
281
|
);
|
|
282
282
|
|
|
283
|
-
/** A D1 migration accepted by
|
|
283
|
+
/** A D1 migration accepted by the Workers Vitest plugin. */
|
|
284
284
|
export interface D1Migration {
|
|
285
285
|
readonly name: string;
|
|
286
286
|
readonly queries: ReadonlyArray<string>;
|
|
@@ -310,7 +310,7 @@ export interface SecretsStoreSecret {
|
|
|
310
310
|
readonly metadata?: { readonly uuid: string };
|
|
311
311
|
}
|
|
312
312
|
|
|
313
|
-
/** Effect-native wrapper around
|
|
313
|
+
/** Effect-native wrapper around the Workers Vitest plugin's Secrets Store admin API. */
|
|
314
314
|
export interface SecretsStoreAdmin {
|
|
315
315
|
readonly raw: NativeSecretsStoreAdmin;
|
|
316
316
|
readonly create: (value: string) => Effect.Effect<string>;
|
|
@@ -445,7 +445,7 @@ const runWorkflowModifier = Effect.fnUntraced(function* <A, E, R>(
|
|
|
445
445
|
}
|
|
446
446
|
|
|
447
447
|
if (callbackExit === undefined) {
|
|
448
|
-
throw new Error("
|
|
448
|
+
throw new Error("The Workers Vitest plugin did not invoke the Workflow modifier callback");
|
|
449
449
|
}
|
|
450
450
|
|
|
451
451
|
return callbackExit;
|
package/src/Worker.ts
CHANGED
|
@@ -46,6 +46,8 @@ export interface WorkerContextService {
|
|
|
46
46
|
options?: Omit<WorkerContextWaitUntilOptions<E, R2>, "mode">,
|
|
47
47
|
): Effect.Effect<void, never, R | R2>;
|
|
48
48
|
readonly passThroughOnException: Effect.Effect<void>;
|
|
49
|
+
/** Abort the current stateless Worker invocation (`ExecutionContext.abort`). */
|
|
50
|
+
abort(reason?: string): Effect.Effect<void>;
|
|
49
51
|
}
|
|
50
52
|
|
|
51
53
|
/**
|
package/src/WorkflowBinding.ts
CHANGED
|
@@ -3,7 +3,9 @@ import type {
|
|
|
3
3
|
Workflow as CloudflareWorkflow,
|
|
4
4
|
WorkflowInstance as CloudflareWorkflowInstance,
|
|
5
5
|
WorkflowInstanceCreateOptions as CloudflareWorkflowInstanceCreateOptions,
|
|
6
|
+
WorkflowInstanceLocationHint as CloudflareWorkflowInstanceLocationHint,
|
|
6
7
|
WorkflowInstanceRestartOptions as CloudflareWorkflowInstanceRestartOptions,
|
|
8
|
+
WorkflowInstanceTerminateOptions as CloudflareWorkflowInstanceTerminateOptions,
|
|
7
9
|
} from "@cloudflare/workers-types";
|
|
8
10
|
import { type Context, Data, Effect, Option, Predicate, Schema as S } from "effect";
|
|
9
11
|
|
|
@@ -23,6 +25,8 @@ export type WorkflowInstanceCreateBatchOptions<Payload, EncodedPayload = unknown
|
|
|
23
25
|
>;
|
|
24
26
|
|
|
25
27
|
export type WorkflowInstanceRestartOptions = CloudflareWorkflowInstanceRestartOptions;
|
|
28
|
+
export type WorkflowInstanceTerminateOptions = CloudflareWorkflowInstanceTerminateOptions;
|
|
29
|
+
export type WorkflowInstanceLocationHint = CloudflareWorkflowInstanceLocationHint;
|
|
26
30
|
|
|
27
31
|
export type WorkflowInstanceStatusName = CloudflareInstanceStatus["status"];
|
|
28
32
|
|
|
@@ -40,10 +44,13 @@ export interface WorkflowInstance<Result> {
|
|
|
40
44
|
readonly id: string;
|
|
41
45
|
readonly pause: Effect.Effect<void, WorkflowOperationError>;
|
|
42
46
|
readonly resume: Effect.Effect<void, WorkflowOperationError>;
|
|
43
|
-
readonly terminate:
|
|
47
|
+
readonly terminate: (
|
|
48
|
+
options?: WorkflowInstanceTerminateOptions,
|
|
49
|
+
) => Effect.Effect<void, WorkflowOperationError>;
|
|
44
50
|
readonly restart: (
|
|
45
51
|
options?: WorkflowInstanceRestartOptions,
|
|
46
52
|
) => Effect.Effect<void, WorkflowOperationError>;
|
|
53
|
+
readonly delete: Effect.Effect<void, WorkflowOperationError>;
|
|
47
54
|
readonly status: Effect.Effect<
|
|
48
55
|
WorkflowInstanceStatus<Result>,
|
|
49
56
|
WorkflowOperationError | WorkflowResultDecodeError
|
|
@@ -165,8 +172,9 @@ export const makeClient = <
|
|
|
165
172
|
id: raw.id,
|
|
166
173
|
pause: operation("pause", () => raw.pause()),
|
|
167
174
|
resume: operation("resume", () => raw.resume()),
|
|
168
|
-
terminate: operation("terminate", () => raw.terminate()),
|
|
175
|
+
terminate: (options) => operation("terminate", () => raw.terminate(options)),
|
|
169
176
|
restart: (options) => operation("restart", () => raw.restart(options)),
|
|
177
|
+
delete: operation("delete", () => raw.delete()),
|
|
170
178
|
status: operation("status", () => raw.status()).pipe(
|
|
171
179
|
Effect.flatMap((status) =>
|
|
172
180
|
Effect.gen(function* () {
|
|
@@ -101,5 +101,6 @@ export const fromExecutionContext = (
|
|
|
101
101
|
options?: Omit<WorkerContextWaitUntilOptions<E, R2>, "mode">,
|
|
102
102
|
) => schedule(effect, options, "propagate"),
|
|
103
103
|
passThroughOnException: Effect.sync(() => ctx.passThroughOnException()),
|
|
104
|
+
abort: (reason?: string) => Effect.sync(() => ctx.abort(reason)),
|
|
104
105
|
};
|
|
105
106
|
};
|