json-rest-api 1.0.0 → 1.0.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.
Files changed (67) hide show
  1. package/.claude/settings.local.json +16 -0
  2. package/LICENSE +674 -0
  3. package/README.md +655 -309
  4. package/RELATIONSHIPS.md +1013 -0
  5. package/TODO_rest-api-plugin-extras.js +142 -0
  6. package/connectors_ideas/express-plugin.js +120 -0
  7. package/connectors_ideas/fastify.js +219 -0
  8. package/connectors_ideas/http-plugin.js +138 -0
  9. package/connectors_ideas/koa-plugin.js +113 -0
  10. package/docs/fileUploads.md +722 -0
  11. package/docs/mini-guides/file-uploads-complete.md +159 -0
  12. package/examples/.gitkeep +0 -0
  13. package/examples/express-example.js +262 -0
  14. package/examples/express-plugin.js +366 -0
  15. package/examples/file-upload-example.js +205 -0
  16. package/examples/filename-strategies.js +140 -0
  17. package/examples/knex-basic.js +66 -0
  18. package/index.js +31 -56
  19. package/lib/payload-validators.js +685 -0
  20. package/lib/rest-api-errors.js +58 -0
  21. package/package.json +41 -14
  22. package/payloadValdators.js +686 -0
  23. package/plugins/core/connectors/express-plugin.js +449 -0
  24. package/plugins/core/connectors/http-plugin.js +450 -0
  25. package/plugins/core/file-handling-plugin.js +338 -0
  26. package/plugins/core/lib/busboy-detector.js +167 -0
  27. package/plugins/core/lib/formidable-detector.js +130 -0
  28. package/plugins/core/rest-api-knex-plugin.js +200 -0
  29. package/plugins/core/rest-api-plugin.js +1419 -0
  30. package/plugins/storage/local-storage.js +218 -0
  31. package/plugins/storage/s3-storage.js +125 -0
  32. package/test-examples/package-lock.json +906 -0
  33. package/test-examples/package.json +15 -0
  34. package/test-examples/test-basic-api.js +11 -0
  35. package/test-examples/test-books-resource.js +116 -0
  36. package/test-examples/test-complete-file-upload.js +140 -0
  37. package/test-examples/test-debug.js +28 -0
  38. package/test-examples/test-express-plugin.js +177 -0
  39. package/test-examples/test-express-simple.js +28 -0
  40. package/test-examples/test-express-with-import.js +71 -0
  41. package/test-examples/test-file-upload.js +132 -0
  42. package/test-examples/test-http-plugin.js +159 -0
  43. package/test-examples/test-programmatic-api.js +188 -0
  44. package/test-examples/test-rest-api-plugin.js +13 -0
  45. package/TODO.todo +0 -113
  46. package/api.js +0 -628
  47. package/docs/API.md +0 -1306
  48. package/docs/FIXES_APPLIED.md +0 -59
  49. package/docs/GUIDES.md +0 -1792
  50. package/docs/RESOURCES_IN_EXPRESS.md +0 -456
  51. package/docs/example-versioning.js +0 -168
  52. package/docs/example.js +0 -195
  53. package/plugins/API guide.md +0 -364
  54. package/plugins/api-registry.js +0 -142
  55. package/plugins/api-versioning.md +0 -135
  56. package/plugins/http.js +0 -273
  57. package/plugins/logging.js +0 -255
  58. package/plugins/memory.js +0 -182
  59. package/plugins/mysql.js +0 -753
  60. package/plugins/openapi.js +0 -401
  61. package/plugins/positioning.js +0 -220
  62. package/plugins/security.js +0 -261
  63. package/plugins/validation.js +0 -173
  64. package/plugins/versioning.js +0 -288
  65. package/resource-helper.js +0 -79
  66. package/schema.js +0 -481
  67. package/test-basic.js +0 -107
