@gnosticdev/hono-actions 2.0.11 → 2.1.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.
@@ -0,0 +1,32 @@
1
+ import z from "astro/zod";
2
+ import * as _$astro from "astro";
3
+
4
+ //#region src/integration.d.ts
5
+ declare const optionsSchema: z.ZodOptional<z.ZodObject<{
6
+ basePath: z.ZodOptional<z.ZodString>;
7
+ actionsPath: z.ZodOptional<z.ZodString>;
8
+ }, z.core.$strip>>;
9
+ type IntegrationOptions = z.output<typeof optionsSchema>;
10
+ /**
11
+ * Astro integration for Hono Actions
12
+ *
13
+ * This integration automatically discovers action files in your project,
14
+ * generates type-safe client code, and sets up API routes.
15
+ *
16
+ * Supprted Adapters:
17
+ * - @astrojs/cloudflare
18
+ * - @astrojs/node
19
+ * - @astrojs/vercel
20
+ * - @astrojs/netlify
21
+ *
22
+ *
23
+ * @param options - Configuration options for the integration
24
+ * @param options.basePath - Base path for API routes (default: '/api')
25
+ * @param options.actionsPath - Custom path to actions file (optional, auto-discovered by default)
26
+ */
27
+ declare const _default: (options?: {
28
+ basePath?: string | undefined;
29
+ actionsPath?: string | undefined;
30
+ } | undefined) => _$astro.AstroIntegration & {};
31
+ //#endregion
32
+ export { type IntegrationOptions, _default as default };
package/dist/index.mjs ADDED
@@ -0,0 +1,418 @@
1
+ import { createRequire } from "node:module";
2
+ import z from "astro/zod";
3
+ import { addVirtualImports, createResolver, defineIntegration } from "astro-integration-kit";
4
+ import fs from "node:fs/promises";
5
+ import path from "node:path";
6
+ import { glob } from "tinyglobby";
7
+
8
+ //#region src/integration-files.ts
9
+ /**
10
+ * Generate router using the buildRouter pattern for better type inference
11
+ * @param opts - The options for generating the router
12
+ * @param opts.basePath - The base path for the router
13
+ * @param opts.relativeActionsPath - The relative path to the actions file
14
+ * @param opts.adapter - The adapter to use for generating the router
15
+ * @returns The generated router code
16
+ *
17
+ * **Supported Adapters:**
18
+ * - `@astrojs/cloudflare`
19
+ * - `@astrojs/node`
20
+ * - `@astrojs/vercel`
21
+ * - `@astrojs/netlify`
22
+ */
23
+ function generateRouter(opts) {
24
+ const { basePath, relativeActionsPath, adapter } = opts;
25
+ let exportedApp = "export default app";
26
+ if (adapter === "@astrojs/netlify") exportedApp = "export default handle(app)";
27
+ return `import type { HonoEnv, MergeActionKeyIntoPath } from '@gnosticdev/hono-actions/actions'
28
+ import { Hono } from 'hono'
29
+ import { cors } from 'hono/cors'
30
+ import { showRoutes } from 'hono/dev'
31
+ import { logger } from 'hono/logger'
32
+ import { prettyJSON } from 'hono/pretty-json'
33
+ import type { ExtractSchema, MergeSchemaPath } from 'hono/types'
34
+ ${adapter === "@astrojs/netlify" ? "import { handle } from 'hono/netlify'" : ""}
35
+
36
+ async function buildRouter(){
37
+ type ActionsWithKeyedPaths = MergeActionKeyIntoPath<typeof honoActions>
38
+ type ActionSchema = ExtractSchema<ActionsWithKeyedPaths[keyof ActionsWithKeyedPaths]>
39
+ const { honoActions} = await import('${relativeActionsPath}')
40
+ const app = new Hono<HonoEnv, MergeSchemaPath<ActionSchema, '${basePath}'>>().basePath('${basePath}')
41
+
42
+ app.use('*', cors(), logger(), prettyJSON())
43
+
44
+ for (const [routeName, action] of Object.entries(honoActions)) {
45
+ app.route(\`/\${routeName}\`, action)
46
+ }
47
+
48
+ return app
49
+ }
50
+
51
+ export type HonoRouter = Awaited<ReturnType<typeof buildRouter>>
52
+
53
+ const app = await buildRouter()
54
+ console.log('------- Hono Routes -------')
55
+ showRoutes(app)
56
+ console.log('---------------------------')
57
+ ${exportedApp}`;
58
+ }
59
+ /**
60
+ * Injects the Hono router into the Astro API route handler at `src/pages/api/[...slug].ts`
61
+ *
62
+ * @param adapter - The adapter in use from the astro config
63
+ *
64
+ * For use with `@astrojs/cloudflare` adapter only (for now).a
65
+ */
66
+ const generateAstroHandler = (adapter, astroMajorVersion = 5) => {
67
+ switch (adapter) {
68
+ case "@astrojs/cloudflare":
69
+ if (astroMajorVersion >= 6) return `
70
+ /// <reference types="./types.d.ts" />
71
+ // Generated by Hono Actions Integration
72
+ // adapter: ${adapter}
73
+ import { env } from 'cloudflare:workers'
74
+ import type { APIContext, APIRoute } from 'astro'
75
+ import router from './router.js'
76
+
77
+ const handler: APIRoute<APIContext> = async (ctx) => {
78
+ return router.fetch(
79
+ ctx.request,
80
+ {
81
+ ...env,
82
+ ASTRO_LOCALS: ctx.locals,
83
+ },
84
+ ctx.locals.cfContext,
85
+ )
86
+ }
87
+
88
+ export { handler as ALL }
89
+ `;
90
+ return `
91
+ /// <reference types="./types.d.ts" />
92
+ // Generated by Hono Actions Integration
93
+ // adapter: ${adapter}
94
+ import type { APIContext, APIRoute } from 'astro'
95
+ import router from './router.js'
96
+
97
+ const handler: APIRoute<APIContext> = async (ctx) => {
98
+ return router.fetch(
99
+ ctx.request,
100
+ {
101
+ ...ctx.locals.runtime.env,
102
+ ASTRO_LOCALS: ctx.locals,
103
+ },
104
+ ctx.locals.runtime.ctx, // required for cloudflare adapter
105
+ )
106
+ }
107
+
108
+ export { handler as ALL }
109
+ `;
110
+ case "@astrojs/node":
111
+ case "@astrojs/vercel": return `
112
+ /// <reference types="./types.d.ts" />
113
+ // Generated by Hono Actions Integration
114
+ // adapter: ${adapter}
115
+ import type { APIContext, APIRoute } from 'astro'
116
+ import router from './router.js'
117
+
118
+ const handler: APIRoute<APIContext> = async (ctx) => {
119
+ return router.fetch(
120
+ ctx.request,
121
+ )
122
+ }
123
+
124
+ export { handler as ALL }
125
+ `;
126
+ case "@astrojs/netlify": return `
127
+ /// <reference types="./types.d.ts" />
128
+ // Generated by Hono Actions Integration
129
+ // adapter: ${adapter}
130
+ import type { APIContext, APIRoute } from 'astro'
131
+ import netlifyHandler from './router.js'
132
+
133
+ const handler: APIRoute<APIContext> = async (ctx) => {
134
+ return netlifyHandler(ctx.request, ctx)
135
+ }
136
+
137
+ export { handler as ALL }
138
+ `;
139
+ default: throw new Error(`Unsupported adapter: ${adapter}`);
140
+ }
141
+ };
142
+ /**
143
+ * Generate Hono client code
144
+ *
145
+ * @param port - The port number for the dev server
146
+ */
147
+ const generateHonoClient = (port) => `
148
+ // Generated by Hono Actions Integration
149
+ import type { HonoRouter } from './router.js'
150
+ import { parseResponse, hc } from 'hono/client'
151
+ import type { DetailedError, ClientRequestOptions } from 'hono/client'
152
+
153
+ function getBaseUrl() {
154
+ // client side can just use the origin
155
+ if (typeof window !== 'undefined') {
156
+ return window.location.origin
157
+ }
158
+
159
+ // dev server (dev server) needs to know the port
160
+ if (import.meta.env.DEV) {
161
+ return 'http://localhost:${port}'
162
+ }
163
+
164
+ // server side (production) needs full url
165
+ if (import.meta.env.SITE) {
166
+ return import.meta.env.SITE
167
+ }
168
+
169
+ return '/'
170
+ }
171
+
172
+ export { parseResponse }
173
+ export type { DetailedError, ClientRequestOptions, HonoRouter }
174
+ export const honoClient = createHonoClient<HonoRouter>(getBaseUrl())
175
+ export function createHonoClient<T extends HonoRouter = HonoRouter>(basePath: string, fetchOptions?: ClientRequestOptions) {
176
+ return hc<T>(basePath, fetchOptions)
177
+ }
178
+ `;
179
+ /**
180
+ * Emits `actions.d.ts` / client module declarations for the active adapter.
181
+ *
182
+ * For `@astrojs/cloudflare` on Astro 5 and below, appends `App.Locals` + `Runtime` so `ASTRO_LOCALS` matches
183
+ * `ctx.locals`. From Astro 6 onward the Cloudflare adapter already declares `App.Locals`, so that block is omitted.
184
+ */
185
+ const generateIntegrationTypes = (adapter, astroMajorVersion = 5) => {
186
+ let actionTypes = `
187
+ // Generated by Hono Actions Integration
188
+ declare module '@gnosticdev/hono-actions/actions' {
189
+ interface Bindings { [key: string]: unknown }
190
+ interface Variables { [key: string]: unknown }
191
+ interface HonoEnv { Bindings: Bindings, Variables: Variables }
192
+ }
193
+ export {}
194
+ `;
195
+ let clientTypes = `
196
+ // Generated by Hono Actions Integration
197
+ declare module '@gnosticdev/hono-actions/client' {
198
+ /**
199
+ * Default hono client using the base url from the environment
200
+ * **Note** if running in production, the \`siteUrl\` option from the astro config will be used.
201
+ * If customization is needed, use the \`createHonoClient\` function instead.
202
+ */
203
+ export const honoClient: typeof import('./client').honoClient
204
+ /**
205
+ * Helper function to parse the response from the Hono client
206
+ */
207
+ export const parseResponse: typeof import('./client').parseResponse
208
+ /**
209
+ * Create a new hono client with custom base url + fetch options
210
+ */
211
+ export const createHonoClient: typeof import('./client').createHonoClient
212
+ export type DetailedError = import('./client').DetailedError
213
+ export type ClientRequestOptions = import('./client').ClientRequestOptions
214
+ /**
215
+ * The hono actions routes. for use in the hono client
216
+ */
217
+ export type HonoRouter = import('./client').HonoRouter
218
+ }
219
+ `;
220
+ switch (adapter) {
221
+ case "@astrojs/cloudflare":
222
+ actionTypes = `
223
+ // Generated by Hono Actions Integration
224
+ // keeping separate from the main types.d.ts to avoid clobbering package exports
225
+ declare module '@gnosticdev/hono-actions/actions' {
226
+ interface Bindings extends Env { ASTRO_LOCALS: App.Locals }
227
+ interface Variables { [key: string]: unknown }
228
+ interface HonoEnv { Bindings: Bindings, Variables: Variables }
229
+ }
230
+ export {}
231
+ `;
232
+ if (astroMajorVersion < 6) clientTypes += `
233
+ type Runtime = import('@astrojs/cloudflare').Runtime<Env>
234
+
235
+ declare namespace App {
236
+ interface Locals extends Runtime {}
237
+ }
238
+ `;
239
+ break;
240
+ default: break;
241
+ }
242
+ return {
243
+ actionTypes,
244
+ clientTypes
245
+ };
246
+ };
247
+
248
+ //#endregion
249
+ //#region src/lib/utils.ts
250
+ /**
251
+ * Reserved routes that are not allowed to be used for actions.
252
+ * @see https://docs.astro.build/en/guides/routing/#reserved-routes
253
+ */
254
+ const reservedRoutes = [
255
+ "_astro",
256
+ "_actions",
257
+ "_server_islands"
258
+ ];
259
+ const SUPPORTED_ADAPTERS = [
260
+ "@astrojs/cloudflare",
261
+ "@astrojs/node",
262
+ "@astrojs/netlify",
263
+ "@astrojs/vercel"
264
+ ];
265
+ function isSupportedAdapter(adapter) {
266
+ return SUPPORTED_ADAPTERS.includes(adapter);
267
+ }
268
+ function parseAstroMajorVersion(version) {
269
+ const majorVersion = Number.parseInt(version, 10);
270
+ if (Number.isNaN(majorVersion)) if (process.env.PACKAGE_VERSION) return Number.parseInt(process.env.PACKAGE_VERSION, 10);
271
+ else throw new Error(`Invalid Astro version: ${version}`);
272
+ return majorVersion;
273
+ }
274
+ function getInstalledAstroVersion() {
275
+ const astroPackage = createRequire(import.meta.url)("astro/package.json");
276
+ if (!astroPackage.version) throw new Error("Could not determine installed Astro version");
277
+ return astroPackage.version;
278
+ }
279
+ function getInstalledAstroMajorVersion() {
280
+ return parseAstroMajorVersion(getInstalledAstroVersion());
281
+ }
282
+
283
+ //#endregion
284
+ //#region src/integration.ts
285
+ const optionsSchema = z.object({
286
+ basePath: z.string().optional(),
287
+ actionsPath: z.string().optional()
288
+ }).optional();
289
+ const VIRTUAL_MODULE_ID_CLIENT = "@gnosticdev/hono-actions/client";
290
+ const VIRTUAL_MODULE_ID_ROUTER = "virtual:hono-actions/router";
291
+ const ACTION_PATTERNS = [
292
+ "src/server/actions.ts",
293
+ "src/hono/actions.ts",
294
+ "src/hono/index.ts",
295
+ "src/hono.ts",
296
+ "src/hono-actions.ts"
297
+ ];
298
+ /**
299
+ * Astro integration for Hono Actions
300
+ *
301
+ * This integration automatically discovers action files in your project,
302
+ * generates type-safe client code, and sets up API routes.
303
+ *
304
+ * Supprted Adapters:
305
+ * - @astrojs/cloudflare
306
+ * - @astrojs/node
307
+ * - @astrojs/vercel
308
+ * - @astrojs/netlify
309
+ *
310
+ *
311
+ * @param options - Configuration options for the integration
312
+ * @param options.basePath - Base path for API routes (default: '/api')
313
+ * @param options.actionsPath - Custom path to actions file (optional, auto-discovered by default)
314
+ */
315
+ var integration_default = defineIntegration({
316
+ name: "@gnosticdev/hono-actions",
317
+ optionsSchema,
318
+ setup: ({ options = {}, name }) => {
319
+ const basePath = options.basePath ?? "/api";
320
+ if (reservedRoutes.includes(basePath)) throw new Error(`Base path ${basePath} is reserved by Astro; pick another (e.g. /api2).`);
321
+ const { resolve } = createResolver(import.meta.url);
322
+ const IS_DEBUG = process.env.__DEBUG__ === "true";
323
+ const astroMajorVersion = getInstalledAstroMajorVersion();
324
+ return {
325
+ name,
326
+ hooks: {
327
+ "astro:config:setup": async (params) => {
328
+ const { logger, injectRoute, createCodegenDir, config } = params;
329
+ logger.info(`using astro major version: ${astroMajorVersion}`);
330
+ const root = config.root.pathname;
331
+ const files = await glob(ACTION_PATTERNS.map((p) => path.join(root, p)), {
332
+ expandDirectories: false,
333
+ absolute: true
334
+ });
335
+ if (IS_DEBUG) {
336
+ logger.info(`DEBUG: Detected Astro major version: ${astroMajorVersion}`);
337
+ logger.info(`DEBUG: Found actions: ${files.join("\n")}`);
338
+ }
339
+ const actionsPath = options.actionsPath ?? files[0];
340
+ if (!actionsPath || actionsPath.includes("node_modules")) {
341
+ logger.warn(`No actions found. Create one of:\n${ACTION_PATTERNS.map((p) => ` - ${p}`).join("\n")}`);
342
+ return;
343
+ }
344
+ const resolvedActionsPath = resolve(actionsPath);
345
+ params.addWatchFile(resolvedActionsPath);
346
+ logger.info(`Found actions: ${path.relative(root, resolvedActionsPath)}`);
347
+ const codeGenDir = createCodegenDir();
348
+ const routerPathAbs = path.join(codeGenDir.pathname, "router.ts");
349
+ const relFromGenToActions = path.relative(codeGenDir.pathname, resolvedActionsPath).split(path.sep).join("/");
350
+ const adapter = params.config.adapter?.name;
351
+ if (!adapter) {
352
+ logger.error(`No Astro adapter found. Add one of:
353
+ - ${SUPPORTED_ADAPTERS.join("\n - ")} to your astro.config.mjs`);
354
+ return;
355
+ }
356
+ if (!isSupportedAdapter(adapter)) {
357
+ logger.error(`Unsupported adapter: ${adapter}. Only ${SUPPORTED_ADAPTERS.join("\n - ")} are supported`);
358
+ return;
359
+ }
360
+ const routerContent = generateRouter({
361
+ basePath,
362
+ relativeActionsPath: relFromGenToActions,
363
+ adapter
364
+ });
365
+ await fs.writeFile(routerPathAbs, routerContent, "utf-8");
366
+ const astroHandlerPathAbs = path.join(codeGenDir.pathname, "api.ts");
367
+ const astroHandlerContent = generateAstroHandler(adapter, astroMajorVersion);
368
+ await fs.writeFile(astroHandlerPathAbs, astroHandlerContent, "utf-8");
369
+ const clientPathAbs = path.join(codeGenDir.pathname, "client.ts");
370
+ if (!config.site) logger.warn("No site url found in astro config, add one if you want to use the hono client with SSR");
371
+ const clientContent = generateHonoClient(config.server.port);
372
+ await fs.writeFile(clientPathAbs, clientContent, "utf-8");
373
+ addVirtualImports(params, {
374
+ name,
375
+ imports: {
376
+ [VIRTUAL_MODULE_ID_CLIENT]: `export * from '${clientPathAbs}';`,
377
+ [VIRTUAL_MODULE_ID_ROUTER]: `export * from '${routerPathAbs}';`
378
+ }
379
+ });
380
+ logger.info("✅ Hono Actions virtual imports added");
381
+ injectRoute({
382
+ pattern: `${basePath}/[...slug]`,
383
+ entrypoint: astroHandlerPathAbs,
384
+ prerender: false
385
+ });
386
+ logger.info(`✅ Hono Actions route mounted at ${basePath}/[...slug]`);
387
+ },
388
+ "astro:config:done": async ({ injectTypes, config, logger }) => {
389
+ const adapter = config.adapter?.name;
390
+ if (!adapter) {
391
+ logger.warn("No adapter found...");
392
+ return;
393
+ }
394
+ if (!isSupportedAdapter(adapter)) {
395
+ logger.warn(`Unsupported adapter: ${adapter}. Only ${SUPPORTED_ADAPTERS.join("\n - ")} are supported`);
396
+ return;
397
+ }
398
+ const { actionTypes, clientTypes } = generateIntegrationTypes(adapter, astroMajorVersion);
399
+ injectTypes({
400
+ filename: "actions.d.ts",
401
+ content: actionTypes
402
+ });
403
+ injectTypes({
404
+ filename: "types.d.ts",
405
+ content: clientTypes
406
+ });
407
+ }
408
+ }
409
+ };
410
+ }
411
+ });
412
+
413
+ //#endregion
414
+ //#region src/index.ts
415
+ var src_default = integration_default;
416
+
417
+ //#endregion
418
+ export { src_default as default };
package/package.json CHANGED
@@ -5,8 +5,8 @@
5
5
  },
