@ontrails/cloudflare 0.2.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 +160 -0
- package/README.md +269 -0
- package/package.json +57 -0
- package/src/d1/index.ts +1087 -0
- package/src/env.ts +309 -0
- package/src/facts.ts +112 -0
- package/src/index.ts +96 -0
- package/src/kv/index.ts +275 -0
- package/src/queues/index.ts +746 -0
- package/src/r2/index.ts +736 -0
- package/src/workers/index.ts +280 -0
package/src/env.ts
ADDED
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Cloudflare env bridge.
|
|
3
|
+
*
|
|
4
|
+
* Worker bindings (KV, D1, R2, queues) arrive per-request on the `env`
|
|
5
|
+
* argument of the Worker `fetch` handler. Trails resources are authored as
|
|
6
|
+
* ordinary `resource()` definitions, so this module provides the seam that
|
|
7
|
+
* connects the two: a subpath registers an {@link EnvBindingSpec} for each
|
|
8
|
+
* resource definition it authors, and the Workers materializer resolves those
|
|
9
|
+
* specs against the live `env` into per-materialization resource overrides.
|
|
10
|
+
*
|
|
11
|
+
* Overrides are re-resolved whenever a new `env` object arrives, and core
|
|
12
|
+
* resolves overrides before its singleton resource cache, so no resource
|
|
13
|
+
* instance can capture a stale env. Every Cloudflare service subpath consumes
|
|
14
|
+
* this one seam.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import {
|
|
18
|
+
InternalError,
|
|
19
|
+
matchesTrailPattern,
|
|
20
|
+
Result,
|
|
21
|
+
filterSurfaceTrails,
|
|
22
|
+
isLiveTrailVersionEntry,
|
|
23
|
+
} from '@ontrails/core';
|
|
24
|
+
import type {
|
|
25
|
+
AnyResource,
|
|
26
|
+
BaseSurfaceOptions,
|
|
27
|
+
ResourceOverrideMap,
|
|
28
|
+
Topo,
|
|
29
|
+
Trail,
|
|
30
|
+
} from '@ontrails/core';
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* The ambient Worker environment: bindings keyed by their wrangler-configured
|
|
34
|
+
* names. Values are runtime binding objects (KV namespaces, D1 databases,
|
|
35
|
+
* R2 buckets, queues), so they are typed as `unknown` and narrowed by each
|
|
36
|
+
* subpath.
|
|
37
|
+
*/
|
|
38
|
+
export type WorkersEnv = Readonly<Record<string, unknown>>;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* How a resource definition materializes from the Worker env.
|
|
42
|
+
*
|
|
43
|
+
* `fromEnv` receives the raw binding value found at `env[binding]` and either
|
|
44
|
+
* narrows it into the resource instance or explains why the binding does not
|
|
45
|
+
* match the resource's expectations.
|
|
46
|
+
*/
|
|
47
|
+
export interface EnvBindingSpec {
|
|
48
|
+
/** The wrangler binding name to read from the Worker env. */
|
|
49
|
+
readonly binding: string;
|
|
50
|
+
/** Narrow the raw binding value into the resource instance. */
|
|
51
|
+
readonly fromEnv: (value: unknown) => Result<unknown, Error>;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const envBindings = new WeakMap<AnyResource, EnvBindingSpec>();
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Register an env binding for a resource definition.
|
|
58
|
+
*
|
|
59
|
+
* Called by Cloudflare subpaths (and available to apps authoring their own
|
|
60
|
+
* env-bound resources) so the Workers materializer knows how to build the
|
|
61
|
+
* resource instance from the per-request env.
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```ts
|
|
65
|
+
* import { resource, Result } from '@ontrails/core';
|
|
66
|
+
* import { registerEnvBinding } from '@ontrails/cloudflare/workers';
|
|
67
|
+
*
|
|
68
|
+
* const queue = resource<{ send(body: string): Promise<void> }>('outbox', {
|
|
69
|
+
* create: () => Result.err(new Error('outbox is only available on Workers')),
|
|
70
|
+
* mock: () => ({ send: () => Promise.resolve() }),
|
|
71
|
+
* });
|
|
72
|
+
* registerEnvBinding(queue, {
|
|
73
|
+
* binding: 'OUTBOX',
|
|
74
|
+
* fromEnv: (value) => Result.ok(value),
|
|
75
|
+
* });
|
|
76
|
+
* ```
|
|
77
|
+
*/
|
|
78
|
+
export const registerEnvBinding = (
|
|
79
|
+
resourceDefinition: AnyResource,
|
|
80
|
+
spec: EnvBindingSpec
|
|
81
|
+
): void => {
|
|
82
|
+
envBindings.set(resourceDefinition, spec);
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Read the env binding registered for a resource definition, if any.
|
|
87
|
+
*
|
|
88
|
+
* @example
|
|
89
|
+
* ```ts
|
|
90
|
+
* import { getEnvBinding } from '@ontrails/cloudflare/workers';
|
|
91
|
+
* import { cloudflareKv } from '@ontrails/cloudflare/kv';
|
|
92
|
+
*
|
|
93
|
+
* const flags = cloudflareKv('flags', { binding: 'FLAGS' });
|
|
94
|
+
* getEnvBinding(flags)?.binding; // 'FLAGS'
|
|
95
|
+
* ```
|
|
96
|
+
*/
|
|
97
|
+
export const getEnvBinding = (
|
|
98
|
+
resourceDefinition: AnyResource
|
|
99
|
+
): EnvBindingSpec | undefined => envBindings.get(resourceDefinition);
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Options for {@link buildEnvResourceOverrides}.
|
|
103
|
+
*
|
|
104
|
+
* `exclude`/`include`/`intent` mirror the fetch kernel's surface selection so
|
|
105
|
+
* env resolution only considers trails the surface actually exposes — a
|
|
106
|
+
* filtered-out trail's bindings are never required. `except` names resource
|
|
107
|
+
* IDs already provided explicitly, which skip env resolution entirely.
|
|
108
|
+
*/
|
|
109
|
+
export interface BuildEnvResourceOverridesOptions extends Pick<
|
|
110
|
+
BaseSurfaceOptions,
|
|
111
|
+
'exclude' | 'include' | 'intent'
|
|
112
|
+
> {
|
|
113
|
+
/** Resource IDs already provided explicitly; env resolution skips them. */
|
|
114
|
+
readonly except?: readonly string[] | undefined;
|
|
115
|
+
/** Worker entrypoint whose reachable resources should be materialized. */
|
|
116
|
+
readonly entrypoint?: 'fetch' | 'queue' | undefined;
|
|
117
|
+
/** Physical queue delivered to the current queue entrypoint. */
|
|
118
|
+
readonly queue?: string | undefined;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const isInternalTrail = (
|
|
122
|
+
graphTrail: Trail<unknown, unknown, unknown>
|
|
123
|
+
): boolean =>
|
|
124
|
+
graphTrail.visibility === 'internal' ||
|
|
125
|
+
graphTrail.meta?.['internal'] === true;
|
|
126
|
+
|
|
127
|
+
const matchesAnyPattern = (
|
|
128
|
+
trailId: string,
|
|
129
|
+
patterns: readonly string[] | undefined
|
|
130
|
+
): boolean =>
|
|
131
|
+
patterns !== undefined &&
|
|
132
|
+
patterns.some((pattern) => matchesTrailPattern(trailId, pattern));
|
|
133
|
+
|
|
134
|
+
const passesIncludeFilter = (
|
|
135
|
+
trailId: string,
|
|
136
|
+
include: readonly string[] | undefined
|
|
137
|
+
): boolean =>
|
|
138
|
+
include === undefined ||
|
|
139
|
+
include.length === 0 ||
|
|
140
|
+
matchesAnyPattern(trailId, include);
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Mirror of Worker activation eligibility for one entrypoint. Activation
|
|
144
|
+
* consumers are skipped by `filterSurfaceTrails`, so the bridge selects them
|
|
145
|
+
* explicitly without making fetch depend on queue-only resources.
|
|
146
|
+
*/
|
|
147
|
+
const isEligibleWorkerActivationTrail = (
|
|
148
|
+
graphTrail: Trail<unknown, unknown, unknown>,
|
|
149
|
+
options: BuildEnvResourceOverridesOptions
|
|
150
|
+
): boolean => {
|
|
151
|
+
const activationKind =
|
|
152
|
+
(options.entrypoint ?? 'fetch') === 'queue' ? 'queue' : 'webhook';
|
|
153
|
+
const hasWorkerActivationSource = graphTrail.activationSources.some(
|
|
154
|
+
(activation) =>
|
|
155
|
+
activation.source.kind === activationKind &&
|
|
156
|
+
(activationKind !== 'queue' ||
|
|
157
|
+
options.queue === undefined ||
|
|
158
|
+
(typeof activation.source.queue === 'string' &&
|
|
159
|
+
activation.source.queue.trim() === options.queue))
|
|
160
|
+
);
|
|
161
|
+
if (!hasWorkerActivationSource) {
|
|
162
|
+
return false;
|
|
163
|
+
}
|
|
164
|
+
if (
|
|
165
|
+
isInternalTrail(graphTrail) &&
|
|
166
|
+
!options.include?.includes(graphTrail.id)
|
|
167
|
+
) {
|
|
168
|
+
return false;
|
|
169
|
+
}
|
|
170
|
+
if (matchesAnyPattern(graphTrail.id, options.exclude)) {
|
|
171
|
+
return false;
|
|
172
|
+
}
|
|
173
|
+
if (!passesIncludeFilter(graphTrail.id, options.include)) {
|
|
174
|
+
return false;
|
|
175
|
+
}
|
|
176
|
+
return (
|
|
177
|
+
options.intent === undefined ||
|
|
178
|
+
options.intent.length === 0 ||
|
|
179
|
+
options.intent.includes(graphTrail.intent)
|
|
180
|
+
);
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
const collectSurfaceEligibleTrails = (
|
|
184
|
+
graph: Topo,
|
|
185
|
+
options: BuildEnvResourceOverridesOptions
|
|
186
|
+
): readonly Trail<unknown, unknown, unknown>[] => {
|
|
187
|
+
const trails = graph.list();
|
|
188
|
+
const eligible = new Map<string, Trail<unknown, unknown, unknown>>();
|
|
189
|
+
if ((options.entrypoint ?? 'fetch') === 'fetch') {
|
|
190
|
+
const filtered = filterSurfaceTrails(trails, {
|
|
191
|
+
exclude: options.exclude,
|
|
192
|
+
include: options.include,
|
|
193
|
+
intent: options.intent,
|
|
194
|
+
});
|
|
195
|
+
for (const graphTrail of filtered) {
|
|
196
|
+
eligible.set(graphTrail.id, graphTrail);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
for (const graphTrail of trails) {
|
|
200
|
+
if (
|
|
201
|
+
!eligible.has(graphTrail.id) &&
|
|
202
|
+
isEligibleWorkerActivationTrail(graphTrail, options)
|
|
203
|
+
) {
|
|
204
|
+
eligible.set(graphTrail.id, graphTrail);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
const byId = new Map(trails.map((graphTrail) => [graphTrail.id, graphTrail]));
|
|
208
|
+
const pending = [...eligible.values()];
|
|
209
|
+
for (const graphTrail of pending) {
|
|
210
|
+
const composedIds = [
|
|
211
|
+
...graphTrail.composes,
|
|
212
|
+
...Object.values(graphTrail.versions ?? {})
|
|
213
|
+
.filter(isLiveTrailVersionEntry)
|
|
214
|
+
.flatMap((entry) => entry.composes ?? []),
|
|
215
|
+
];
|
|
216
|
+
for (const reference of composedIds) {
|
|
217
|
+
const composedId =
|
|
218
|
+
typeof reference === 'string' ? reference : reference.id;
|
|
219
|
+
const composed = byId.get(composedId);
|
|
220
|
+
if (composed !== undefined && !eligible.has(composed.id)) {
|
|
221
|
+
eligible.set(composed.id, composed);
|
|
222
|
+
pending.push(composed);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
return [...eligible.values()];
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* All resources a trail can execute with: the current contract's declarations
|
|
231
|
+
* plus any live fork version entry's own `resources`, since core runs
|
|
232
|
+
* supported historical forks with the entry's resource set.
|
|
233
|
+
*/
|
|
234
|
+
const declaredTrailResources = (
|
|
235
|
+
graphTrail: Trail<unknown, unknown, unknown>
|
|
236
|
+
): readonly AnyResource[] => [
|
|
237
|
+
...graphTrail.resources,
|
|
238
|
+
...Object.values(graphTrail.versions ?? {})
|
|
239
|
+
.filter(isLiveTrailVersionEntry)
|
|
240
|
+
.flatMap((entry) => entry.resources ?? []),
|
|
241
|
+
];
|
|
242
|
+
|
|
243
|
+
const collectEnvBoundResources = (
|
|
244
|
+
graph: Topo,
|
|
245
|
+
options: BuildEnvResourceOverridesOptions
|
|
246
|
+
): readonly AnyResource[] => {
|
|
247
|
+
const except = new Set(options.except);
|
|
248
|
+
const collected = new Map<string, AnyResource>();
|
|
249
|
+
for (const graphTrail of collectSurfaceEligibleTrails(graph, options)) {
|
|
250
|
+
for (const declared of declaredTrailResources(graphTrail)) {
|
|
251
|
+
if (
|
|
252
|
+
!collected.has(declared.id) &&
|
|
253
|
+
!except.has(declared.id) &&
|
|
254
|
+
envBindings.has(declared)
|
|
255
|
+
) {
|
|
256
|
+
collected.set(declared.id, declared);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
return [...collected.values()];
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Resolve every env-bound resource declared by the topo's surface-eligible
|
|
265
|
+
* trails (including live fork-version resources) into a resource override map
|
|
266
|
+
* for one Worker env.
|
|
267
|
+
*
|
|
268
|
+
* Returns `Result.err` when a required binding is missing from the env or a
|
|
269
|
+
* binding value fails the resource's narrowing check. Trails filtered off the
|
|
270
|
+
* surface by `exclude`/`include`/`intent` never require their bindings, and
|
|
271
|
+
* resource IDs listed in `except` are skipped because the caller already
|
|
272
|
+
* provides them.
|
|
273
|
+
*
|
|
274
|
+
* @example
|
|
275
|
+
* ```ts
|
|
276
|
+
* import { buildEnvResourceOverrides } from '@ontrails/cloudflare/workers';
|
|
277
|
+
*
|
|
278
|
+
* const overrides = buildEnvResourceOverrides(graph, env);
|
|
279
|
+
* if (overrides.isErr()) throw overrides.error;
|
|
280
|
+
* ```
|
|
281
|
+
*/
|
|
282
|
+
export const buildEnvResourceOverrides = (
|
|
283
|
+
graph: Topo,
|
|
284
|
+
env: WorkersEnv,
|
|
285
|
+
options: BuildEnvResourceOverridesOptions = {}
|
|
286
|
+
): Result<ResourceOverrideMap, Error> => {
|
|
287
|
+
const overrides: Record<string, unknown> = {};
|
|
288
|
+
for (const declared of collectEnvBoundResources(graph, options)) {
|
|
289
|
+
const spec = envBindings.get(declared);
|
|
290
|
+
if (spec === undefined) {
|
|
291
|
+
continue;
|
|
292
|
+
}
|
|
293
|
+
const value = env[spec.binding];
|
|
294
|
+
if (value === undefined) {
|
|
295
|
+
return Result.err(
|
|
296
|
+
new InternalError(
|
|
297
|
+
`Worker env is missing binding "${spec.binding}" required by resource "${declared.id}". Declare the binding in your wrangler configuration (for example kv_namespaces, d1_databases, r2_buckets, or queues) or provide an explicit resource override.`,
|
|
298
|
+
{ context: { binding: spec.binding, resourceId: declared.id } }
|
|
299
|
+
)
|
|
300
|
+
);
|
|
301
|
+
}
|
|
302
|
+
const instance = spec.fromEnv(value);
|
|
303
|
+
if (instance.isErr()) {
|
|
304
|
+
return instance;
|
|
305
|
+
}
|
|
306
|
+
overrides[declared.id] = instance.value;
|
|
307
|
+
}
|
|
308
|
+
return Result.ok(overrides);
|
|
309
|
+
};
|
package/src/facts.ts
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cloudflare lock facts.
|
|
3
|
+
*
|
|
4
|
+
* The adapter's `trails.lock` overlay overlay: `derive` derives the
|
|
5
|
+
* topo's env-bound resources (resources with a registered
|
|
6
|
+
* {@link EnvBindingSpec | env binding}, such as every `cloudflareKv`
|
|
7
|
+
* definition) into `overlays.cloudflare`, listing the wrangler binding name
|
|
8
|
+
* each resource resolves from. The import from `@ontrails/adapter-kit` is
|
|
9
|
+
* type-only — the adapter never depends on the adapter kit at runtime.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import type { Overlay } from '@ontrails/adapter-kit';
|
|
13
|
+
import type { AnyResource, Topo } from '@ontrails/core';
|
|
14
|
+
import { z } from 'zod';
|
|
15
|
+
|
|
16
|
+
import { getEnvBinding } from './env.js';
|
|
17
|
+
import type { EnvBindingSpec } from './env.js';
|
|
18
|
+
|
|
19
|
+
const cloudflareFactsSchema = z
|
|
20
|
+
.object({
|
|
21
|
+
bindings: z.array(
|
|
22
|
+
z
|
|
23
|
+
.object({
|
|
24
|
+
binding: z.string(),
|
|
25
|
+
resourceId: z.string(),
|
|
26
|
+
})
|
|
27
|
+
.strict()
|
|
28
|
+
),
|
|
29
|
+
})
|
|
30
|
+
.strict();
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* The facts embedded at `overlays.cloudflare` in `trails.lock`: one entry
|
|
34
|
+
* per env-bound resource, pairing the resource ID with its wrangler binding
|
|
35
|
+
* name.
|
|
36
|
+
*/
|
|
37
|
+
export type CloudflareLockFacts = z.infer<typeof cloudflareFactsSchema>;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Every resource visible on the topo: module-registered resources plus
|
|
41
|
+
* resources declared on trail contracts (including fork version entries),
|
|
42
|
+
* which core executes with but `topo()` does not auto-register.
|
|
43
|
+
*/
|
|
44
|
+
const collectTopoResources = (graph: Topo): readonly AnyResource[] => {
|
|
45
|
+
const collected = new Map<string, AnyResource>();
|
|
46
|
+
for (const definition of graph.listResources()) {
|
|
47
|
+
collected.set(definition.id, definition);
|
|
48
|
+
}
|
|
49
|
+
for (const graphTrail of graph.list()) {
|
|
50
|
+
const declared = [
|
|
51
|
+
...graphTrail.resources,
|
|
52
|
+
...Object.values(graphTrail.versions ?? {}).flatMap(
|
|
53
|
+
(entry) => entry.resources ?? []
|
|
54
|
+
),
|
|
55
|
+
];
|
|
56
|
+
for (const definition of declared) {
|
|
57
|
+
if (!collected.has(definition.id)) {
|
|
58
|
+
collected.set(definition.id, definition);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return [...collected.values()];
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const derive = (graph: Topo): CloudflareLockFacts => {
|
|
66
|
+
const bindings = collectTopoResources(graph)
|
|
67
|
+
.map((definition) => ({
|
|
68
|
+
definition,
|
|
69
|
+
spec: getEnvBinding(definition),
|
|
70
|
+
}))
|
|
71
|
+
.filter(
|
|
72
|
+
(entry): entry is { definition: AnyResource; spec: EnvBindingSpec } =>
|
|
73
|
+
entry.spec !== undefined
|
|
74
|
+
)
|
|
75
|
+
.map((entry) => ({
|
|
76
|
+
binding: entry.spec.binding,
|
|
77
|
+
resourceId: entry.definition.id,
|
|
78
|
+
}))
|
|
79
|
+
.toSorted(
|
|
80
|
+
(a, b) =>
|
|
81
|
+
a.resourceId.localeCompare(b.resourceId) ||
|
|
82
|
+
a.binding.localeCompare(b.binding)
|
|
83
|
+
);
|
|
84
|
+
return { bindings };
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* The Cloudflare adapter's `trails.lock` overlay overlay.
|
|
89
|
+
*
|
|
90
|
+
* An app opts in by exporting `trailsOverlays` next to its topo export;
|
|
91
|
+
* `trails compile` then validates `derive(topo)` against the facts schema
|
|
92
|
+
* and embeds the result as `overlays.cloudflare`, listing every env-bound
|
|
93
|
+
* resource's wrangler binding. Derivation is deterministic: the same topo
|
|
94
|
+
* always yields the same facts, sorted by resource ID then binding.
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* ```ts
|
|
98
|
+
* import { cloudflareOverlay, cloudflareKv } from '@ontrails/cloudflare';
|
|
99
|
+
* import { topo } from '@ontrails/core';
|
|
100
|
+
*
|
|
101
|
+
* export const flags = cloudflareKv('flags', { binding: 'FLAGS' });
|
|
102
|
+
* export const app = topo('my-worker', { flags });
|
|
103
|
+
* export const trailsOverlays = [cloudflareOverlay];
|
|
104
|
+
* // `trails compile` embeds overlays.cloudflare:
|
|
105
|
+
* // { bindings: [{ binding: 'FLAGS', resourceId: 'flags' }] }
|
|
106
|
+
* ```
|
|
107
|
+
*/
|
|
108
|
+
export const cloudflareOverlay = {
|
|
109
|
+
derive,
|
|
110
|
+
namespace: 'cloudflare',
|
|
111
|
+
schema: cloudflareFactsSchema,
|
|
112
|
+
} satisfies Overlay;
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@ontrails/cloudflare` — the Cloudflare adapter collection.
|
|
3
|
+
*
|
|
4
|
+
* Service subpaths are the primary entry points:
|
|
5
|
+
* - `@ontrails/cloudflare/workers` — HTTP surface materializer (fetch handler)
|
|
6
|
+
* - `@ontrails/cloudflare/kv` — key-value resource
|
|
7
|
+
* - `@ontrails/cloudflare/d1` — D1-backed store resource
|
|
8
|
+
* - `@ontrails/cloudflare/r2` — R2 blob/object resource
|
|
9
|
+
* - `@ontrails/cloudflare/queues` — Queue producer resource and consumer
|
|
10
|
+
* materializer
|
|
11
|
+
*
|
|
12
|
+
* The root export re-exports the subpaths for convenience and adapter
|
|
13
|
+
* tooling, and owns the adapter's `trails.lock` overlay overlay
|
|
14
|
+
* (`cloudflareOverlay`).
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
export { cloudflareOverlay } from './facts.js';
|
|
18
|
+
export type { CloudflareLockFacts } from './facts.js';
|
|
19
|
+
export { cloudflareD1, connectD1 } from './d1/index.js';
|
|
20
|
+
export type {
|
|
21
|
+
CloudflareD1AllResult,
|
|
22
|
+
CloudflareD1Connection,
|
|
23
|
+
CloudflareD1Database,
|
|
24
|
+
CloudflareD1Options,
|
|
25
|
+
CloudflareD1PreparedStatement,
|
|
26
|
+
CloudflareD1Resource,
|
|
27
|
+
CloudflareD1RunResult,
|
|
28
|
+
ConnectD1Options,
|
|
29
|
+
} from './d1/index.js';
|
|
30
|
+
export {
|
|
31
|
+
buildEnvResourceOverrides,
|
|
32
|
+
getEnvBinding,
|
|
33
|
+
registerEnvBinding,
|
|
34
|
+
} from './env.js';
|
|
35
|
+
export type {
|
|
36
|
+
BuildEnvResourceOverridesOptions,
|
|
37
|
+
EnvBindingSpec,
|
|
38
|
+
WorkersEnv,
|
|
39
|
+
} from './env.js';
|
|
40
|
+
export { cloudflareKv, createMemoryKv } from './kv/index.js';
|
|
41
|
+
export type {
|
|
42
|
+
CloudflareKv,
|
|
43
|
+
CloudflareKvListKey,
|
|
44
|
+
CloudflareKvListOptions,
|
|
45
|
+
CloudflareKvListResult,
|
|
46
|
+
CloudflareKvOptions,
|
|
47
|
+
CloudflareKvPutOptions,
|
|
48
|
+
CreateMemoryKvOptions,
|
|
49
|
+
} from './kv/index.js';
|
|
50
|
+
export { cloudflareR2, createMemoryR2, r2ObjectToBlobRef } from './r2/index.js';
|
|
51
|
+
export type {
|
|
52
|
+
CloudflareR2Bucket,
|
|
53
|
+
CloudflareR2Conditional,
|
|
54
|
+
CloudflareR2GetOptions,
|
|
55
|
+
CloudflareR2HttpMetadata,
|
|
56
|
+
CloudflareR2ListOptions,
|
|
57
|
+
CloudflareR2Object,
|
|
58
|
+
CloudflareR2ObjectBody,
|
|
59
|
+
CloudflareR2Objects,
|
|
60
|
+
CloudflareR2Options,
|
|
61
|
+
CloudflareR2PutBody,
|
|
62
|
+
CloudflareR2PutOptions,
|
|
63
|
+
CloudflareR2Range,
|
|
64
|
+
CloudflareR2StorageClass,
|
|
65
|
+
MemoryCloudflareR2Bucket,
|
|
66
|
+
R2ObjectToBlobRefOptions,
|
|
67
|
+
} from './r2/index.js';
|
|
68
|
+
export {
|
|
69
|
+
cloudflareQueue,
|
|
70
|
+
createMemoryQueue,
|
|
71
|
+
createQueueHandler,
|
|
72
|
+
} from './queues/index.js';
|
|
73
|
+
export type {
|
|
74
|
+
CloudflareQueue,
|
|
75
|
+
CloudflareQueueBatch,
|
|
76
|
+
CloudflareQueueHandler,
|
|
77
|
+
CloudflareQueueMessage,
|
|
78
|
+
CloudflareQueueMetrics,
|
|
79
|
+
CloudflareQueueOptions,
|
|
80
|
+
CloudflareQueueRetryOptions,
|
|
81
|
+
CloudflareQueueSendBatchOptions,
|
|
82
|
+
CloudflareQueueSendOptions,
|
|
83
|
+
CloudflareQueueSendRequest,
|
|
84
|
+
CloudflareQueueSendResult,
|
|
85
|
+
CloudflareQueuesContentType,
|
|
86
|
+
CreateQueueHandlerOptions,
|
|
87
|
+
MemoryCloudflareQueue,
|
|
88
|
+
MemoryQueueMessage,
|
|
89
|
+
} from './queues/index.js';
|
|
90
|
+
export { createWorkersHandler } from './workers/index.js';
|
|
91
|
+
export type {
|
|
92
|
+
CloudflareWorker,
|
|
93
|
+
CreateWorkersHandlerOptions,
|
|
94
|
+
WorkersExecutionContext,
|
|
95
|
+
WorkersResourceOverrides,
|
|
96
|
+
} from './workers/index.js';
|