@workkit/hono 0.0.1 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -8,7 +8,7 @@
8
8
  "import type { MiddlewareHandler } from \"hono\";\nimport type { CacheOptions } from \"./types\";\n\n/**\n * Cache middleware for Hono — caches responses using the Cache API.\n *\n * Only caches successful (2xx) responses. Serves cached responses on cache hit.\n * Uses Cloudflare's Cache API by default.\n *\n * @example\n * ```ts\n * app.get('/api/data', cacheResponse({ ttl: 300 }), async (c) => {\n * return c.json(await fetchData())\n * })\n * ```\n */\nexport function cacheResponse(options: CacheOptions): MiddlewareHandler {\n\tconst { ttl, keyFn, methods = [\"GET\"] } = options;\n\n\treturn async (c, next) => {\n\t\t// Only cache specified methods\n\t\tif (!methods.includes(c.req.method)) {\n\t\t\tawait next();\n\t\t\treturn;\n\t\t}\n\n\t\tconst cacheKey = keyFn ? keyFn(c) : c.req.url;\n\t\tconst cacheRequest = new Request(cacheKey);\n\n\t\t// Try to get the cache instance\n\t\tconst cache = options.cache ?? (typeof caches !== \"undefined\" ? caches.default : null);\n\t\tif (!cache) {\n\t\t\t// No cache available, skip caching\n\t\t\tawait next();\n\t\t\treturn;\n\t\t}\n\n\t\t// Check for cached response\n\t\tconst cached = await cache.match(cacheRequest);\n\t\tif (cached) {\n\t\t\treturn cached;\n\t\t}\n\n\t\t// Execute handler\n\t\tawait next();\n\n\t\t// Only cache successful responses\n\t\tconst response = c.res;\n\t\tif (response.status >= 200 && response.status < 300) {\n\t\t\t// Clone the response and add cache headers\n\t\t\tconst cloned = response.clone();\n\t\t\tconst cachedResponse = new Response(cloned.body, {\n\t\t\t\tstatus: cloned.status,\n\t\t\t\tstatusText: cloned.statusText,\n\t\t\t\theaders: new Headers(cloned.headers),\n\t\t\t});\n\t\t\tcachedResponse.headers.set(\"Cache-Control\", `s-maxage=${ttl}`);\n\n\t\t\t// Store in cache — use waitUntil if available, otherwise await directly\n\t\t\tconst putPromise = cache.put(cacheRequest, cachedResponse);\n\t\t\ttry {\n\t\t\t\tc.executionCtx.waitUntil(putPromise);\n\t\t\t} catch {\n\t\t\t\t// executionCtx not available (e.g., in tests), await directly\n\t\t\t\tawait putPromise;\n\t\t\t}\n\t\t}\n\t};\n}\n",
9
9
  "import type { EnvSchema, InferEnv } from \"@workkit/env\";\nimport type { Context } from \"hono\";\nimport type { WorkkitEnv } from \"./types\";\n\n/**\n * Get the validated, typed environment from Hono context.\n *\n * Requires the workkit() middleware to have run first.\n * Throws if env has not been validated yet.\n *\n * @example\n * ```ts\n * app.get('/test', (c) => {\n * const env = getEnv(c)\n * return c.json({ key: env.API_KEY })\n * })\n * ```\n */\nexport function getEnv<T extends EnvSchema>(c: Context<WorkkitEnv<T>>): InferEnv<T> {\n\tconst validated = c.get(\"workkit:envValidated\");\n\tif (!validated) {\n\t\tthrow new Error(\n\t\t\t\"workkit:env is not available. Did you forget to add the workkit() middleware?\",\n\t\t);\n\t}\n\treturn c.get(\"workkit:env\");\n}\n"
10
10
  ],
11
- "mappings": "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",
12
- "debugId": "4C2D147FF9900DA464756E2164756E21",
11
+ "mappings": "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",
12
+ "debugId": "0CE4411E8BEEF18964756E2164756E21",
13
13
  "names": []
14
14
  }
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@workkit/hono",
3
- "version": "0.0.1",
3
+ "version": "0.1.0",
4
4
  "description": "Hono middleware that integrates workkit utilities — env validation, error handling, rate limiting, caching",
5
5
  "license": "MIT",
6
6
  "author": "Bikash Dash <beeeku>",
