@velajs/cloudflare 1.9.0 → 1.10.1

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.
Files changed (107) hide show
  1. package/CHANGELOG.md +8 -3
  2. package/dist/index.d.ts +805 -39
  3. package/dist/index.js +1645 -37
  4. package/dist/index.js.map +1 -0
  5. package/package.json +55 -41
  6. package/dist/binding-ref.d.ts +0 -8
  7. package/dist/binding-ref.js +0 -19
  8. package/dist/cloudflare-application.d.ts +0 -125
  9. package/dist/cloudflare-application.js +0 -186
  10. package/dist/cloudflare-factory.d.ts +0 -88
  11. package/dist/cloudflare-factory.js +0 -101
  12. package/dist/decorators/env.d.ts +0 -16
  13. package/dist/decorators/env.js +0 -22
  14. package/dist/decorators/queue-consumer.d.ts +0 -23
  15. package/dist/decorators/queue-consumer.js +0 -40
  16. package/dist/decorators/scheduled.d.ts +0 -20
  17. package/dist/decorators/scheduled.js +0 -36
  18. package/dist/env-ref.d.ts +0 -10
  19. package/dist/env-ref.js +0 -13
  20. package/dist/modules/ai.module.d.ts +0 -1
  21. package/dist/modules/ai.module.js +0 -8
  22. package/dist/modules/create-binding-module.d.ts +0 -14
  23. package/dist/modules/create-binding-module.js +0 -42
  24. package/dist/modules/d1.module.d.ts +0 -1
  25. package/dist/modules/d1.module.js +0 -8
  26. package/dist/modules/durable-object.module.d.ts +0 -1
  27. package/dist/modules/durable-object.module.js +0 -8
  28. package/dist/modules/env.module.d.ts +0 -17
  29. package/dist/modules/env.module.js +0 -35
  30. package/dist/modules/hyperdrive.module.d.ts +0 -1
  31. package/dist/modules/hyperdrive.module.js +0 -8
  32. package/dist/modules/kv.module.d.ts +0 -1
  33. package/dist/modules/kv.module.js +0 -8
  34. package/dist/modules/queue.module.d.ts +0 -1
  35. package/dist/modules/queue.module.js +0 -8
  36. package/dist/modules/r2.module.d.ts +0 -1
  37. package/dist/modules/r2.module.js +0 -8
  38. package/dist/modules/vectorize.module.d.ts +0 -1
  39. package/dist/modules/vectorize.module.js +0 -8
  40. package/dist/services/ai.service.d.ts +0 -6
  41. package/dist/services/ai.service.js +0 -33
  42. package/dist/services/d1.service.d.ts +0 -6
  43. package/dist/services/d1.service.js +0 -33
  44. package/dist/services/durable-object.service.d.ts +0 -6
  45. package/dist/services/durable-object.service.js +0 -33
  46. package/dist/services/env.service.d.ts +0 -31
  47. package/dist/services/env.service.js +0 -36
  48. package/dist/services/flagship-flag.driver.d.ts +0 -57
  49. package/dist/services/flagship-flag.driver.js +0 -49
  50. package/dist/services/hyperdrive.service.d.ts +0 -12
  51. package/dist/services/hyperdrive.service.js +0 -51
  52. package/dist/services/kv-cache.store.d.ts +0 -19
  53. package/dist/services/kv-cache.store.js +0 -58
  54. package/dist/services/kv-flag.driver.d.ts +0 -48
  55. package/dist/services/kv-flag.driver.js +0 -62
  56. package/dist/services/kv.service.d.ts +0 -11
  57. package/dist/services/kv.service.js +0 -33
  58. package/dist/services/queue.service.d.ts +0 -6
  59. package/dist/services/queue.service.js +0 -33
  60. package/dist/services/r2.service.d.ts +0 -6
  61. package/dist/services/r2.service.js +0 -33
  62. package/dist/services/vectorize.service.d.ts +0 -6
  63. package/dist/services/vectorize.service.js +0 -33
  64. package/dist/storage/index.d.ts +0 -7
  65. package/dist/storage/index.js +0 -6
  66. package/dist/storage/r2-storage.driver.d.ts +0 -19
  67. package/dist/storage/r2-storage.driver.js +0 -61
  68. package/dist/storage/storage-manager.service.d.ts +0 -16
  69. package/dist/storage/storage-manager.service.js +0 -56
  70. package/dist/storage/storage.controller.d.ts +0 -16
  71. package/dist/storage/storage.controller.js +0 -88
  72. package/dist/storage/storage.module.d.ts +0 -7
  73. package/dist/storage/storage.module.js +0 -37
  74. package/dist/storage/storage.service.d.ts +0 -20
  75. package/dist/storage/storage.service.js +0 -78
  76. package/dist/storage/storage.tokens.d.ts +0 -3
  77. package/dist/storage/storage.tokens.js +0 -2
  78. package/dist/storage/storage.types.d.ts +0 -17
  79. package/dist/storage/storage.types.js +0 -1
  80. package/dist/tokens.d.ts +0 -12
  81. package/dist/tokens.js +0 -12
  82. package/dist/types.d.ts +0 -13
  83. package/dist/types.js +0 -1
  84. package/dist/websocket/broadcast.d.ts +0 -15
  85. package/dist/websocket/broadcast.js +0 -26
  86. package/dist/websocket/cf-room-registry.d.ts +0 -23
  87. package/dist/websocket/cf-room-registry.js +0 -65
  88. package/dist/websocket/cf-ws-client.d.ts +0 -28
  89. package/dist/websocket/cf-ws-client.js +0 -83
  90. package/dist/websocket/cloudflare-websocket.module.d.ts +0 -11
  91. package/dist/websocket/cloudflare-websocket.module.js +0 -27
  92. package/dist/websocket/do-bootstrap.d.ts +0 -21
  93. package/dist/websocket/do-bootstrap.js +0 -50
  94. package/dist/websocket/do-state.d.ts +0 -25
  95. package/dist/websocket/do-state.js +0 -4
  96. package/dist/websocket/do-websocket-host.d.ts +0 -28
  97. package/dist/websocket/do-websocket-host.js +0 -69
  98. package/dist/websocket/index.d.ts +0 -13
  99. package/dist/websocket/index.js +0 -13
  100. package/dist/websocket/room-id.d.ts +0 -6
  101. package/dist/websocket/room-id.js +0 -12
  102. package/dist/websocket/websocket-routing.d.ts +0 -14
  103. package/dist/websocket/websocket-routing.js +0 -45
  104. package/dist/websocket/websocket.durable-object.d.ts +0 -15
  105. package/dist/websocket/websocket.durable-object.js +0 -72
  106. package/dist/websocket/ws-server-holder.d.ts +0 -16
  107. package/dist/websocket/ws-server-holder.js +0 -34
