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