@velajs/cloudflare 1.2.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,12 +1,22 @@
1
1
  import type { Hono } from 'hono';
2
2
  import { type VelaApplication } from '@velajs/vela';
3
3
  import type { CloudflareEnv } from './types';
4
+ /**
5
+ * Options accepted by {@link CloudflareApplication.mountOpenApi}.
6
+ *
7
+ * Re-exposes vela's `MountOpenApiOptions` type — derived structurally from
8
+ * the underlying `VelaApplication.mountOpenApi` signature so consumers don't
9
+ * have to reach into vela's internal subpaths to type the argument.
10
+ */
11
+ export type MountOpenApiOptions = Parameters<VelaApplication['mountOpenApi']>[0];
4
12
  /**
5
13
  * Wraps VelaApplication with Cloudflare-specific handlers:
6
14
  * - `fetch` — HTTP request handler (from Hono)
7
15
  * - `scheduled` — Cron trigger handler (matches `@Scheduled()` decorators
8
16
  * AND vela's own `@Cron()` jobs)
9
17
  * - `queue` — Queue consumer handler (matches `@QueueConsumer()` decorators)
18
+ * - `mountOpenApi` — Serve an OpenAPI document (and optional Scalar UI) on
19
+ * the underlying Hono app
10
20
  *
11
21
  * @example
12
22
  * ```ts
@@ -17,6 +27,16 @@ import type { CloudflareEnv } from './types';
17
27
  * queue: app.queue.bind(app),
18
28
  * };
19
29
  * ```
30
+ *
31
+ * @example
32
+ * ```ts
33
+ * // Serve OpenAPI docs alongside your routes
34
+ * const app = await createCloudflareApp(AppModule);
35
+ * const document = createOpenApiDocument(AppModule);
36
+ * app.mountOpenApi({ document, ui: 'scalar' });
37
+ * // GET /openapi.json -> JSON document
38
+ * // GET /scalar -> Scalar UI (loads from CDN)
39
+ * ```
20
40
  */