6
6
  "dependencies": {
7
7
  "@hono/standard-validator": "^0.2.0",
8
- "@hono/zod-validator": "^0.2.2",
9
- "astro-integration-kit": "^0.19.0",
8
+ "@hono/zod-validator": "^0.7.6",
9
+ "astro-integration-kit": "^0.20.0",
10
10
  "tinyglobby": "^0.2.15"
11
11
  },
12
12
  "description": "Define server actions with built-in validation, error handling, and a pre-built hono client for calling the routes.",
@@ -16,19 +16,15 @@
16
16
  "@astrojs/node": "catalog:",
17
17
  "@astrojs/vercel": "catalog:",
18
18
  "@biomejs/biome": "catalog:",
19
+ "@standard-schema/spec": "^1.1.0",
19
20
  "astro": "catalog:",
20
- "tsup": "^8.5.0",
21
+ "tsdown": "^0.21.7",
21
22
  "typescript": "catalog:"
22
23
  },
23
24
  "exports": {
24
- ".": {
25
- "types": "./dist/index.d.ts",
26
- "default": "./dist/index.js"
27
- },
28
- "./*": {
29
- "types": "./dist/*.d.ts",
30
- "default": "./dist/*.js"
31
- }
25
+ ".": "./dist/index.mjs",
26
+ "./actions": "./dist/actions.mjs",
27
+ "./package.json": "./package.json"
32
28
  },
