s3db.js 13.5.1 → 13.6.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 (108) hide show
  1. package/README.md +89 -19
  2. package/dist/{s3db.cjs.js → s3db.cjs} +29780 -24384
  3. package/dist/s3db.cjs.map +1 -0
  4. package/dist/s3db.es.js +24263 -18860
  5. package/dist/s3db.es.js.map +1 -1
  6. package/package.json +227 -21
  7. package/src/concerns/id.js +90 -6
  8. package/src/concerns/index.js +2 -1
  9. package/src/concerns/password-hashing.js +150 -0
  10. package/src/database.class.js +4 -0
  11. package/src/plugins/api/auth/basic-auth.js +23 -1
  12. package/src/plugins/api/auth/index.js +49 -3
  13. package/src/plugins/api/auth/oauth2-auth.js +171 -0
  14. package/src/plugins/api/auth/oidc-auth.js +789 -0
  15. package/src/plugins/api/auth/oidc-client.js +462 -0
  16. package/src/plugins/api/auth/path-auth-matcher.js +284 -0
  17. package/src/plugins/api/concerns/event-emitter.js +134 -0
  18. package/src/plugins/api/concerns/failban-manager.js +651 -0
  19. package/src/plugins/api/concerns/guards-helpers.js +402 -0
  20. package/src/plugins/api/concerns/metrics-collector.js +346 -0
  21. package/src/plugins/api/concerns/opengraph-helper.js +116 -0
  22. package/src/plugins/api/concerns/state-machine.js +288 -0
  23. package/src/plugins/api/index.js +514 -54
  24. package/src/plugins/api/middlewares/failban.js +305 -0
  25. package/src/plugins/api/middlewares/rate-limit.js +301 -0
  26. package/src/plugins/api/middlewares/request-id.js +74 -0
  27. package/src/plugins/api/middlewares/security-headers.js +120 -0
  28. package/src/plugins/api/middlewares/session-tracking.js +194 -0
  29. package/src/plugins/api/routes/auth-routes.js +23 -3
  30. package/src/plugins/api/routes/resource-routes.js +71 -29
  31. package/src/plugins/api/server.js +1017 -94
  32. package/src/plugins/api/utils/guards.js +213 -0
  33. package/src/plugins/api/utils/mime-types.js +154 -0
  34. package/src/plugins/api/utils/openapi-generator.js +44 -11
  35. package/src/plugins/api/utils/path-matcher.js +173 -0
  36. package/src/plugins/api/utils/static-filesystem.js +262 -0
  37. package/src/plugins/api/utils/static-s3.js +231 -0
  38. package/src/plugins/api/utils/template-engine.js +262 -0
  39. package/src/plugins/cloud-inventory/drivers/alibaba-driver.js +853 -0
  40. package/src/plugins/cloud-inventory/drivers/aws-driver.js +2554 -0
  41. package/src/plugins/cloud-inventory/drivers/azure-driver.js +637 -0
  42. package/src/plugins/cloud-inventory/drivers/base-driver.js +99 -0
  43. package/src/plugins/cloud-inventory/drivers/cloudflare-driver.js +620 -0
  44. package/src/plugins/cloud-inventory/drivers/digitalocean-driver.js +698 -0
  45. package/src/plugins/cloud-inventory/drivers/gcp-driver.js +645 -0
  46. package/src/plugins/cloud-inventory/drivers/hetzner-driver.js +559 -0
  47. package/src/plugins/cloud-inventory/drivers/linode-driver.js +614 -0
  48. package/src/plugins/cloud-inventory/drivers/mock-drivers.js +449 -0
  49. package/src/plugins/cloud-inventory/drivers/mongodb-atlas-driver.js +771 -0
  50. package/src/plugins/cloud-inventory/drivers/oracle-driver.js +768 -0
  51. package/src/plugins/cloud-inventory/drivers/vultr-driver.js +636 -0
  52. package/src/plugins/cloud-inventory/index.js +20 -0
  53. package/src/plugins/cloud-inventory/registry.js +146 -0
  54. package/src/plugins/cloud-inventory/terraform-exporter.js +362 -0
  55. package/src/plugins/cloud-inventory.plugin.js +1333 -0
  56. package/src/plugins/concerns/plugin-dependencies.js +61 -1
  57. package/src/plugins/eventual-consistency/analytics.js +1 -0
  58. package/src/plugins/identity/README.md +335 -0
  59. package/src/plugins/identity/concerns/mfa-manager.js +204 -0
  60. package/src/plugins/identity/concerns/password.js +138 -0
  61. package/src/plugins/identity/concerns/resource-schemas.js +273 -0
  62. package/src/plugins/identity/concerns/token-generator.js +172 -0
  63. package/src/plugins/identity/email-service.js +422 -0
  64. package/src/plugins/identity/index.js +1052 -0
  65. package/src/plugins/identity/oauth2-server.js +1033 -0
  66. package/src/plugins/identity/oidc-discovery.js +285 -0
  67. package/src/plugins/identity/rsa-keys.js +323 -0
  68. package/src/plugins/identity/server.js +500 -0
  69. package/src/plugins/identity/session-manager.js +453 -0
  70. package/src/plugins/identity/ui/layouts/base.js +251 -0
  71. package/src/plugins/identity/ui/middleware.js +135 -0
  72. package/src/plugins/identity/ui/pages/admin/client-form.js +247 -0
  73. package/src/plugins/identity/ui/pages/admin/clients.js +179 -0
  74. package/src/plugins/identity/ui/pages/admin/dashboard.js +181 -0
  75. package/src/plugins/identity/ui/pages/admin/user-form.js +283 -0
  76. package/src/plugins/identity/ui/pages/admin/users.js +263 -0
  77. package/src/plugins/identity/ui/pages/consent.js +262 -0
  78. package/src/plugins/identity/ui/pages/forgot-password.js +104 -0
  79. package/src/plugins/identity/ui/pages/login.js +144 -0
  80. package/src/plugins/identity/ui/pages/mfa-backup-codes.js +180 -0
  81. package/src/plugins/identity/ui/pages/mfa-enrollment.js +187 -0
  82. package/src/plugins/identity/ui/pages/mfa-verification.js +178 -0
  83. package/src/plugins/identity/ui/pages/oauth-error.js +225 -0
  84. package/src/plugins/identity/ui/pages/profile.js +361 -0
  85. package/src/plugins/identity/ui/pages/register.js +226 -0
  86. package/src/plugins/identity/ui/pages/reset-password.js +128 -0
  87. package/src/plugins/identity/ui/pages/verify-email.js +172 -0
  88. package/src/plugins/identity/ui/routes.js +2541 -0
  89. package/src/plugins/identity/ui/styles/main.css +465 -0
  90. package/src/plugins/index.js +4 -1
  91. package/src/plugins/ml/base-model.class.js +32 -7
  92. package/src/plugins/ml/classification-model.class.js +1 -1
  93. package/src/plugins/ml/timeseries-model.class.js +3 -1
  94. package/src/plugins/ml.plugin.js +124 -32
  95. package/src/plugins/shared/error-handler.js +147 -0
  96. package/src/plugins/shared/index.js +9 -0
  97. package/src/plugins/shared/middlewares/compression.js +117 -0
  98. package/src/plugins/shared/middlewares/cors.js +49 -0
  99. package/src/plugins/shared/middlewares/index.js +11 -0
  100. package/src/plugins/shared/middlewares/logging.js +54 -0
  101. package/src/plugins/shared/middlewares/rate-limit.js +73 -0
  102. package/src/plugins/shared/middlewares/security.js +158 -0
  103. package/src/plugins/shared/response-formatter.js +264 -0
  104. package/src/plugins/tfstate/README.md +126 -126
  105. package/src/resource.class.js +140 -12
  106. package/src/schema.class.js +30 -1
  107. package/src/validator.class.js +57 -6
  108. package/dist/s3db.cjs.js.map +0 -1
