@gnosticdev/hono-actions 1.2.5 → 2.0.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/README.md +78 -0
- package/dist/index.js +79 -36
- package/package.json +7 -2
package/README.md
CHANGED
|
@@ -18,16 +18,94 @@ This package requires:
|
|
|
18
18
|
|
|
19
19
|
- `astro`: ^5.13.0
|
|
20
20
|
|
|
21
|
+
## Supported Adapters
|
|
22
|
+
|
|
23
|
+
This integration works with all supported Astro adapters:
|
|
24
|
+
|
|
25
|
+
- `@astrojs/cloudflare`
|
|
26
|
+
- `@astrojs/node`
|
|
27
|
+
- `@astrojs/vercel`
|
|
28
|
+
- `@astrojs/netlify`
|
|
29
|
+
|
|
21
30
|
## Setup
|
|
22
31
|
|
|
23
32
|
### 1. Add the integration to your Astro config
|
|
24
33
|
|
|
34
|
+
The integration works with all Astro adapters. Here are examples for each:
|
|
35
|
+
|
|
36
|
+
#### Cloudflare
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
// astro.config.ts
|
|
40
|
+
import { defineConfig } from 'astro/config'
|
|
41
|
+
import cloudflare from '@astrojs/cloudflare'
|
|
42
|
+
import honoActions from '@gnosticdev/hono-actions/integration'
|
|
43
|
+
|
|
44
|
+
export default defineConfig({
|
|
45
|
+
output: 'server',
|
|
46
|
+
adapter: cloudflare(),
|
|
47
|
+
integrations: [
|
|
48
|
+
honoActions({
|
|
49
|
+
basePath: '/api', // Optional: default is '/api'
|
|
50
|
+
actionsPath: 'src/server/actions.ts' // Optional: custom path to your actions file
|
|
51
|
+
})
|
|
52
|
+
]
|
|
53
|
+
})
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
#### Node.js
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
// astro.config.ts
|
|
60
|
+
import { defineConfig } from 'astro/config'
|
|
61
|
+
import node from '@astrojs/node'
|
|
62
|
+
import honoActions from '@gnosticdev/hono-actions/integration'
|
|
63
|
+
|
|
64
|
+
export default defineConfig({
|
|
65
|
+
output: 'server',
|
|
66
|
+
adapter: node({
|
|
67
|
+
mode: 'standalone' // or 'middleware'
|
|
68
|
+
}),
|
|
69
|
+
integrations: [
|
|
70
|
+
honoActions({
|
|
71
|
+
basePath: '/api', // Optional: default is '/api'
|
|
72
|
+
actionsPath: 'src/server/actions.ts' // Optional: custom path to your actions file
|
|
73
|
+
})
|
|
74
|
+
]
|
|
75
|
+
})
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
#### Vercel
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
// astro.config.ts
|
|
82
|
+
import { defineConfig } from 'astro/config'
|
|
83
|
+
import vercel from '@astrojs/vercel/serverless'
|
|
84
|
+
import honoActions from '@gnosticdev/hono-actions/integration'
|
|
85
|
+
|
|
86
|
+
export default defineConfig({
|
|
87
|
+
output: 'server',
|
|
88
|
+
adapter: vercel(),
|
|
89
|
+
integrations: [
|
|
90
|
+
honoActions({
|
|
91
|
+
basePath: '/api', // Optional: default is '/api'
|
|
92
|
+
actionsPath: 'src/server/actions.ts' // Optional: custom path to your actions file
|
|
93
|
+
})
|
|
94
|
+
]
|
|
95
|
+
})
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
#### Netlify
|
|
99
|
+
|
|
25
100
|
```typescript
|
|
26
101
|
// astro.config.ts
|
|
27
102
|
import { defineConfig } from 'astro/config'
|
|
103
|
+
import netlify from '@astrojs/netlify'
|
|
28
104
|
import honoActions from '@gnosticdev/hono-actions/integration'
|
|
29
105
|
|
|
30
106
|
export default defineConfig({
|
|
107
|
+
output: 'server',
|
|
108
|
+
adapter: netlify(),
|
|
31
109
|
integrations: [
|
|
32
110
|
honoActions({
|
|
33
111
|
basePath: '/api', // Optional: default is '/api'
|
package/dist/index.js
CHANGED
|
@@ -11,7 +11,11 @@ import { glob } from "tinyglobby";
|
|
|
11
11
|
|
|
12
12
|
// src/integration-files.ts
|
|
13
13
|
function generateRouter(opts) {
|
|
14
|
-
const { basePath, relativeActionsPath } = opts;
|
|
14
|
+
const { basePath, relativeActionsPath, adapter } = opts;
|
|
15
|
+
let exportedApp = `export default app`;
|
|
16
|
+
if (adapter === "@astrojs/netlify") {
|
|
17
|
+
exportedApp = `export default handle(app)`;
|
|
18
|
+
}
|
|
15
19
|
return `import type { HonoEnv, MergeActionKeyIntoPath } from '@gnosticdev/hono-actions/actions'
|
|
16
20
|
import { Hono } from 'hono'
|
|
17
21
|
import { cors } from 'hono/cors'
|
|
@@ -19,12 +23,13 @@ import { showRoutes } from 'hono/dev'
|
|
|
19
23
|
import { logger } from 'hono/logger'
|
|
20
24
|
import { prettyJSON } from 'hono/pretty-json'
|
|
21
25
|
import type { ExtractSchema, MergeSchemaPath } from 'hono/types'
|
|
26
|
+
${adapter === "@astrojs/netlify" ? "import { handle } from 'hono/netlify'" : ""}
|
|
22
27
|
|
|
23
28
|
async function buildRouter(){
|
|
24
29
|
type ActionsWithKeyedPaths = MergeActionKeyIntoPath<typeof honoActions>
|
|
25
30
|
type ActionSchema = ExtractSchema<ActionsWithKeyedPaths[keyof ActionsWithKeyedPaths]>
|
|
26
31
|
const { honoActions} = await import('${relativeActionsPath}')
|
|
27
|
-
const app = new Hono<HonoEnv, MergeSchemaPath<ActionSchema,
|
|
32
|
+
const app = new Hono<HonoEnv, MergeSchemaPath<ActionSchema, '${basePath}'>>().basePath('${basePath}')
|
|
28
33
|
|
|
29
34
|
app.use('*', cors(), logger(), prettyJSON())
|
|
30
35
|
|
|
@@ -41,7 +46,7 @@ const app = await buildRouter()
|
|
|
41
46
|
console.log('------- Hono Routes -------')
|
|
42
47
|
showRoutes(app)
|
|
43
48
|
console.log('---------------------------')
|
|
44
|
-
|
|
49
|
+
${exportedApp}`;
|
|
45
50
|
}
|
|
46
51
|
var generateAstroHandler = (adapter) => {
|
|
47
52
|
switch (adapter) {
|
|
@@ -49,17 +54,49 @@ var generateAstroHandler = (adapter) => {
|
|
|
49
54
|
return `
|
|
50
55
|
/// <reference types="./types.d.ts" />
|
|
51
56
|
// Generated by Hono Actions Integration
|
|
57
|
+
// adapter: ${adapter}
|
|
58
|
+
import type { APIContext, APIRoute } from 'astro'
|
|
59
|
+
import router from './router.js'
|
|
60
|
+
|
|
61
|
+
const handler: APIRoute<APIContext> = async (ctx) => {
|
|
62
|
+
return router.fetch(
|
|
63
|
+
ctx.request,
|
|
64
|
+
ctx.locals.runtime.env, // required for cloudflare adapter
|
|
65
|
+
ctx.locals.runtime.ctx, // required for cloudflare adapter
|
|
66
|
+
)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export { handler as ALL }
|
|
70
|
+
`;
|
|
71
|
+
case "@astrojs/node":
|
|
72
|
+
case "@astrojs/vercel":
|
|
73
|
+
return `
|
|
74
|
+
/// <reference types="./types.d.ts" />
|
|
75
|
+
// Generated by Hono Actions Integration
|
|
76
|
+
// adapter: ${adapter}
|
|
52
77
|
import type { APIContext, APIRoute } from 'astro'
|
|
53
78
|
import router from './router.js'
|
|
54
79
|
|
|
55
80
|
const handler: APIRoute<APIContext> = async (ctx) => {
|
|
56
81
|
return router.fetch(
|
|
57
82
|
ctx.request,
|
|
58
|
-
ctx.locals.runtime.env,
|
|
59
|
-
ctx.locals.runtime.ctx,
|
|
60
83
|
)
|
|
61
84
|
}
|
|
62
85
|
|
|
86
|
+
export { handler as ALL }
|
|
87
|
+
`;
|
|
88
|
+
case "@astrojs/netlify":
|
|
89
|
+
return `
|
|
90
|
+
/// <reference types="./types.d.ts" />
|
|
91
|
+
// Generated by Hono Actions Integration
|
|
92
|
+
// adapter: ${adapter}
|
|
93
|
+
import type { APIContext, APIRoute } from 'astro'
|
|
94
|
+
import netlifyHandler from './router.js'
|
|
95
|
+
|
|
96
|
+
const handler: APIRoute<APIContext> = async (ctx) => {
|
|
97
|
+
return netlifyHandler(ctx.request, ctx)
|
|
98
|
+
}
|
|
99
|
+
|
|
63
100
|
export { handler as ALL }
|
|
64
101
|
`;
|
|
65
102
|
default:
|
|
@@ -70,6 +107,7 @@ var generateHonoClient = (port) => `
|
|
|
70
107
|
// Generated by Hono Actions Integration
|
|
71
108
|
import type { HonoRouter } from './router.js'
|
|
72
109
|
import { hc, parseResponse } from 'hono/client'
|
|
110
|
+
import type { DetailedError } from 'hono/client'
|
|
73
111
|
|
|
74
112
|
function getBaseUrl() {
|
|
75
113
|
// client side can just use the base path
|
|
@@ -86,11 +124,16 @@ function getBaseUrl() {
|
|
|
86
124
|
return import.meta.env.SITE ?? ''
|
|
87
125
|
}
|
|
88
126
|
export { parseResponse, hc }
|
|
127
|
+
export type { DetailedError }
|
|
89
128
|
export const honoClient = hc<HonoRouter>(getBaseUrl())
|
|
90
129
|
`;
|
|
91
130
|
|
|
92
131
|
// src/lib/utils.ts
|
|
93
132
|
var reservedRoutes = ["_astro", "_actions", "_server_islands"];
|
|
133
|
+
var SUPPORTED_ADAPTERS = ["@astrojs/cloudflare", "@astrojs/node", "@astrojs/netlify", "@astrojs/vercel"];
|
|
134
|
+
function isSupportedAdapter(adapter) {
|
|
135
|
+
return SUPPORTED_ADAPTERS.includes(adapter);
|
|
136
|
+
}
|
|
94
137
|
|
|
95
138
|
// src/integration.ts
|
|
96
139
|
var optionsSchema = z.object({
|
|
@@ -119,10 +162,6 @@ var ACTION_PATTERNS = [
|
|
|
119
162
|
"src/hono/index.ts",
|
|
120
163
|
"src/hono.ts"
|
|
121
164
|
];
|
|
122
|
-
var SUPPORTED_ADAPTERS = ["@astrojs/cloudflare"];
|
|
123
|
-
function isSupportedAdapter(adapter) {
|
|
124
|
-
return SUPPORTED_ADAPTERS.includes(adapter);
|
|
125
|
-
}
|
|
126
165
|
var integration_default = defineIntegration({
|
|
127
166
|
name: "@gnosticdev/hono-actions",
|
|
128
167
|
optionsSchema,
|
|
@@ -164,33 +203,31 @@ ${ACTION_PATTERNS.map((p) => ` - ${p}`).join("\n")}`
|
|
|
164
203
|
"router.ts"
|
|
165
204
|
);
|
|
166
205
|
const relFromGenToActions = path.relative(codeGenDir.pathname, resolvedActionsPath).split(path.sep).join("/");
|
|
167
|
-
const routerContent = generateRouter({
|
|
168
|
-
basePath,
|
|
169
|
-
relativeActionsPath: relFromGenToActions
|
|
170
|
-
});
|
|
171
|
-
await fs.writeFile(routerPathAbs, routerContent, "utf-8");
|
|
172
|
-
const astroHandlerPathAbs = path.join(
|
|
173
|
-
codeGenDir.pathname,
|
|
174
|
-
"api.ts"
|
|
175
|
-
);
|
|
176
206
|
const adapter = params.config.adapter?.name;
|
|
177
207
|
if (!adapter) {
|
|
178
208
|
logger.error(
|
|
179
209
|
`No Astro adapter found. Add one of:
|
|
180
|
-
|
|
210
|
+
- ${SUPPORTED_ADAPTERS.join("\n - ")} to your astro.config.mjs`
|
|
181
211
|
);
|
|
182
212
|
return;
|
|
183
213
|
}
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
cause: `Only ${SUPPORTED_ADAPTERS.join(
|
|
190
|
-
", "
|
|
191
|
-
)} are supported for now`
|
|
192
|
-
});
|
|
214
|
+
if (!isSupportedAdapter(adapter)) {
|
|
215
|
+
logger.error(
|
|
216
|
+
`Unsupported adapter: ${adapter}. Only ${SUPPORTED_ADAPTERS.join("\n - ")} are supported`
|
|
217
|
+
);
|
|
218
|
+
return;
|
|
193
219
|
}
|
|
220
|
+
const routerContent = generateRouter({
|
|
221
|
+
basePath,
|
|
222
|
+
relativeActionsPath: relFromGenToActions,
|
|
223
|
+
adapter
|
|
224
|
+
});
|
|
225
|
+
await fs.writeFile(routerPathAbs, routerContent, "utf-8");
|
|
226
|
+
const astroHandlerPathAbs = path.join(
|
|
227
|
+
codeGenDir.pathname,
|
|
228
|
+
"api.ts"
|
|
229
|
+
);
|
|
230
|
+
const astroHandlerContent = generateAstroHandler(adapter);
|
|
194
231
|
await fs.writeFile(
|
|
195
232
|
astroHandlerPathAbs,
|
|
196
233
|
astroHandlerContent,
|
|
@@ -241,22 +278,28 @@ export {}
|
|
|
241
278
|
declare module '@gnosticdev/hono-actions/client' {
|
|
242
279
|
export const honoClient: typeof import('./client').honoClient
|
|
243
280
|
export const parseResponse: typeof import('./client').parseResponse
|
|
281
|
+
exoprt type DetailedError = import('./client').DetailedError
|
|
244
282
|
}
|
|
245
283
|
`;
|
|
246
|
-
|
|
284
|
+
const adapter = config.adapter?.name;
|
|
285
|
+
if (!adapter) {
|
|
247
286
|
logger.warn("No adapter found...");
|
|
248
287
|
return;
|
|
249
288
|
}
|
|
250
|
-
if (
|
|
251
|
-
logger.warn(
|
|
289
|
+
if (!isSupportedAdapter(adapter)) {
|
|
290
|
+
logger.warn(
|
|
291
|
+
`Unsupported adapter: ${adapter}. Only ${SUPPORTED_ADAPTERS.join("\n - ")} are supported`
|
|
292
|
+
);
|
|
252
293
|
return;
|
|
253
294
|
}
|
|
254
|
-
|
|
295
|
+
if (adapter === "@astrojs/cloudflare") {
|
|
296
|
+
clientTypes += `
|
|
255
297
|
type Runtime = import('@astrojs/cloudflare').Runtime<Env>
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
`;
|
|
298
|
+
declare namespace App {
|
|
299
|
+
interface Locals extends Runtime {}
|
|
300
|
+
}
|
|
301
|
+
`;
|
|
302
|
+
}
|
|
260
303
|
injectTypes({
|
|
261
304
|
filename: "types.d.ts",
|
|
262
305
|
content: clientTypes
|
package/package.json
CHANGED
|
@@ -14,7 +14,12 @@
|
|
|
14
14
|
"devDependencies": {
|
|
15
15
|
"tsup": "^8.5.0",
|
|
16
16
|
"typescript": "catalog:",
|
|
17
|
-
"vitest": "catalog:"
|
|
17
|
+
"vitest": "catalog:",
|
|
18
|
+
"@astrojs/cloudflare": "catalog:",
|
|
19
|
+
"@astrojs/netlify": "catalog:",
|
|
20
|
+
"@astrojs/node": "catalog:",
|
|
21
|
+
"@astrojs/vercel": "catalog:",
|
|
22
|
+
"astro": "catalog:"
|
|
18
23
|
},
|
|
19
24
|
"exports": {
|
|
20
25
|
".": {
|
|
@@ -56,5 +61,5 @@
|
|
|
56
61
|
},
|
|
57
62
|
"type": "module",
|
|
58
63
|
"types": "./dist/index.d.ts",
|
|
59
|
-
"version": "
|
|
64
|
+
"version": "2.0.0"
|
|
60
65
|
}
|