33
29
  "files": [
34
30
  "dist"
@@ -45,21 +41,26 @@
45
41
  "cloudflare"
46
42
  ],
47
43
  "license": "MIT",
48
- "main": "./dist/index.js",
49
44
  "name": "@gnosticdev/hono-actions",
50
45
  "peerDependencies": {
51
- "astro": "^5.13.0",
46
+ "astro": "^5.13.0 || ^6.0.0",
52
47
  "hono": "^4.10.6"
53
48
  },
49
+ "optionalDependencies": {
50
+ "zod": "^4.3.6"
51
+ },
54
52
  "publishConfig": {
55
53
  "access": "public"
56
54
  },
57
55
  "scripts": {
58
- "build": "tsup",
59
- "dev": "tsup --watch",
56
+ "build": "tsdown",
57
+ "dev": "tsdown --watch",
60
58
  "typecheck": "tsc --noEmit"
61
59
  },
62
60
  "type": "module",
63
61
  "types": "./dist/index.d.ts",
64
- "version": "2.0.11"
62
+ "version": "2.1.1",
63
+ "inlinedDependencies": {
64
+ "@standard-schema/spec": "1.1.0"
65
+ }
65
66
  }
package/dist/actions.d.ts DELETED
@@ -1,160 +0,0 @@
1
- import * as hono_hono_base from 'hono/hono-base';
2
- import * as hono_utils_types from 'hono/utils/types';
3
- import { z } from 'astro/zod';
4
- import { Hono, Context } from 'hono';
5
- import { MergeSchemaPath } from 'hono/types';
6
-
7
- /**
8
- * Standard error codes for actions
9
- */
10
- type ActionErrorCode = 'INPUT_VALIDATION_ERROR' | 'EXTERNAL_API_ERROR' | 'INTERNAL_SERVER_ERROR' | 'UNKNOWN_ERROR' | 'LOCATION_NOT_FOUND' | 'SESSION_NOT_FOUND' | (string & {});
11
- declare class HonoActionError<TMessage extends string, TCode extends ActionErrorCode, TIssue = any> extends Error {
12
- code: TCode;
13
- issue?: TIssue;
14
- constructor({ message, code, issue, }: {
15
- message: TMessage;
16
- code: TCode;
17
- issue?: TIssue;
18
- });
19
- }
20
-
21
- interface Bindings {
22
- }
23
- interface Variables {
24
- /** Variables */
25
- [key: string]: unknown;
26
- }
27
- /**
28
- * HonoEnv is passed to the Hono context to provide types on `ctx.env`.
29
- *
30
- * We are using `HonoEnv` to avoid confusion with the Cloudflare types on `Env` -> which cooresponds to `Bindings`
31
- *
32
- * * **NOTE** For Cloudflare users, you can declare this in your src/env.d.ts file to get strong
33
- * typing for `ctx.env`.
34
- *
35
- * ```ts
36
- * declare namespace App {
37
- * interface Locals extends Runtime {}
38
- * }
39
- * ```
40
- */
41
- interface HonoEnv {
42
- Bindings: Bindings;
43
- Variables: Variables;
44
- }
45
- type HonoActionSchema = z.ZodType<any, z.ZodTypeDef, any>;
46
- /**
47
- * Merge each action key into its route path.
48
- *
49
- * Given a map of actions where each `Hono` app defines handlers at `"/"`, this
50
- * transforms the schema so each action's path becomes `"/${key}"`.
51
- *
52
- * Example:
53
- * ```ts
54
- * const honoActions: {
55
- * myAction: Hono<HonoEnv, { '/': { $post: any } }, '/'>
56
- * anotherAction: Hono<HonoEnv, { '/': { $post: any } }, '/'>
57
- * }
58
- *
59
- * type ActionsWithKeyedPaths = MergeActionKeyIntoPath<typeof honoActions>
60
- * // => {
61
- * // myAction: Hono<HonoEnv, { '/myAction': { $post: any } }, '/'>
62
- * // anotherAction: Hono<HonoEnv, { '/anotherAction': { $post: any } }, '/'>
63
- * // }
64
- * ```
65
- */
66
- type MergeActionKeyIntoPath<TActions extends Record<string, Hono<any, any, any>>> = {
67
- [K in keyof TActions]: TActions[K] extends Hono<infer TEnv, infer TSchema, infer TBase> ? Hono<TEnv, MergeSchemaPath<TSchema, `/${Extract<K, string>}`>, TBase> : never;
68
- };
69
- type HonoActionParams<TSchema extends HonoActionSchema, TReturn, TEnv extends HonoEnv, TContext extends Context<TEnv, any, any>> = {
70
- schema?: TSchema;
71
- handler: (params: z.output<TSchema>, context: TContext extends infer Ctx ? Ctx : never) => Promise<TReturn>;
72
- };
73
- /**
74
- * Defines a POST route with Zod validation for the request body.
75
- *
76
- * @param schema - The Zod schema for validation (optional).
77
- * @param handler - The handler function for the action.
78
- * @returns A Hono app instance with the defined route
79
- */
80
- declare function defineHonoAction<TEnv extends HonoEnv, TSchema extends HonoActionSchema, TReturn, TContext extends Context<TEnv, any, any>>({ schema, handler }: HonoActionParams<TSchema, TReturn, TEnv, TContext>): hono_hono_base.HonoBase<TEnv, {
81
- "/": {
82
- $post: {
83
- input: unknown extends ((undefined extends z.input<TSchema> ? true : false) extends true ? {
84
- json?: z.input<TSchema> | undefined;
85
- } : {
86
- json: z.input<TSchema>;
87
- }) ? {} : (undefined extends z.input<TSchema> ? true : false) extends true ? {
88
- json?: z.input<TSchema> | undefined;
89
- } : {
90
- json: z.input<TSchema>;
91
- };
92
- output: {
93
- data: null;
94
- error: {
95
- message: string;
96
- code: string;
97
- };
98
- };
99
- outputFormat: "json";
100
- status: 500;
101
- } | {
102
- input: unknown extends ((undefined extends z.input<TSchema> ? true : false) extends true ? {
103
- json?: z.input<TSchema> | undefined;
104
- } : {
105
- json: z.input<TSchema>;
106
- }) ? {} : (undefined extends z.input<TSchema> ? true : false) extends true ? {
107
- json?: z.input<TSchema> | undefined;
108
- } : {
109
- json: z.input<TSchema>;
110
- };
111
- output: unknown extends (Awaited<TReturn> | null extends bigint | readonly bigint[] ? never : { [K in keyof {
112
- data: Awaited<TReturn>;
113
- error: null;
114
- } as ({
115
- data: Awaited<TReturn>;
116
- error: null;
117
- }[K] extends infer T ? T extends {
118
- data: Awaited<TReturn>;
119
- error: null;
120
- }[K] ? T extends hono_utils_types.InvalidJSONValue ? true : false : never : never) extends true ? never : K]: boolean extends ({
121
- data: Awaited<TReturn>;
122
- error: null;
123
- }[K] extends infer T_1 ? T_1 extends {
124
- data: Awaited<TReturn>;
125
- error: null;
126
- }[K] ? T_1 extends hono_utils_types.InvalidJSONValue ? true : false : never : never) ? hono_utils_types.JSONParsed<{
127
- data: Awaited<TReturn>;
128
- error: null;
129
- }[K], bigint | readonly bigint[]> | undefined : hono_utils_types.JSONParsed<{
130
- data: Awaited<TReturn>;
131
- error: null;
132
- }[K], bigint | readonly bigint[]>; }) ? {} : Awaited<TReturn> | null extends bigint | readonly bigint[] ? never : { [K in keyof {
133
- data: Awaited<TReturn>;
134
- error: null;
135
- } as ({
136
- data: Awaited<TReturn>;
137
- error: null;
138
- }[K] extends infer T ? T extends {
139
- data: Awaited<TReturn>;
140
- error: null;
141
- }[K] ? T extends hono_utils_types.InvalidJSONValue ? true : false : never : never) extends true ? never : K]: boolean extends ({
142
- data: Awaited<TReturn>;
143
- error: null;
144
- }[K] extends infer T_1 ? T_1 extends {
145
- data: Awaited<TReturn>;
146
- error: null;
147
- }[K] ? T_1 extends hono_utils_types.InvalidJSONValue ? true : false : never : never) ? hono_utils_types.JSONParsed<{
148
- data: Awaited<TReturn>;
149
- error: null;
150
- }[K], bigint | readonly bigint[]> | undefined : hono_utils_types.JSONParsed<{
151
- data: Awaited<TReturn>;
152
- error: null;
153
- }[K], bigint | readonly bigint[]>; };
154
- outputFormat: "json";
155
- status: 200;
156
- };
157
- };
158
- }, "/", "/">;
159
-
160
- export { type Bindings, HonoActionError, type HonoEnv, type MergeActionKeyIntoPath, type Variables, defineHonoAction };