@@ -0,0 +1,262 @@
1
+ /**
2
+ * Template Engine Support for API Plugin
3
+ *
4
+ * Provides c.render() helper that works with multiple template engines:
5
+ * - EJS (for mrt-shortner compatibility)
6
+ * - Pug (formerly Jade)
7
+ * - JSX (Hono native)
8
+ * - Custom engines via setRenderer()
9
+ *
10
+ * @example
11
+ * // EJS usage
12
+ * app.use('*', setupTemplateEngine({
13
+ * engine: 'ejs',
14
+ * templatesDir: './views',
15
+ * layout: 'layouts/main'
16
+ * }));
17
+ *
18
+ * app.get('/page', async (c) => {
19
+ * return c.render('landing', { urlCount: 1000 });
20
+ * });
21
+ *
22
+ * @example
23
+ * // Pug usage
24
+ * app.use('*', setupTemplateEngine({
25
+ * engine: 'pug',
26
+ * templatesDir: './views'
27
+ * }));
28
+ *
29
+ * app.get('/page', async (c) => {
30
+ * return c.render('landing', { urlCount: 1000 });
31
+ * });
32
+ *
33
+ * @example
34
+ * // JSX usage (no setup needed)
35
+ * app.get('/page', (c) => {
36
+ * return c.render(<h1>Hello</h1>);
37
+ * });
38
+ */
39
+
40
+ import { readFile } from 'fs/promises';
41
+ import { join, resolve } from 'path';
42
+ import { existsSync } from 'fs';
43
+
44
+ /**
45
+ * Lazy-load EJS (peer dependency)
46
+ * @returns {Promise<Object>} EJS module
47
+ */
48
+ async function loadEJS() {
49
+ try {
50
+ const ejs = await import('ejs');
51
+ return ejs.default || ejs;
52
+ } catch (err) {
53
+ throw new Error(
54
+ 'EJS template engine not installed. Install with: npm install ejs\n' +
55
+ 'EJS is a peer dependency to keep the core package lightweight.'
56
+ );
57
+ }
58
+ }
59
+
60
+ /**
61
+ * Lazy-load Pug (peer dependency)
62
+ * @returns {Promise<Object>} Pug module
63
+ */
64
+ async function loadPug() {
65
+ try {
66
+ const pug = await import('pug');
67
+ return pug.default || pug;
68
+ } catch (err) {
69
+ throw new Error(
70
+ 'Pug template engine not installed. Install with: npm install pug\n' +
71
+ 'Pug is a peer dependency to keep the core package lightweight.'
72
+ );
73
+ }
74
+ }
75
+
76
+ /**
77
+ * Setup template engine middleware
78
+ * @param {Object} options - Template engine options
79
+ * @param {string} options.engine - Engine name: 'ejs', 'pug', 'jsx', 'custom'
80
+ * @param {string} options.templatesDir - Directory containing templates (required for EJS/Pug)
81
+ * @param {string} options.layout - Default layout template (optional for EJS)
82
+ * @param {Object} options.engineOptions - Additional engine-specific options
83
+ * @param {Function} options.customRenderer - Custom render function (for 'custom' engine)
84
+ * @returns {Function} Hono middleware
85
+ */
86
+ export function setupTemplateEngine(options = {}) {
87
+ const {
88
+ engine = 'jsx',
89
+ templatesDir = './views',
90
+ layout = null,
91
+ engineOptions = {},
92
+ customRenderer = null
93
+ } = options;
94
+
95
+ // Resolve templates directory
96
+ const templatesPath = resolve(templatesDir);
97
+
98
+ return async (c, next) => {
99
+ /**
100
+ * Render template with data
101
+ * @param {string|JSX.Element} template - Template name (for EJS/Pug) or JSX element
102
+ * @param {Object} data - Data to pass to template
103
+ * @param {Object} renderOptions - Render-specific options
104
+ * @returns {Response} HTML response
105
+ */
106
+ c.render = async (template, data = {}, renderOptions = {}) => {
107
+ // JSX: Direct rendering (Hono native)
108
+ if (typeof template === 'object' && template !== null) {
109
+ // Assume it's a JSX element
110
+ return c.html(template);
111
+ }
112
+
113
+ // Pug: File-based rendering
114
+ if (engine === 'pug') {
115
+ // Lazy-load Pug
116
+ const pug = await loadPug();
117
+
118
+ const templateFile = template.endsWith('.pug') ? template : `${template}.pug`;
119
+ const templatePath = join(templatesPath, templateFile);
120
+
121
+ if (!existsSync(templatePath)) {
122
+ throw new Error(`Template not found: ${templatePath}`);
123
+ }
124
+
125
+ // Merge global data + render data
126
+ const renderData = {
127
+ ...data,
128
+ // Add helpers that Pug templates might expect
129
+ _url: c.req.url,
130
+ _path: c.req.path,
131
+ _method: c.req.method
132
+ };
133
+
134
+ // Render template
135
+ const html = pug.renderFile(templatePath, {
136
+ ...renderData,
137
+ ...engineOptions,
138
+ ...renderOptions
139
+ });
140
+
141
+ return c.html(html);
142
+ }
143
+
144
+ // EJS: File-based rendering
145
+ if (engine === 'ejs') {
146
+ // Lazy-load EJS
147
+ const ejs = await loadEJS();
148
+
149
+ const templateFile = template.endsWith('.ejs') ? template : `${template}.ejs`;
150
+ const templatePath = join(templatesPath, templateFile);
151
+
152
+ if (!existsSync(templatePath)) {
153
+ throw new Error(`Template not found: ${templatePath}`);
154
+ }
155
+
156
+ // Read and render template
157
+ const templateContent = await readFile(templatePath, 'utf-8');
158
+
159
+ // Merge global data + render data
160
+ const renderData = {
161
+ ...data,
162
+ // Add helpers that EJS templates might expect
163
+ _url: c.req.url,
164
+ _path: c.req.path,
165
+ _method: c.req.method
166
+ };
167
+
168
+ // Render template
169
+ const html = ejs.render(templateContent, renderData, {
170
+ filename: templatePath, // For includes to work
171
+ ...engineOptions,
172
+ ...renderOptions
173
+ });
174
+
175
+ // If layout specified, wrap in layout
176
+ if (layout || renderOptions.layout) {
177
+ const layoutName = renderOptions.layout || layout;
178
+ const layoutFile = layoutName.endsWith('.ejs') ? layoutName : `${layoutName}.ejs`;
179
+ const layoutPath = join(templatesPath, layoutFile);
180
+
181
+ if (!existsSync(layoutPath)) {
182
+ throw new Error(`Layout not found: ${layoutPath}`);
183
+ }
184
+
185
+ const layoutContent = await readFile(layoutPath, 'utf-8');
186
+ const wrappedHtml = ejs.render(layoutContent, {
187
+ ...renderData,
188
+ body: html // Content goes into <%- body %>
189
+ }, {
190
+ filename: layoutPath,
191
+ ...engineOptions
192
+ });
193
+
194
+ return c.html(wrappedHtml);
195
+ }
196
+
197
+ return c.html(html);
198
+ }
199
+
200
+ // Custom: User-provided renderer
201
+ if (engine === 'custom' && customRenderer) {
202
+ return customRenderer(c, template, data, renderOptions);
203
+ }
204
+
205
+ throw new Error(`Unsupported template engine: ${engine}`);
206
+ };
207
+
208
+ await next();
209
+ };
210
+ }
211
+
212
+ /**
213
+ * Create EJS template engine middleware (convenience wrapper)
214
+ * @param {string} templatesDir - Directory containing templates
215
+ * @param {Object} options - Additional options
216
+ * @returns {Function} Hono middleware
217
+ */
218
+ export function ejsEngine(templatesDir, options = {}) {
219
+ return setupTemplateEngine({
220
+ engine: 'ejs',
221
+ templatesDir,
222
+ ...options
223
+ });
224
+ }
225
+
226
+ /**
227
+ * Create Pug template engine middleware (convenience wrapper)
228
+ * @param {string} templatesDir - Directory containing templates
229
+ * @param {Object} options - Additional options
230
+ * @returns {Function} Hono middleware
231
+ */
232
+ export function pugEngine(templatesDir, options = {}) {
233
+ return setupTemplateEngine({
234
+ engine: 'pug',
235
+ templatesDir,
236
+ ...options
237
+ });
238
+ }
239
+
240
+ /**
241
+ * Create JSX template engine middleware (convenience wrapper)
242
+ * Note: JSX rendering is built into Hono, this just provides c.render()
243
+ * @returns {Function} Hono middleware
244
+ */
245
+ export function jsxEngine() {
246
+ return async (c, next) => {
247
+ c.render = (template, data = {}) => {
248
+ if (typeof template === 'object' && template !== null) {
249
+ return c.html(template);
250
+ }
251
+ throw new Error('JSX engine requires JSX element, not string template name');
252
+ };
253
+ await next();
254
+ };
255
+ }
256
+
257
+ export default {
258
+ setupTemplateEngine,
259
+ ejsEngine,
260
+ pugEngine,
261
+ jsxEngine
262
+ };