devflare 1.0.0-next.45 → 1.0.0-next.47
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/LLM.md +18 -13
- package/dist/test/alarm.d.ts +55 -0
- package/dist/test/alarm.d.ts.map +1 -0
- package/dist/test/cf.d.ts +22 -0
- package/dist/test/cf.d.ts.map +1 -1
- package/dist/test/index.d.ts +3 -1
- package/dist/test/index.d.ts.map +1 -1
- package/dist/test/index.js +354 -49
- package/dist/test/offline-bindings.d.ts +47 -15
- package/dist/test/offline-bindings.d.ts.map +1 -1
- package/dist/test/utilities/analytics-engine.d.ts +22 -0
- package/dist/test/utilities/analytics-engine.d.ts.map +1 -0
- package/dist/test/utilities/env.d.ts +3 -0
- package/dist/test/utilities/env.d.ts.map +1 -1
- package/dist/test/utilities/vectorize.d.ts +38 -0
- package/dist/test/utilities/vectorize.d.ts.map +1 -0
- package/dist/test/utilities.d.ts +2 -0
- package/dist/test/utilities.d.ts.map +1 -1
- package/package.json +1 -1
package/LLM.md
CHANGED
|
@@ -4411,6 +4411,8 @@ That is the main reason the built-in harness scales: the same config and file co
|
|
|
4411
4411
|
|
|
4412
4412
|
These helpers are runtime-shaped and context-accurate for handler logic, but they do not try to recreate every internal Cloudflare dispatch step byte for byte. Their timing rules are documented explicitly instead of being left to guesswork.
|
|
4413
4413
|
|
|
4414
|
+
Each surface is also exported standalone for tree-shaking — `cf.alarm.trigger()` is the same function as the named `alarm` export, just as `cf.queue` mirrors `queue`. The Durable Object `alarm` helper takes a DO instance you construct in the test (not a handler file path), mirroring how the runtime wrapper invokes `alarm()`.
|
|
4415
|
+
|
|
4414
4416
|
##### Reference table
|
|
4415
4417
|
|
|
4416
4418
|
| Helper | Current behavior |
|
|
@@ -4420,6 +4422,7 @@ These helpers are runtime-shaped and context-accurate for handler logic, but the
|
|
|
4420
4422
|
| `cf.scheduled.trigger()` | Waits for scheduled background work before it returns. |
|
|
4421
4423
|
| `cf.email.send()` | In `createTestContext()` tests, directly invokes the configured local email handler and waits for its queued `waitUntil()` work; otherwise it falls back to the local email endpoint. |
|
|
4422
4424
|
| `cf.tail.trigger()` | Works when `src/tail.ts` exists, supports a default or named `tail` export, and waits for the handler plus its `waitUntil()` work before it returns. |
|
|
4425
|
+
| `cf.alarm.trigger(instance)` | Fires a Durable Object instance’s `alarm()` handler under a `durable-object-alarm` event context (the standalone `alarm` export is the same trigger) and awaits it, returning `{ success, error? }`. |
|
|
4423
4426
|
|
|
4424
4427
|
> **Warning — Do not assert the wrong timing contract**
|
|
4425
4428
|
>
|
|
@@ -4739,8 +4742,8 @@ The `devflare/test` entrypoint intentionally has multiple lanes: runtime-shaped
|
|
|
4739
4742
|
| Export family | Smallest use | Status |
|
|
4740
4743
|
| --- | --- | --- |
|
|
4741
4744
|
| `createTestContext`, `env`, `cf` | Runtime-shaped Worker tests with cleanup. | Recommended |
|
|
4742
|
-
| `cf.worker`, `cf.queue`, `cf.scheduled`, `cf.email`, `cf.tail` | Trigger the matching Worker surface directly. | Recommended |
|
|
4743
|
-
| `worker`, `queue`, `scheduled`, `email`, `tail` | Direct helper modules behind the unified `cf` API. | Advanced |
|
|
4745
|
+
| `cf.worker`, `cf.queue`, `cf.scheduled`, `cf.email`, `cf.tail`, `cf.alarm` | Trigger the matching Worker (or Durable Object alarm) surface directly. | Recommended |
|
|
4746
|
+
| `worker`, `queue`, `scheduled`, `email`, `tail`, `alarm` | Direct helper modules behind the unified `cf` API. | Advanced |
|
|
4744
4747
|
| `createOfflineEnv`, `createOfflineBindings`, `describeOfflineSupport`, `getOfflineSupportMatrix` | Pure config-derived binding fixtures without runtime startup. | Recommended for offline-first unit tests |
|
|
4745
4748
|
| `createMockKV`, `createMockD1`, `createMockR2`, `createMockQueue`, `createMockEnv` | Small pure unit tests without Miniflare. | Recommended when runtime dispatch is irrelevant |
|
|
4746
4749
|
| `createMockRateLimit`, `createMockVersionMetadata`, `createMockWorkerLoader`, `createMockSecretsStoreSecret` | Pure fixture for one platform-shaped binding. | Recommended |
|
|
@@ -4758,12 +4761,13 @@ The `devflare/test` entrypoint intentionally has multiple lanes: runtime-shaped
|
|
|
4758
4761
|
| --- | --- |
|
|
4759
4762
|
| `createTestContext` | Boot the nearest Devflare config in the test harness. |
|
|
4760
4763
|
| `env` | Read bindings and call `env.dispose()` in harness tests. |
|
|
4761
|
-
| `cf` | Unified Worker, queue, scheduled, email, and
|
|
4764
|
+
| `cf` | Unified Worker, queue, scheduled, email, tail, and DO alarm trigger API. |
|
|
4762
4765
|
| `worker` | Direct Worker fetch helper behind `cf.worker`. |
|
|
4763
4766
|
| `queue` | Direct queue helper behind `cf.queue`. |
|
|
4764
4767
|
| `scheduled` | Direct scheduled helper behind `cf.scheduled`. |
|
|
4765
4768
|
| `email` | Direct email helper behind `cf.email`. |
|
|
4766
4769
|
| `tail` | Direct tail helper behind `cf.tail`. |
|
|
4770
|
+
| `alarm` | Direct Durable Object alarm helper behind `cf.alarm`. |
|
|
4767
4771
|
| `shouldSkip` | Skip Cloudflare-auth, paid, remote, or local engine tests explicitly. |
|
|
4768
4772
|
| `containers` | Default Docker/Podman-backed container manager. |
|
|
4769
4773
|
| `createContainerManager` | Create an isolated container manager for tests. |
|
|
@@ -4794,6 +4798,8 @@ The `devflare/test` entrypoint intentionally has multiple lanes: runtime-shaped
|
|
|
4794
4798
|
| `createMockStreamBinding` | Mock a Stream binding. |
|
|
4795
4799
|
| `createMockFlagshipBinding` | Mock a Flagship feature-flag binding. |
|
|
4796
4800
|
| `createMockArtifacts` | Mock Artifacts repo APIs. |
|
|
4801
|
+
| `createMockVectorize` | Mock a Vectorize index (in-memory cosine query). |
|
|
4802
|
+
| `createMockAnalyticsEngine` | Mock an Analytics Engine dataset (write-only recording stub). |
|
|
4797
4803
|
| `createMockSecretsStoreSecret` | Mock a Secrets Store secret. |
|
|
4798
4804
|
| `createMockEnv` | Create a pure env with selected mock bindings. |
|
|
4799
4805
|
| `hasServiceBindings` | Advanced/internal service-binding resolution predicate. |
|
|
@@ -9921,7 +9927,7 @@ describe.skipIf(skipVectorize)('Vectorize binding', () => {
|
|
|
9921
9927
|
|
|
9922
9928
|
- Use `shouldSkip.vectorize` so missing remote prerequisites are explicit instead of noisy.
|
|
9923
9929
|
- Keep the vector size and index name close to the test so the contract remains visible.
|
|
9924
|
-
-
|
|
9930
|
+
- For app-level paths, `createMockVectorize()` (or `createMockEnv({ vectorize })` / `createOfflineEnv()`) is a deterministic in-memory index: `insert`/`upsert`/`delete`/`getByIds` plus a real cosine-ranked `query()` honoring `topK`, `returnValues`, `returnMetadata`, `namespace`, and metadata `filter`. It models the binding shape and ranking math, not Cloudflare’s hosted indexing/relevance/scale — use the remote smoke test for those.
|
|
9925
9931
|
|
|
9926
9932
|
#### When to move beyond the default harness
|
|
9927
9933
|
|
|
@@ -10821,7 +10827,7 @@ Use Cloudflare when analytics delivery itself is a release-critical guarantee. T
|
|
|
10821
10827
|
|
|
10822
10828
|
##### Key points
|
|
10823
10829
|
|
|
10824
|
-
-
|
|
10830
|
+
- For app-level tests, `createMockAnalyticsEngine()` (or `createMockEnv({ analyticsEngine })` / `createOfflineEnv()`) is a write-only recording stub: it records every `writeDataPoint()` into `.writtenDataPoints` so you can assert what the worker emitted. Analytics Engine has no in-worker read API, so the stub records writes — it does not query.
|
|
10825
10831
|
- Preview-scoped dataset names can be materialized, but Devflare does not provision or delete datasets because Analytics Engine creates them on first write.
|
|
10826
10832
|
- Tests should focus on event-producing behavior rather than pretending you need a full local analytics backend.
|
|
10827
10833
|
|
|
@@ -10966,17 +10972,16 @@ If you later need stronger end-to-end confidence, add a higher-level integration
|
|
|
10966
10972
|
|
|
10967
10973
|
```ts
|
|
10968
10974
|
import { expect, test } from 'bun:test'
|
|
10969
|
-
|
|
10970
|
-
const writes: unknown[] = []
|
|
10971
|
-
const analytics = {
|
|
10972
|
-
writeDataPoint(point: unknown) {
|
|
10973
|
-
writes.push(point)
|
|
10974
|
-
}
|
|
10975
|
-
}
|
|
10975
|
+
import { createMockAnalyticsEngine } from 'devflare/test'
|
|
10976
10976
|
|
|
10977
10977
|
test('records an analytics point', () => {
|
|
10978
|
+
const analytics = createMockAnalyticsEngine()
|
|
10979
|
+
|
|
10978
10980
|
analytics.writeDataPoint({ indexes: ['search'], blobs: ['devflare'] })
|
|
10979
|
-
|
|
10981
|
+
|
|
10982
|
+
expect(analytics.writtenDataPoints).toEqual([
|
|
10983
|
+
{ indexes: ['search'], blobs: ['devflare'] }
|
|
10984
|
+
])
|
|
10980
10985
|
})
|
|
10981
10986
|
```
|
|
10982
10987
|
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal shape a Durable Object instance must satisfy to have its alarm fired:
|
|
3
|
+
* an `alarm()` method, plus the `state`/`ctx` and `env` the runtime injects.
|
|
4
|
+
* Matches the wrapper the Devflare DO transform generates around `alarm()`.
|
|
5
|
+
*/
|
|
6
|
+
export interface AlarmTriggerTarget {
|
|
7
|
+
alarm?: (...args: unknown[]) => unknown;
|
|
8
|
+
state?: DurableObjectState;
|
|
9
|
+
ctx?: DurableObjectState;
|
|
10
|
+
env?: unknown;
|
|
11
|
+
}
|
|
12
|
+
export interface AlarmTriggerOptions {
|
|
13
|
+
/**
|
|
14
|
+
* Durable Object state to attach to the alarm event. Defaults to the
|
|
15
|
+
* instance's `state` (or `ctx`) when present.
|
|
16
|
+
*/
|
|
17
|
+
state?: DurableObjectState;
|
|
18
|
+
/**
|
|
19
|
+
* Env to attach to the alarm event. Defaults to the instance's `env` when
|
|
20
|
+
* present, otherwise an empty object.
|
|
21
|
+
*/
|
|
22
|
+
env?: unknown;
|
|
23
|
+
}
|
|
24
|
+
export interface AlarmTriggerResult {
|
|
25
|
+
/** Whether the alarm handler completed successfully. */
|
|
26
|
+
success: boolean;
|
|
27
|
+
/** Error message if the handler threw. */
|
|
28
|
+
error?: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Trigger a Durable Object's `alarm()` handler.
|
|
32
|
+
*
|
|
33
|
+
* This mirrors how the Devflare runtime invokes a DO alarm: it builds a
|
|
34
|
+
* `durable-object-alarm` event with the instance's env + state, installs it into
|
|
35
|
+
* AsyncLocalStorage via `runWithEventContext`, and calls the instance's
|
|
36
|
+
* `alarm()` with that event (so `getDurableObjectAlarmEvent()` works inside the
|
|
37
|
+
* handler). The instance keeps using its own `this.env` / `this.ctx`; the event
|
|
38
|
+
* is supplied for context-aware code paths.
|
|
39
|
+
*
|
|
40
|
+
* @param target - The Durable Object instance whose `alarm()` should be fired.
|
|
41
|
+
* @param options - Optional explicit `state`/`env` for the alarm event.
|
|
42
|
+
* @returns Result object with success status.
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* const counter = new Counter(state, env)
|
|
46
|
+
* await counter.scheduleAlarm()
|
|
47
|
+
* const result = await cf.alarm.trigger(counter)
|
|
48
|
+
* expect(result.success).toBe(true)
|
|
49
|
+
*/
|
|
50
|
+
declare function trigger(target: AlarmTriggerTarget, options?: AlarmTriggerOptions): Promise<AlarmTriggerResult>;
|
|
51
|
+
export declare const alarm: {
|
|
52
|
+
trigger: typeof trigger;
|
|
53
|
+
};
|
|
54
|
+
export {};
|
|
55
|
+
//# sourceMappingURL=alarm.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"alarm.d.ts","sourceRoot":"","sources":["../../src/test/alarm.ts"],"names":[],"mappings":"AAqBA;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IAClC,KAAK,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAA;IACvC,KAAK,CAAC,EAAE,kBAAkB,CAAA;IAC1B,GAAG,CAAC,EAAE,kBAAkB,CAAA;IACxB,GAAG,CAAC,EAAE,OAAO,CAAA;CACb;AAED,MAAM,WAAW,mBAAmB;IACnC;;;OAGG;IACH,KAAK,CAAC,EAAE,kBAAkB,CAAA;IAC1B;;;OAGG;IACH,GAAG,CAAC,EAAE,OAAO,CAAA;CACb;AAED,MAAM,WAAW,kBAAkB;IAClC,wDAAwD;IACxD,OAAO,EAAE,OAAO,CAAA;IAChB,0CAA0C;IAC1C,KAAK,CAAC,EAAE,MAAM,CAAA;CACd;AAMD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,iBAAe,OAAO,CACrB,MAAM,EAAE,kBAAkB,EAC1B,OAAO,GAAE,mBAAwB,GAC/B,OAAO,CAAC,kBAAkB,CAAC,CAuB7B;AAMD,eAAO,MAAM,KAAK;;CAEjB,CAAA"}
|
package/dist/test/cf.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
export { alarm } from './alarm.js';
|
|
1
2
|
export { email } from './email.js';
|
|
2
3
|
export { queue } from './queue.js';
|
|
3
4
|
export { scheduled } from './scheduled.js';
|
|
4
5
|
export { worker } from './worker.js';
|
|
5
6
|
export { tail } from './tail.js';
|
|
7
|
+
export type { AlarmTriggerTarget, AlarmTriggerOptions, AlarmTriggerResult } from './alarm.js';
|
|
6
8
|
export type { EmailSendOptions, ReceivedEmail, EmailReceiveCallback } from './email.js';
|
|
7
9
|
export type { QueueMessageOptions, QueueTriggerResult } from './queue.js';
|
|
8
10
|
export type { ScheduledTriggerOptions, ScheduledTriggerResult } from './scheduled.js';
|
|
@@ -17,6 +19,7 @@ export type { TraceItemOptions, TailTriggerResult } from './tail.js';
|
|
|
17
19
|
* - `cf.scheduled` — Cron/scheduled handler testing
|
|
18
20
|
* - `cf.worker` — Fetch handler testing
|
|
19
21
|
* - `cf.tail` — Tail helper surface (uses `files.tail`, or auto-detects `src/tail.ts` when present)
|
|
22
|
+
* - `cf.alarm` — Durable Object alarm handler testing (fires a DO instance's `alarm()`)
|
|
20
23
|
*
|
|
21
24
|
* The helpers use the real Miniflare-backed bindings created by `createTestContext()`,
|
|
22
25
|
* but several helper surfaces still synthesize event/controller objects around those
|
|
@@ -140,5 +143,24 @@ export declare const cf: {
|
|
|
140
143
|
trigger: (items: Array<import("@cloudflare/workers-types").TraceItem | import("./tail.js").TraceItemOptions>) => Promise<import("./tail.js").TailTriggerResult>;
|
|
141
144
|
create: (options?: import("./tail.js").TraceItemOptions) => import("@cloudflare/workers-types").TraceItem;
|
|
142
145
|
};
|
|
146
|
+
/**
|
|
147
|
+
* Durable Object alarm handler testing.
|
|
148
|
+
*
|
|
149
|
+
* - `cf.alarm.trigger(instance, options?)` — Fire a DO instance's `alarm()`
|
|
150
|
+
* handler under a `durable-object-alarm` event context and assert effects.
|
|
151
|
+
*
|
|
152
|
+
* Unlike the other surfaces this operates directly on a Durable Object
|
|
153
|
+
* instance you construct in the test (it does not resolve a handler file),
|
|
154
|
+
* mirroring how the Devflare DO wrapper invokes `alarm()` at runtime.
|
|
155
|
+
*
|
|
156
|
+
* @example
|
|
157
|
+
* const counter = new Counter(state, env)
|
|
158
|
+
* await counter.scheduleAlarm()
|
|
159
|
+
* const result = await cf.alarm.trigger(counter)
|
|
160
|
+
* expect(result.success).toBe(true)
|
|
161
|
+
*/
|
|
162
|
+
alarm: {
|
|
163
|
+
trigger: (target: import("./alarm.js").AlarmTriggerTarget, options?: import("./alarm.js").AlarmTriggerOptions) => Promise<import("./alarm.js").AlarmTriggerResult>;
|
|
164
|
+
};
|
|
143
165
|
};
|
|
144
166
|
//# sourceMappingURL=cf.d.ts.map
|
package/dist/test/cf.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cf.d.ts","sourceRoot":"","sources":["../../src/test/cf.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cf.d.ts","sourceRoot":"","sources":["../../src/test/cf.ts"],"names":[],"mappings":"AAkCA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAC/B,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAC/B,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAC/B,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACvC,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAG7B,YAAY,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAA;AAC1F,YAAY,EAAE,gBAAgB,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAA;AACpF,YAAY,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAA;AACtE,YAAY,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAA;AAClF,YAAY,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAA;AAClD,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAA;AAEjE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AACH,eAAO,MAAM,EAAE;IACd;;;;;;;;;;;OAWG;;;;;;;IAGH;;;;;;;OAOG;;;;;IAGH;;;;;;;;;OASG;;;;IAGH;;;;;;;;;;;;OAYG;;;;;;;;;IAGH;;;;;;;;OAQG;;;;;IAGH;;;;;;;;;;;;;;;OAeG;;;;CAEH,CAAA"}
|
package/dist/test/index.d.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
export { createTestContext, env, type DevflareEnv, type TestEnv } from './simple-context.js';
|
|
2
2
|
export { cf } from './cf.js';
|
|
3
|
+
export { alarm } from './alarm.js';
|
|
3
4
|
export { email } from './email.js';
|
|
4
5
|
export { queue } from './queue.js';
|
|
5
6
|
export { scheduled } from './scheduled.js';
|
|
6
7
|
export { worker } from './worker.js';
|
|
7
8
|
export { tail } from './tail.js';
|
|
9
|
+
export type { AlarmTriggerTarget, AlarmTriggerOptions, AlarmTriggerResult } from './alarm.js';
|
|
8
10
|
export type { EmailSendOptions, ReceivedEmail, EmailReceiveCallback } from './email.js';
|
|
9
11
|
export type { QueueMessageOptions, QueueTriggerResult } from './queue.js';
|
|
10
12
|
export type { ScheduledTriggerOptions, ScheduledTriggerResult } from './scheduled.js';
|
|
@@ -15,5 +17,5 @@ export { shouldSkip } from './should-skip.js';
|
|
|
15
17
|
export { containers, createContainerManager, detectContainerEngine, getContainerSkipReason, stopActiveContainers, type ContainerCommandResult, type ContainerCommandRunner, type ContainerEngineCheck, type ContainerEngineName, type ContainerEnginePreference, type ContainerEngineStatus, type ContainerManager, type ContainerManagerOptions, type DevflareContainerInstance, type LocalContainerState, type StartContainerOptions } from './containers.js';
|
|
16
18
|
export { createOfflineBindings, createOfflineEnv, describeOfflineSupport, getOfflineSupportMatrix, type OfflineBindingFixtures, type OfflineBindingsResult, type OfflineMissingFixture, type OfflineRemoteBoundary, type OfflineSupportEntry, type OfflineSupportTier } from './offline-bindings.js';
|
|
17
19
|
export { createMockAISearchInstance, createMockAISearchNamespace, type MockAISearchInstance, type MockAISearchInstanceOptions, type MockAISearchItemFixture, type MockAISearchNamespace, type MockAISearchNamespaceOptions } from './ai-search.js';
|
|
18
|
-
export { createMockTestContext, createMockKV, createMockD1, createMockR2, createMockQueue, createMockRateLimit, createMockVersionMetadata, createMockHyperdrive, createMockWorkerLoader, createMockMTLSCertificate, createMockDispatchNamespace, createMockWorkflow, createMockPipeline, createMockImagesBinding, createMockMediaBinding, createMockStreamBinding, createMockFlagshipBinding, createMockArtifacts, createMockSecretsStoreSecret, createMockEnv, withTestContext, type TestContext, type TestContextOptions, type MockEnvOptions, type MockRateLimitOptions, type MockWorkerLoaderOptions, type MockFetchInput, type MockFetcherHandler, type MockDispatchNamespaceOptions, type MockWorkflowOptions, type MockWorkflowInstanceOptions, type MockPipeline, type MockImagesBindingOptions, type MockMediaBindingOptions, type MockStreamBindingOptions, type MockFlagshipBindingOptions, type MockArtifactsOptions } from './utilities.js';
|
|
20
|
+
export { createMockTestContext, createMockKV, createMockD1, createMockR2, createMockQueue, createMockRateLimit, createMockVersionMetadata, createMockHyperdrive, createMockWorkerLoader, createMockMTLSCertificate, createMockDispatchNamespace, createMockWorkflow, createMockPipeline, createMockImagesBinding, createMockMediaBinding, createMockStreamBinding, createMockFlagshipBinding, createMockArtifacts, createMockVectorize, createMockAnalyticsEngine, createMockSecretsStoreSecret, createMockEnv, withTestContext, type TestContext, type TestContextOptions, type MockEnvOptions, type MockRateLimitOptions, type MockWorkerLoaderOptions, type MockFetchInput, type MockFetcherHandler, type MockDispatchNamespaceOptions, type MockWorkflowOptions, type MockWorkflowInstanceOptions, type MockPipeline, type MockImagesBindingOptions, type MockMediaBindingOptions, type MockStreamBindingOptions, type MockFlagshipBindingOptions, type MockArtifactsOptions, type MockVectorizeOptions, type MockVectorizeIndex, type MockAnalyticsEngineDataset } from './utilities.js';
|
|
19
21
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/test/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/test/index.ts"],"names":[],"mappings":"AAKA,OAAO,EACN,iBAAiB,EACjB,GAAG,EACH,KAAK,WAAW,EAChB,KAAK,OAAO,EACZ,MAAM,kBAAkB,CAAA;AAGzB,OAAO,EAAE,EAAE,EAAE,MAAM,MAAM,CAAA;AACzB,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAC/B,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAC/B,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACvC,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAG7B,YAAY,EAAE,gBAAgB,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAA;AACpF,YAAY,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAA;AACtE,YAAY,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAA;AAClF,YAAY,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAA;AAClD,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAA;AAGjE,OAAO,EACN,kBAAkB,EAClB,sBAAsB,EACtB,iBAAiB,EACjB,iBAAiB,EACjB,gBAAgB,EAChB,KAAK,cAAc,EACnB,KAAK,wBAAwB,EAC7B,KAAK,mBAAmB,EACxB,MAAM,4BAA4B,CAAA;AAGnC,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAG1C,OAAO,EACN,UAAU,EACV,sBAAsB,EACtB,qBAAqB,EACrB,sBAAsB,EACtB,oBAAoB,EACpB,KAAK,sBAAsB,EAC3B,KAAK,sBAAsB,EAC3B,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,yBAAyB,EAC9B,KAAK,qBAAqB,EAC1B,KAAK,gBAAgB,EACrB,KAAK,uBAAuB,EAC5B,KAAK,yBAAyB,EAC9B,KAAK,mBAAmB,EACxB,KAAK,qBAAqB,EAC1B,MAAM,cAAc,CAAA;AAGrB,OAAO,EACN,qBAAqB,EACrB,gBAAgB,EAChB,sBAAsB,EACtB,uBAAuB,EACvB,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,MAAM,oBAAoB,CAAA;AAG3B,OAAO,EACN,0BAA0B,EAC1B,2BAA2B,EAC3B,KAAK,oBAAoB,EACzB,KAAK,2BAA2B,EAChC,KAAK,uBAAuB,EAC5B,KAAK,qBAAqB,EAC1B,KAAK,4BAA4B,EACjC,MAAM,aAAa,CAAA;AAGpB,OAAO,EACN,qBAAqB,EACrB,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,mBAAmB,EACnB,yBAAyB,EACzB,oBAAoB,EACpB,sBAAsB,EACtB,yBAAyB,EACzB,2BAA2B,EAC3B,kBAAkB,EAClB,kBAAkB,EAClB,uBAAuB,EACvB,sBAAsB,EACtB,uBAAuB,EACvB,yBAAyB,EACzB,mBAAmB,EACnB,4BAA4B,EAC5B,aAAa,EACb,eAAe,EACf,KAAK,WAAW,EAChB,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,oBAAoB,EACzB,KAAK,uBAAuB,EAC5B,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,4BAA4B,EACjC,KAAK,mBAAmB,EACxB,KAAK,2BAA2B,EAChC,KAAK,YAAY,EACjB,KAAK,wBAAwB,EAC7B,KAAK,uBAAuB,EAC5B,KAAK,wBAAwB,EAC7B,KAAK,0BAA0B,EAC/B,KAAK,oBAAoB,EACzB,MAAM,aAAa,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/test/index.ts"],"names":[],"mappings":"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"}
|
package/dist/test/index.js
CHANGED
|
@@ -4,7 +4,7 @@ import { _ as normalizeSecretsStoreBinding, f as normalizeMediaBinding, h as nor
|
|
|
4
4
|
import { t as applyLocalDevVarsToConfig } from "../_chunks/local-dev-vars-CTSa-wvF.js";
|
|
5
5
|
import { g as isAuthenticated, p as getApiToken } from "../_chunks/api-TzdliH-6.js";
|
|
6
6
|
import { d as getPrimaryAccount, n as getEffectiveAccountId } from "../_chunks/preferences-BKp_7XJx.js";
|
|
7
|
-
import { A as createTailEvent, D as createFetchEvent, E as createEmailEvent, F as BridgeClient, M as createEnvProxy, O as createQueueEvent, P as setBindingHints, _ as runWithContext, k as createScheduledEvent, v as runWithEventContext } from "../_chunks/context-CX50Y2Kb.js";
|
|
7
|
+
import { A as createTailEvent, D as createFetchEvent, E as createEmailEvent, F as BridgeClient, M as createEnvProxy, O as createQueueEvent, P as setBindingHints, _ as runWithContext, k as createScheduledEvent, v as runWithEventContext, x as createDurableObjectAlarmEvent } from "../_chunks/context-CX50Y2Kb.js";
|
|
8
8
|
import { createLocalSendEmailBinding, wrapEnvSendEmailBindings } from "../utils/send-email.js";
|
|
9
9
|
import { n as __setTestContext, r as env, t as __clearTestContext } from "../_chunks/env-S0_nMVz1.js";
|
|
10
10
|
import { d as invokeFetchModule, m as resolveFetchHandler, r as matchFetchRoute, t as createRouteResolve } from "../_chunks/runtime-FvXvfuZ2.js";
|
|
@@ -1226,7 +1226,231 @@ function createMockArtifacts(options = {}) {
|
|
|
1226
1226
|
};
|
|
1227
1227
|
}
|
|
1228
1228
|
//#endregion
|
|
1229
|
+
//#region src/test/utilities/vectorize.ts
|
|
1230
|
+
function toNumberArray(values) {
|
|
1231
|
+
return Array.isArray(values) ? values.slice() : Array.from(values);
|
|
1232
|
+
}
|
|
1233
|
+
function cloneVector(vector) {
|
|
1234
|
+
return {
|
|
1235
|
+
id: vector.id,
|
|
1236
|
+
values: toNumberArray(vector.values),
|
|
1237
|
+
...vector.namespace !== void 0 && { namespace: vector.namespace },
|
|
1238
|
+
...vector.metadata !== void 0 && { metadata: structuredClone(vector.metadata) }
|
|
1239
|
+
};
|
|
1240
|
+
}
|
|
1241
|
+
/**
|
|
1242
|
+
* Cosine similarity between two equal-length vectors. Returns 0 when either
|
|
1243
|
+
* vector has zero magnitude (undefined direction), matching a "no similarity"
|
|
1244
|
+
* result rather than throwing.
|
|
1245
|
+
*/
|
|
1246
|
+
function cosineSimilarity(a, b) {
|
|
1247
|
+
let dot = 0;
|
|
1248
|
+
let magA = 0;
|
|
1249
|
+
let magB = 0;
|
|
1250
|
+
const length = Math.min(a.length, b.length);
|
|
1251
|
+
for (let i = 0; i < length; i++) {
|
|
1252
|
+
dot += a[i] * b[i];
|
|
1253
|
+
magA += a[i] * a[i];
|
|
1254
|
+
magB += b[i] * b[i];
|
|
1255
|
+
}
|
|
1256
|
+
if (magA === 0 || magB === 0) return 0;
|
|
1257
|
+
return dot / (Math.sqrt(magA) * Math.sqrt(magB));
|
|
1258
|
+
}
|
|
1259
|
+
function readMetadataField(metadata, field) {
|
|
1260
|
+
return metadata?.[field];
|
|
1261
|
+
}
|
|
1262
|
+
function compareScalar(op, actual, expected) {
|
|
1263
|
+
switch (op) {
|
|
1264
|
+
case "$eq": return actual === expected;
|
|
1265
|
+
case "$ne": return actual !== expected;
|
|
1266
|
+
case "$lt": return typeof actual === "number" && typeof expected === "number" && actual < expected;
|
|
1267
|
+
case "$lte": return typeof actual === "number" && typeof expected === "number" && actual <= expected;
|
|
1268
|
+
case "$gt": return typeof actual === "number" && typeof expected === "number" && actual > expected;
|
|
1269
|
+
case "$gte": return typeof actual === "number" && typeof expected === "number" && actual >= expected;
|
|
1270
|
+
default: throw new Error(`Mock Vectorize query filter operator "${op}" is not supported. Supported operators: $eq, $ne, $lt, $lte, $gt, $gte, $in, $nin.`);
|
|
1271
|
+
}
|
|
1272
|
+
}
|
|
1273
|
+
function evaluateOperator(op, actual, expected) {
|
|
1274
|
+
if (op === "$in") return Array.isArray(expected) && expected.includes(actual);
|
|
1275
|
+
if (op === "$nin") return !Array.isArray(expected) || !expected.includes(actual);
|
|
1276
|
+
return compareScalar(op, actual, expected);
|
|
1277
|
+
}
|
|
1278
|
+
/**
|
|
1279
|
+
* Evaluates one field's condition: either a scalar `$eq` shorthand or an
|
|
1280
|
+
* operator object where every operator must hold.
|
|
1281
|
+
*/
|
|
1282
|
+
function matchesCondition(actual, condition) {
|
|
1283
|
+
if (condition === null || typeof condition !== "object" || Array.isArray(condition)) return actual === condition;
|
|
1284
|
+
return Object.entries(condition).every(([op, expected]) => evaluateOperator(op, actual, expected));
|
|
1285
|
+
}
|
|
1286
|
+
/**
|
|
1287
|
+
* Evaluates a Vectorize metadata filter against a stored vector's metadata,
|
|
1288
|
+
* mirroring the documented filter grammar (scalar equality shorthand plus the
|
|
1289
|
+
* `$eq/$ne/$lt/$lte/$gt/$gte` and `$in/$nin` operators). All fields must match.
|
|
1290
|
+
*/
|
|
1291
|
+
function matchesFilter(metadata, filter) {
|
|
1292
|
+
return Object.entries(filter).every(([field, condition]) => matchesCondition(readMetadataField(metadata, field), condition));
|
|
1293
|
+
}
|
|
1294
|
+
function applyMetadataRetrieval(metadata, returnMetadata) {
|
|
1295
|
+
if (metadata === void 0) return;
|
|
1296
|
+
if (returnMetadata === void 0 || returnMetadata === false || returnMetadata === "none") return;
|
|
1297
|
+
return structuredClone(metadata);
|
|
1298
|
+
}
|
|
1299
|
+
/**
|
|
1300
|
+
* Creates a deterministic in-memory Vectorize index binding for pure unit tests.
|
|
1301
|
+
*
|
|
1302
|
+
* @example
|
|
1303
|
+
* ```ts
|
|
1304
|
+
* const index = createMockVectorize({
|
|
1305
|
+
* vectors: [{ id: 'a', values: [1, 0], metadata: { topic: 'cats' } }]
|
|
1306
|
+
* })
|
|
1307
|
+
* await index.insert([{ id: 'b', values: [0, 1] }])
|
|
1308
|
+
* const result = await index.query([1, 0], { topK: 1, returnMetadata: true })
|
|
1309
|
+
* // result.matches[0].id === 'a'
|
|
1310
|
+
* ```
|
|
1311
|
+
*/
|
|
1312
|
+
function createMockVectorize(options = {}) {
|
|
1313
|
+
const store = /* @__PURE__ */ new Map();
|
|
1314
|
+
let inferredDimensions = options.dimensions;
|
|
1315
|
+
const noteDimensions = (vector) => {
|
|
1316
|
+
if (inferredDimensions === void 0) inferredDimensions = toNumberArray(vector.values).length;
|
|
1317
|
+
};
|
|
1318
|
+
for (const vector of options.vectors ?? []) {
|
|
1319
|
+
const stored = cloneVector(vector);
|
|
1320
|
+
noteDimensions(stored);
|
|
1321
|
+
store.set(stored.id, stored);
|
|
1322
|
+
}
|
|
1323
|
+
const insert = async (vectors, { overwrite }) => {
|
|
1324
|
+
const ids = [];
|
|
1325
|
+
for (const vector of vectors) {
|
|
1326
|
+
if (!overwrite && store.has(vector.id)) throw new Error(`Mock Vectorize insert failed: a vector with id "${vector.id}" already exists. Use upsert() to replace it.`);
|
|
1327
|
+
const stored = cloneVector(vector);
|
|
1328
|
+
noteDimensions(stored);
|
|
1329
|
+
store.set(stored.id, stored);
|
|
1330
|
+
ids.push(stored.id);
|
|
1331
|
+
}
|
|
1332
|
+
return {
|
|
1333
|
+
ids,
|
|
1334
|
+
count: ids.length
|
|
1335
|
+
};
|
|
1336
|
+
};
|
|
1337
|
+
const deleteByIds = async (ids) => {
|
|
1338
|
+
const deleted = [];
|
|
1339
|
+
for (const id of ids) if (store.delete(id)) deleted.push(id);
|
|
1340
|
+
return {
|
|
1341
|
+
ids: deleted,
|
|
1342
|
+
count: deleted.length
|
|
1343
|
+
};
|
|
1344
|
+
};
|
|
1345
|
+
return {
|
|
1346
|
+
async describe() {
|
|
1347
|
+
return {
|
|
1348
|
+
id: `mock-${options.name ?? "mock-vectorize"}`,
|
|
1349
|
+
name: options.name ?? "mock-vectorize",
|
|
1350
|
+
config: {
|
|
1351
|
+
dimensions: inferredDimensions ?? 0,
|
|
1352
|
+
metric: options.metric ?? "cosine"
|
|
1353
|
+
},
|
|
1354
|
+
vectorsCount: store.size
|
|
1355
|
+
};
|
|
1356
|
+
},
|
|
1357
|
+
async insert(vectors) {
|
|
1358
|
+
return insert(vectors, { overwrite: false });
|
|
1359
|
+
},
|
|
1360
|
+
async upsert(vectors) {
|
|
1361
|
+
return insert(vectors, { overwrite: true });
|
|
1362
|
+
},
|
|
1363
|
+
async deleteByIds(ids) {
|
|
1364
|
+
return deleteByIds(ids);
|
|
1365
|
+
},
|
|
1366
|
+
async delete(ids) {
|
|
1367
|
+
return deleteByIds(ids);
|
|
1368
|
+
},
|
|
1369
|
+
async getByIds(ids) {
|
|
1370
|
+
const result = [];
|
|
1371
|
+
for (const id of ids) {
|
|
1372
|
+
const vector = store.get(id);
|
|
1373
|
+
if (vector) result.push(cloneVector(vector));
|
|
1374
|
+
}
|
|
1375
|
+
return result;
|
|
1376
|
+
},
|
|
1377
|
+
async query(vector, queryOptions) {
|
|
1378
|
+
const queryVector = toNumberArray(vector);
|
|
1379
|
+
const topK = queryOptions?.topK ?? 5;
|
|
1380
|
+
const namespace = queryOptions?.namespace;
|
|
1381
|
+
const filter = queryOptions?.filter;
|
|
1382
|
+
const returnValues = queryOptions?.returnValues ?? false;
|
|
1383
|
+
const returnMetadata = queryOptions?.returnMetadata;
|
|
1384
|
+
const matches = Array.from(store.values()).filter((candidate) => namespace === void 0 || candidate.namespace === namespace).filter((candidate) => filter === void 0 || matchesFilter(candidate.metadata, filter)).map((candidate) => ({
|
|
1385
|
+
candidate,
|
|
1386
|
+
score: cosineSimilarity(queryVector, toNumberArray(candidate.values))
|
|
1387
|
+
})).sort((a, b) => b.score - a.score || a.candidate.id.localeCompare(b.candidate.id)).slice(0, topK).map(({ candidate, score }) => {
|
|
1388
|
+
const match = {
|
|
1389
|
+
id: candidate.id,
|
|
1390
|
+
score,
|
|
1391
|
+
...candidate.namespace !== void 0 && { namespace: candidate.namespace }
|
|
1392
|
+
};
|
|
1393
|
+
if (returnValues) match.values = toNumberArray(candidate.values);
|
|
1394
|
+
const metadata = applyMetadataRetrieval(candidate.metadata, returnMetadata);
|
|
1395
|
+
if (metadata !== void 0) match.metadata = metadata;
|
|
1396
|
+
return match;
|
|
1397
|
+
});
|
|
1398
|
+
return {
|
|
1399
|
+
matches,
|
|
1400
|
+
count: matches.length
|
|
1401
|
+
};
|
|
1402
|
+
},
|
|
1403
|
+
_getVectors() {
|
|
1404
|
+
return Array.from(store.values()).map(cloneVector);
|
|
1405
|
+
}
|
|
1406
|
+
};
|
|
1407
|
+
}
|
|
1408
|
+
//#endregion
|
|
1409
|
+
//#region src/test/utilities/analytics-engine.ts
|
|
1410
|
+
/**
|
|
1411
|
+
* Creates a write-only Analytics Engine dataset binding for pure unit tests.
|
|
1412
|
+
*
|
|
1413
|
+
* @example
|
|
1414
|
+
* ```ts
|
|
1415
|
+
* const dataset = createMockAnalyticsEngine()
|
|
1416
|
+
* dataset.writeDataPoint({ indexes: ['user-1'], doubles: [1], blobs: ['signup'] })
|
|
1417
|
+
* expect(dataset.writtenDataPoints).toEqual([
|
|
1418
|
+
* { indexes: ['user-1'], doubles: [1], blobs: ['signup'] }
|
|
1419
|
+
* ])
|
|
1420
|
+
* ```
|
|
1421
|
+
*/
|
|
1422
|
+
function createMockAnalyticsEngine() {
|
|
1423
|
+
const dataPoints = [];
|
|
1424
|
+
return {
|
|
1425
|
+
writeDataPoint(event) {
|
|
1426
|
+
dataPoints.push(event ? structuredClone(event) : {});
|
|
1427
|
+
},
|
|
1428
|
+
get writtenDataPoints() {
|
|
1429
|
+
return dataPoints;
|
|
1430
|
+
},
|
|
1431
|
+
get points() {
|
|
1432
|
+
return dataPoints;
|
|
1433
|
+
},
|
|
1434
|
+
clear() {
|
|
1435
|
+
dataPoints.length = 0;
|
|
1436
|
+
}
|
|
1437
|
+
};
|
|
1438
|
+
}
|
|
1439
|
+
//#endregion
|
|
1229
1440
|
//#region src/test/utilities/env.ts
|
|
1441
|
+
function isVectorizeBinding$1(value) {
|
|
1442
|
+
return typeof value.query === "function";
|
|
1443
|
+
}
|
|
1444
|
+
function addVectorizeMockBindings(env, vectorize) {
|
|
1445
|
+
if (Array.isArray(vectorize)) {
|
|
1446
|
+
for (const name of vectorize) env[name] = createMockVectorize();
|
|
1447
|
+
return;
|
|
1448
|
+
}
|
|
1449
|
+
if (vectorize) for (const [name, value] of Object.entries(vectorize)) env[name] = isVectorizeBinding$1(value) ? value : createMockVectorize(value);
|
|
1450
|
+
}
|
|
1451
|
+
function addAnalyticsEngineMockBindings(env, analyticsEngine) {
|
|
1452
|
+
for (const name of analyticsEngine ?? []) env[name] = createMockAnalyticsEngine();
|
|
1453
|
+
}
|
|
1230
1454
|
/**
|
|
1231
1455
|
* Creates a complete mock environment with specified bindings
|
|
1232
1456
|
*
|
|
@@ -1264,6 +1488,8 @@ function createMockEnv(options = {}) {
|
|
|
1264
1488
|
else if (options.media) env.MEDIA = options.media;
|
|
1265
1489
|
if (Array.isArray(options.artifacts)) for (const name of options.artifacts) env[name] = createMockArtifacts();
|
|
1266
1490
|
else if (options.artifacts) for (const [name, artifactsOptions] of Object.entries(options.artifacts)) env[name] = isArtifactsBinding$1(artifactsOptions) ? artifactsOptions : createMockArtifacts(artifactsOptions);
|
|
1491
|
+
addVectorizeMockBindings(env, options.vectorize);
|
|
1492
|
+
addAnalyticsEngineMockBindings(env, options.analyticsEngine);
|
|
1267
1493
|
if (options.secretsStore) for (const [name, value] of Object.entries(options.secretsStore)) env[name] = createMockSecretsStoreSecret(value);
|
|
1268
1494
|
if (options.vars) Object.assign(env, options.vars);
|
|
1269
1495
|
if (options.secrets) Object.assign(env, options.secrets);
|
|
@@ -2054,7 +2280,7 @@ function createMessageBatch(messages) {
|
|
|
2054
2280
|
* ])
|
|
2055
2281
|
* ```
|
|
2056
2282
|
*/
|
|
2057
|
-
async function trigger$
|
|
2283
|
+
async function trigger$3(messages) {
|
|
2058
2284
|
if (!queueHandlerPath) throw new Error("Queue handler not configured. Make sure your devflare.config.ts has files.queue set, and the file exists at the specified path (default: src/queue.ts)");
|
|
2059
2285
|
if (!configDir$3 || !testEnvGetter$3) throw new Error("Queue helper not initialized. Call createTestContext() before using cf.queue.trigger()");
|
|
2060
2286
|
const handlerModule = await import(join$1(configDir$3, queueHandlerPath));
|
|
@@ -2108,10 +2334,10 @@ async function trigger$2(messages) {
|
|
|
2108
2334
|
* ```
|
|
2109
2335
|
*/
|
|
2110
2336
|
async function send(message) {
|
|
2111
|
-
return trigger$
|
|
2337
|
+
return trigger$3([message]);
|
|
2112
2338
|
}
|
|
2113
2339
|
const queue = {
|
|
2114
|
-
trigger: trigger$
|
|
2340
|
+
trigger: trigger$3,
|
|
2115
2341
|
send
|
|
2116
2342
|
};
|
|
2117
2343
|
//#endregion
|
|
@@ -2159,7 +2385,7 @@ function resetScheduledState() {
|
|
|
2159
2385
|
* // Trigger without cron (just scheduled time)
|
|
2160
2386
|
* await cf.scheduled.trigger()
|
|
2161
2387
|
*/
|
|
2162
|
-
async function trigger$
|
|
2388
|
+
async function trigger$2(cronOrOptions) {
|
|
2163
2389
|
if (!scheduledHandlerPath) throw new Error("Scheduled handler not configured. Make sure your devflare.config.ts has files.scheduled set, and the file exists at the specified path (default: src/scheduled.ts)");
|
|
2164
2390
|
if (!configDir$2 || !testEnvGetter$2) throw new Error("Scheduled helper not initialized. Call createTestContext() before using cf.scheduled.trigger()");
|
|
2165
2391
|
const options = typeof cronOrOptions === "string" ? { cron: cronOrOptions } : cronOrOptions ?? {};
|
|
@@ -2198,7 +2424,7 @@ async function trigger$1(cronOrOptions) {
|
|
|
2198
2424
|
};
|
|
2199
2425
|
}
|
|
2200
2426
|
}
|
|
2201
|
-
const scheduled = { trigger: trigger$
|
|
2427
|
+
const scheduled = { trigger: trigger$2 };
|
|
2202
2428
|
//#endregion
|
|
2203
2429
|
//#region src/test/tail.ts
|
|
2204
2430
|
let tailHandlerPath = null;
|
|
@@ -2267,7 +2493,7 @@ function createTraceItem(options) {
|
|
|
2267
2493
|
* ])
|
|
2268
2494
|
* ```
|
|
2269
2495
|
*/
|
|
2270
|
-
async function trigger(items) {
|
|
2496
|
+
async function trigger$1(items) {
|
|
2271
2497
|
if (!tailHandlerPath) throw new Error("Tail handler not configured. Add a src/tail.ts file exporting tail(), or configure a tail handler before calling cf.tail.trigger().");
|
|
2272
2498
|
if (!configDir$1 || !testEnvGetter$1) throw new Error("Tail helper not initialized. Call createTestContext() before using cf.tail.trigger()");
|
|
2273
2499
|
const traceItems = items.map((item) => {
|
|
@@ -2314,7 +2540,7 @@ function create(options = {}) {
|
|
|
2314
2540
|
return createTraceItem(options);
|
|
2315
2541
|
}
|
|
2316
2542
|
const tail = {
|
|
2317
|
-
trigger,
|
|
2543
|
+
trigger: trigger$1,
|
|
2318
2544
|
create
|
|
2319
2545
|
};
|
|
2320
2546
|
//#endregion
|
|
@@ -3493,6 +3719,43 @@ async function createTestContext(configPath) {
|
|
|
3493
3719
|
__setTestContext(createBridgeEnvAccessor(state, hints, shouldPreferBridgeBinding), disposeContext);
|
|
3494
3720
|
}
|
|
3495
3721
|
//#endregion
|
|
3722
|
+
//#region src/test/alarm.ts
|
|
3723
|
+
/**
|
|
3724
|
+
* Trigger a Durable Object's `alarm()` handler.
|
|
3725
|
+
*
|
|
3726
|
+
* This mirrors how the Devflare runtime invokes a DO alarm: it builds a
|
|
3727
|
+
* `durable-object-alarm` event with the instance's env + state, installs it into
|
|
3728
|
+
* AsyncLocalStorage via `runWithEventContext`, and calls the instance's
|
|
3729
|
+
* `alarm()` with that event (so `getDurableObjectAlarmEvent()` works inside the
|
|
3730
|
+
* handler). The instance keeps using its own `this.env` / `this.ctx`; the event
|
|
3731
|
+
* is supplied for context-aware code paths.
|
|
3732
|
+
*
|
|
3733
|
+
* @param target - The Durable Object instance whose `alarm()` should be fired.
|
|
3734
|
+
* @param options - Optional explicit `state`/`env` for the alarm event.
|
|
3735
|
+
* @returns Result object with success status.
|
|
3736
|
+
*
|
|
3737
|
+
* @example
|
|
3738
|
+
* const counter = new Counter(state, env)
|
|
3739
|
+
* await counter.scheduleAlarm()
|
|
3740
|
+
* const result = await cf.alarm.trigger(counter)
|
|
3741
|
+
* expect(result.success).toBe(true)
|
|
3742
|
+
*/
|
|
3743
|
+
async function trigger(target, options = {}) {
|
|
3744
|
+
if (!target || typeof target.alarm !== "function") throw new Error("cf.alarm.trigger(target): the target Durable Object instance has no alarm() method. Pass a DO instance whose class defines an async alarm() handler (and enable alarms via the @durableObject({ alarms: true }) decorator so the runtime wraps it).");
|
|
3745
|
+
const state = options.state ?? target.state ?? target.ctx;
|
|
3746
|
+
const alarmEvent = createDurableObjectAlarmEvent(options.env ?? target.env ?? {}, state);
|
|
3747
|
+
try {
|
|
3748
|
+
await runWithEventContext(alarmEvent, () => target.alarm?.(alarmEvent));
|
|
3749
|
+
return { success: true };
|
|
3750
|
+
} catch (error) {
|
|
3751
|
+
return {
|
|
3752
|
+
success: false,
|
|
3753
|
+
error: error instanceof Error ? error.message : String(error)
|
|
3754
|
+
};
|
|
3755
|
+
}
|
|
3756
|
+
}
|
|
3757
|
+
const alarm = { trigger };
|
|
3758
|
+
//#endregion
|
|
3496
3759
|
//#region src/test/cf.ts
|
|
3497
3760
|
/**
|
|
3498
3761
|
* Unified Cloudflare test helpers.
|
|
@@ -3503,6 +3766,7 @@ async function createTestContext(configPath) {
|
|
|
3503
3766
|
* - `cf.scheduled` — Cron/scheduled handler testing
|
|
3504
3767
|
* - `cf.worker` — Fetch handler testing
|
|
3505
3768
|
* - `cf.tail` — Tail helper surface (uses `files.tail`, or auto-detects `src/tail.ts` when present)
|
|
3769
|
+
* - `cf.alarm` — Durable Object alarm handler testing (fires a DO instance's `alarm()`)
|
|
3506
3770
|
*
|
|
3507
3771
|
* The helpers use the real Miniflare-backed bindings created by `createTestContext()`,
|
|
3508
3772
|
* but several helper surfaces still synthesize event/controller objects around those
|
|
@@ -3553,7 +3817,8 @@ const cf = {
|
|
|
3553
3817
|
queue,
|
|
3554
3818
|
scheduled,
|
|
3555
3819
|
worker,
|
|
3556
|
-
tail
|
|
3820
|
+
tail,
|
|
3821
|
+
alarm
|
|
3557
3822
|
};
|
|
3558
3823
|
//#endregion
|
|
3559
3824
|
//#region src/test/should-skip.ts
|
|
@@ -4246,6 +4511,18 @@ function createMockAISearchNamespace(options = {}) {
|
|
|
4246
4511
|
//#endregion
|
|
4247
4512
|
//#region src/test/offline-bindings.ts
|
|
4248
4513
|
const SUPPORT_MATRIX = {
|
|
4514
|
+
durableObjects: {
|
|
4515
|
+
service: "durableObjects",
|
|
4516
|
+
tier: "offline-native",
|
|
4517
|
+
reason: "Miniflare executes Durable Object classes locally, so createTestContext() runs them fully offline. There is no pure in-memory createMockEnv() mock for a DO (a real instance needs the Miniflare runtime).",
|
|
4518
|
+
recommendation: "Use createTestContext() (Miniflare-backed) to run Durable Objects locally; there is no standalone createMockEnv() DO fixture."
|
|
4519
|
+
},
|
|
4520
|
+
services: {
|
|
4521
|
+
service: "services",
|
|
4522
|
+
tier: "offline-native",
|
|
4523
|
+
reason: "Miniflare resolves service bindings worker-to-worker locally, so createTestContext() runs them fully offline. There is no pure in-memory createMockEnv() mock (a real service binding needs the Miniflare runtime to wire the target Worker).",
|
|
4524
|
+
recommendation: "Use createTestContext() (Miniflare-backed) for worker-to-worker service bindings; there is no standalone createMockEnv() service fixture."
|
|
4525
|
+
},
|
|
4249
4526
|
rateLimits: {
|
|
4250
4527
|
service: "rateLimits",
|
|
4251
4528
|
tier: "offline-native",
|
|
@@ -4368,9 +4645,15 @@ const SUPPORT_MATRIX = {
|
|
|
4368
4645
|
},
|
|
4369
4646
|
vectorize: {
|
|
4370
4647
|
service: "vectorize",
|
|
4371
|
-
tier: "
|
|
4372
|
-
reason: "Cloudflare
|
|
4373
|
-
recommendation: "Use DEVFLARE_REMOTE=1/devflare remote enable for real
|
|
4648
|
+
tier: "offline-fixture",
|
|
4649
|
+
reason: "Vector storage and cosine-similarity query are deterministic in-memory; Cloudflare's real indexing/ranking/scale are hosted — use remote mode for those.",
|
|
4650
|
+
recommendation: "Use createMockVectorize() or createOfflineEnv() for app-level vector tests; use DEVFLARE_REMOTE=1/devflare remote enable for real index relevance and scale."
|
|
4651
|
+
},
|
|
4652
|
+
analyticsEngine: {
|
|
4653
|
+
service: "analyticsEngine",
|
|
4654
|
+
tier: "offline-fixture",
|
|
4655
|
+
reason: "Analytics Engine writes are recordable in-memory (createMockAnalyticsEngine), but there is no in-worker read API — querying is the hosted SQL API/dashboard.",
|
|
4656
|
+
recommendation: "Use createMockAnalyticsEngine() to assert recorded writeDataPoint() calls; query analytics through the hosted SQL API/dashboard."
|
|
4374
4657
|
},
|
|
4375
4658
|
builds: {
|
|
4376
4659
|
service: "builds",
|
|
@@ -4439,6 +4722,9 @@ function isArtifactsBinding(value) {
|
|
|
4439
4722
|
function isAISearchInstance(value) {
|
|
4440
4723
|
return typeof value?.search === "function";
|
|
4441
4724
|
}
|
|
4725
|
+
function isVectorizeBinding(value) {
|
|
4726
|
+
return typeof value?.query === "function";
|
|
4727
|
+
}
|
|
4442
4728
|
function isAISearchNamespace(value) {
|
|
4443
4729
|
return typeof value?.get === "function";
|
|
4444
4730
|
}
|
|
@@ -4456,6 +4742,27 @@ function addStaticBindings(env, config) {
|
|
|
4456
4742
|
function addRateLimitBindings(env, bindings) {
|
|
4457
4743
|
for (const [name, binding] of Object.entries(bindings?.rateLimits ?? {})) env[name] = createMockRateLimit(binding.simple);
|
|
4458
4744
|
}
|
|
4745
|
+
function addKVBindings(env, bindings, fixtures) {
|
|
4746
|
+
for (const name of Object.keys(bindings?.kv ?? {})) env[name] = fixtures.kv?.[name] ?? createMockKV();
|
|
4747
|
+
}
|
|
4748
|
+
function addD1Bindings(env, bindings, fixtures) {
|
|
4749
|
+
for (const name of Object.keys(bindings?.d1 ?? {})) env[name] = fixtures.d1?.[name] ?? createMockD1();
|
|
4750
|
+
}
|
|
4751
|
+
function addR2Bindings(env, bindings, fixtures) {
|
|
4752
|
+
for (const name of Object.keys(bindings?.r2 ?? {})) env[name] = fixtures.r2?.[name] ?? createMockR2();
|
|
4753
|
+
}
|
|
4754
|
+
function addQueueBindings(env, bindings, fixtures) {
|
|
4755
|
+
for (const name of Object.keys(bindings?.queues?.producers ?? {})) env[name] = fixtures.queues?.[name] ?? createMockQueue();
|
|
4756
|
+
}
|
|
4757
|
+
function addVectorizeBindings(env, bindings, fixtures) {
|
|
4758
|
+
for (const name of Object.keys(bindings?.vectorize ?? {})) {
|
|
4759
|
+
const fixture = fixtures.vectorize?.[name];
|
|
4760
|
+
env[name] = isVectorizeBinding(fixture) ? fixture : createMockVectorize(fixture);
|
|
4761
|
+
}
|
|
4762
|
+
}
|
|
4763
|
+
function addAnalyticsEngineBindings(env, bindings, fixtures) {
|
|
4764
|
+
for (const name of Object.keys(bindings?.analyticsEngine ?? {})) env[name] = fixtures.analyticsEngine?.[name] ?? createMockAnalyticsEngine();
|
|
4765
|
+
}
|
|
4459
4766
|
function addVersionMetadataBinding(env, bindings) {
|
|
4460
4767
|
if (bindings?.versionMetadata) env[bindings.versionMetadata.binding] = createMockVersionMetadata();
|
|
4461
4768
|
}
|
|
@@ -4567,55 +4874,47 @@ function addAISearchNamespaceBindings(env, bindings, fixtures) {
|
|
|
4567
4874
|
}
|
|
4568
4875
|
}
|
|
4569
4876
|
/**
|
|
4570
|
-
*
|
|
4571
|
-
*
|
|
4572
|
-
* `
|
|
4573
|
-
*
|
|
4574
|
-
*
|
|
4575
|
-
*
|
|
4576
|
-
*
|
|
4877
|
+
* Wiring bindings (durableObjects/services) have no pure-offline fixture: they
|
|
4878
|
+
* need a real Miniflare runtime, which only `createTestContext()` provides.
|
|
4879
|
+
* `createOfflineBindings()` therefore cannot populate them, and leaving them
|
|
4880
|
+
* silently absent from `env` is a surprise. Surface each one in
|
|
4881
|
+
* `missingFixtures` (with `env` left unset rather than a fake) so callers see
|
|
4882
|
+
* exactly which bindings require `createTestContext()` / a cross-worker setup
|
|
4883
|
+
* instead of getting an `undefined` lookup at use time.
|
|
4884
|
+
*
|
|
4885
|
+
* Storage bindings (kv/d1/r2/queues) DO have deterministic in-memory mocks, so
|
|
4886
|
+
* `createOfflineBindings()` auto-creates them — they are not listed here.
|
|
4577
4887
|
*/
|
|
4578
|
-
const OFFLINE_UNAVAILABLE_STORAGE_BINDINGS = [
|
|
4579
|
-
"kv",
|
|
4580
|
-
"d1",
|
|
4581
|
-
"r2",
|
|
4582
|
-
"durableObjects",
|
|
4583
|
-
"services"
|
|
4584
|
-
];
|
|
4888
|
+
const OFFLINE_UNAVAILABLE_STORAGE_BINDINGS = ["durableObjects", "services"];
|
|
4585
4889
|
function addUnsupportedStorageBindings(bindings, missingFixtures) {
|
|
4586
4890
|
for (const service of OFFLINE_UNAVAILABLE_STORAGE_BINDINGS) {
|
|
4587
4891
|
const group = bindings?.[service];
|
|
4588
4892
|
for (const name of Object.keys(group ?? {})) missingFixtures.push({
|
|
4589
4893
|
service,
|
|
4590
4894
|
binding: name,
|
|
4591
|
-
reason: `${service} binding "${name}" needs a real Miniflare runtime and is not created by createOfflineBindings(); it will be undefined. Use createTestContext() (Miniflare-backed)
|
|
4895
|
+
reason: `${service} binding "${name}" needs a real Miniflare runtime and is not created by createOfflineBindings(); it will be undefined. Use createTestContext() (Miniflare-backed) for this binding.`
|
|
4592
4896
|
});
|
|
4593
4897
|
}
|
|
4594
|
-
const queueProducers = (bindings?.queues)?.producers ?? {};
|
|
4595
|
-
for (const name of Object.keys(queueProducers)) missingFixtures.push({
|
|
4596
|
-
service: "queues",
|
|
4597
|
-
binding: name,
|
|
4598
|
-
reason: `queues producer binding "${name}" needs a real Miniflare runtime and is not created by createOfflineBindings(); it will be undefined. Use createTestContext() or createMockQueue() for this binding.`
|
|
4599
|
-
});
|
|
4600
4898
|
}
|
|
4601
4899
|
function addRemoteBoundaries(remoteBoundaries, bindings) {
|
|
4602
4900
|
if (bindings?.ai) addBoundary(remoteBoundaries, "ai", bindings.ai.binding || "AI", "Workers AI inference is not available in offline local simulations.");
|
|
4603
|
-
for (const name of Object.keys(bindings?.vectorize ?? {})) addBoundary(remoteBoundaries, "vectorize", name, "Vectorize has no offline local simulation in Cloudflare local development.");
|
|
4604
4901
|
for (const name of Object.keys(bindings?.vpcServices ?? {})) addBoundary(remoteBoundaries, "vpcServices", name, "VPC services are proxy-only locally — Miniflare's vpc-services plugin needs a remote proxy connection, so there is no offline simulation.");
|
|
4605
4902
|
for (const name of Object.keys(bindings?.vpcNetworks ?? {})) addBoundary(remoteBoundaries, "vpcNetworks", name, "VPC networks are proxy-only locally — Miniflare's vpc-networks plugin needs a remote proxy connection, so there is no offline simulation.");
|
|
4606
4903
|
}
|
|
4607
4904
|
/**
|
|
4608
4905
|
* Builds a deterministic, pure-test env object from Devflare config.
|
|
4609
4906
|
*
|
|
4610
|
-
* Covers the bindings that have a pure-offline simulator or fixture
|
|
4611
|
-
*
|
|
4612
|
-
*
|
|
4613
|
-
*
|
|
4614
|
-
*
|
|
4615
|
-
*
|
|
4616
|
-
*
|
|
4617
|
-
* (
|
|
4618
|
-
* `createTestContext()`
|
|
4907
|
+
* Covers the bindings that have a pure-offline simulator or fixture: the core
|
|
4908
|
+
* storage mocks (`kv`, `d1`, `r2`, `queues`) are **auto-created** from the
|
|
4909
|
+
* existing `createMock*()` helpers (an explicit `fixtures.{kv,d1,r2,queues}`
|
|
4910
|
+
* entry overrides the auto-mock), alongside rate limits, version metadata,
|
|
4911
|
+
* hyperdrive, worker loaders, mTLS, dispatch namespaces, workflows, pipelines,
|
|
4912
|
+
* images, media, stream, flagship, artifacts, secrets store, AI Search,
|
|
4913
|
+
* Vectorize, and Analytics Engine. It does **not** create the wiring bindings
|
|
4914
|
+
* (`durableObjects`, `services`) — those require a real Miniflare runtime, which
|
|
4915
|
+
* only `createTestContext()` provides. When such a binding is present in config
|
|
4916
|
+
* it is reported in the returned `missingFixtures` (its `env` entry is left
|
|
4917
|
+
* unset rather than silently faked); use `createTestContext()` for those.
|
|
4619
4918
|
*/
|
|
4620
4919
|
function createOfflineBindings(config, fixtures = {}, options = {}) {
|
|
4621
4920
|
const env = {};
|
|
@@ -4624,6 +4923,12 @@ function createOfflineBindings(config, fixtures = {}, options = {}) {
|
|
|
4624
4923
|
const bindings = config.bindings;
|
|
4625
4924
|
const localSecretValues = options.cwd && options.useLocalSecrets !== false ? resolveLocalSecretValuesForBindings(config, options.cwd) : {};
|
|
4626
4925
|
addStaticBindings(env, config);
|
|
4926
|
+
addKVBindings(env, bindings, fixtures);
|
|
4927
|
+
addD1Bindings(env, bindings, fixtures);
|
|
4928
|
+
addR2Bindings(env, bindings, fixtures);
|
|
4929
|
+
addQueueBindings(env, bindings, fixtures);
|
|
4930
|
+
addVectorizeBindings(env, bindings, fixtures);
|
|
4931
|
+
addAnalyticsEngineBindings(env, bindings, fixtures);
|
|
4627
4932
|
addRateLimitBindings(env, bindings);
|
|
4628
4933
|
addVersionMetadataBinding(env, bindings);
|
|
4629
4934
|
addHyperdriveBindings(env, bindings, fixtures, missingFixtures);
|
|
@@ -4653,14 +4958,14 @@ function createOfflineBindings(config, fixtures = {}, options = {}) {
|
|
|
4653
4958
|
/**
|
|
4654
4959
|
* Convenience wrapper for callers that only need the derived env object.
|
|
4655
4960
|
*
|
|
4656
|
-
* Note: the
|
|
4657
|
-
* `durableObjects`, `services`) are **not**
|
|
4658
|
-
* `undefined` in the returned env
|
|
4659
|
-
* `createTestContext()` or
|
|
4660
|
-
* `
|
|
4961
|
+
* Note: the storage mocks (`kv`, `d1`, `r2`, `queues`) are auto-created here, but
|
|
4962
|
+
* the wiring bindings (`durableObjects`, `services`) are **not** — they need a
|
|
4963
|
+
* real Miniflare runtime and will be `undefined` in the returned env. Use
|
|
4964
|
+
* `createTestContext()` for them, or call `createOfflineBindings()` to inspect
|
|
4965
|
+
* `missingFixtures` for the exact list.
|
|
4661
4966
|
*/
|
|
4662
4967
|
function createOfflineEnv(config, fixtures = {}, options = {}) {
|
|
4663
4968
|
return createOfflineBindings(config, fixtures, options).env;
|
|
4664
4969
|
}
|
|
4665
4970
|
//#endregion
|
|
4666
|
-
export { cf, clearBundleCache, containers, createContainerManager, createMockAISearchInstance, createMockAISearchNamespace, createMockArtifacts, createMockD1, createMockDispatchNamespace, createMockEnv, createMockFlagshipBinding, createMockHyperdrive, createMockImagesBinding, createMockKV, createMockMTLSCertificate, createMockMediaBinding, createMockPipeline, createMockQueue, createMockR2, createMockRateLimit, createMockSecretsStoreSecret, createMockStreamBinding, createMockTestContext, createMockVersionMetadata, createMockWorkerLoader, createMockWorkflow, createOfflineBindings, createOfflineEnv, createTestContext, describeOfflineSupport, detectContainerEngine, email, env, getContainerSkipReason, getOfflineSupportMatrix, hasCrossWorkerDOs, hasServiceBindings, queue, resolveDOBindings, resolveServiceBindings, scheduled, shouldSkip, stopActiveContainers, tail, withTestContext, worker };
|
|
4971
|
+
export { alarm, cf, clearBundleCache, containers, createContainerManager, createMockAISearchInstance, createMockAISearchNamespace, createMockAnalyticsEngine, createMockArtifacts, createMockD1, createMockDispatchNamespace, createMockEnv, createMockFlagshipBinding, createMockHyperdrive, createMockImagesBinding, createMockKV, createMockMTLSCertificate, createMockMediaBinding, createMockPipeline, createMockQueue, createMockR2, createMockRateLimit, createMockSecretsStoreSecret, createMockStreamBinding, createMockTestContext, createMockVectorize, createMockVersionMetadata, createMockWorkerLoader, createMockWorkflow, createOfflineBindings, createOfflineEnv, createTestContext, describeOfflineSupport, detectContainerEngine, email, env, getContainerSkipReason, getOfflineSupportMatrix, hasCrossWorkerDOs, hasServiceBindings, queue, resolveDOBindings, resolveServiceBindings, scheduled, shouldSkip, stopActiveContainers, tail, withTestContext, worker };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Pipeline } from 'cloudflare:pipelines';
|
|
2
2
|
import { type DevflareConfig } from '../config/index.js';
|
|
3
3
|
import { type MockAISearchInstanceOptions, type MockAISearchNamespaceOptions } from './ai-search.js';
|
|
4
|
-
import { type MockArtifactsOptions, type MockDispatchNamespaceOptions, type MockFetcherHandler, type MockFlagshipBindingOptions, type MockImagesBindingOptions, type MockMediaBindingOptions, type MockStreamBindingOptions, type MockWorkerLoaderOptions, type MockWorkflowOptions } from './utilities.js';
|
|
4
|
+
import { type MockArtifactsOptions, type MockDispatchNamespaceOptions, type MockFetcherHandler, type MockFlagshipBindingOptions, type MockImagesBindingOptions, type MockMediaBindingOptions, type MockStreamBindingOptions, type MockVectorizeOptions, type MockWorkerLoaderOptions, type MockWorkflowOptions } from './utilities.js';
|
|
5
5
|
export type OfflineSupportTier = 'offline-native' | 'offline-fixture' | 'remote-boundary';
|
|
6
6
|
export interface OfflineSupportEntry {
|
|
7
7
|
service: string;
|
|
@@ -21,6 +21,36 @@ export interface OfflineMissingFixture {
|
|
|
21
21
|
reason: string;
|
|
22
22
|
}
|
|
23
23
|
export interface OfflineBindingFixtures {
|
|
24
|
+
/**
|
|
25
|
+
* Explicit KV namespace bindings. Any KV binding in config without an entry
|
|
26
|
+
* here is auto-created with `createMockKV()`.
|
|
27
|
+
*/
|
|
28
|
+
kv?: Record<string, KVNamespace>;
|
|
29
|
+
/**
|
|
30
|
+
* Explicit D1 database bindings. Any D1 binding in config without an entry
|
|
31
|
+
* here is auto-created with `createMockD1()`.
|
|
32
|
+
*/
|
|
33
|
+
d1?: Record<string, D1Database>;
|
|
34
|
+
/**
|
|
35
|
+
* Explicit R2 bucket bindings. Any R2 binding in config without an entry here
|
|
36
|
+
* is auto-created with `createMockR2()`.
|
|
37
|
+
*/
|
|
38
|
+
r2?: Record<string, R2Bucket>;
|
|
39
|
+
/**
|
|
40
|
+
* Explicit queue-producer bindings. Any queue producer in config without an
|
|
41
|
+
* entry here is auto-created with `createMockQueue()`.
|
|
42
|
+
*/
|
|
43
|
+
queues?: Record<string, Queue>;
|
|
44
|
+
/**
|
|
45
|
+
* Vectorize index bindings. Any vectorize binding in config without an entry
|
|
46
|
+
* here is auto-created with `createMockVectorize()`.
|
|
47
|
+
*/
|
|
48
|
+
vectorize?: Record<string, MockVectorizeOptions | VectorizeIndex>;
|
|
49
|
+
/**
|
|
50
|
+
* Analytics Engine dataset bindings. Any analyticsEngine binding in config
|
|
51
|
+
* without an entry here is auto-created with `createMockAnalyticsEngine()`.
|
|
52
|
+
*/
|
|
53
|
+
analyticsEngine?: Record<string, AnalyticsEngineDataset>;
|
|
24
54
|
secretsStore?: Record<string, string>;
|
|
25
55
|
workerLoaders?: Record<string, MockWorkerLoaderOptions>;
|
|
26
56
|
mtlsCertificates?: Record<string, MockFetcherHandler>;
|
|
@@ -58,25 +88,27 @@ export declare function describeOfflineSupport(service: string): OfflineSupportE
|
|
|
58
88
|
/**
|
|
59
89
|
* Builds a deterministic, pure-test env object from Devflare config.
|
|
60
90
|
*
|
|
61
|
-
* Covers the bindings that have a pure-offline simulator or fixture
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
* (
|
|
69
|
-
* `createTestContext()`
|
|
91
|
+
* Covers the bindings that have a pure-offline simulator or fixture: the core
|
|
92
|
+
* storage mocks (`kv`, `d1`, `r2`, `queues`) are **auto-created** from the
|
|
93
|
+
* existing `createMock*()` helpers (an explicit `fixtures.{kv,d1,r2,queues}`
|
|
94
|
+
* entry overrides the auto-mock), alongside rate limits, version metadata,
|
|
95
|
+
* hyperdrive, worker loaders, mTLS, dispatch namespaces, workflows, pipelines,
|
|
96
|
+
* images, media, stream, flagship, artifacts, secrets store, AI Search,
|
|
97
|
+
* Vectorize, and Analytics Engine. It does **not** create the wiring bindings
|
|
98
|
+
* (`durableObjects`, `services`) — those require a real Miniflare runtime, which
|
|
99
|
+
* only `createTestContext()` provides. When such a binding is present in config
|
|
100
|
+
* it is reported in the returned `missingFixtures` (its `env` entry is left
|
|
101
|
+
* unset rather than silently faked); use `createTestContext()` for those.
|
|
70
102
|
*/
|
|
71
103
|
export declare function createOfflineBindings(config: OfflineConfig, fixtures?: OfflineBindingFixtures, options?: OfflineBindingOptions): OfflineBindingsResult;
|
|
72
104
|
/**
|
|
73
105
|
* Convenience wrapper for callers that only need the derived env object.
|
|
74
106
|
*
|
|
75
|
-
* Note: the
|
|
76
|
-
* `durableObjects`, `services`) are **not**
|
|
77
|
-
* `undefined` in the returned env
|
|
78
|
-
* `createTestContext()` or
|
|
79
|
-
* `
|
|
107
|
+
* Note: the storage mocks (`kv`, `d1`, `r2`, `queues`) are auto-created here, but
|
|
108
|
+
* the wiring bindings (`durableObjects`, `services`) are **not** — they need a
|
|
109
|
+
* real Miniflare runtime and will be `undefined` in the returned env. Use
|
|
110
|
+
* `createTestContext()` for them, or call `createOfflineBindings()` to inspect
|
|
111
|
+
* `missingFixtures` for the exact list.
|
|
80
112
|
*/
|
|
81
113
|
export declare function createOfflineEnv(config: OfflineConfig, fixtures?: OfflineBindingFixtures, options?: OfflineBindingOptions): Record<string, unknown>;
|
|
82
114
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"offline-bindings.d.ts","sourceRoot":"","sources":["../../src/test/offline-bindings.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AACpD,OAAO,EAAE,KAAK,cAAc,EAA8B,MAAM,WAAW,CAAA;AAE3E,OAAO,EACN,KAAK,2BAA2B,EAChC,KAAK,4BAA4B,EAGjC,MAAM,aAAa,CAAA;AACpB,OAAO,EACN,KAAK,oBAAoB,EACzB,KAAK,4BAA4B,EACjC,KAAK,kBAAkB,EACvB,KAAK,0BAA0B,EAC/B,KAAK,wBAAwB,EAC7B,KAAK,uBAAuB,EAC5B,KAAK,wBAAwB,EAC7B,KAAK,uBAAuB,EAC5B,KAAK,mBAAmB,
|
|
1
|
+
{"version":3,"file":"offline-bindings.d.ts","sourceRoot":"","sources":["../../src/test/offline-bindings.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export type MockAnalyticsEngineDataset = AnalyticsEngineDataset & {
|
|
2
|
+
/** Every data point passed to `writeDataPoint()`, in call order. */
|
|
3
|
+
readonly writtenDataPoints: AnalyticsEngineDataPoint[];
|
|
4
|
+
/** Alias for {@link writtenDataPoints} (parity with other record-only mocks). */
|
|
5
|
+
readonly points: AnalyticsEngineDataPoint[];
|
|
6
|
+
/** Clear the recorded data points. */
|
|
7
|
+
clear(): void;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Creates a write-only Analytics Engine dataset binding for pure unit tests.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```ts
|
|
14
|
+
* const dataset = createMockAnalyticsEngine()
|
|
15
|
+
* dataset.writeDataPoint({ indexes: ['user-1'], doubles: [1], blobs: ['signup'] })
|
|
16
|
+
* expect(dataset.writtenDataPoints).toEqual([
|
|
17
|
+
* { indexes: ['user-1'], doubles: [1], blobs: ['signup'] }
|
|
18
|
+
* ])
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export declare function createMockAnalyticsEngine(): MockAnalyticsEngineDataset;
|
|
22
|
+
//# sourceMappingURL=analytics-engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analytics-engine.d.ts","sourceRoot":"","sources":["../../../src/test/utilities/analytics-engine.ts"],"names":[],"mappings":"AAYA,MAAM,MAAM,0BAA0B,GAAG,sBAAsB,GAAG;IACjE,oEAAoE;IACpE,QAAQ,CAAC,iBAAiB,EAAE,wBAAwB,EAAE,CAAA;IACtD,iFAAiF;IACjF,QAAQ,CAAC,MAAM,EAAE,wBAAwB,EAAE,CAAA;IAC3C,sCAAsC;IACtC,KAAK,IAAI,IAAI,CAAA;CACb,CAAA;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,yBAAyB,IAAI,0BAA0B,CAmBtE"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Pipeline } from 'cloudflare:pipelines';
|
|
2
2
|
import { type MockArtifactsOptions } from './artifacts.js';
|
|
3
3
|
import { type MockDispatchNamespaceOptions, type MockFetcherHandler, type MockRateLimitOptions, type MockWorkerLoaderOptions } from './platform.js';
|
|
4
|
+
import { type MockVectorizeOptions } from './vectorize.js';
|
|
4
5
|
import { type MockWorkflowOptions } from './workflows.js';
|
|
5
6
|
export interface MockEnvOptions {
|
|
6
7
|
kv?: string[];
|
|
@@ -18,6 +19,8 @@ export interface MockEnvOptions {
|
|
|
18
19
|
images?: string | ImagesBinding;
|
|
19
20
|
media?: string | MediaBinding;
|
|
20
21
|
artifacts?: string[] | Record<string, MockArtifactsOptions | Artifacts>;
|
|
22
|
+
vectorize?: string[] | Record<string, MockVectorizeOptions | VectorizeIndex>;
|
|
23
|
+
analyticsEngine?: string[];
|
|
21
24
|
secretsStore?: Record<string, string>;
|
|
22
25
|
durableObjects?: string[];
|
|
23
26
|
vars?: Record<string, string>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../../src/test/utilities/env.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;
|
|
1
|
+
{"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../../src/test/utilities/env.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAEpD,OAAO,EAAE,KAAK,oBAAoB,EAA2C,MAAM,aAAa,CAAA;AAIhG,OAAO,EACN,KAAK,4BAA4B,EACjC,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,EACzB,KAAK,uBAAuB,EAQ5B,MAAM,YAAY,CAAA;AAGnB,OAAO,EAAE,KAAK,oBAAoB,EAAuB,MAAM,aAAa,CAAA;AAC5E,OAAO,EAAE,KAAK,mBAAmB,EAA0C,MAAM,aAAa,CAAA;AAE9F,MAAM,WAAW,cAAc;IAC9B,EAAE,CAAC,EAAE,MAAM,EAAE,CAAA;IACb,EAAE,CAAC,EAAE,MAAM,EAAE,CAAA;IACb,EAAE,CAAC,EAAE,MAAM,EAAE,CAAA;IACb,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAA;IACjD,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CAAC,CAAA;IAChD,aAAa,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAA;IAClE,gBAAgB,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAA;IAChE,kBAAkB,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,4BAA4B,CAAC,CAAA;IAC5E,SAAS,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,mBAAmB,GAAG,QAAQ,CAAC,CAAA;IACrE,SAAS,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;IAC/C,MAAM,CAAC,EAAE,MAAM,GAAG,aAAa,CAAA;IAC/B,KAAK,CAAC,EAAE,MAAM,GAAG,YAAY,CAAA;IAC7B,SAAS,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,oBAAoB,GAAG,SAAS,CAAC,CAAA;IACvE,SAAS,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,oBAAoB,GAAG,cAAc,CAAC,CAAA;IAC5E,eAAe,CAAC,EAAE,MAAM,EAAE,CAAA;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACrC,cAAc,CAAC,EAAE,MAAM,EAAE,CAAA;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAChC;AAoCD;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,OAAO,GAAE,cAAmB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAkKnF"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export interface MockVectorizeOptions {
|
|
2
|
+
/** Index name reported by `describe()` (default `mock-vectorize`). */
|
|
3
|
+
name?: string;
|
|
4
|
+
/** Distance metric reported by `describe()` (default `cosine`). */
|
|
5
|
+
metric?: VectorizeDistanceMetric;
|
|
6
|
+
/**
|
|
7
|
+
* Dimensions reported by `describe()`. When omitted it is inferred from the
|
|
8
|
+
* first inserted/seeded vector; before any vector exists `describe()` reports
|
|
9
|
+
* `0`.
|
|
10
|
+
*/
|
|
11
|
+
dimensions?: number;
|
|
12
|
+
/** Vectors seeded into the index up front. */
|
|
13
|
+
vectors?: VectorizeVector[];
|
|
14
|
+
}
|
|
15
|
+
export type MockVectorizeIndex = VectorizeIndex & {
|
|
16
|
+
/** Inspect every stored vector (test helper). */
|
|
17
|
+
_getVectors(): VectorizeVector[];
|
|
18
|
+
/**
|
|
19
|
+
* Delete vectors by id. Convenience alias for `deleteByIds` so tests can call
|
|
20
|
+
* the same verb as KV/R2 mocks.
|
|
21
|
+
*/
|
|
22
|
+
delete(ids: string[]): Promise<VectorizeVectorMutation>;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Creates a deterministic in-memory Vectorize index binding for pure unit tests.
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```ts
|
|
29
|
+
* const index = createMockVectorize({
|
|
30
|
+
* vectors: [{ id: 'a', values: [1, 0], metadata: { topic: 'cats' } }]
|
|
31
|
+
* })
|
|
32
|
+
* await index.insert([{ id: 'b', values: [0, 1] }])
|
|
33
|
+
* const result = await index.query([1, 0], { topK: 1, returnMetadata: true })
|
|
34
|
+
* // result.matches[0].id === 'a'
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
export declare function createMockVectorize(options?: MockVectorizeOptions): MockVectorizeIndex;
|
|
38
|
+
//# sourceMappingURL=vectorize.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vectorize.d.ts","sourceRoot":"","sources":["../../../src/test/utilities/vectorize.ts"],"names":[],"mappings":"AAiBA,MAAM,WAAW,oBAAoB;IACpC,sEAAsE;IACtE,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,mEAAmE;IACnE,MAAM,CAAC,EAAE,uBAAuB,CAAA;IAChC;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,8CAA8C;IAC9C,OAAO,CAAC,EAAE,eAAe,EAAE,CAAA;CAC3B;AAED,MAAM,MAAM,kBAAkB,GAAG,cAAc,GAAG;IACjD,iDAAiD;IACjD,WAAW,IAAI,eAAe,EAAE,CAAA;IAChC;;;OAGG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAAA;CACvD,CAAA;AA6HD;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,oBAAyB,GAAG,kBAAkB,CAkI1F"}
|
package/dist/test/utilities.d.ts
CHANGED
|
@@ -8,5 +8,7 @@ export * from './utilities/workflows.js';
|
|
|
8
8
|
export * from './utilities/media.js';
|
|
9
9
|
export * from './utilities/stream-flagship.js';
|
|
10
10
|
export * from './utilities/artifacts.js';
|
|
11
|
+
export * from './utilities/vectorize.js';
|
|
12
|
+
export * from './utilities/analytics-engine.js';
|
|
11
13
|
export * from './utilities/env.js';
|
|
12
14
|
//# sourceMappingURL=utilities.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utilities.d.ts","sourceRoot":"","sources":["../../src/test/utilities.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAA;AACnC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,mBAAmB,CAAA;AACjC,cAAc,sBAAsB,CAAA;AACpC,cAAc,uBAAuB,CAAA;AACrC,cAAc,mBAAmB,CAAA;AACjC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,uBAAuB,CAAA;AACrC,cAAc,iBAAiB,CAAA"}
|
|
1
|
+
{"version":3,"file":"utilities.d.ts","sourceRoot":"","sources":["../../src/test/utilities.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAA;AACnC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,mBAAmB,CAAA;AACjC,cAAc,sBAAsB,CAAA;AACpC,cAAc,uBAAuB,CAAA;AACrC,cAAc,mBAAmB,CAAA;AACjC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,uBAAuB,CAAA;AACrC,cAAc,uBAAuB,CAAA;AACrC,cAAc,8BAA8B,CAAA;AAC5C,cAAc,iBAAiB,CAAA"}
|
package/package.json
CHANGED