@@ -1,186 +0,0 @@
1
- import { CRON_METADATA, PipelineRunner, buildEntrypointExecutionContext, registerEntrypointKind, runInEntrypointScope, shouldFilterCatch } from "@velajs/vela";
2
- import { ComponentManager } from "@velajs/vela/internal";
3
- import { collectWsGatewayRoutes } from "./websocket/websocket-routing.js";
4
- // vela's own @Cron jobs run via the same Workers cron trigger — declare an
5
- // entrypoint kind over vela's metadata key (the open-kind system makes
6
- // cross-package declarations first-class).
7
- registerEntrypointKind({
8
- kind: 'cf:vela-cron',
9
- metaKey: CRON_METADATA,
10
- level: 'method'
11
- });
12
- function invoke(instance, methodName, args) {
13
- const method = instance[methodName];
14
- if (typeof method !== 'function') {
15
- throw new Error(`Method '${methodName}' is not a function on ${instance.constructor.name}`);
16
- }
17
- return method.apply(instance, args);
18
- }
19
- /**
20
- * Wraps VelaApplication with Cloudflare-specific handlers:
21
- * - `fetch` — HTTP request handler (from Hono)
22
- * - `scheduled` — Cron trigger handler (matches `@Scheduled()` decorators
23
- * AND vela's own `@Cron()` jobs)
24
- * - `queue` — Queue consumer handler (matches `@QueueConsumer()` decorators)
25
- * - `mountOpenApi` — Serve an OpenAPI document (and optional Scalar UI) on
26
- * the underlying Hono app
27
- *
28
- * @example
29
- * ```ts
30
- * const app = await createCloudflareApp(AppModule);
31
- * export default {
32
- * fetch: app.fetch,
33
- * scheduled: app.scheduled.bind(app),
34
- * queue: app.queue.bind(app),
35
- * };
36
- * ```
37
- *
38
- * @example
39
- * ```ts
40
- * // Serve OpenAPI docs alongside your routes
41
- * const app = await createCloudflareApp(AppModule);
42
- * const document = createOpenApiDocument(AppModule);
43
- * app.mountOpenApi({ document, ui: 'scalar' });
44
- * // GET /openapi.json -> JSON document
45
- * // GET /scalar -> Scalar UI (loads from CDN)
46
- * ```
47
- */ export class CloudflareApplication {
48
- app;
49
- wsGatewayRoutes = [];
50
- constructor(app){
51
- this.app = app;
52
- }
53
- get fetch() {
54
- return this.app.fetch;
55
- }
56
- getHonoApp() {
57
- return this.app.getHonoApp();
58
- }
59
- /**
60
- * Resolve a provider from the application's DI container (delegates to
61
- * `VelaApplication.get`). Handy for grabbing a service — e.g. an auth service —
62
- * to use inside `createCloudflareApp({ middleware: [...] })` request middleware,
63
- * which runs outside the DI request pipeline.
64
- *
65
- * @example
66
- * ```ts
67
- * const app = await createCloudflareApp(AppModule);
68
- * const auth = app.get<BetterAuthService>(BetterAuthService);
69
- * ```
70
- */ get(token) {
71
- return this.app.get(token);
72
- }
73
- /**
74
- * Serve a pre-built OpenAPI document (and optionally a Scalar UI) on the
75
- * underlying Hono app. Delegates verbatim to `VelaApplication.mountOpenApi`,
76
- * so the JSON endpoint defaults to `/openapi.json` and the Scalar UI (when
77
- * opted in) defaults to `/scalar`. Edge-safe — the UI HTML loads Scalar from
78
- * a CDN at runtime, nothing is bundled server-side.
79
- *
80
- * @example
81
- * ```ts
82
- * import { createOpenApiDocument } from '@velajs/vela';
83
- *
84
- * const app = await createCloudflareApp(AppModule);
85
- * const document = createOpenApiDocument(AppModule, {
86
- * info: { title: 'My API', version: '1.0.0' },
87
- * });
88
- * app.mountOpenApi({ document, ui: 'scalar' });
89
- * // GET /openapi.json -> { openapi: '3.1.0', ... }
90
- * // GET /scalar -> Scalar UI HTML
91
- * ```
92
- */ mountOpenApi(options) {
93
- this.app.mountOpenApi(options);
94
- return this;
95
- }
96
- /**
97
- * @internal — scans instances for `@WebSocketGateway({ path, binding })`
98
- * upgrade routes. Queue/scheduled handlers are NOT scanned anymore: they
99
- * come from `app.entrypoints` (`cf:queue` / `cf:scheduled` / `cf:vela-cron`
100
- * kinds) at dispatch time.
101
- */ scanInstances(instances) {
102
- for (const instance of instances){
103
- if (!instance || typeof instance !== 'object') continue;
104
- this.wsGatewayRoutes.push(...collectWsGatewayRoutes(instance));
105
- }
106
- }
107
- /** @internal — upgrade routes discovered from `@WebSocketGateway({ path, binding })`. */ getWsGatewayRoutes() {
108
- return this.wsGatewayRoutes;
109
- }
110
- /**
111
- * Handle Cloudflare scheduled (cron) events.
112
- * Matches the event's cron expression to `@Scheduled()` and vela `@Cron()`
113
- * handlers read from `app.entrypoints`; each handler runs inside a fresh
114
- * request-scoped child (request-scoped providers rebuild per tick).
115
- */ async scheduled(event, env, ctx) {
116
- const handlers = [
117
- ...this.app.entrypoints.ofKind('cf:scheduled').map((ep)=>({
118
- ep,
119
- cron: ep.meta.cron
120
- })),
121
- ...this.app.entrypoints.ofKind('cf:vela-cron').map((ep)=>({
122
- ep,
123
- cron: ep.meta.expression
124
- }))
125
- ].filter((h)=>h.cron === event.cron);
126
- await Promise.all(handlers.map(({ ep })=>this.dispatchEntrypoint(ep, [
127
- event,
128
- env,
129
- ctx
130
- ])));
131
- }
132
- /**
133
- * Run one entrypoint handler inside a fresh request scope, through the
134
- * shared guard → interceptor pipeline (components declared with
135
- * `@UseGuards`/`@UseInterceptors`/`@UseFilters` on the consumer class or
136
- * method). HTTP-global components deliberately do NOT apply — an HTTP auth
137
- * guard has no business rejecting a queue batch. Unclaimed errors rethrow
138
- * so the platform's retry semantics stay intact.
139
- */ async dispatchEntrypoint(ep, args) {
140
- const targetClass = ep.token;
141
- const methodName = String(ep.methodName);
142
- const context = buildEntrypointExecutionContext(ep.kind, targetClass, methodName, args[0]);
143
- await runInEntrypointScope(this.app.getContainer(), async (scope)=>{
144
- const instance = scope.resolve(ep.token);
145
- const guards = ComponentManager.resolveGuards(ComponentManager.getScopedComponents('guard', targetClass, methodName), scope);
146
- const interceptors = ComponentManager.resolveInterceptors(ComponentManager.getScopedComponents('interceptor', targetClass, methodName), scope);
147
- // Closest-first, mirroring the HTTP/WS dispatchers.
148
- const filters = ComponentManager.resolveFilters([
149
- ...ComponentManager.getScopedComponents('filter', targetClass, methodName)
150
- ].reverse(), scope);
151
- try {
152
- await PipelineRunner.run({
153
- context,
154
- guards,
155
- interceptors,
156
- resolveArgs: async ()=>args,
157
- invoke: async (resolved)=>invoke(instance, methodName, resolved)
158
- });
159
- } catch (error) {
160
- for (const filter of filters){
161
- if (shouldFilterCatch(filter, error)) {
162
- await filter.catch(error, context);
163
- return;
164
- }
165
- }
166
- throw error;
167
- }
168
- });
169
- }
170
- /**
171
- * Handle Cloudflare Queue consumer events.
172
- * Matches the batch queue name to `@QueueConsumer()` handlers read from
173
- * `app.entrypoints`; each batch is processed inside a fresh request-scoped
174
- * child (request-scoped providers rebuild per batch — no boot-time captives).
175
- */ async queue(batch, env, ctx) {
176
- const handlers = this.app.entrypoints.ofKind('cf:queue').filter((ep)=>ep.meta.queueName === batch.queue);
177
- await Promise.all(handlers.map((ep)=>this.dispatchEntrypoint(ep, [
178
- batch,
179
- env,
180
- ctx
181
- ])));
182
- }
183
- async close(signal) {
184
- return this.app.close(signal);
185
- }
186
- }
@@ -1,88 +0,0 @@
1
- import type { MiddlewareHandler } from 'hono';
2
- import type { RuntimeAdapter, Type } from '@velajs/vela';
3
- import { CloudflareApplication } from './cloudflare-application';
4
- /**
5
- * Options for {@link createCloudflareApp}.
6
- *
7
- * Mirrors a tight subset of vela's `BootstrapOptions` — only the surface
8
- * that makes sense for a Workers consumer is re-exposed.
9
- */
10
- export interface CreateCloudflareAppOptions {
11
- /**
12
- * Forwarded to `VelaFactory.create({ globalPrefix })`. Prepended to every
13
- * route registered by `@Controller(...)` (and any other route emitter)
14
- * inside the application, so a value of `'/v1'` turns `@Controller('/users')`
15
- * into `/v1/users`.
16
- *
17
- * @example
18
- * ```ts
19
- * const app = await createCloudflareApp(AppModule, { globalPrefix: '/v1' });
20
- * ```
21
- */
22
- globalPrefix?: string;
23
- /**
24
- * Extra Hono middleware to register on the underlying Hono app. Runs
25
- * AFTER the one-time binding-init middleware this adapter mounts
26
- * internally, so any handler in `middleware` can safely read from
27
- * `BindingRef` instances and Cloudflare env bindings.
28
- *
29
- * @example
30
- * ```ts
31
- * const app = await createCloudflareApp(AppModule, {
32
- * middleware: [
33
- * async (c, next) => {
34
- * c.set('requestId', crypto.randomUUID());
35
- * await next();
36
- * },
37
- * ],
38
- * });
39
- * ```
40
- */
41
- middleware?: MiddlewareHandler[];
42
- }
43
- /**
44
- * Create a Cloudflare Workers application.
45
- *
46
- * Sets up a one-time Hono middleware that captures `c.env` on the first
47
- * request and initializes all configured binding refs. Optional
48
- * {@link CreateCloudflareAppOptions} are forwarded to the underlying
49
- * `VelaFactory.create` so consumers don't have to wrap the resulting
50
- * application in an outer Hono just to set a `globalPrefix` or attach
51
- * extra request middleware.
52
- *
53
- * @example
54
- * ```ts
55
- * // Minimal — backwards compatible
56
- * const app = await createCloudflareApp(AppModule);
57
- * export default app; // has .fetch, .scheduled, .queue
58
- * ```
59
- *
60
- * @example
61
- * ```ts
62
- * // With a global prefix and outer middleware
63
- * const app = await createCloudflareApp(AppModule, {
64
- * globalPrefix: '/v1',
65
- * middleware: [
66
- * async (c, next) => {
67
- * c.set('tenantId', c.req.header('x-tenant-id') ?? 'public');
68
- * await next();
69
- * },
70
- * ],
71
- * });
72
- * ```
73
- */
74
- /**
75
- * The Cloudflare platform binding as a vela {@link RuntimeAdapter}: a one-time
76
- * request middleware captures `c.env` on the first request and initializes
77
- * every `BindingRef`/`EnvRef` (collected at `onBootstrap`, before any request
78
- * can arrive). Adapter `requestMiddleware` is prepended to the global chain by
79
- * `VelaFactory.create`, so user middleware can safely read binding refs.
80
- *
81
- * Exposed so consumers composing `VelaFactory.create` themselves can opt in:
82
- *
83
- * ```ts
84
- * const app = await VelaFactory.create(AppModule, { adapters: [cloudflareAdapter()] });
85
- * ```
86
- */
87
- export declare function cloudflareAdapter(): RuntimeAdapter;
88
- export declare function createCloudflareApp(rootModule: Type, options?: CreateCloudflareAppOptions): Promise<CloudflareApplication>;
@@ -1,101 +0,0 @@
1
- import { VelaFactory } from "@velajs/vela";
2
- import { BindingRef } from "./binding-ref.js";
3
- import { CloudflareApplication } from "./cloudflare-application.js";
4
- import { EnvRef } from "./env-ref.js";
5
- import { registerWebSocketRoutes } from "./websocket/websocket-routing.js";
6
- // Walks every provider registered in the container and pulls out the
7
- // BindingRef instances. Replaces the old module-level `bindingsRegistry`
8
- // global so two CloudflareApplication instances in one process don't
9
- // share state.
10
- function collectBindingRefs(container) {
11
- // Enumerate per-instance useValue providers across ALL module buckets. Two
12
- // same-type binding modules (e.g. KVModule.forRoot for CACHE and SESSIONS)
13
- // share one token but live in distinct buckets — resolving the token would
14
- // return only the first, leaving the others uninitialized.
15
- const refs = [];
16
- for (const value of container.getUseValues()){
17
- if (value instanceof BindingRef) refs.push(value);
18
- }
19
- return refs;
20
- }
21
- /**
22
- * Create a Cloudflare Workers application.
23
- *
24
- * Sets up a one-time Hono middleware that captures `c.env` on the first
25
- * request and initializes all configured binding refs. Optional
26
- * {@link CreateCloudflareAppOptions} are forwarded to the underlying
27
- * `VelaFactory.create` so consumers don't have to wrap the resulting
28
- * application in an outer Hono just to set a `globalPrefix` or attach
29
- * extra request middleware.
30
- *
31
- * @example
32
- * ```ts
33
- * // Minimal — backwards compatible
34
- * const app = await createCloudflareApp(AppModule);
35
- * export default app; // has .fetch, .scheduled, .queue
36
- * ```
37
- *
38
- * @example
39
- * ```ts
40
- * // With a global prefix and outer middleware
41
- * const app = await createCloudflareApp(AppModule, {
42
- * globalPrefix: '/v1',
43
- * middleware: [
44
- * async (c, next) => {
45
- * c.set('tenantId', c.req.header('x-tenant-id') ?? 'public');
46
- * await next();
47
- * },
48
- * ],
49
- * });
50
- * ```
51
- */ /**
52
- * The Cloudflare platform binding as a vela {@link RuntimeAdapter}: a one-time
53
- * request middleware captures `c.env` on the first request and initializes
54
- * every `BindingRef`/`EnvRef` (collected at `onBootstrap`, before any request
55
- * can arrive). Adapter `requestMiddleware` is prepended to the global chain by
56
- * `VelaFactory.create`, so user middleware can safely read binding refs.
57
- *
58
- * Exposed so consumers composing `VelaFactory.create` themselves can opt in:
59
- *
60
- * ```ts
61
- * const app = await VelaFactory.create(AppModule, { adapters: [cloudflareAdapter()] });
62
- * ```
63
- */ export function cloudflareAdapter() {
64
- let initialized = false;
65
- let refs = [];
66
- return {
67
- name: 'cloudflare',
68
- requestMiddleware: [
69
- async (c, next)=>{
70
- if (!initialized) {
71
- initialized = true;
72
- const env = c.env ?? {};
73
- for (const ref of refs){
74
- // EnvRef holds the whole env; every other ref holds one binding.
75
- if (ref instanceof EnvRef) ref._initialize(env);
76
- else ref._initialize(env[ref.bindingName]);
77
- }
78
- }
79
- await next();
80
- }
81
- ],
82
- onBootstrap: ({ container })=>{
83
- refs = collectBindingRefs(container);
84
- }
85
- };
86
- }
87
- export async function createCloudflareApp(rootModule, options = {}) {
88
- const velaApp = await VelaFactory.create(rootModule, {
89
- globalPrefix: options.globalPrefix,
90
- middleware: options.middleware,
91
- adapters: [
92
- cloudflareAdapter()
93
- ]
94
- });
95
- const cfApp = new CloudflareApplication(velaApp);
96
- cfApp.scanInstances(velaApp.getInstances());
97
- // Register WebSocket upgrade routes for any @WebSocketGateway({ path, binding }).
98
- // Each forwards the upgrade to the room's Durable Object (which owns the socket).
99
- registerWebSocketRoutes(cfApp.getHonoApp(), cfApp.getWsGatewayRoutes());
100
- return cfApp;
101
- }
@@ -1,16 +0,0 @@
1
- /**
2
- * Parameter decorator to inject Cloudflare environment bindings.
3
- *
4
- * Without arguments, returns the entire `env` object.
5
- * With a binding name, returns that specific binding.
6
- *
7
- * @example
8
- * ```ts
9
- * @Get()
10
- * handle(@Env() env: CloudflareEnv) { ... }
11
- *
12
- * @Get()
13
- * handle(@Env('MY_KV') kv: KVNamespace) { ... }
14
- * ```
15
- */
16
- export declare const Env: (data?: string | undefined, ...pipes: import("@velajs/vela").PipeType[]) => ParameterDecorator;
@@ -1,22 +0,0 @@
1
- import { createParamDecorator } from "@velajs/vela";
2
- /**
3
- * Parameter decorator to inject Cloudflare environment bindings.
4
- *
5
- * Without arguments, returns the entire `env` object.
6
- * With a binding name, returns that specific binding.
7
- *
8
- * @example
9
- * ```ts
10
- * @Get()
11
- * handle(@Env() env: CloudflareEnv) { ... }
12
- *
13
- * @Get()
14
- * handle(@Env('MY_KV') kv: KVNamespace) { ... }
15
- * ```
16
- */ export const Env = createParamDecorator((bindingName, ctx)=>{
17
- // Hono Context has .env on Cloudflare Workers
18
- const c = ctx.getContext();
19
- const env = c.env;
20
- if (!env) return undefined;
21
- return bindingName ? env[bindingName] : env;
22
- });
@@ -1,23 +0,0 @@
1
- export interface QueueConsumerMetadata {
2
- queueName: string;
3
- methodName: string;
4
- }
5
- /**
6
- * Marks a method as a queue consumer handler.
7
- *
8
- * @example
9
- * ```ts
10
- * @Injectable()
11
- * class WorkerService {
12
- * @QueueConsumer('email-queue')
13
- * async processEmails(batch: MessageBatch) {
14
- * for (const msg of batch.messages) {
15
- * console.log('Processing:', msg.body);
16
- * msg.ack();
17
- * }
18
- * }
19
- * }
20
- * ```
21
- */
22
- export declare function QueueConsumer(queueName: string): MethodDecorator;
23
- export declare function getQueueConsumerMetadata(target: object): QueueConsumerMetadata[];
@@ -1,40 +0,0 @@
1
- import { defineMetadata, getMetadata, registerEntrypointKind } from "@velajs/vela";
2
- const QUEUE_CONSUMER_METADATA_KEY = 'cloudflare:queue-consumer';
3
- // Open entrypoint kind: any adapter can enumerate queue consumers via
4
- // `app.entrypoints.ofKind('cf:queue')` — declared here, next to the decorator,
5
- // with zero vela-core involvement.
6
- registerEntrypointKind({
7
- kind: 'cf:queue',
8
- metaKey: QUEUE_CONSUMER_METADATA_KEY,
9
- level: 'method'
10
- });
11
- /**
12
- * Marks a method as a queue consumer handler.
13
- *
14
- * @example
15
- * ```ts
16
- * @Injectable()
17
- * class WorkerService {
18
- * @QueueConsumer('email-queue')
19
- * async processEmails(batch: MessageBatch) {
20
- * for (const msg of batch.messages) {
21
- * console.log('Processing:', msg.body);
22
- * msg.ack();
23
- * }
24
- * }
25
- * }
26
- * ```
27
- */ export function QueueConsumer(queueName) {
28
- return (target, propertyKey, _descriptor)=>{
29
- const existing = getMetadata(QUEUE_CONSUMER_METADATA_KEY, target.constructor) ?? [];
30
- existing.push({
31
- queueName,
32
- methodName: String(propertyKey)
33
- });
34
- defineMetadata(QUEUE_CONSUMER_METADATA_KEY, existing, target.constructor);
35
- };
36
- }
37
- export function getQueueConsumerMetadata(target) {
38
- const ctor = target.constructor ?? target;
39
- return getMetadata(QUEUE_CONSUMER_METADATA_KEY, ctor) ?? [];
40
- }
@@ -1,20 +0,0 @@
1
- export interface ScheduledMetadata {
2
- cron: string;
3
- methodName: string;
4
- }
5
- /**
6
- * Marks a method as a scheduled (cron) handler.
7
- *
8
- * @example
9
- * ```ts
10
- * @Injectable()
11
- * class WorkerService {
12
- * @Scheduled('0 * * * *')
13
- * async hourlyCron() {
14
- * console.log('Running hourly');
15
- * }
16
- * }
17
- * ```
18
- */
19
- export declare function Scheduled(cron: string): MethodDecorator;
20
- export declare function getScheduledMetadata(target: object): ScheduledMetadata[];
@@ -1,36 +0,0 @@
1
- import { defineMetadata, getMetadata, registerEntrypointKind } from "@velajs/vela";
2
- const SCHEDULED_METADATA_KEY = 'cloudflare:scheduled';
3
- // Open entrypoint kind: adapters enumerate cron handlers via
4
- // `app.entrypoints.ofKind('cf:scheduled')` — declared next to the decorator.
5
- registerEntrypointKind({
6
- kind: 'cf:scheduled',
7
- metaKey: SCHEDULED_METADATA_KEY,
8
- level: 'method'
9
- });
10
- /**
11
- * Marks a method as a scheduled (cron) handler.
12
- *
13
- * @example
14
- * ```ts
15
- * @Injectable()
16
- * class WorkerService {
17
- * @Scheduled('0 * * * *')
18
- * async hourlyCron() {
19
- * console.log('Running hourly');
20
- * }
21
- * }
22
- * ```
23
- */ export function Scheduled(cron) {
24
- return (target, propertyKey, _descriptor)=>{
25
- const existing = getMetadata(SCHEDULED_METADATA_KEY, target.constructor) ?? [];
26
- existing.push({
27
- cron,
28
- methodName: String(propertyKey)
29
- });
30
- defineMetadata(SCHEDULED_METADATA_KEY, existing, target.constructor);
31
- };
32
- }
33
- export function getScheduledMetadata(target) {
34
- const ctor = target.constructor ?? target;
35
- return getMetadata(SCHEDULED_METADATA_KEY, ctor) ?? [];
36
- }
package/dist/env-ref.d.ts DELETED
@@ -1,10 +0,0 @@
1
- import { BindingRef } from './binding-ref';
2
- /**
3
- * Holds the entire Cloudflare Worker `env` record (bindings + vars/secrets),
4
- * not a single binding. Subclasses {@link BindingRef} so createCloudflareApp's
5
- * binding-init middleware collects and initializes it through the same path;
6
- * the factory special-cases it to pass the full `env` instead of one binding.
7
- */
8
- export declare class EnvRef extends BindingRef<Record<string, unknown>> {
9
- constructor();
10
- }
package/dist/env-ref.js DELETED
@@ -1,13 +0,0 @@
1
- import { BindingRef } from "./binding-ref.js";
2
- // Sentinel binding name for the whole-env holder — never used as an env key.
3
- const ENV_SENTINEL = '__cf_env__';
4
- /**
5
- * Holds the entire Cloudflare Worker `env` record (bindings + vars/secrets),
6
- * not a single binding. Subclasses {@link BindingRef} so createCloudflareApp's
7
- * binding-init middleware collects and initializes it through the same path;
8
- * the factory special-cases it to pass the full `env` instead of one binding.
9
- */ export class EnvRef extends BindingRef {
10
- constructor(){
11
- super(ENV_SENTINEL);
12
- }
13
- }
@@ -1 +0,0 @@
1
- export declare const AIModule: import("./create-binding-module").BindingModuleStatic;
@@ -1,8 +0,0 @@
1
- import { AIService } from "../services/ai.service.js";
2
- import { AI_BINDING_REF } from "../tokens.js";
3
- import { createBindingModule } from "./create-binding-module.js";
4
- export const AIModule = createBindingModule({
5
- name: 'AI',
6
- serviceClass: AIService,
7
- bindingRefToken: AI_BINDING_REF
8
- });
@@ -1,14 +0,0 @@
1
- import { type DynamicModule, type InjectionToken, type Type } from '@velajs/vela';
2
- import { BindingRef } from '../binding-ref';
3
- interface CreateBindingModuleOptions<TService> {
4
- name: string;
5
- serviceClass: Type<TService>;
6
- bindingRefToken: InjectionToken<BindingRef>;
7
- }
8
- export interface BindingModuleStatic {
9
- forRoot(options: {
10
- binding: string;
11
- }): DynamicModule;
12
- }
13
- export declare function createBindingModule<TService>(opts: CreateBindingModuleOptions<TService>): BindingModuleStatic;
14
- export {};
@@ -1,42 +0,0 @@
1
- import { defineConfigurableModule } from "@velajs/vela";
2
- import { BindingRef } from "../binding-ref.js";
3
- // Single factory for every Cloudflare binding module (KV, D1, R2, ...).
4
- // Each binding module is just a bag of (token, service); this generates the
5
- // canonical forRoot() shape via vela's `defineConfigurableModule` engine.
6
- //
7
- // Identity model (post vela audit #2):
8
- // - One real module class is declared per binding TYPE (KV, D1, R2, ...).
9
- // Its `name` property is set so error messages and diagnostics carry
10
- // the friendly name (e.g. `KVModule`).
11
- // - Each `forRoot({ binding })` returns `{ module, key: binding, ... }`.
12
- // Vela dedups by (module, key), so two `KVModule.forRoot({...})` calls
13
- // with different bindings coexist as distinct module instances; two
14
- // calls with the same binding dedup.
15
- export function createBindingModule(opts) {
16
- // Fresh module class per binding TYPE (one KVModule, one D1Module, ...).
17
- // The computed-property-name idiom is the canonical JS way to give a
18
- // class expression a dynamic `name`: NamedEvaluation reads the property
19
- // key and stamps it on the class at creation, instead of patching the
20
- // (configurable, non-writable) `name` slot via Object.defineProperty.
21
- const className = `${opts.name}Module`;
22
- const moduleClass = {
23
- [className]: class {
24
- }
25
- }[className];
26
- return defineConfigurableModule({
27
- module: moduleClass,
28
- methodName: 'forRoot',
29
- keyFrom: ({ binding })=>binding,
30
- providers: ({ binding })=>[
31
- {
32
- provide: opts.bindingRefToken,
33
- useValue: new BindingRef(binding)
34
- },
35
- opts.serviceClass
36
- ],
37
- exports: [
38
- opts.serviceClass,
39
- opts.bindingRefToken
40
- ]
41
- });
42
- }
@@ -1 +0,0 @@
1
- export declare const D1Module: import("./create-binding-module").BindingModuleStatic;
@@ -1,8 +0,0 @@
1
- import { D1Service } from "../services/d1.service.js";
2
- import { D1_BINDING_REF } from "../tokens.js";
3
- import { createBindingModule } from "./create-binding-module.js";
4
- export const D1Module = createBindingModule({
5
- name: 'D1',
6
- serviceClass: D1Service,
7
- bindingRefToken: D1_BINDING_REF
8
- });
@@ -1 +0,0 @@
1
- export declare const DurableObjectModule: import("./create-binding-module").BindingModuleStatic;
@@ -1,8 +0,0 @@
1
- import { DurableObjectService } from "../services/durable-object.service.js";
2
- import { DO_BINDING_REF } from "../tokens.js";
3
- import { createBindingModule } from "./create-binding-module.js";
4
- export const DurableObjectModule = createBindingModule({
5
- name: 'DurableObject',
6
- serviceClass: DurableObjectService,
7
- bindingRefToken: DO_BINDING_REF
8
- });