21
41
  export declare class CloudflareApplication {
22
42
  private app;
@@ -25,6 +45,40 @@ export declare class CloudflareApplication {
25
45
  constructor(app: VelaApplication);
26
46
  get fetch(): Hono['fetch'];
27
47
  getHonoApp(): Hono;
48
+ /**
49
+ * Resolve a provider from the application's DI container (delegates to
50
+ * `VelaApplication.get`). Handy for grabbing a service — e.g. an auth service —
51
+ * to use inside `createCloudflareApp({ middleware: [...] })` request middleware,
52
+ * which runs outside the DI request pipeline.
53
+ *
54
+ * @example
55
+ * ```ts
56
+ * const app = await createCloudflareApp(AppModule);
57
+ * const auth = app.get<BetterAuthService>(BetterAuthService);
58
+ * ```
59
+ */
60
+ get<T>(token: Parameters<VelaApplication['get']>[0]): T;
61
+ /**
62
+ * Serve a pre-built OpenAPI document (and optionally a Scalar UI) on the
63
+ * underlying Hono app. Delegates verbatim to `VelaApplication.mountOpenApi`,
64
+ * so the JSON endpoint defaults to `/openapi.json` and the Scalar UI (when
65
+ * opted in) defaults to `/scalar`. Edge-safe — the UI HTML loads Scalar from
66
+ * a CDN at runtime, nothing is bundled server-side.
67
+ *
68
+ * @example
69
+ * ```ts
70
+ * import { createOpenApiDocument } from '@velajs/vela';
71
+ *
72
+ * const app = await createCloudflareApp(AppModule);
73
+ * const document = createOpenApiDocument(AppModule, {
74
+ * info: { title: 'My API', version: '1.0.0' },
75
+ * });
76
+ * app.mountOpenApi({ document, ui: 'scalar' });
77
+ * // GET /openapi.json -> { openapi: '3.1.0', ... }
78
+ * // GET /scalar -> Scalar UI HTML
79
+ * ```
80
+ */
81
+ mountOpenApi(options: MountOpenApiOptions): this;
28
82
  /** @internal — scans instances for @Scheduled, @Cron, and @QueueConsumer metadata */
29
83
  scanInstances(instances: unknown[]): void;
30
84
  /**
@@ -14,6 +14,8 @@ function invoke(instance, methodName, args) {
14
14
  * - `scheduled` — Cron trigger handler (matches `@Scheduled()` decorators
15
15
  * AND vela's own `@Cron()` jobs)
16
16
  * - `queue` — Queue consumer handler (matches `@QueueConsumer()` decorators)
17
+ * - `mountOpenApi` — Serve an OpenAPI document (and optional Scalar UI) on
18
+ * the underlying Hono app
17
19
  *
18
20
  * @example
19
21
  * ```ts
@@ -24,6 +26,16 @@ function invoke(instance, methodName, args) {
24
26
  * queue: app.queue.bind(app),
25
27
  * };
26
28
  * ```
29
+ *
30
+ * @example
31
+ * ```ts
32
+ * // Serve OpenAPI docs alongside your routes
33
+ * const app = await createCloudflareApp(AppModule);
34
+ * const document = createOpenApiDocument(AppModule);
35
+ * app.mountOpenApi({ document, ui: 'scalar' });
36
+ * // GET /openapi.json -> JSON document
37
+ * // GET /scalar -> Scalar UI (loads from CDN)
38
+ * ```
27
39
  */ export class CloudflareApplication {
28
40
  app;
29
41
  scheduledHandlers = [];
@@ -37,6 +49,43 @@ function invoke(instance, methodName, args) {
37
49
  getHonoApp() {
38
50
  return this.app.getHonoApp();
39
51
  }
52
+ /**
53
+ * Resolve a provider from the application's DI container (delegates to
54
+ * `VelaApplication.get`). Handy for grabbing a service — e.g. an auth service —
55
+ * to use inside `createCloudflareApp({ middleware: [...] })` request middleware,
56
+ * which runs outside the DI request pipeline.
57
+ *
58
+ * @example
59
+ * ```ts
60
+ * const app = await createCloudflareApp(AppModule);
61
+ * const auth = app.get<BetterAuthService>(BetterAuthService);
62
+ * ```
63
+ */ get(token) {
64
+ return this.app.get(token);
65
+ }
66
+ /**
67
+ * Serve a pre-built OpenAPI document (and optionally a Scalar UI) on the
68
+ * underlying Hono app. Delegates verbatim to `VelaApplication.mountOpenApi`,
69
+ * so the JSON endpoint defaults to `/openapi.json` and the Scalar UI (when
70
+ * opted in) defaults to `/scalar`. Edge-safe — the UI HTML loads Scalar from
71
+ * a CDN at runtime, nothing is bundled server-side.
72
+ *
73
+ * @example
74
+ * ```ts
75
+ * import { createOpenApiDocument } from '@velajs/vela';
76
+ *
77
+ * const app = await createCloudflareApp(AppModule);
78
+ * const document = createOpenApiDocument(AppModule, {
79
+ * info: { title: 'My API', version: '1.0.0' },
80
+ * });
81
+ * app.mountOpenApi({ document, ui: 'scalar' });
82
+ * // GET /openapi.json -> { openapi: '3.1.0', ... }
83
+ * // GET /scalar -> Scalar UI HTML
84
+ * ```
85
+ */ mountOpenApi(options) {
86
+ this.app.mountOpenApi(options);
87
+ return this;
88
+ }
40
89
  /** @internal — scans instances for @Scheduled, @Cron, and @QueueConsumer metadata */ scanInstances(instances) {
41
90
  for (const instance of instances){
42
91
  if (!instance || typeof instance !== 'object') continue;
@@ -1,15 +1,74 @@
1
+ import type { MiddlewareHandler } from 'hono';
1
2
  import type { Type } from '@velajs/vela';
2
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
+ }
3
43
  /**
4
44
  * Create a Cloudflare Workers application.
5
45
  *
6
46
  * Sets up a one-time Hono middleware that captures `c.env` on the first
7
- * request and initializes all configured binding refs.
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.
8
52
  *
9
53
  * @example
10
54
  * ```ts
55
+ * // Minimal — backwards compatible
11
56
  * const app = await createCloudflareApp(AppModule);
12
57
  * export default app; // has .fetch, .scheduled, .queue
13
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
+ * ```
14
73
  */
15
- export declare function createCloudflareApp(rootModule: Type): Promise<CloudflareApplication>;
74
+ export declare function createCloudflareApp(rootModule: Type, options?: CreateCloudflareAppOptions): Promise<CloudflareApplication>;
@@ -1,6 +1,7 @@
1
1
  import { VelaFactory } from "@velajs/vela";
2
2
  import { BindingRef } from "./binding-ref.js";
3
3
  import { CloudflareApplication } from "./cloudflare-application.js";
4
+ import { EnvRef } from "./env-ref.js";
4
5
  // Walks every provider registered in the container and pulls out the
5
6
  // BindingRef instances. Replaces the old module-level `bindingsRegistry`
6
7
  // global so two CloudflareApplication instances in one process don't
@@ -22,28 +23,54 @@ function collectBindingRefs(container) {
22
23
  * Create a Cloudflare Workers application.
23
24
  *
24
25
  * Sets up a one-time Hono middleware that captures `c.env` on the first
25
- * request and initializes all configured binding refs.
26
+ * request and initializes all configured binding refs. Optional
27
+ * {@link CreateCloudflareAppOptions} are forwarded to the underlying
28
+ * `VelaFactory.create` so consumers don't have to wrap the resulting
29
+ * application in an outer Hono just to set a `globalPrefix` or attach
30
+ * extra request middleware.
26
31
  *
27
32
  * @example
28
33
  * ```ts
34
+ * // Minimal — backwards compatible
29
35
  * const app = await createCloudflareApp(AppModule);
30
36
  * export default app; // has .fetch, .scheduled, .queue
31
37
  * ```
32
- */ export async function createCloudflareApp(rootModule) {
38
+ *
39
+ * @example
40
+ * ```ts
41
+ * // With a global prefix and outer middleware
42
+ * const app = await createCloudflareApp(AppModule, {
43
+ * globalPrefix: '/v1',
44
+ * middleware: [
45
+ * async (c, next) => {
46
+ * c.set('tenantId', c.req.header('x-tenant-id') ?? 'public');
47
+ * await next();
48
+ * },
49
+ * ],
50
+ * });
51
+ * ```
52
+ */ export async function createCloudflareApp(rootModule, options = {}) {
33
53
  let initialized = false;
34
54
  let refs;
55
+ const bindingInit = async (c, next)=>{
56
+ if (!initialized) {
57
+ initialized = true;
58
+ const env = c.env ?? {};
59
+ for (const ref of refs){
60
+ // EnvRef holds the whole env; every other ref holds one binding.
61
+ if (ref instanceof EnvRef) ref._initialize(env);
62
+ else ref._initialize(env[ref.bindingName]);
63
+ }
64
+ }
65
+ await next();
66
+ };
67
+ // IMPORTANT: keep the binding-init middleware FIRST so user middleware
68
+ // can safely read binding refs / `c.env` derivatives on the first request.
35
69
  const velaApp = await VelaFactory.create(rootModule, {
70
+ globalPrefix: options.globalPrefix,
36
71
  middleware: [
37
- async (c, next)=>{
38
- if (!initialized) {
39
- initialized = true;
40
- const env = c.env ?? {};
41
- for (const ref of refs){
42
- ref._initialize(env[ref.bindingName]);
43
- }
44
- }
45
- await next();
46
- }
72
+ bindingInit,
73
+ ...options.middleware ?? []
47
74
  ]
48
75
  });
49
76
  refs = collectBindingRefs(velaApp.getContainer());
@@ -0,0 +1,10 @@
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
+ }
@@ -0,0 +1,13 @@
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
+ }
package/dist/index.d.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  export { createCloudflareApp } from './cloudflare-factory';
2
+ export type { CreateCloudflareAppOptions } from './cloudflare-factory';
2
3
  export { CloudflareApplication } from './cloudflare-application';
4
+ export type { MountOpenApiOptions } from './cloudflare-application';
3
5
  export { KVModule } from './modules/kv.module';
4
6
  export { D1Module } from './modules/d1.module';
5
7
  export { R2Module } from './modules/r2.module';
@@ -8,6 +10,7 @@ export { DurableObjectModule } from './modules/durable-object.module';
8
10
  export { AIModule } from './modules/ai.module';
9
11
  export { VectorizeModule } from './modules/vectorize.module';
10
12
  export { HyperdriveModule } from './modules/hyperdrive.module';
13
+ export { EnvModule } from './modules/env.module';
11
14
  export { KVService } from './services/kv.service';
12
15
  export { D1Service } from './services/d1.service';
13
16
  export { R2Service } from './services/r2.service';
@@ -16,6 +19,7 @@ export { DurableObjectService } from './services/durable-object.service';
16
19
  export { AIService } from './services/ai.service';
17
20
  export { VectorizeService } from './services/vectorize.service';
18
21
  export { HyperdriveService } from './services/hyperdrive.service';
22
+ export { EnvService } from './services/env.service';
19
23
  export { Env } from './decorators/env';
20
24
  export { Scheduled } from './decorators/scheduled';
21
25
  export { QueueConsumer } from './decorators/queue-consumer';
package/dist/index.js CHANGED
@@ -10,6 +10,7 @@ export { DurableObjectModule } from "./modules/durable-object.module.js";
10
10
  export { AIModule } from "./modules/ai.module.js";
11
11
  export { VectorizeModule } from "./modules/vectorize.module.js";
12
12
  export { HyperdriveModule } from "./modules/hyperdrive.module.js";
13
+ export { EnvModule } from "./modules/env.module.js";
13
14
  // Services
14
15
  export { KVService } from "./services/kv.service.js";
15
16
  export { D1Service } from "./services/d1.service.js";
@@ -19,6 +20,7 @@ export { DurableObjectService } from "./services/durable-object.service.js";
19
20
  export { AIService } from "./services/ai.service.js";
20
21
  export { VectorizeService } from "./services/vectorize.service.js";
21
22
  export { HyperdriveService } from "./services/hyperdrive.service.js";
23
+ export { EnvService } from "./services/env.service.js";
22
24
  // Decorators
23
25
  export { Env } from "./decorators/env.js";
24
26
  export { Scheduled } from "./decorators/scheduled.js";
@@ -0,0 +1,17 @@
1
+ import type { DynamicModule } from '@velajs/vela';
2
+ /**
3
+ * Provides {@link EnvService} GLOBALLY so any module's provider factories can
4
+ * `inject: [EnvService]`. Register once on the root module:
5
+ *
6
+ * ```ts
7
+ * @Module({ imports: [EnvModule.forRoot(), AuthModule.forRootAsync({ ... })] })
8
+ * class AppModule {}
9
+ * ```
10
+ *
11
+ * The {@link EnvRef} it provides is collected and initialized by
12
+ * createCloudflareApp's binding-init middleware on the first request (the
13
+ * factory passes it the full `env`, not a single binding).
14
+ */
15
+ export declare class EnvModule {
16
+ static forRoot(): DynamicModule;
17
+ }
@@ -0,0 +1,35 @@
1
+ import { EnvRef } from "../env-ref.js";
2
+ import { EnvService } from "../services/env.service.js";
3
+ import { ENV_REF } from "../tokens.js";
4
+ /**
5
+ * Provides {@link EnvService} GLOBALLY so any module's provider factories can
6
+ * `inject: [EnvService]`. Register once on the root module:
7
+ *
8
+ * ```ts
9
+ * @Module({ imports: [EnvModule.forRoot(), AuthModule.forRootAsync({ ... })] })
10
+ * class AppModule {}
11
+ * ```
12
+ *
13
+ * The {@link EnvRef} it provides is collected and initialized by
14
+ * createCloudflareApp's binding-init middleware on the first request (the
15
+ * factory passes it the full `env`, not a single binding).
16
+ */ export class EnvModule {
17
+ static forRoot() {
18
+ const ref = new EnvRef();
19
+ return {
20
+ module: EnvModule,
21
+ global: true,
22
+ providers: [
23
+ {
24
+ provide: ENV_REF,
25
+ useValue: ref
26
+ },
27
+ EnvService
28
+ ],
29
+ exports: [
30
+ EnvService,
31
+ ENV_REF
32
+ ]
33
+ };
34
+ }
35
+ }
@@ -0,0 +1,31 @@
1
+ import type { EnvRef } from '../env-ref';
2
+ /**
3
+ * Injectable access to the full Cloudflare Worker `env` (bindings + vars +
4
+ * secrets).
5
+ *
6
+ * The per-binding services (`D1Service`, `KVService`, …) each expose a single
7
+ * binding, and the `@Env()` param decorator only works inside a request-scoped
8
+ * controller handler. `EnvService` fills the gap: it can be injected into
9
+ * PROVIDER FACTORIES — e.g. `SomeModule.forRootAsync({ inject: [EnvService] })`
10
+ * — so a factory can read secrets/origins without reaching for the request.
11
+ *
12
+ * Reads are lazy. `env` only exists per request, so a factory (which runs at
13
+ * bootstrap) must capture the `EnvService` and read inside its callback:
14
+ *
15
+ * ```ts
16
+ * AuthModule.forRootAsync({
17
+ * inject: [EnvService],
18
+ * useFactory: (env: EnvService) => buildAuth(() => env.get<string>('AUTH_SECRET')),
19
+ * });
20
+ * ```
21
+ *
22
+ * Reading eagerly at bootstrap (`env.get(...)` before any request) throws.
23
+ */
24
+ export declare class EnvService {
25
+ private ref;
26
+ constructor(ref: EnvRef);
27
+ /** The full env record. Throws if read before the first request. */
28
+ get env(): Record<string, unknown>;
29
+ /** Read a single env entry (binding, var, or secret) by name. */
30
+ get<T = unknown>(key: string): T | undefined;
31
+ }
@@ -0,0 +1,36 @@
1
+ function _ts_decorate(decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ }
7
+ function _ts_metadata(k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ }
10
+ function _ts_param(paramIndex, decorator) {
11
+ return function(target, key) {
12
+ decorator(target, key, paramIndex);
13
+ };
14
+ }
15
+ import { Inject, Injectable } from "@velajs/vela";
16
+ import { ENV_REF } from "../tokens.js";
17
+ export class EnvService {
18
+ ref;
19
+ constructor(ref){
20
+ this.ref = ref;
21
+ }
22
+ /** The full env record. Throws if read before the first request. */ get env() {
23
+ return this.ref.value;
24
+ }
25
+ /** Read a single env entry (binding, var, or secret) by name. */ get(key) {
26
+ return this.ref.value[key];
27
+ }
28
+ }
29
+ EnvService = _ts_decorate([
30
+ Injectable(),
31
+ _ts_param(0, Inject(ENV_REF)),
32
+ _ts_metadata("design:type", Function),
33
+ _ts_metadata("design:paramtypes", [
34
+ typeof EnvRef === "undefined" ? Object : EnvRef
35
+ ])
36
+ ], EnvService);
package/dist/tokens.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { InjectionToken } from '@velajs/vela';
2
2
  import type { BindingRef } from './binding-ref';
3
+ import type { EnvRef } from './env-ref';
3
4
  export declare const KV_BINDING_REF: InjectionToken<BindingRef<unknown>>;
4
5
  export declare const D1_BINDING_REF: InjectionToken<BindingRef<unknown>>;
5
6
  export declare const R2_BINDING_REF: InjectionToken<BindingRef<unknown>>;
@@ -8,3 +9,4 @@ export declare const DO_BINDING_REF: InjectionToken<BindingRef<unknown>>;
8
9
  export declare const AI_BINDING_REF: InjectionToken<BindingRef<unknown>>;
9
10
  export declare const VECTORIZE_BINDING_REF: InjectionToken<BindingRef<unknown>>;
10
11
  export declare const HYPERDRIVE_BINDING_REF: InjectionToken<BindingRef<unknown>>;
12
+ export declare const ENV_REF: InjectionToken<EnvRef>;
package/dist/tokens.js CHANGED
@@ -8,3 +8,5 @@ export const DO_BINDING_REF = new InjectionToken('CF_DO_BINDING_REF');
8
8
  export const AI_BINDING_REF = new InjectionToken('CF_AI_BINDING_REF');
9
9
  export const VECTORIZE_BINDING_REF = new InjectionToken('CF_VECTORIZE_BINDING_REF');
10
10
  export const HYPERDRIVE_BINDING_REF = new InjectionToken('CF_HYPERDRIVE_BINDING_REF');
11
+ // Token for the whole-env holder (full c.env), backing EnvService.
12
+ export const ENV_REF = new InjectionToken('CF_ENV_REF');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@velajs/cloudflare",
3
- "version": "1.2.0",
3
+ "version": "1.5.0",
4
4
  "description": "Cloudflare Workers integration for Vela framework",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -17,6 +17,13 @@
17
17
  "LICENSE",
18
18
  "CHANGELOG.md"
19
19
  ],
20
+ "scripts": {
21
+ "build": "rm -rf dist && swc src -d dist --strip-leading-paths && tsc --emitDeclarationOnly",
22
+ "test": "vitest run",
23
+ "typecheck": "tsc --noEmit",
24
+ "prepare": "swc src -d dist --strip-leading-paths && tsc --emitDeclarationOnly",
25
+ "prepublishOnly": "pnpm run typecheck && pnpm test"
26
+ },
20
27
  "sideEffects": false,
21
28
  "keywords": [
22
29
  "vela",
@@ -45,22 +52,24 @@
45
52
  },
46
53
  "peerDependencies": {
47
54
  "@cloudflare/workers-types": ">=4",
48
- "@velajs/vela": ">=1.5.0",
55
+ "@velajs/vela": ">=1.8.5",
49
56
  "hono": ">=4"
50
57
  },
51
58
  "devDependencies": {
52
- "@cloudflare/workers-types": "^4",
53
- "@swc/cli": "^0.8.0",
54
- "@swc/core": "^1.15.11",
55
- "@velajs/vela": "^1.5.0",
56
- "hono": "^4",
57
- "typescript": "^5",
59
+ "@cloudflare/workers-types": "^4.20260624.1",
60
+ "@swc/cli": "^0.8.1",
61
+ "@swc/core": "^1.15.43",
62
+ "@velajs/vela": "^1.8.5",
63
+ "hono": "^4.12.27",
64
+ "typescript": "^6.0.3",
58
65
  "unplugin-swc": "^1.5.9",
59
- "vitest": "^4.0.18"
66
+ "vitest": "^4.1.9"
60
67
  },
61
- "scripts": {
62
- "build": "rm -rf dist && swc src -d dist --strip-leading-paths && tsc --emitDeclarationOnly",
63
- "test": "vitest run",
64
- "typecheck": "tsc --noEmit"
68
+ "packageManager": "pnpm@10.20.0",
69
+ "pnpm": {
70
+ "onlyBuiltDependencies": [
71
+ "@swc/core",
72
+ "esbuild"
73
+ ]
65
74
  }
66
- }
75
+ }