@ahmedbaset/adminjs-hono 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.
Files changed (59) hide show
  1. package/.eslintrc.cjs +20 -0
  2. package/README.md +239 -0
  3. package/examples/auth.ts +76 -0
  4. package/examples/simple.ts +42 -0
  5. package/lib/authentication/login.handler.d.ts +11 -0
  6. package/lib/authentication/login.handler.d.ts.map +1 -0
  7. package/lib/authentication/login.handler.js +155 -0
  8. package/lib/authentication/logout.handler.d.ts +11 -0
  9. package/lib/authentication/logout.handler.d.ts.map +1 -0
  10. package/lib/authentication/logout.handler.js +50 -0
  11. package/lib/authentication/protected-routes.handler.d.ts +11 -0
  12. package/lib/authentication/protected-routes.handler.d.ts.map +1 -0
  13. package/lib/authentication/protected-routes.handler.js +26 -0
  14. package/lib/authentication/refresh.handler.d.ts +13 -0
  15. package/lib/authentication/refresh.handler.d.ts.map +1 -0
  16. package/lib/authentication/refresh.handler.js +42 -0
  17. package/lib/buildAuthenticatedRouter.d.ts +15 -0
  18. package/lib/buildAuthenticatedRouter.d.ts.map +1 -0
  19. package/lib/buildAuthenticatedRouter.js +61 -0
  20. package/lib/buildRouter.d.ts +53 -0
  21. package/lib/buildRouter.d.ts.map +1 -0
  22. package/lib/buildRouter.js +178 -0
  23. package/lib/convertRoutes.d.ts +9 -0
  24. package/lib/convertRoutes.d.ts.map +1 -0
  25. package/lib/convertRoutes.js +10 -0
  26. package/lib/errors.d.ts +10 -0
  27. package/lib/errors.d.ts.map +1 -0
  28. package/lib/errors.js +15 -0
  29. package/lib/formParser.d.ts +13 -0
  30. package/lib/formParser.d.ts.map +1 -0
  31. package/lib/formParser.js +53 -0
  32. package/lib/index.d.ts +55 -0
  33. package/lib/index.d.ts.map +1 -0
  34. package/lib/index.js +48 -0
  35. package/lib/logger.d.ts +7 -0
  36. package/lib/logger.d.ts.map +1 -0
  37. package/lib/logger.js +17 -0
  38. package/lib/session.d.ts +25 -0
  39. package/lib/session.d.ts.map +1 -0
  40. package/lib/session.js +56 -0
  41. package/lib/types.d.ts +46 -0
  42. package/lib/types.d.ts.map +1 -0
  43. package/lib/types.js +1 -0
  44. package/package.json +44 -0
  45. package/src/authentication/login.handler.ts +193 -0
  46. package/src/authentication/logout.handler.ts +62 -0
  47. package/src/authentication/protected-routes.handler.ts +38 -0
  48. package/src/authentication/refresh.handler.ts +59 -0
  49. package/src/buildAuthenticatedRouter.ts +92 -0
  50. package/src/buildRouter.ts +224 -0
  51. package/src/convertRoutes.ts +10 -0
  52. package/src/errors.ts +24 -0
  53. package/src/formParser.ts +73 -0
  54. package/src/index.ts +74 -0
  55. package/src/logger.ts +18 -0
  56. package/src/session.ts +71 -0
  57. package/src/types.ts +53 -0
  58. package/tsconfig.json +21 -0
  59. package/vitest.config.ts +12 -0
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Registers token refresh route with the Hono app
3
+ * Delegates to authentication provider's refresh method if available
4
+ *
5
+ * @param app - Hono app instance
6
+ * @param admin - AdminJS instance
7
+ * @param auth - Authentication options
8
+ */
9
+ export function withRefresh(app, admin, auth) {
10
+ const { provider } = auth;
11
+ // Only register refresh route if provider supports it
12
+ if (!provider || !provider.handleRefresh) {
13
+ return;
14
+ }
15
+ // Typically refresh is at /refresh, but this depends on the provider
16
+ const refreshPath = '/refresh';
17
+ app.post(refreshPath, async (c) => {
18
+ try {
19
+ const fields = c.get('fields') || {};
20
+ const session = c.get('session');
21
+ // Call provider's refresh method
22
+ const refreshedUser = await provider.handleRefresh({
23
+ headers: Object.fromEntries(c.req.raw.headers.entries()),
24
+ query: c.req.query(),
25
+ params: c.req.param(),
26
+ data: fields,
27
+ }, { req: c, res: c });
28
+ if (refreshedUser) {
29
+ // Update session with new credentials
30
+ session.adminUser = refreshedUser;
31
+ return c.json({ success: true });
32
+ }
33
+ else {
34
+ return c.json({ success: false, error: 'Refresh failed' }, 401);
35
+ }
36
+ }
37
+ catch (error) {
38
+ console.error('Token refresh error:', error);
39
+ return c.json({ success: false, error: error.message || 'Refresh failed' }, 401);
40
+ }
41
+ });
42
+ }
@@ -0,0 +1,15 @@
1
+ import AdminJS from 'adminjs';
2
+ import type { Hono } from 'hono';
3
+ import type { AuthenticationOptions, SessionOptions, UploadOptions } from './types.js';
4
+ /**
5
+ * Builds a Hono app with AdminJS routes protected by session-based authentication
6
+ *
7
+ * @param admin - The AdminJS instance
8
+ * @param auth - Authentication configuration
9
+ * @param predefinedApp - Optional existing Hono app to use
10
+ * @param sessionOptions - Optional session configuration
11
+ * @param uploadOptions - Optional upload configuration
12
+ * @returns Configured Hono app with authentication
13
+ */
14
+ export declare function buildAuthenticatedRouter(admin: AdminJS, auth: AuthenticationOptions, predefinedApp?: Hono, sessionOptions?: SessionOptions, uploadOptions?: UploadOptions): Hono;
15
+ //# sourceMappingURL=buildAuthenticatedRouter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buildAuthenticatedRouter.d.ts","sourceRoot":"","sources":["../src/buildAuthenticatedRouter.ts"],"names":[],"mappings":"AAAA,OAAO,OAAkC,MAAM,SAAS,CAAA;AACxD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAWhC,OAAO,KAAK,EAAE,qBAAqB,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAItF;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,OAAO,EACd,IAAI,EAAE,qBAAqB,EAC3B,aAAa,CAAC,EAAE,IAAI,EACpB,cAAc,CAAC,EAAE,cAAc,EAC/B,aAAa,CAAC,EAAE,aAAa,GAC5B,IAAI,CA2DN"}
@@ -0,0 +1,61 @@
1
+ import { Router as AdminRouter } from 'adminjs';
2
+ import { withLogin } from './authentication/login.handler.js';
3
+ import { withLogout } from './authentication/logout.handler.js';
4
+ import { withProtectedRoutesHandler } from './authentication/protected-routes.handler.js';
5
+ import { withRefresh } from './authentication/refresh.handler.js';
6
+ import { buildAssets, buildRoutes, initializeAdmin } from './buildRouter.js';
7
+ import { INVALID_AUTH_CONFIG_ERROR, MISSING_AUTH_CONFIG_ERROR, WrongArgumentError, } from './errors.js';
8
+ import { createFormParserMiddleware } from './formParser.js';
9
+ import { createSessionMiddleware } from './session.js';
10
+ /**
11
+ * Builds a Hono app with AdminJS routes protected by session-based authentication
12
+ *
13
+ * @param admin - The AdminJS instance
14
+ * @param auth - Authentication configuration
15
+ * @param predefinedApp - Optional existing Hono app to use
16
+ * @param sessionOptions - Optional session configuration
17
+ * @param uploadOptions - Optional upload configuration
18
+ * @returns Configured Hono app with authentication
19
+ */
20
+ export function buildAuthenticatedRouter(admin, auth, predefinedApp, sessionOptions, uploadOptions) {
21
+ // Initialize AdminJS
22
+ initializeAdmin(admin);
23
+ // Validate authentication configuration
24
+ if (!auth.authenticate && !auth.provider) {
25
+ throw new WrongArgumentError(MISSING_AUTH_CONFIG_ERROR);
26
+ }
27
+ if (auth.authenticate && auth.provider) {
28
+ throw new WrongArgumentError(INVALID_AUTH_CONFIG_ERROR);
29
+ }
30
+ // Use provided app or create new Hono instance
31
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
32
+ const { Hono: HonoClass } = require('hono');
33
+ const app = predefinedApp ?? new HonoClass();
34
+ // Get routes and assets from AdminJS
35
+ const { routes, assets } = AdminRouter;
36
+ // If provider is configured, add its UI props to AdminJS env
37
+ if (auth.provider) {
38
+ admin.options.env = {
39
+ ...admin.options.env,
40
+ ...auth.provider.getUiProps(),
41
+ };
42
+ }
43
+ // Configure session middleware
44
+ const cookieName = auth.cookieName || 'adminjs';
45
+ app.use('*', createSessionMiddleware(auth.cookiePassword, cookieName, sessionOptions));
46
+ // Register form parsing middleware
47
+ app.use('*', createFormParserMiddleware(uploadOptions));
48
+ // Register login handler (must be before protected routes middleware)
49
+ withLogin(app, admin, auth);
50
+ // Register logout handler (must be before protected routes middleware)
51
+ withLogout(app, admin, auth);
52
+ // Build assets (must be before protected routes middleware)
53
+ buildAssets(assets, routes, app, admin);
54
+ // Register protected routes middleware (applies to all subsequent routes)
55
+ withProtectedRoutesHandler(app, admin);
56
+ // Register refresh handler (after protected routes middleware)
57
+ withRefresh(app, admin, auth);
58
+ // Build routes (after protected routes middleware)
59
+ buildRoutes(routes, app, admin);
60
+ return app;
61
+ }
@@ -0,0 +1,53 @@
1
+ import AdminJS, { Router as AdminRouter } from 'adminjs';
2
+ import type { Hono, Handler } from 'hono';
3
+ import type { HonoVariables } from './types.js';
4
+ /**
5
+ * Validates and initializes an AdminJS instance
6
+ * @param admin - The AdminJS instance to initialize
7
+ * @throws {WrongArgumentError} If the admin parameter is not a valid AdminJS instance
8
+ */
9
+ export declare function initializeAdmin(admin: AdminJS): void;
10
+ /**
11
+ * Creates a Hono route handler from an AdminJS route
12
+ * Extracts request data and invokes the AdminJS controller
13
+ *
14
+ * @param admin - The AdminJS instance
15
+ * @param route - The AdminJS route definition
16
+ * @returns Hono handler function
17
+ */
18
+ export declare function routeHandler(admin: AdminJS, route: (typeof AdminRouter)['routes'][0]): Handler<{
19
+ Variables: HonoVariables;
20
+ }>;
21
+ /**
22
+ * Registers a single AdminJS route with the Hono app
23
+ * @param route - The AdminJS route to register
24
+ * @param app - The Hono app instance
25
+ * @param admin - The AdminJS instance
26
+ */
27
+ export declare function buildRoute(route: (typeof AdminRouter)['routes'][number], app: Hono, admin: AdminJS): void;
28
+ /**
29
+ * Registers all AdminJS routes with the Hono app
30
+ * @param routes - Array of AdminJS routes
31
+ * @param app - The Hono app instance
32
+ * @param admin - The AdminJS instance
33
+ */
34
+ export declare function buildRoutes(routes: (typeof AdminRouter)['routes'], app: Hono, admin: AdminJS): void;
35
+ /**
36
+ * Registers AdminJS asset routes with the Hono app
37
+ * @param assets - Array of AdminJS assets
38
+ * @param routes - Array of AdminJS routes (to find component bundler route)
39
+ * @param app - The Hono app instance
40
+ * @param admin - The AdminJS instance
41
+ */
42
+ export declare function buildAssets(assets: (typeof AdminRouter)['assets'], routes: (typeof AdminRouter)['routes'], app: Hono, admin: AdminJS): void;
43
+ import type { UploadOptions } from './types.js';
44
+ /**
45
+ * Builds a Hono app with AdminJS routes (without authentication)
46
+ *
47
+ * @param admin - The AdminJS instance
48
+ * @param predefinedApp - Optional existing Hono app to use
49
+ * @param uploadOptions - Optional upload configuration
50
+ * @returns Configured Hono app
51
+ */
52
+ export declare function buildRouter(admin: AdminJS, predefinedApp?: Hono, uploadOptions?: UploadOptions): Hono;
53
+ //# sourceMappingURL=buildRouter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buildRouter.d.ts","sourceRoot":"","sources":["../src/buildRouter.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,EAAE,EAAE,MAAM,IAAI,WAAW,EAAE,MAAM,SAAS,CAAA;AACxD,OAAO,KAAK,EAAE,IAAI,EAAE,OAAO,EAAW,MAAM,MAAM,CAAA;AAIlD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAE/C;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAQpD;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,OAAO,EACd,KAAK,EAAE,CAAC,OAAO,WAAW,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,GACvC,OAAO,CAAC;IAAE,SAAS,EAAE,aAAa,CAAA;CAAE,CAAC,CA+CvC;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CACxB,KAAK,EAAE,CAAC,OAAO,WAAW,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,EAC7C,GAAG,EAAE,IAAI,EACT,KAAK,EAAE,OAAO,GACb,IAAI,CAUN;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,CAAC,OAAO,WAAW,CAAC,CAAC,QAAQ,CAAC,EACtC,GAAG,EAAE,IAAI,EACT,KAAK,EAAE,OAAO,GACb,IAAI,CAEN;AA0BD;;;;;;GAMG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,CAAC,OAAO,WAAW,CAAC,CAAC,QAAQ,CAAC,EACtC,MAAM,EAAE,CAAC,OAAO,WAAW,CAAC,CAAC,QAAQ,CAAC,EACtC,GAAG,EAAE,IAAI,EACT,KAAK,EAAE,OAAO,GACb,IAAI,CAgCN;AAED,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAG/C;;;;;;;GAOG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,OAAO,EACd,aAAa,CAAC,EAAE,IAAI,EACpB,aAAa,CAAC,EAAE,aAAa,GAC5B,IAAI,CAoBN"}
@@ -0,0 +1,178 @@
1
+ import { Router as AdminRouter } from 'adminjs';
2
+ import { WrongArgumentError, INVALID_ADMINJS_INSTANCE } from './errors.js';
3
+ import { log } from './logger.js';
4
+ import { convertToHonoRoute } from './convertRoutes.js';
5
+ /**
6
+ * Validates and initializes an AdminJS instance
7
+ * @param admin - The AdminJS instance to initialize
8
+ * @throws {WrongArgumentError} If the admin parameter is not a valid AdminJS instance
9
+ */
10
+ export function initializeAdmin(admin) {
11
+ if (admin?.constructor?.name !== 'AdminJS') {
12
+ throw new WrongArgumentError(INVALID_ADMINJS_INSTANCE);
13
+ }
14
+ admin.initialize().then(() => {
15
+ log.debug('AdminJS: bundle ready');
16
+ });
17
+ }
18
+ /**
19
+ * Creates a Hono route handler from an AdminJS route
20
+ * Extracts request data and invokes the AdminJS controller
21
+ *
22
+ * @param admin - The AdminJS instance
23
+ * @param route - The AdminJS route definition
24
+ * @returns Hono handler function
25
+ */
26
+ export function routeHandler(admin, route) {
27
+ return async (c) => {
28
+ // Get session from context (may be undefined for non-authenticated routes)
29
+ const session = c.get('session');
30
+ const adminUser = session?.adminUser;
31
+ // Instantiate the AdminJS controller
32
+ const controller = new route.Controller({ admin }, adminUser);
33
+ // Extract request data
34
+ const params = c.req.param();
35
+ const query = c.req.query();
36
+ const method = c.req.method.toLowerCase();
37
+ // Get parsed form data from context (set by form parser middleware)
38
+ const fields = c.get('fields') || {};
39
+ const files = c.get('files') || {};
40
+ const payload = {
41
+ ...fields,
42
+ ...files,
43
+ };
44
+ // Execute the controller action
45
+ const html = await controller[route.action]({
46
+ ...c.req,
47
+ params,
48
+ query,
49
+ payload,
50
+ method,
51
+ }, c.res);
52
+ // Set Content-Type header if specified
53
+ if (route.contentType) {
54
+ c.header('Content-Type', route.contentType);
55
+ }
56
+ // Return response
57
+ if (html) {
58
+ return c.body(html);
59
+ }
60
+ // If no response body, return empty response
61
+ return c.body(null);
62
+ };
63
+ }
64
+ /**
65
+ * Registers a single AdminJS route with the Hono app
66
+ * @param route - The AdminJS route to register
67
+ * @param app - The Hono app instance
68
+ * @param admin - The AdminJS instance
69
+ */
70
+ export function buildRoute(route, app, admin) {
71
+ // Convert AdminJS route path to Hono format
72
+ const honoPath = convertToHonoRoute(route.path);
73
+ // Register handler based on HTTP method
74
+ if (route.method === 'GET') {
75
+ app.get(honoPath, routeHandler(admin, route));
76
+ }
77
+ else if (route.method === 'POST') {
78
+ app.post(honoPath, routeHandler(admin, route));
79
+ }
80
+ }
81
+ /**
82
+ * Registers all AdminJS routes with the Hono app
83
+ * @param routes - Array of AdminJS routes
84
+ * @param app - The Hono app instance
85
+ * @param admin - The AdminJS instance
86
+ */
87
+ export function buildRoutes(routes, app, admin) {
88
+ routes.forEach((route) => buildRoute(route, app, admin));
89
+ }
90
+ /**
91
+ * Determines Content-Type header based on file extension
92
+ * @param path - File path
93
+ * @returns Content-Type string
94
+ */
95
+ function getContentType(path) {
96
+ if (path.endsWith('.js')) {
97
+ return 'application/javascript';
98
+ }
99
+ else if (path.endsWith('.css')) {
100
+ return 'text/css';
101
+ }
102
+ else if (path.endsWith('.html')) {
103
+ return 'text/html';
104
+ }
105
+ else if (path.endsWith('.json')) {
106
+ return 'application/json';
107
+ }
108
+ else if (path.endsWith('.png')) {
109
+ return 'image/png';
110
+ }
111
+ else if (path.endsWith('.jpg') || path.endsWith('.jpeg')) {
112
+ return 'image/jpeg';
113
+ }
114
+ else if (path.endsWith('.svg')) {
115
+ return 'image/svg+xml';
116
+ }
117
+ return 'application/octet-stream';
118
+ }
119
+ /**
120
+ * Registers AdminJS asset routes with the Hono app
121
+ * @param assets - Array of AdminJS assets
122
+ * @param routes - Array of AdminJS routes (to find component bundler route)
123
+ * @param app - The Hono app instance
124
+ * @param admin - The AdminJS instance
125
+ */
126
+ export function buildAssets(assets, routes, app, admin) {
127
+ // Register component bundler route if it exists
128
+ const componentBundlerRoute = routes.find((r) => r.action === 'bundleComponents');
129
+ if (componentBundlerRoute) {
130
+ buildRoute(componentBundlerRoute, app, admin);
131
+ }
132
+ // Register static asset routes
133
+ assets.forEach((asset) => {
134
+ app.get(asset.path, async (c) => {
135
+ try {
136
+ // Read file using Node.js fs (for Node runtime)
137
+ // For other runtimes, this would need runtime detection
138
+ const fs = await import('fs/promises');
139
+ const path = await import('path');
140
+ const filePath = path.resolve(asset.src);
141
+ const fileContent = await fs.readFile(filePath);
142
+ // Set appropriate Content-Type header
143
+ const contentType = getContentType(asset.path);
144
+ c.header('Content-Type', contentType);
145
+ return c.body(fileContent);
146
+ }
147
+ catch (error) {
148
+ console.error(`Error serving asset ${asset.path}:`, error);
149
+ return c.text('Asset not found', 404);
150
+ }
151
+ });
152
+ });
153
+ }
154
+ import { createFormParserMiddleware } from './formParser.js';
155
+ /**
156
+ * Builds a Hono app with AdminJS routes (without authentication)
157
+ *
158
+ * @param admin - The AdminJS instance
159
+ * @param predefinedApp - Optional existing Hono app to use
160
+ * @param uploadOptions - Optional upload configuration
161
+ * @returns Configured Hono app
162
+ */
163
+ export function buildRouter(admin, predefinedApp, uploadOptions) {
164
+ // Initialize AdminJS
165
+ initializeAdmin(admin);
166
+ // Use provided app or create new Hono instance
167
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
168
+ const { Hono: HonoClass } = require('hono');
169
+ const app = predefinedApp ?? new HonoClass();
170
+ // Get routes and assets from AdminJS
171
+ const { routes, assets } = AdminRouter;
172
+ // Register form parsing middleware
173
+ app.use('*', createFormParserMiddleware(uploadOptions));
174
+ // Build assets and routes
175
+ buildAssets(assets, routes, app, admin);
176
+ buildRoutes(routes, app, admin);
177
+ return app;
178
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Converts AdminJS route path format to Hono route path format
3
+ * AdminJS uses {param} notation while Hono uses :param notation
4
+ *
5
+ * @param path - AdminJS route path (e.g., "/resources/{resourceId}/actions/{action}")
6
+ * @returns Hono route path (e.g., "/resources/:resourceId/actions/:action")
7
+ */
8
+ export declare function convertToHonoRoute(path: string): string;
9
+ //# sourceMappingURL=convertRoutes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"convertRoutes.d.ts","sourceRoot":"","sources":["../src/convertRoutes.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEvD"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Converts AdminJS route path format to Hono route path format
3
+ * AdminJS uses {param} notation while Hono uses :param notation
4
+ *
5
+ * @param path - AdminJS route path (e.g., "/resources/{resourceId}/actions/{action}")
6
+ * @returns Hono route path (e.g., "/resources/:resourceId/actions/:action")
7
+ */
8
+ export function convertToHonoRoute(path) {
9
+ return path.replace(/\{([^}]+)\}/g, ':$1');
10
+ }
@@ -0,0 +1,10 @@
1
+ export declare class WrongArgumentError extends Error {
2
+ constructor(message: string);
3
+ }
4
+ export declare const INVALID_ADMINJS_INSTANCE = "You have to pass an instance of AdminJS to the buildRouter() function";
5
+ export declare const MISSING_AUTH_CONFIG_ERROR = "You must provide either \"authenticate\" function or \"provider\" in authentication options";
6
+ export declare const INVALID_AUTH_CONFIG_ERROR = "You cannot provide both \"authenticate\" function and \"provider\" in authentication options";
7
+ export declare class OldBodyParserUsedError extends Error {
8
+ constructor();
9
+ }
10
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,kBAAmB,SAAQ,KAAK;gBAC/B,OAAO,EAAE,MAAM;CAI5B;AAED,eAAO,MAAM,wBAAwB,0EACoC,CAAA;AAEzE,eAAO,MAAM,yBAAyB,gGACqD,CAAA;AAE3F,eAAO,MAAM,yBAAyB,iGACsD,CAAA;AAE5F,qBAAa,sBAAuB,SAAQ,KAAK;;CAOhD"}
package/lib/errors.js ADDED
@@ -0,0 +1,15 @@
1
+ export class WrongArgumentError extends Error {
2
+ constructor(message) {
3
+ super(message);
4
+ this.name = 'WrongArgumentError';
5
+ }
6
+ }
7
+ export const INVALID_ADMINJS_INSTANCE = 'You have to pass an instance of AdminJS to the buildRouter() function';
8
+ export const MISSING_AUTH_CONFIG_ERROR = 'You must provide either "authenticate" function or "provider" in authentication options';
9
+ export const INVALID_AUTH_CONFIG_ERROR = 'You cannot provide both "authenticate" function and "provider" in authentication options';
10
+ export class OldBodyParserUsedError extends Error {
11
+ constructor() {
12
+ super('You are using old body-parser middleware which is not compatible with AdminJS. Please remove it.');
13
+ this.name = 'OldBodyParserUsedError';
14
+ }
15
+ }
@@ -0,0 +1,13 @@
1
+ import type { MiddlewareHandler } from 'hono';
2
+ import type { UploadOptions, HonoVariables } from './types.js';
3
+ /**
4
+ * Creates middleware to parse form data (multipart/form-data and application/x-www-form-urlencoded)
5
+ * Extracts fields and files from the request and stores them in context variables
6
+ *
7
+ * @param options - Upload configuration options
8
+ * @returns Hono middleware handler
9
+ */
10
+ export declare function createFormParserMiddleware(options?: UploadOptions): MiddlewareHandler<{
11
+ Variables: HonoVariables;
12
+ }>;
13
+ //# sourceMappingURL=formParser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formParser.d.ts","sourceRoot":"","sources":["../src/formParser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAW,MAAM,MAAM,CAAA;AACtD,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAE9D;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CACxC,OAAO,CAAC,EAAE,aAAa,GACtB,iBAAiB,CAAC;IAAE,SAAS,EAAE,aAAa,CAAA;CAAE,CAAC,CA4DjD"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Creates middleware to parse form data (multipart/form-data and application/x-www-form-urlencoded)
3
+ * Extracts fields and files from the request and stores them in context variables
4
+ *
5
+ * @param options - Upload configuration options
6
+ * @returns Hono middleware handler
7
+ */
8
+ export function createFormParserMiddleware(options) {
9
+ return async (c, next) => {
10
+ const contentType = c.req.header('content-type');
11
+ if (contentType?.includes('multipart/form-data') ||
12
+ contentType?.includes('application/x-www-form-urlencoded')) {
13
+ try {
14
+ const formData = await c.req.formData();
15
+ const fields = {};
16
+ const files = {};
17
+ for (const [key, value] of formData.entries()) {
18
+ if (value instanceof File) {
19
+ // Check file size if maxFileSize is specified
20
+ if (options?.maxFileSize && value.size > options.maxFileSize) {
21
+ throw new Error(`File ${value.name} exceeds maximum size of ${options.maxFileSize} bytes`);
22
+ }
23
+ files[key] = value;
24
+ }
25
+ else {
26
+ fields[key] = value;
27
+ }
28
+ }
29
+ // Check total fields size if maxFieldsSize is specified
30
+ if (options?.maxFieldsSize) {
31
+ const totalFieldsSize = Object.values(fields).reduce((sum, val) => sum + String(val).length, 0);
32
+ if (totalFieldsSize > options.maxFieldsSize) {
33
+ throw new Error(`Total fields size exceeds maximum of ${options.maxFieldsSize} bytes`);
34
+ }
35
+ }
36
+ // Check number of fields if maxFields is specified
37
+ if (options?.maxFields && Object.keys(fields).length > options.maxFields) {
38
+ throw new Error(`Number of fields exceeds maximum of ${options.maxFields}`);
39
+ }
40
+ c.set('fields', fields);
41
+ c.set('files', files);
42
+ }
43
+ catch (error) {
44
+ // Handle parsing errors gracefully
45
+ console.error('Form parsing error:', error);
46
+ c.set('fields', {});
47
+ c.set('files', {});
48
+ throw error;
49
+ }
50
+ }
51
+ await next();
52
+ };
53
+ }
package/lib/index.d.ts ADDED
@@ -0,0 +1,55 @@
1
+ import { buildAuthenticatedRouter } from './buildAuthenticatedRouter.js';
2
+ import { buildRouter } from './buildRouter.js';
3
+ /**
4
+ * @module @adminjs/hono
5
+ *
6
+ * AdminJS adapter for Hono web framework
7
+ *
8
+ * Provides two main functions:
9
+ * - buildRouter: Creates a Hono app with AdminJS routes (no authentication)
10
+ * - buildAuthenticatedRouter: Creates a Hono app with AdminJS routes protected by session authentication
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * import { Hono } from 'hono'
15
+ * import AdminJS from 'adminjs'
16
+ * import { buildRouter } from '@adminjs/hono'
17
+ *
18
+ * const admin = new AdminJS({
19
+ * databases: [],
20
+ * rootPath: '/admin',
21
+ * })
22
+ *
23
+ * const app = new Hono()
24
+ * const adminRouter = buildRouter(admin)
25
+ * app.route('/admin', adminRouter)
26
+ * ```
27
+ */
28
+ /**
29
+ * Plugin name
30
+ */
31
+ export declare const name = "AdminJSHono";
32
+ /**
33
+ * Plugin interface
34
+ */
35
+ export type HonoPlugin = {
36
+ name: string;
37
+ buildAuthenticatedRouter: typeof buildAuthenticatedRouter;
38
+ buildRouter: typeof buildRouter;
39
+ };
40
+ /**
41
+ * Default plugin export
42
+ */
43
+ declare const plugin: HonoPlugin;
44
+ export default plugin;
45
+ export { buildRouter } from './buildRouter.js';
46
+ export { buildAuthenticatedRouter } from './buildAuthenticatedRouter.js';
47
+ export type { AuthenticationOptions, UploadOptions, AuthenticationMaxRetriesOptions, AuthenticationContext, SessionOptions, SessionData, } from './types.js';
48
+ export { convertToHonoRoute } from './convertRoutes.js';
49
+ export * from './errors.js';
50
+ export { log } from './logger.js';
51
+ export { withLogin } from './authentication/login.handler.js';
52
+ export { withLogout } from './authentication/logout.handler.js';
53
+ export { withProtectedRoutesHandler } from './authentication/protected-routes.handler.js';
54
+ export { withRefresh } from './authentication/refresh.handler.js';
55
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAA;AACxE,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAE9C;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH;;GAEG;AACH,eAAO,MAAM,IAAI,gBAAgB,CAAA;AAEjC;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,EAAE,MAAM,CAAA;IACZ,wBAAwB,EAAE,OAAO,wBAAwB,CAAA;IACzD,WAAW,EAAE,OAAO,WAAW,CAAA;CAChC,CAAA;AAED;;GAEG;AACH,QAAA,MAAM,MAAM,EAAE,UAA4D,CAAA;AAE1E,eAAe,MAAM,CAAA;AAGrB,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAA;AAGxE,YAAY,EACV,qBAAqB,EACrB,aAAa,EACb,+BAA+B,EAC/B,qBAAqB,EACrB,cAAc,EACd,WAAW,GACZ,MAAM,YAAY,CAAA;AAGnB,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AACvD,cAAc,aAAa,CAAA;AAC3B,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAA;AAGjC,OAAO,EAAE,SAAS,EAAE,MAAM,mCAAmC,CAAA;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,oCAAoC,CAAA;AAC/D,OAAO,EAAE,0BAA0B,EAAE,MAAM,8CAA8C,CAAA;AACzF,OAAO,EAAE,WAAW,EAAE,MAAM,qCAAqC,CAAA"}
package/lib/index.js ADDED
@@ -0,0 +1,48 @@
1
+ import { buildAuthenticatedRouter } from './buildAuthenticatedRouter.js';
2
+ import { buildRouter } from './buildRouter.js';
3
+ /**
4
+ * @module @adminjs/hono
5
+ *
6
+ * AdminJS adapter for Hono web framework
7
+ *
8
+ * Provides two main functions:
9
+ * - buildRouter: Creates a Hono app with AdminJS routes (no authentication)
10
+ * - buildAuthenticatedRouter: Creates a Hono app with AdminJS routes protected by session authentication
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * import { Hono } from 'hono'
15
+ * import AdminJS from 'adminjs'
16
+ * import { buildRouter } from '@adminjs/hono'
17
+ *
18
+ * const admin = new AdminJS({
19
+ * databases: [],
20
+ * rootPath: '/admin',
21
+ * })
22
+ *
23
+ * const app = new Hono()
24
+ * const adminRouter = buildRouter(admin)
25
+ * app.route('/admin', adminRouter)
26
+ * ```
27
+ */
28
+ /**
29
+ * Plugin name
30
+ */
31
+ export const name = 'AdminJSHono';
32
+ /**
33
+ * Default plugin export
34
+ */
35
+ const plugin = { name, buildAuthenticatedRouter, buildRouter };
36
+ export default plugin;
37
+ // Export main functions
38
+ export { buildRouter } from './buildRouter.js';
39
+ export { buildAuthenticatedRouter } from './buildAuthenticatedRouter.js';
40
+ // Export utilities
41
+ export { convertToHonoRoute } from './convertRoutes.js';
42
+ export * from './errors.js';
43
+ export { log } from './logger.js';
44
+ // Export authentication handlers (for advanced usage)
45
+ export { withLogin } from './authentication/login.handler.js';
46
+ export { withLogout } from './authentication/logout.handler.js';
47
+ export { withProtectedRoutesHandler } from './authentication/protected-routes.handler.js';
48
+ export { withRefresh } from './authentication/refresh.handler.js';
@@ -0,0 +1,7 @@
1
+ export declare const log: {
2
+ debug: (...args: unknown[]) => void;
3
+ info: (...args: unknown[]) => void;
4
+ warn: (...args: unknown[]) => void;
5
+ error: (...args: unknown[]) => void;
6
+ };
7
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,GAAG;qBACG,OAAO,EAAE;oBAKV,OAAO,EAAE;oBAGT,OAAO,EAAE;qBAGR,OAAO,EAAE;CAG3B,CAAA"}
package/lib/logger.js ADDED
@@ -0,0 +1,17 @@
1
+ const DEBUG = process.env.ADMINJS_HONO_DEBUG === 'true';
2
+ export const log = {
3
+ debug: (...args) => {
4
+ if (DEBUG) {
5
+ console.log('[AdminJS Hono]', ...args);
6
+ }
7
+ },
8
+ info: (...args) => {
9
+ console.log('[AdminJS Hono]', ...args);
10
+ },
11
+ warn: (...args) => {
12
+ console.warn('[AdminJS Hono]', ...args);
13
+ },
14
+ error: (...args) => {
15
+ console.error('[AdminJS Hono]', ...args);
16
+ },
17
+ };
@@ -0,0 +1,25 @@
1
+ import type { MiddlewareHandler } from 'hono';
2
+ import type { SessionData, SessionOptions, HonoVariables } from './types.js';
3
+ /**
4
+ * Creates session middleware for Hono
5
+ * Manages cookie-based sessions with in-memory storage
6
+ *
7
+ * @param secret - Secret key for session (currently unused, for future HMAC signing)
8
+ * @param cookieName - Name of the session cookie
9
+ * @param options - Session cookie options
10
+ * @returns Hono middleware handler
11
+ */
12
+ export declare function createSessionMiddleware(secret: string, cookieName: string, options?: SessionOptions): MiddlewareHandler<{
13
+ Variables: HonoVariables;
14
+ }>;
15
+ /**
16
+ * Destroys a session by removing it from the store
17
+ * @param sessionId - The session ID to destroy
18
+ */
19
+ export declare function destroySession(sessionId: string): void;
20
+ /**
21
+ * Gets the session store (for testing purposes)
22
+ * @returns The session store Map
23
+ */
24
+ export declare function getSessionStore(): Map<string, SessionData>;
25
+ //# sourceMappingURL=session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAW,MAAM,MAAM,CAAA;AACtD,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAa5E;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,cAAc,GACvB,iBAAiB,CAAC;IAAE,SAAS,EAAE,aAAa,CAAA;CAAE,CAAC,CA0BjD;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAEtD;AAED;;;GAGG;AACH,wBAAgB,eAAe,IAAI,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAE1D"}