7
7
  "repository": {
8
8
  "type": "git",
9
- "url": "https://github.com/beeeku/workkit",
9
+ "url": "git+https://github.com/beeeku/workkit.git",
10
10
  "directory": "integrations/hono"
11
11
  },
12
12
  "type": "module",
@@ -15,18 +15,18 @@
15
15
  "import": {
16
16
  "types": "./dist/index.d.ts",
17
17
  "default": "./dist/index.js"
18
- },
19
- "require": {
20
- "types": "./dist/index.d.cts",
21
- "default": "./dist/index.cjs"
22
18
  }
23
19
  }
24
20
  },
25
- "main": "./dist/index.cjs",
26
21
  "module": "./dist/index.js",
27
22
  "types": "./dist/index.d.ts",
28
- "files": ["dist"],
23
+ "files": [
24
+ "dist"
25
+ ],
29
26
  "sideEffects": false,
27
+ "publishConfig": {
28
+ "access": "public"
29
+ },
30
30
  "scripts": {
31
31
  "build": "bunup",
32
32
  "test": "vitest run",
@@ -35,7 +35,6 @@
35
35
  "clean": "rm -rf dist"
36
36
  },
37
37
  "dependencies": {
38
- "@workkit/types": "workspace:*",
39
38
  "@workkit/errors": "workspace:*",
40
39
  "@workkit/env": "workspace:*"
41
40
  },
@@ -43,12 +42,9 @@
43
42
  "hono": ">=4.0.0"
44
43
  },
45
44
  "devDependencies": {
46
- "@cloudflare/workers-types": "^4.20250310.0",
47
- "bunup": "0.16.31",
48
- "expect-type": "^1.1.0",
45
+ "@workkit/types": "workspace:*",
49
46
  "hono": "^4.7.0",
50
- "typescript": "^5.7.0",
51
- "vitest": "^3.0.0"
47
+ "zod": "^4.3.6"
52
48
  },
