@rx-ted/packages-honest-plugins 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.
- package/CHANGELOG.md +13 -0
- package/README.md +45 -0
- package/api-doc/.turbo/turbo-build.log +1 -0
- package/api-doc/.turbo/turbo-test.log +11 -0
- package/api-doc/.turbo/turbo-typecheck.log +1 -0
- package/api-doc/CHANGELOG.md +22 -0
- package/api-doc/README.md +80 -0
- package/api-doc/dist/api-doc.plugin.d.ts +53 -0
- package/api-doc/dist/api-doc.plugin.js +452 -0
- package/api-doc/dist/index.d.ts +5 -0
- package/api-doc/dist/index.js +3 -0
- package/api-doc/dist/interfaces/renderer.interface.d.ts +7 -0
- package/api-doc/dist/interfaces/renderer.interface.js +1 -0
- package/api-doc/dist/renderers/scalar.renderer.d.ts +10 -0
- package/api-doc/dist/renderers/scalar.renderer.js +76 -0
- package/api-doc/dist/renderers/swagger.renderer.d.ts +10 -0
- package/api-doc/dist/renderers/swagger.renderer.js +83 -0
- package/api-doc/node_modules/.bin/esbuild +22 -0
- package/api-doc/node_modules/.bin/jiti +22 -0
- package/api-doc/node_modules/.bin/sass +22 -0
- package/api-doc/node_modules/.bin/tsx +22 -0
- package/api-doc/node_modules/.bin/vite +22 -0
- package/api-doc/node_modules/.bin/vitest +22 -0
- package/api-doc/node_modules/.bin/yaml +22 -0
- package/api-doc/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
- package/api-doc/package.json +48 -0
- package/api-doc/src/api-doc.plugin.ts +554 -0
- package/api-doc/src/index.ts +5 -0
- package/api-doc/src/interfaces/renderer.interface.ts +5 -0
- package/api-doc/src/plugin.test.ts +740 -0
- package/api-doc/src/renderers/scalar.renderer.ts +82 -0
- package/api-doc/src/renderers/swagger.renderer.ts +89 -0
- package/api-doc/tsconfig.json +21 -0
- package/api-doc/vitest.config.ts +13 -0
- package/cache/.turbo/turbo-build.log +1 -0
- package/cache/.turbo/turbo-test.log +16 -0
- package/cache/CHANGELOG.md +23 -0
- package/cache/README.md +79 -0
- package/cache/dist/cache-service.d.ts +8 -0
- package/cache/dist/cache-service.js +21 -0
- package/cache/dist/cacheable.d.ts +2 -0
- package/cache/dist/cacheable.js +10 -0
- package/cache/dist/cloudflare/driver.d.ts +23 -0
- package/cache/dist/cloudflare/driver.js +102 -0
- package/cache/dist/cloudflare/index.d.ts +3 -0
- package/cache/dist/cloudflare/index.js +2 -0
- package/cache/dist/cloudflare/plugin.d.ts +19 -0
- package/cache/dist/cloudflare/plugin.js +58 -0
- package/cache/dist/index.d.ts +11 -0
- package/cache/dist/index.js +14 -0
- package/cache/dist/local/driver.d.ts +2 -0
- package/cache/dist/local/driver.js +98 -0
- package/cache/dist/local/index.d.ts +2 -0
- package/cache/dist/local/index.js +2 -0
- package/cache/dist/local/plugin.d.ts +14 -0
- package/cache/dist/local/plugin.js +24 -0
- package/cache/dist/redis/driver.d.ts +10 -0
- package/cache/dist/redis/driver.js +102 -0
- package/cache/dist/redis/index.d.ts +4 -0
- package/cache/dist/redis/index.js +2 -0
- package/cache/dist/redis/plugin.d.ts +25 -0
- package/cache/dist/redis/plugin.js +61 -0
- package/cache/dist/resolve.d.ts +24 -0
- package/cache/dist/resolve.js +114 -0
- package/cache/dist/types.d.ts +18 -0
- package/cache/dist/types.js +1 -0
- package/cache/node_modules/.bin/esbuild +22 -0
- package/cache/node_modules/.bin/jiti +22 -0
- package/cache/node_modules/.bin/sass +22 -0
- package/cache/node_modules/.bin/tsx +22 -0
- package/cache/node_modules/.bin/vite +22 -0
- package/cache/node_modules/.bin/vitest +22 -0
- package/cache/node_modules/.bin/yaml +22 -0
- package/cache/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
- package/cache/package.json +46 -0
- package/cache/src/cache-service.test.ts +16 -0
- package/cache/src/cache-service.ts +15 -0
- package/cache/src/cacheable.test.ts +78 -0
- package/cache/src/cacheable.ts +16 -0
- package/cache/src/cloudflare/driver.test.ts +188 -0
- package/cache/src/cloudflare/driver.ts +118 -0
- package/cache/src/cloudflare/index.ts +3 -0
- package/cache/src/cloudflare/plugin.ts +71 -0
- package/cache/src/index.test.ts +68 -0
- package/cache/src/index.ts +20 -0
- package/cache/src/local/driver.ts +117 -0
- package/cache/src/local/index.ts +2 -0
- package/cache/src/local/plugin.ts +34 -0
- package/cache/src/redis/driver.test.ts +71 -0
- package/cache/src/redis/driver.ts +124 -0
- package/cache/src/redis/index.ts +4 -0
- package/cache/src/redis/plugin.ts +84 -0
- package/cache/src/resolve.test.ts +257 -0
- package/cache/src/resolve.ts +140 -0
- package/cache/src/types.ts +14 -0
- package/cache/tsconfig.json +21 -0
- package/cache/vitest.config.ts +13 -0
- package/db/.turbo/turbo-build.log +1 -0
- package/db/.turbo/turbo-test.log +21 -0
- package/db/CHANGELOG.md +26 -0
- package/db/README.md +99 -0
- package/db/dist/constants.d.ts +1 -0
- package/db/dist/constants.js +1 -0
- package/db/dist/d1/index.d.ts +3 -0
- package/db/dist/d1/index.js +2 -0
- package/db/dist/d1/plugin.d.ts +18 -0
- package/db/dist/d1/plugin.js +104 -0
- package/db/dist/db-service.d.ts +7 -0
- package/db/dist/db-service.js +21 -0
- package/db/dist/index.d.ts +15 -0
- package/db/dist/index.js +20 -0
- package/db/dist/mysql/client.d.ts +36 -0
- package/db/dist/mysql/client.js +84 -0
- package/db/dist/mysql/driver.d.ts +18 -0
- package/db/dist/mysql/driver.js +107 -0
- package/db/dist/mysql/index.d.ts +11 -0
- package/db/dist/mysql/index.js +11 -0
- package/db/dist/mysql/plugin.d.ts +51 -0
- package/db/dist/mysql/plugin.js +94 -0
- package/db/dist/mysql/types.d.ts +38 -0
- package/db/dist/mysql/types.js +1 -0
- package/db/dist/postgres/index.d.ts +2 -0
- package/db/dist/postgres/index.js +3 -0
- package/db/dist/repository.d.ts +14 -0
- package/db/dist/repository.js +79 -0
- package/db/dist/resolve.d.ts +6 -0
- package/db/dist/resolve.js +81 -0
- package/db/dist/schema-builder/column-builder.d.ts +26 -0
- package/db/dist/schema-builder/column-builder.js +53 -0
- package/db/dist/schema-builder/compile-d1.d.ts +5 -0
- package/db/dist/schema-builder/compile-d1.js +67 -0
- package/db/dist/schema-builder/compile-mysql.d.ts +12 -0
- package/db/dist/schema-builder/compile-mysql.js +78 -0
- package/db/dist/schema-builder/index.d.ts +8 -0
- package/db/dist/schema-builder/index.js +22 -0
- package/db/dist/schema-builder/table-builder.d.ts +16 -0
- package/db/dist/schema-builder/table-builder.js +38 -0
- package/db/dist/schema-builder/types.d.ts +26 -0
- package/db/dist/schema-builder/types.js +1 -0
- package/db/dist/schema-builder/zod-bridge.d.ts +24 -0
- package/db/dist/schema-builder/zod-bridge.js +53 -0
- package/db/dist/sqlite/index.d.ts +4 -0
- package/db/dist/sqlite/index.js +2 -0
- package/db/dist/sqlite/plugin.d.ts +17 -0
- package/db/dist/sqlite/plugin.js +33 -0
- package/db/dist/types.d.ts +42 -0
- package/db/dist/types.js +1 -0
- package/db/node_modules/.bin/esbuild +22 -0
- package/db/node_modules/.bin/jiti +22 -0
- package/db/node_modules/.bin/sass +22 -0
- package/db/node_modules/.bin/tsx +22 -0
- package/db/node_modules/.bin/vite +22 -0
- package/db/node_modules/.bin/vitest +22 -0
- package/db/node_modules/.bin/yaml +22 -0
- package/db/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
- package/db/package.json +59 -0
- package/db/src/constants.test.ts +8 -0
- package/db/src/constants.ts +1 -0
- package/db/src/d1/index.ts +13 -0
- package/db/src/d1/plugin.ts +135 -0
- package/db/src/db-service.ts +14 -0
- package/db/src/index.test.ts +63 -0
- package/db/src/index.ts +57 -0
- package/db/src/mysql/client.ts +112 -0
- package/db/src/mysql/driver.test.ts +190 -0
- package/db/src/mysql/driver.ts +116 -0
- package/db/src/mysql/index.ts +51 -0
- package/db/src/mysql/plugin.test.ts +228 -0
- package/db/src/mysql/plugin.ts +128 -0
- package/db/src/mysql/types.ts +32 -0
- package/db/src/postgres/index.ts +15 -0
- package/db/src/repository.test.ts +195 -0
- package/db/src/repository.ts +95 -0
- package/db/src/resolve.ts +105 -0
- package/db/src/schema-builder/column-builder.test.ts +55 -0
- package/db/src/schema-builder/column-builder.ts +87 -0
- package/db/src/schema-builder/compile-d1.test.ts +60 -0
- package/db/src/schema-builder/compile-d1.ts +70 -0
- package/db/src/schema-builder/compile-mysql.test.ts +64 -0
- package/db/src/schema-builder/compile-mysql.ts +102 -0
- package/db/src/schema-builder/index.test.ts +36 -0
- package/db/src/schema-builder/index.ts +41 -0
- package/db/src/schema-builder/table-builder.test.ts +55 -0
- package/db/src/schema-builder/table-builder.ts +50 -0
- package/db/src/schema-builder/types.test.ts +68 -0
- package/db/src/schema-builder/types.ts +30 -0
- package/db/src/schema-builder/zod-bridge.ts +89 -0
- package/db/src/sqlite/index.ts +14 -0
- package/db/src/sqlite/plugin.ts +46 -0
- package/db/src/types.ts +45 -0
- package/db/tsconfig.json +21 -0
- package/db/vitest.config.ts +13 -0
- package/mail/.turbo/turbo-build.log +1 -0
- package/mail/.turbo/turbo-test.log +12 -0
- package/mail/.turbo/turbo-typecheck.log +1 -0
- package/mail/CHANGELOG.md +25 -0
- package/mail/README.md +214 -0
- package/mail/dist/index.d.ts +4 -0
- package/mail/dist/index.js +2 -0
- package/mail/dist/plugin.d.ts +64 -0
- package/mail/dist/plugin.js +232 -0
- package/mail/dist/providers/brevo.provider.d.ts +15 -0
- package/mail/dist/providers/brevo.provider.js +75 -0
- package/mail/dist/providers/custom.provider.d.ts +9 -0
- package/mail/dist/providers/custom.provider.js +22 -0
- package/mail/dist/providers/resend.provider.d.ts +16 -0
- package/mail/dist/providers/resend.provider.js +77 -0
- package/mail/dist/providers/smtp.provider.d.ts +21 -0
- package/mail/dist/providers/smtp.provider.js +86 -0
- package/mail/dist/rate-limiter.d.ts +16 -0
- package/mail/dist/rate-limiter.js +49 -0
- package/mail/dist/types.d.ts +68 -0
- package/mail/dist/types.js +6 -0
- package/mail/node_modules/.bin/esbuild +22 -0
- package/mail/node_modules/.bin/jiti +22 -0
- package/mail/node_modules/.bin/sass +22 -0
- package/mail/node_modules/.bin/tsx +22 -0
- package/mail/node_modules/.bin/vite +22 -0
- package/mail/node_modules/.bin/vitest +22 -0
- package/mail/node_modules/.bin/yaml +22 -0
- package/mail/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
- package/mail/package.json +52 -0
- package/mail/src/index.ts +4 -0
- package/mail/src/plugin.test.ts +219 -0
- package/mail/src/plugin.ts +313 -0
- package/mail/src/providers/brevo.provider.ts +78 -0
- package/mail/src/providers/custom.provider.ts +29 -0
- package/mail/src/providers/resend.provider.ts +74 -0
- package/mail/src/providers/smtp.provider.ts +85 -0
- package/mail/src/rate-limiter.test.ts +81 -0
- package/mail/src/rate-limiter.ts +54 -0
- package/mail/src/types.ts +81 -0
- package/mail/tsconfig.json +21 -0
- package/mail/vitest.config.ts +13 -0
- package/package.json +36 -0
- package/s3/.turbo/turbo-build.log +1 -0
- package/s3/.turbo/turbo-test.log +11 -0
- package/s3/CHANGELOG.md +20 -0
- package/s3/README.md +90 -0
- package/s3/dist/index.d.ts +6 -0
- package/s3/dist/index.js +4 -0
- package/s3/dist/s3-service.d.ts +7 -0
- package/s3/dist/s3-service.js +21 -0
- package/s3/dist/s3.driver.d.ts +6 -0
- package/s3/dist/s3.driver.js +221 -0
- package/s3/dist/s3.plugin.d.ts +24 -0
- package/s3/dist/s3.plugin.js +58 -0
- package/s3/dist/types.d.ts +30 -0
- package/s3/dist/types.js +1 -0
- package/s3/node_modules/.bin/esbuild +22 -0
- package/s3/node_modules/.bin/jiti +22 -0
- package/s3/node_modules/.bin/sass +22 -0
- package/s3/node_modules/.bin/tsx +22 -0
- package/s3/node_modules/.bin/vite +22 -0
- package/s3/node_modules/.bin/vitest +22 -0
- package/s3/node_modules/.bin/yaml +22 -0
- package/s3/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
- package/s3/package.json +47 -0
- package/s3/src/index.test.ts +20 -0
- package/s3/src/index.ts +13 -0
- package/s3/src/s3-service.ts +14 -0
- package/s3/src/s3.driver.ts +259 -0
- package/s3/src/s3.plugin.ts +80 -0
- package/s3/src/types.ts +37 -0
- package/s3/tsconfig.json +21 -0
- package/s3/vitest.config.ts +13 -0
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import type { IDocRenderer } from '../interfaces/renderer.interface';
|
|
2
|
+
|
|
3
|
+
export class ScalarRenderer implements IDocRenderer {
|
|
4
|
+
readonly name = 'scalar';
|
|
5
|
+
|
|
6
|
+
renderHtml(config: { specUrl: string; uiTitle: string }): string {
|
|
7
|
+
const { specUrl, uiTitle } = config;
|
|
8
|
+
|
|
9
|
+
return `<!DOCTYPE html>
|
|
10
|
+
<html>
|
|
11
|
+
<head>
|
|
12
|
+
<meta charset="UTF-8">
|
|
13
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
14
|
+
<title>${this.escapeHtml(uiTitle)}</title>
|
|
15
|
+
<style>body { margin: 0; }</style>
|
|
16
|
+
</head>
|
|
17
|
+
<body>
|
|
18
|
+
<div id="app"></div>
|
|
19
|
+
<script src="https://cdn.jsdelivr.net/npm/@scalar/api-reference@1.52.6/dist/browser/standalone.min.js"></script>
|
|
20
|
+
<script>
|
|
21
|
+
(async function() {
|
|
22
|
+
const savedAuth = localStorage.getItem('scalar_auth');
|
|
23
|
+
let parsedAuth = {};
|
|
24
|
+
if (savedAuth) {
|
|
25
|
+
try {
|
|
26
|
+
parsedAuth = JSON.parse(savedAuth);
|
|
27
|
+
} catch(e) {
|
|
28
|
+
console.error('Failed to parse saved auth:', e);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
try {
|
|
33
|
+
const res = await fetch('${this.escapeJsString(specUrl)}');
|
|
34
|
+
const body = await res.json();
|
|
35
|
+
const spec = body && body.data ? body.data : body;
|
|
36
|
+
|
|
37
|
+
Scalar.createApiReference(document.getElementById('app'), {
|
|
38
|
+
spec: { content: spec },
|
|
39
|
+
authentication: {
|
|
40
|
+
preferredSecurityScheme: 'bearerAuth',
|
|
41
|
+
...parsedAuth
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
} catch(e) {
|
|
45
|
+
console.error('Failed to load API spec:', e);
|
|
46
|
+
document.getElementById('app').textContent = 'Failed to load API documentation: ' + e.message;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
try {
|
|
50
|
+
const app = document.getElementById('app');
|
|
51
|
+
if (app) {
|
|
52
|
+
app.addEventListener('scalar-authorization-change', function(event) {
|
|
53
|
+
const detail = event.detail;
|
|
54
|
+
if (detail && Object.keys(detail).length > 0) {
|
|
55
|
+
localStorage.setItem('scalar_auth', JSON.stringify(detail));
|
|
56
|
+
} else {
|
|
57
|
+
localStorage.removeItem('scalar_auth');
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
} catch(e) {
|
|
62
|
+
console.error('Failed to setup auth listener:', e);
|
|
63
|
+
}
|
|
64
|
+
})();
|
|
65
|
+
</script>
|
|
66
|
+
</body>
|
|
67
|
+
</html>`.trim();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
private escapeHtml(value: string): string {
|
|
71
|
+
return value
|
|
72
|
+
.replace(/&/g, '&')
|
|
73
|
+
.replace(/</g, '<')
|
|
74
|
+
.replace(/>/g, '>')
|
|
75
|
+
.replace(/"/g, '"')
|
|
76
|
+
.replace(/'/g, ''');
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
private escapeJsString(value: string): string {
|
|
80
|
+
return value.replace(/\\/g, '\\\\').replace(/'/g, "\\'");
|
|
81
|
+
}
|
|
82
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import type { IDocRenderer } from '../interfaces/renderer.interface';
|
|
2
|
+
|
|
3
|
+
export class SwaggerRenderer implements IDocRenderer {
|
|
4
|
+
readonly name = 'swagger';
|
|
5
|
+
|
|
6
|
+
renderHtml(config: { specUrl: string; uiTitle: string }): string {
|
|
7
|
+
const { specUrl, uiTitle } = config;
|
|
8
|
+
|
|
9
|
+
return `<!DOCTYPE html>
|
|
10
|
+
<html lang="en">
|
|
11
|
+
<head>
|
|
12
|
+
<meta charset="utf-8" />
|
|
13
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
14
|
+
<title>${this.escapeHtml(uiTitle)}</title>
|
|
15
|
+
<link rel="stylesheet" href="https://unpkg.com/swagger-ui-dist@5/swagger-ui.css" />
|
|
16
|
+
</head>
|
|
17
|
+
<body>
|
|
18
|
+
<div id="swagger-ui"></div>
|
|
19
|
+
<script src="https://unpkg.com/swagger-ui-dist@5/swagger-ui-bundle.js"></script>
|
|
20
|
+
<script>
|
|
21
|
+
const savedAuth = localStorage.getItem('swagger_auth');
|
|
22
|
+
let authorizations = [];
|
|
23
|
+
if (savedAuth) {
|
|
24
|
+
try {
|
|
25
|
+
authorizations = JSON.parse(savedAuth);
|
|
26
|
+
} catch (e) {
|
|
27
|
+
console.error('Failed to parse saved auth:', e);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
window.onload = function () {
|
|
32
|
+
window.ui = SwaggerUIBundle({
|
|
33
|
+
url: "${this.escapeJsString(specUrl)}",
|
|
34
|
+
dom_id: '#swagger-ui',
|
|
35
|
+
responseInterceptor: function(res) {
|
|
36
|
+
if (res.obj && res.obj.data) {
|
|
37
|
+
res.obj = res.obj.data;
|
|
38
|
+
}
|
|
39
|
+
return res;
|
|
40
|
+
},
|
|
41
|
+
onComplete: function() {
|
|
42
|
+
if (authorizations.length > 0) {
|
|
43
|
+
authorizations.forEach(auth => {
|
|
44
|
+
window.ui.preauthorizeApiKey(auth.name, auth.value);
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const originalAuthorize = window.ui.authorize;
|
|
49
|
+
window.ui.authorize = function() {
|
|
50
|
+
const result = originalAuthorize.apply(this, arguments);
|
|
51
|
+
const currentAuth = [];
|
|
52
|
+
const securityDefinitions = window.ui.spec().securityDefinitions || {};
|
|
53
|
+
Object.keys(securityDefinitions).forEach(name => {
|
|
54
|
+
const auth = window.ui.auth().data[name];
|
|
55
|
+
if (auth) {
|
|
56
|
+
currentAuth.push({ name, value: auth });
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
localStorage.setItem('swagger_auth', JSON.stringify(currentAuth));
|
|
60
|
+
return result;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const originalLogout = window.ui.logout;
|
|
64
|
+
window.ui.logout = function() {
|
|
65
|
+
const result = originalLogout.apply(this, arguments);
|
|
66
|
+
localStorage.removeItem('swagger_auth');
|
|
67
|
+
return result;
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
};
|
|
72
|
+
</script>
|
|
73
|
+
</body>
|
|
74
|
+
</html>`.trim();
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
private escapeHtml(value: string): string {
|
|
78
|
+
return value
|
|
79
|
+
.replace(/&/g, '&')
|
|
80
|
+
.replace(/</g, '<')
|
|
81
|
+
.replace(/>/g, '>')
|
|
82
|
+
.replace(/"/g, '"')
|
|
83
|
+
.replace(/'/g, ''');
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
private escapeJsString(value: string): string {
|
|
87
|
+
return value.replace(/\\/g, '\\\\').replace(/'/g, "\\'");
|
|
88
|
+
}
|
|
89
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "es2022",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "bundler",
|
|
6
|
+
"strict": true,
|
|
7
|
+
"declaration": true,
|
|
8
|
+
"sourceMap": false,
|
|
9
|
+
"experimentalDecorators": true,
|
|
10
|
+
"emitDecoratorMetadata": true,
|
|
11
|
+
"types": ["node"],
|
|
12
|
+
"esModuleInterop": true,
|
|
13
|
+
"skipLibCheck": true,
|
|
14
|
+
"isolatedModules": true,
|
|
15
|
+
"verbatimModuleSyntax": true,
|
|
16
|
+
"rootDir": "./src",
|
|
17
|
+
"outDir": "./dist"
|
|
18
|
+
},
|
|
19
|
+
"include": ["src"],
|
|
20
|
+
"exclude": ["**/*.test.ts"]
|
|
21
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { defineConfig } from 'vitest/config';
|
|
2
|
+
import { getWorkspaceAliases } from '../../../vitest.workspace-aliases';
|
|
3
|
+
|
|
4
|
+
export default defineConfig({
|
|
5
|
+
resolve: {
|
|
6
|
+
alias: getWorkspaceAliases(),
|
|
7
|
+
},
|
|
8
|
+
test: {
|
|
9
|
+
globals: true,
|
|
10
|
+
environment: 'node',
|
|
11
|
+
exclude: ['**/node_modules/**'],
|
|
12
|
+
},
|
|
13
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
$ tsc -p tsconfig.json
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
$ vitest run
|
|
2
|
+
|
|
3
|
+
[1m[30m[46m RUN [49m[39m[22m [36mv4.1.8 [39m[90m/Users/ben/projects/app/packages/honest-plugins/cache[39m
|
|
4
|
+
|
|
5
|
+
[32m✓[39m src/cacheable.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 5[2mms[22m[39m
|
|
6
|
+
[32m✓[39m src/redis/driver.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 6[2mms[22m[39m
|
|
7
|
+
[32m✓[39m src/cloudflare/driver.test.ts [2m([22m[2m22 tests[22m[2m)[22m[32m 5[2mms[22m[39m
|
|
8
|
+
[32m✓[39m src/resolve.test.ts [2m([22m[2m18 tests[22m[2m)[22m[32m 9[2mms[22m[39m
|
|
9
|
+
[32m✓[39m src/cache-service.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 2[2mms[22m[39m
|
|
10
|
+
[32m✓[39m src/index.test.ts [2m([22m[2m12 tests[22m[2m)[22m[32m 2[2mms[22m[39m
|
|
11
|
+
|
|
12
|
+
[2m Test Files [22m [1m[32m6 passed[39m[22m[90m (6)[39m
|
|
13
|
+
[2m Tests [22m [1m[32m63 passed[39m[22m[90m (63)[39m
|
|
14
|
+
[2m Start at [22m 14:17:12
|
|
15
|
+
[2m Duration [22m 492ms[2m (transform 541ms, setup 0ms, import 880ms, tests 28ms, environment 0ms)[22m
|
|
16
|
+
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# @rx-ted/packages-honest-plugins-cache
|
|
2
|
+
|
|
3
|
+
## 1.0.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 11bbae7: Remove defunct packages (web-admin, auth, http-client, search) and introduce barrel packages for consolidated exports. Migrate all internal imports from scoped plugin names (`@rx-ted/packages-honest-plugins-db`) to path-based barrel imports (`@rx-ted/packages-honest-plugins/db`). Reset all package versions to 1.0.0 with consolidated changelogs. Clean up obsolete documentation across the monorepo.
|
|
8
|
+
- Updated dependencies [11bbae7]
|
|
9
|
+
- @rx-ted/packages-core@1.0.1
|
|
10
|
+
- @rx-ted/packages-honest@1.0.1
|
|
11
|
+
|
|
12
|
+
## 1.0.0
|
|
13
|
+
|
|
14
|
+
Initial consolidated release.
|
|
15
|
+
|
|
16
|
+
### Features
|
|
17
|
+
|
|
18
|
+
- Cache plugin for @rx-ted/packages-honest
|
|
19
|
+
- Redis driver support
|
|
20
|
+
- Cloudflare KV driver support
|
|
21
|
+
- Local in-memory cache with TTL
|
|
22
|
+
- Cacheable decorator for method-level caching
|
|
23
|
+
- Shared `resolveBinding` utility from core
|
package/cache/README.md
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# @rx-ted/packages-honest-plugins-cache
|
|
2
|
+
|
|
3
|
+
Cache plugin for [@rx-ted/packages-honest](https://github.com/rx-ted/honest). Supports Redis, Cloudflare KV, and in-memory caching.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Multi-driver**: Redis, Cloudflare KV, local in-memory
|
|
8
|
+
- **Auto-detect**: driver resolved from `CACHE` env var
|
|
9
|
+
- **Runtime-agnostic**: works on Node.js, Bun, Deno, and Cloudflare Workers
|
|
10
|
+
- **Cacheable helper**: `cacheable()` for easy cache-through patterns
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
pnpm add @rx-ted/packages-honest-plugins-cache
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Peer dependencies: `@rx-ted/packages-honest`, `hono`
|
|
19
|
+
|
|
20
|
+
## Usage
|
|
21
|
+
|
|
22
|
+
### Register as a plugin
|
|
23
|
+
|
|
24
|
+
```ts
|
|
25
|
+
import { CachePlugin } from '@rx-ted/packages-honest-plugins/cache';
|
|
26
|
+
|
|
27
|
+
const plugin = new CachePlugin({
|
|
28
|
+
// driver is auto-detected from CACHE env var
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
const { hono } = await Application.create(AppModule, {
|
|
32
|
+
plugins: [plugin],
|
|
33
|
+
});
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Subpath exports
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
import { CachePlugin } from '@rx-ted/packages-honest-plugins/cache' // auto-detect
|
|
40
|
+
import { CachePlugin } from '@rx-ted/packages-honest-plugins/cache/redis' // Redis
|
|
41
|
+
import { CachePlugin } from '@rx-ted/packages-honest-plugins/cache/local' // in-memory
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Access the cache
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
import { ComponentManager } from '@rx-ted/packages-honest';
|
|
48
|
+
import { CacheService } from '@rx-ted/packages-honest-plugins/cache';
|
|
49
|
+
|
|
50
|
+
const cache = ComponentManager.getPlugin<CacheService>('cache');
|
|
51
|
+
await cache.set('key', 'value', 3600); // TTL in seconds
|
|
52
|
+
const value = await cache.get('key');
|
|
53
|
+
await cache.del('key');
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Cacheable helper
|
|
57
|
+
|
|
58
|
+
```ts
|
|
59
|
+
import { cacheable } from '@rx-ted/packages-honest-plugins/cache';
|
|
60
|
+
|
|
61
|
+
const user = await cacheable('user:123', 300, async () => {
|
|
62
|
+
return await db.query.users.findFirst({ where: eq(users.id, '123') });
|
|
63
|
+
});
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Supported Drivers
|
|
67
|
+
|
|
68
|
+
| Driver | Env var | Package |
|
|
69
|
+
|--------|---------|---------|
|
|
70
|
+
| Redis | `CACHE=redis` | `redis` |
|
|
71
|
+
| Cloudflare KV | `CACHE=kv` | (Wrangler bindings) |
|
|
72
|
+
| Local (memory) | `CACHE=local` | (none) |
|
|
73
|
+
|
|
74
|
+
## Scripts
|
|
75
|
+
|
|
76
|
+
| Script | Description |
|
|
77
|
+
|--------|-------------|
|
|
78
|
+
| `pnpm test` | Run tests |
|
|
79
|
+
| `pnpm build` | Build |
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
import { Service, ComponentManager } from '@rx-ted/packages-honest';
|
|
11
|
+
export const CACHE_GLOBAL_KEY = 'app:cache';
|
|
12
|
+
let CacheService = class CacheService {
|
|
13
|
+
constructor() {
|
|
14
|
+
return ComponentManager.getPlugin(CACHE_GLOBAL_KEY);
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
CacheService = __decorate([
|
|
18
|
+
Service(),
|
|
19
|
+
__metadata("design:paramtypes", [])
|
|
20
|
+
], CacheService);
|
|
21
|
+
export { CacheService };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { CacheDriver } from '../types';
|
|
2
|
+
export interface KvNamespace {
|
|
3
|
+
get(key: string): Promise<string | null>;
|
|
4
|
+
put(key: string, value: string, options?: {
|
|
5
|
+
expirationTtl?: number;
|
|
6
|
+
}): Promise<void>;
|
|
7
|
+
delete(key: string): Promise<void>;
|
|
8
|
+
list(options?: {
|
|
9
|
+
prefix?: string;
|
|
10
|
+
cursor?: string;
|
|
11
|
+
}): Promise<{
|
|
12
|
+
keys: {
|
|
13
|
+
name: string;
|
|
14
|
+
}[];
|
|
15
|
+
list_complete: boolean;
|
|
16
|
+
cursor?: string;
|
|
17
|
+
cacheStatus: string | null;
|
|
18
|
+
}>;
|
|
19
|
+
}
|
|
20
|
+
export interface CloudflareKvOptions {
|
|
21
|
+
namespace: KvNamespace;
|
|
22
|
+
}
|
|
23
|
+
export declare function createCloudflareKvDriver(namespace: KvNamespace): CacheDriver;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
class CloudflareKvDriver {
|
|
2
|
+
namespace;
|
|
3
|
+
constructor(namespace) {
|
|
4
|
+
this.namespace = namespace;
|
|
5
|
+
}
|
|
6
|
+
async get(key) {
|
|
7
|
+
if (!this.namespace)
|
|
8
|
+
return null;
|
|
9
|
+
const value = await this.namespace.get(key);
|
|
10
|
+
if (value === null)
|
|
11
|
+
return null;
|
|
12
|
+
return JSON.parse(value);
|
|
13
|
+
}
|
|
14
|
+
async set(key, value, ttl) {
|
|
15
|
+
if (!this.namespace)
|
|
16
|
+
return false;
|
|
17
|
+
const serialized = JSON.stringify(value);
|
|
18
|
+
const options = {};
|
|
19
|
+
if (ttl) {
|
|
20
|
+
options.expirationTtl = Math.max(ttl, 60);
|
|
21
|
+
}
|
|
22
|
+
await this.namespace.put(key, serialized, options);
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
async delete(key) {
|
|
26
|
+
if (!this.namespace)
|
|
27
|
+
return false;
|
|
28
|
+
await this.namespace.delete(key);
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
async exists(key) {
|
|
32
|
+
if (!this.namespace)
|
|
33
|
+
return false;
|
|
34
|
+
const value = await this.namespace.get(key);
|
|
35
|
+
return value !== null;
|
|
36
|
+
}
|
|
37
|
+
async mget(keys) {
|
|
38
|
+
return Promise.all(keys.map((key) => this.get(key)));
|
|
39
|
+
}
|
|
40
|
+
async mset(items) {
|
|
41
|
+
await Promise.all(items.map((item) => this.set(item.key, item.value, item.ttl)));
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
async deleteByPattern(pattern) {
|
|
45
|
+
if (!this.namespace)
|
|
46
|
+
return 0;
|
|
47
|
+
const prefix = pattern.replace(/\*.*$/, '');
|
|
48
|
+
let cursor;
|
|
49
|
+
let total = 0;
|
|
50
|
+
do {
|
|
51
|
+
const result = await this.namespace.list({ prefix, cursor });
|
|
52
|
+
if (result.keys.length > 0) {
|
|
53
|
+
await Promise.all(result.keys.map((k) => this.namespace.delete(k.name)));
|
|
54
|
+
total += result.keys.length;
|
|
55
|
+
}
|
|
56
|
+
cursor = result.list_complete ? undefined : result.cursor;
|
|
57
|
+
} while (cursor);
|
|
58
|
+
return total;
|
|
59
|
+
}
|
|
60
|
+
async incr(key) {
|
|
61
|
+
if (!this.namespace)
|
|
62
|
+
return 0;
|
|
63
|
+
const raw = await this.namespace.get(key);
|
|
64
|
+
const current = raw !== null ? Number(JSON.parse(raw)) : 0;
|
|
65
|
+
const next = current + 1;
|
|
66
|
+
await this.namespace.put(key, JSON.stringify(next));
|
|
67
|
+
return next;
|
|
68
|
+
}
|
|
69
|
+
async decr(key) {
|
|
70
|
+
if (!this.namespace)
|
|
71
|
+
return 0;
|
|
72
|
+
const raw = await this.namespace.get(key);
|
|
73
|
+
const current = raw !== null ? Number(JSON.parse(raw)) : 0;
|
|
74
|
+
const next = current - 1;
|
|
75
|
+
await this.namespace.put(key, JSON.stringify(next));
|
|
76
|
+
return next;
|
|
77
|
+
}
|
|
78
|
+
async expire(key, ttl) {
|
|
79
|
+
if (!this.namespace)
|
|
80
|
+
return false;
|
|
81
|
+
const value = await this.namespace.get(key);
|
|
82
|
+
if (value === null)
|
|
83
|
+
return false;
|
|
84
|
+
await this.namespace.put(key, value, { expirationTtl: ttl });
|
|
85
|
+
return true;
|
|
86
|
+
}
|
|
87
|
+
async close() { }
|
|
88
|
+
async healthCheck() {
|
|
89
|
+
if (!this.namespace)
|
|
90
|
+
return false;
|
|
91
|
+
try {
|
|
92
|
+
await this.namespace.get('__health_check__');
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
export function createCloudflareKvDriver(namespace) {
|
|
101
|
+
return new CloudflareKvDriver(namespace);
|
|
102
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type ILogger } from '@rx-ted/packages-core';
|
|
2
|
+
import type { Application, IPlugin } from '@rx-ted/packages-honest';
|
|
3
|
+
import type { KvNamespace } from './driver';
|
|
4
|
+
export declare const CLOUDFLARE_KV_CONTEXT_KEY = "honest:cloudflare-kv";
|
|
5
|
+
export interface CloudflareKvPluginOptions {
|
|
6
|
+
namespace?: KvNamespace;
|
|
7
|
+
binding?: string;
|
|
8
|
+
}
|
|
9
|
+
export declare class CloudflareKvPlugin implements IPlugin {
|
|
10
|
+
private options;
|
|
11
|
+
static readonly globalKey = "cloudflare-kv";
|
|
12
|
+
readonly name = "cloudflare-kv-plugin";
|
|
13
|
+
readonly version = "1.0.0";
|
|
14
|
+
logger?: ILogger;
|
|
15
|
+
private driver?;
|
|
16
|
+
constructor(options: CloudflareKvPluginOptions);
|
|
17
|
+
beforeModulesRegistered(app: Application): Promise<void>;
|
|
18
|
+
close(): Promise<void>;
|
|
19
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { ENV_SYMBOL, resolveBinding } from '@rx-ted/packages-core';
|
|
2
|
+
import { ComponentManager, resolvePluginLogger } from '@rx-ted/packages-honest';
|
|
3
|
+
import { createCloudflareKvDriver } from './driver';
|
|
4
|
+
import { CACHE_GLOBAL_KEY } from '../cache-service';
|
|
5
|
+
export const CLOUDFLARE_KV_CONTEXT_KEY = 'honest:cloudflare-kv';
|
|
6
|
+
export class CloudflareKvPlugin {
|
|
7
|
+
options;
|
|
8
|
+
static globalKey = 'cloudflare-kv';
|
|
9
|
+
name = 'cloudflare-kv-plugin';
|
|
10
|
+
version = '1.0.0';
|
|
11
|
+
logger;
|
|
12
|
+
driver;
|
|
13
|
+
constructor(options) {
|
|
14
|
+
this.options = options;
|
|
15
|
+
}
|
|
16
|
+
async beforeModulesRegistered(app) {
|
|
17
|
+
this.logger ??= resolvePluginLogger(this.name);
|
|
18
|
+
this.logger.info('Cloudflare KV: connecting...');
|
|
19
|
+
const appEnv = ComponentManager.hasPlugin(ENV_SYMBOL)
|
|
20
|
+
? ComponentManager.getPlugin(ENV_SYMBOL)
|
|
21
|
+
: undefined;
|
|
22
|
+
const ns = this.options.namespace ?? resolveBinding(this.options.binding ?? '', appEnv);
|
|
23
|
+
if (ns) {
|
|
24
|
+
this.driver = createCloudflareKvDriver(ns);
|
|
25
|
+
}
|
|
26
|
+
else if (this.options.binding) {
|
|
27
|
+
this.driver = createLazyDriver(() => resolveBinding(this.options.binding, appEnv));
|
|
28
|
+
this.logger.info(`Cloudflare KV: binding "${this.options.binding}" deferred`);
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
throw new Error('Cloudflare KV: namespace or binding option required');
|
|
32
|
+
}
|
|
33
|
+
app.getContext().set(CLOUDFLARE_KV_CONTEXT_KEY, this.driver);
|
|
34
|
+
ComponentManager.registerPlugin(CACHE_GLOBAL_KEY, this.driver);
|
|
35
|
+
this.logger.info('Cloudflare KV: connected');
|
|
36
|
+
}
|
|
37
|
+
async close() {
|
|
38
|
+
await this.driver?.close();
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function createLazyDriver(resolve) {
|
|
42
|
+
let cached = null;
|
|
43
|
+
const noop = () => Promise.resolve(null);
|
|
44
|
+
return new Proxy({}, {
|
|
45
|
+
get(_, prop) {
|
|
46
|
+
if (!cached) {
|
|
47
|
+
const ns = resolve();
|
|
48
|
+
if (ns)
|
|
49
|
+
cached = createCloudflareKvDriver(ns);
|
|
50
|
+
}
|
|
51
|
+
if (cached) {
|
|
52
|
+
const val = cached[prop];
|
|
53
|
+
return typeof val === 'function' ? val.bind(cached) : val;
|
|
54
|
+
}
|
|
55
|
+
return noop;
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export { CACHE_GLOBAL_KEY, CacheService } from './cache-service';
|
|
2
|
+
export type { CacheDriver } from './types';
|
|
3
|
+
export { cacheable } from './cacheable';
|
|
4
|
+
export { CachePlugin, findKvBinding, resolveBinding } from './resolve';
|
|
5
|
+
export type { CachePluginOptions } from './resolve';
|
|
6
|
+
export * from './redis';
|
|
7
|
+
export * as redis from './redis';
|
|
8
|
+
export * from './cloudflare';
|
|
9
|
+
export * as cloudflare from './cloudflare';
|
|
10
|
+
export * from './local';
|
|
11
|
+
export * as local from './local';
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// Shared
|
|
2
|
+
export { CACHE_GLOBAL_KEY, CacheService } from './cache-service';
|
|
3
|
+
export { cacheable } from './cacheable';
|
|
4
|
+
// Auto-detect cache plugin (recommended)
|
|
5
|
+
export { CachePlugin, findKvBinding, resolveBinding } from './resolve';
|
|
6
|
+
// Redis driver
|
|
7
|
+
export * from './redis';
|
|
8
|
+
export * as redis from './redis';
|
|
9
|
+
// Cloudflare KV driver
|
|
10
|
+
export * from './cloudflare';
|
|
11
|
+
export * as cloudflare from './cloudflare';
|
|
12
|
+
// Local in-memory driver (dev)
|
|
13
|
+
export * from './local';
|
|
14
|
+
export * as local from './local';
|