@@ -0,0 +1,113 @@
1
+ /**
2
+ * http-plugin-koa.js
3
+ * This plugin for Hooked API provides a lightweight HTTP layer using the Koa.js framework.
4
+ * It automatically generates JSON:API compliant RESTful routes for each scope using `koa-router`.
5
+ *
6
+ * It assumes you have `koa-bodyparser` installed and used before this plugin.
7
+ * You'll need to install dependencies: npm install koa koa-router koa-bodyparser qs
8
+ */
9
+ import KoaRouter from 'koa-router';
10
+ import qs from 'qs'; // The same query string parser Express uses
11
+ import { HookedApiError } from './hooked-api.js';
12
+ import { handleKoaApiError } from './error-handler-koa.js';
13
+
14
+ export const HttpKoaPlugin = {
15
+ name: 'http-koa',
16
+
17
+ install(context, api) {
18
+ const { pluginOptions, log } = context;
19
+ const httpOptions = pluginOptions.http || {};
20
+ const { app, prefix = '/api' } = httpOptions;
21
+
22
+ if (!app) {
23
+ throw new HookedApiError(
24
+ "The 'http-koa' plugin requires a Koa 'app' instance to be passed in the options. Example: api.use(HttpKoaPlugin, { http: { app: myKoaApp } })",
25
+ 'CONFIGURATION_ERROR'
26
+ );
27
+ }
28
+
29
+ // Create a router instance for our API routes
30
+ const router = new KoaRouter({ prefix });
31
+
32
+ /**
33
+ * Creates a generic Koa middleware for a specific API method.
34
+ * @param {string} methodName - The name of the scope method to call (e.g., 'get', 'query').
35
+ * @returns {Function} An async Koa middleware function.
36
+ */
37
+ const _createKoaHandler = (methodName) => {
38
+ return async (ctx) => {
39
+ const { scopeName, id } = ctx.params;
40
+
41
+ try {
42
+ // 1. Translate Koa ctx into API method params
43
+ const apiParams = {};
44
+
45
+ if (['get', 'put', 'patch', 'delete'].includes(methodName)) {
46
+ apiParams.id = id;
47
+ }
48
+ if (['post', 'put', 'patch'].includes(methodName)) {
49
+ // Assumes koa-bodyparser is used
50
+ apiParams.inputRecord = ctx.request.body;
51
+ }
52
+ // Use qs to properly parse nested query objects
53
+ apiParams.queryParams = ctx.querystring ? qs.parse(ctx.querystring) : {};
54
+
55
+ log.debug(`Koa request for ${scopeName}.${methodName}`, { id, query: apiParams.queryParams });
56
+
57
+ // 2. Execute the corresponding API method
58
+ const result = await api.scopes[scopeName][methodName](apiParams);
59
+
60
+ // 3. Set the successful Koa response
61
+ switch (methodName) {
62
+ case 'post':
63
+ ctx.status = 201;
64
+ ctx.body = result;
65
+ break;
66
+ case 'delete':
67
+ ctx.status = 204;
68
+ // No body for 204
69
+ break;
70
+ default:
71
+ ctx.status = 200;
72
+ ctx.body = result;
73
+ }
74
+
75
+ } catch (error) {
76
+ // 4. Handle any errors thrown by the API
77
+ handleKoaApiError(error, ctx, log);
78
+ }
79
+ };
80
+ };
81
+
82
+ /**
83
+ * Creates all the standard RESTful routes for a given scope on the router.
84
+ * @param {string} scopeName - The name of the scope to create routes for.
85
+ */
86
+ const _createRoutesForScope = (scopeName) => {
87
+ const collectionPath = `/${scopeName}`;
88
+ const resourcePath = `${collectionPath}/:id`;
89
+
90
+ log.info(`Creating Koa HTTP routes for scope: '${scopeName}'`);
91
+
92
+ router.get(collectionPath, _createKoaHandler('query'));
93
+ router.get(resourcePath, _createKoaHandler('get'));
94
+ router.post(collectionPath, _createKoaHandler('post'));
95
+ router.put(resourcePath, _createKoaHandler('put'));
96
+ router.patch(resourcePath, _createKoaHandler('patch'));
97
+ router.del(resourcePath, _createKoaHandler('delete')); // .del is koa-router's alias for delete
98
+ };
99
+
100
+ // --- Main Logic: Wrap `addScope` to automate route creation ---
101
+ const originalAddScope = api.addScope;
102
+
103
+ api.addScope = (name, options, extras) => {
104
+ const result = originalAddScope.call(api, name, options, extras);
105
+ _createRoutesForScope(name);
106
+ return result;
107
+ };
108
+
109
+ // Apply the router middleware to the Koa app
110
+ app.use(router.routes()).use(router.allowedMethods());
111
+ log.info(`Koa router installed with prefix '${prefix}'.`);
112
+ }
113
+ };