53
49
  "keywords": [
54
50
  "cloudflare",
package/dist/index.cjs DELETED
@@ -1,209 +0,0 @@
1
- var import_node_module = require("node:module");
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropNames = Object.getOwnPropertyNames;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __moduleCache = /* @__PURE__ */ new WeakMap;
7
- var __toCommonJS = (from) => {
8
- var entry = __moduleCache.get(from), desc;
9
- if (entry)
10
- return entry;
11
- entry = __defProp({}, "__esModule", { value: true });
12
- if (from && typeof from === "object" || typeof from === "function")
13
- __getOwnPropNames(from).map((key) => !__hasOwnProp.call(entry, key) && __defProp(entry, key, {
14
- get: () => from[key],
15
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
16
- }));
17
- __moduleCache.set(from, entry);
18
- return entry;
19
- };
20
- var __export = (target, all) => {
21
- for (var name in all)
22
- __defProp(target, name, {
23
- get: all[name],
24
- enumerable: true,
25
- configurable: true,
26
- set: (newValue) => all[name] = () => newValue
27
- });
28
- };
29
-
30
- // src/index.ts
31
- var exports_src = {};
32
- __export(exports_src, {
33
- workkitErrorHandler: () => workkitErrorHandler,
34
- workkit: () => workkit,
35
- rateLimit: () => rateLimit,
36
- parseDuration: () => parseDuration,
37
- getEnv: () => getEnv,
38
- fixedWindow: () => fixedWindow,
39
- cacheResponse: () => cacheResponse
40
- });
41
- module.exports = __toCommonJS(exports_src);
42
-
43
- // src/middleware.ts
44
- var import_env = require("@workkit/env");
45
- function workkit(options) {
46
- let cachedEnv = null;
47
- return async (c, next) => {
48
- if (!cachedEnv) {
49
- const rawEnv = c.env;
50
- cachedEnv = await import_env.parseEnv(rawEnv, options.env);
51
- }
52
- c.set("workkit:env", cachedEnv);
53
- c.set("workkit:envValidated", true);
54
- await next();
55
- };
56
- }
57
- // src/error-handler.ts
58
- var import_errors = require("@workkit/errors");
59
- function workkitErrorHandler(options = {}) {
60
- const { includeStack = false, onError } = options;
61
- return async (err, c) => {
62
- if (onError) {
63
- try {
64
- await onError(err, c);
65
- } catch {}
66
- }
67
- if (import_errors.isWorkkitError(err)) {
68
- return workkitErrorToResponse(err, includeStack);
69
- }
70
- const wrapped = new import_errors.InternalError(err instanceof Error ? err.message : "An unexpected error occurred", { cause: err });
71
- return workkitErrorToResponse(wrapped, includeStack);
72
- };
73
- }
74
- function workkitErrorToResponse(error, includeStack) {
75
- const body = {
76
- error: {
77
- code: error.code,
78
- message: error.message,
79
- statusCode: error.statusCode
80
- }
81
- };
82
- if ("issues" in error && Array.isArray(error.issues)) {
83
- body.error.issues = error.issues;
84
- }
85
- if (includeStack && error.stack) {
86
- body.error.stack = error.stack;
87
- }
88
- const headers = {
89
- "Content-Type": "application/json"
90
- };
91
- if (error instanceof import_errors.RateLimitError && error.retryAfterMs) {
92
- headers["Retry-After"] = String(Math.ceil(error.retryAfterMs / 1000));
93
- }
94
- return new Response(JSON.stringify(body), {
95
- status: error.statusCode,
96
- headers
97
- });
98
- }
99
- // src/rate-limit.ts
100
- var import_errors2 = require("@workkit/errors");
101
- function rateLimit(options) {
102
- const { limiter, keyFn, onRateLimited } = options;
103
- return async (c, next) => {
104
- const key = await keyFn(c);
105
- const result = await limiter.check(key);
106
- c.header("X-RateLimit-Limit", String(result.remaining + (result.allowed ? 0 : 1)));
107
- c.header("X-RateLimit-Remaining", String(result.remaining));
108
- c.header("X-RateLimit-Reset", String(Math.ceil(result.resetAt / 1000)));
109
- if (!result.allowed) {
110
- if (onRateLimited) {
111
- return onRateLimited(c, result);
112
- }
113
- const retryAfterMs = result.resetAt - Date.now();
114
- throw new import_errors2.RateLimitError("Rate limit exceeded", retryAfterMs > 0 ? retryAfterMs : undefined);
115
- }
116
- await next();
117
- };
118
- }
119
- function parseDuration(duration) {
120
- const match = duration.match(/^(\d+)(s|m|h|d)$/);
121
- if (!match) {
122
- throw new Error(`Invalid duration format: "${duration}". Use e.g. '1m', '5m', '1h', '1d'.`);
123
- }
124
- const value = Number.parseInt(match[1], 10);
125
- const unit = match[2];
126
- switch (unit) {
127
- case "s":
128
- return value * 1000;
129
- case "m":
130
- return value * 60 * 1000;
131
- case "h":
132
- return value * 60 * 60 * 1000;
133
- case "d":
134
- return value * 24 * 60 * 60 * 1000;
135
- default:
136
- throw new Error(`Unknown duration unit: "${unit}"`);
137
- }
138
- }
139
- function fixedWindow(options) {
140
- const { namespace, limit, window: windowStr, prefix = "rl:" } = options;
141
- const windowMs = parseDuration(windowStr);
142
- return {
143
- async check(key) {
144
- const now = Date.now();
145
- const windowStart = Math.floor(now / windowMs) * windowMs;
146
- const resetAt = windowStart + windowMs;
147
- const kvKey = `${prefix}${key}:${windowStart}`;
148
- const current = await namespace.get(kvKey);
149
- const count = current ? Number.parseInt(current, 10) : 0;
150
- if (count >= limit) {
151
- return { allowed: false, remaining: 0, resetAt };
152
- }
153
- const ttlSeconds = Math.ceil(windowMs / 1000);
154
- await namespace.put(kvKey, String(count + 1), {
155
- expirationTtl: ttlSeconds
156
- });
157
- return { allowed: true, remaining: limit - count - 1, resetAt };
158
- }
159
- };
160
- }
161
- // src/cache.ts
162
- function cacheResponse(options) {
163
- const { ttl, keyFn, methods = ["GET"] } = options;
164
- return async (c, next) => {
165
- if (!methods.includes(c.req.method)) {
166
- await next();
167
- return;
168
- }
169
- const cacheKey = keyFn ? keyFn(c) : c.req.url;
170
- const cacheRequest = new Request(cacheKey);
171
- const cache = options.cache ?? (typeof caches !== "undefined" ? caches.default : null);
172
- if (!cache) {
173
- await next();
174
- return;
175
- }
176
- const cached = await cache.match(cacheRequest);
177
- if (cached) {
178
- return cached;
179
- }
180
- await next();
181
- const response = c.res;
182
- if (response.status >= 200 && response.status < 300) {
183
- const cloned = response.clone();
184
- const cachedResponse = new Response(cloned.body, {
185
- status: cloned.status,
186
- statusText: cloned.statusText,
187
- headers: new Headers(cloned.headers)
188
- });
189
- cachedResponse.headers.set("Cache-Control", `s-maxage=${ttl}`);
190
- const putPromise = cache.put(cacheRequest, cachedResponse);
191
- try {
192
- c.executionCtx.waitUntil(putPromise);
193
- } catch {
194
- await putPromise;
195
- }
196
- }
197
- };
198
- }
199
- // src/helpers.ts
200
- function getEnv(c) {
201
- const validated = c.get("workkit:envValidated");
202
- if (!validated) {
203
- throw new Error("workkit:env is not available. Did you forget to add the workkit() middleware?");
204
- }
205
- return c.get("workkit:env");
206
- }
207
-
208
- //# debugId=4C2D147FF9900DA464756E2164756E21
209
- //# sourceMappingURL=index.js.map
package/dist/index.d.cts DELETED
@@ -1,186 +0,0 @@
1
- import { EnvSchema as EnvSchema2 } from "@workkit/env";
2
- import { MiddlewareHandler } from "hono";
3
- import { EnvSchema, InferEnv } from "@workkit/env";
4
- import { Context, Env } from "hono";
5
- /**
6
- * Options for the workkit() middleware.
7
- */
8
- interface WorkkitOptions<T extends EnvSchema> {
9
- /** Environment schema to validate against on first request */
10
- env: T;
11
- }
12
- /**
13
- * Options for the workkitErrorHandler.
14
- */
15
- interface ErrorHandlerOptions {
16
- /** Include stack trace in error response (never in production) */
17
- includeStack?: boolean;
18
- /** Custom error callback for logging/reporting */
19
- onError?: (err: Error, c: Context) => void | Promise<void>;
20
- }
21
- /**
22
- * A rate limiter instance that checks whether a key is allowed.
23
- */
24
- interface RateLimiter {
25
- /** Check if the key is allowed. Returns { allowed, remaining, resetAt } */
26
- check(key: string): Promise<RateLimitResult>;
27
- }
28
- /**
29
- * Result of a rate limit check.
30
- */
31
- interface RateLimitResult {
32
- /** Whether the request is allowed */
33
- allowed: boolean;
34
- /** Remaining requests in the current window */
35
- remaining: number;
36
- /** When the window resets (ms since epoch) */
37
- resetAt: number;
38
- }
39
- /**
40
- * Options for the rateLimit middleware.
41
- */
42
- interface RateLimitOptions {
43
- /** The rate limiter implementation */
44
- limiter: RateLimiter;
45
- /** Function to extract the rate limit key from context (e.g., IP address) */
46
- keyFn: (c: Context) => string | Promise<string>;
47
- /** Custom response when rate limited (optional) */
48
- onRateLimited?: (c: Context, result: RateLimitResult) => Response | Promise<Response>;
49
- }
50
- /**
51
- * Options for fixed-window rate limiter.
52
- */
53
- interface FixedWindowOptions {
54
- /** KV namespace for storing counters */
55
- namespace: KVNamespace;
56
- /** Maximum requests per window */
57
- limit: number;
58
- /** Window duration — e.g. '1m', '5m', '1h', '1d' */
59
- window: string;
60
- /** Optional prefix for KV keys */
61
- prefix?: string;
62
- }
63
- /**
64
- * Options for the cacheResponse middleware.
65
- */
66
- interface CacheOptions {
67
- /** Cache TTL in seconds */
68
- ttl: number;
69
- /** Function to generate the cache key (defaults to request URL) */
70
- keyFn?: (c: Context) => string;
71
- /** Cache API instance (defaults to caches.default) */
72
- cache?: Cache;
73
- /** HTTP methods to cache (defaults to ['GET']) */
74
- methods?: string[];
75
- }
76
- /**
77
- * Hono environment type with workkit context variables.
78
- */
79
- interface WorkkitEnv<T extends EnvSchema = EnvSchema> extends Env {
80
- Variables: {
81
- "workkit:env": InferEnv<T>;
82
- "workkit:envValidated": boolean;
83
- };
84
- }
85
- /**
86
- * Main workkit middleware — validates environment bindings on first request
87
- * and stores the parsed, typed env in Hono's context.
88
- *
89
- * Validation runs once (on the first request) and the result is cached
90
- * for subsequent requests within the same Worker invocation.
91
- *
92
- * @example
93
- * ```ts
94
- * const app = new Hono()
95
- * app.use(workkit({ env: { API_KEY: z.string().min(1) } }))
96
- * app.get('/', (c) => {
97
- * const env = c.get('workkit:env') // typed
98
- * })
99
- * ```
100
- */
101
- declare function workkit<T extends EnvSchema2>(options: WorkkitOptions<T>): MiddlewareHandler<WorkkitEnv<T>>;
102
- import { ErrorHandler } from "hono";
103
- /**
104
- * Hono error handler that converts WorkkitErrors to proper HTTP responses.
105
- *
106
- * - WorkkitError instances → structured JSON with their status code
107
- * - RateLimitError → includes Retry-After header
108
- * - ValidationError → includes issues array
109
- * - Unknown errors → 500 Internal Server Error
110
- *
111
- * @example
112
- * ```ts
113
- * app.onError(workkitErrorHandler({
114
- * includeStack: false,
115
- * onError: (err, c) => console.error(err),
116
- * }))
117
- * ```
118
- */
119
- declare function workkitErrorHandler(options?: ErrorHandlerOptions): ErrorHandler;
120
- import { MiddlewareHandler as MiddlewareHandler2 } from "hono";
121
- /**
122
- * Rate limit middleware for Hono.
123
- *
124
- * @example
125
- * ```ts
126
- * app.use('/api/*', rateLimit({
127
- * limiter: fixedWindow({ namespace: env.KV, limit: 100, window: '1m' }),
128
- * keyFn: (c) => c.req.header('CF-Connecting-IP') ?? 'unknown',
129
- * }))
130
- * ```
131
- */
132
- declare function rateLimit(options: RateLimitOptions): MiddlewareHandler2;
133
- /**
134
- * Parse a duration string like '1m', '5m', '1h', '1d' into milliseconds.
135
- */
136
- declare function parseDuration(duration: string): number;
137
- /**
138
- * Creates a fixed-window rate limiter backed by KV.
139
- *
140
- * Each window is stored as a KV key with an expiration TTL.
141
- * Uses KV's eventual consistency — suitable for soft rate limiting,
142
- * not cryptographic precision.
143
- *
144
- * @example
145
- * ```ts
146
- * const limiter = fixedWindow({
147
- * namespace: env.RATE_LIMIT_KV,
148
- * limit: 100,
149
- * window: '1m',
150
- * })
151
- * ```
152
- */
153
- declare function fixedWindow(options: FixedWindowOptions): RateLimiter;
154
- import { MiddlewareHandler as MiddlewareHandler3 } from "hono";
155
- /**
156
- * Cache middleware for Hono — caches responses using the Cache API.
157
- *
158
- * Only caches successful (2xx) responses. Serves cached responses on cache hit.
159
- * Uses Cloudflare's Cache API by default.
160
- *
161
- * @example
162
- * ```ts
163
- * app.get('/api/data', cacheResponse({ ttl: 300 }), async (c) => {
164
- * return c.json(await fetchData())
165
- * })
166
- * ```
167
- */
168
- declare function cacheResponse(options: CacheOptions): MiddlewareHandler3;
169
- import { EnvSchema as EnvSchema3, InferEnv as InferEnv2 } from "@workkit/env";
170
- import { Context as Context2 } from "hono";
171
- /**
172
- * Get the validated, typed environment from Hono context.
173
- *
174
- * Requires the workkit() middleware to have run first.
175
- * Throws if env has not been validated yet.
176
- *
177
- * @example
178
- * ```ts
179
- * app.get('/test', (c) => {
180
- * const env = getEnv(c)
181
- * return c.json({ key: env.API_KEY })
182
- * })
183
- * ```
184
- */
185
- declare function getEnv<T extends EnvSchema3>(c: Context2<WorkkitEnv<T>>): InferEnv2<T>;
186
- export { workkitErrorHandler, workkit, rateLimit, parseDuration, getEnv, fixedWindow, cacheResponse, WorkkitOptions, WorkkitEnv, RateLimiter, RateLimitResult, RateLimitOptions, FixedWindowOptions, ErrorHandlerOptions, CacheOptions };