mates-fullstack 1.0.0-beta.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/README.md +311 -0
- package/dist/arctic-auth.d.ts +101 -0
- package/dist/arctic-auth.d.ts.map +1 -0
- package/dist/arctic-auth.js +538 -0
- package/dist/arctic-auth.js.map +1 -0
- package/dist/asset-manifest.d.ts +14 -0
- package/dist/asset-manifest.d.ts.map +1 -0
- package/dist/asset-manifest.js +102 -0
- package/dist/asset-manifest.js.map +1 -0
- package/dist/browser.d.ts +18 -0
- package/dist/browser.d.ts.map +1 -0
- package/dist/browser.js +25 -0
- package/dist/browser.js.map +1 -0
- package/dist/build-esbuild.d.ts +29 -0
- package/dist/build-esbuild.d.ts.map +1 -0
- package/dist/build-esbuild.js +699 -0
- package/dist/build-esbuild.js.map +1 -0
- package/dist/build-prod.d.ts +126 -0
- package/dist/build-prod.d.ts.map +1 -0
- package/dist/build-prod.js +1014 -0
- package/dist/build-prod.js.map +1 -0
- package/dist/cli-new.d.ts +14 -0
- package/dist/cli-new.d.ts.map +1 -0
- package/dist/cli-new.js +637 -0
- package/dist/cli-new.js.map +1 -0
- package/dist/client.d.ts +43 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +130 -0
- package/dist/client.js.map +1 -0
- package/dist/cors.d.ts +16 -0
- package/dist/cors.d.ts.map +1 -0
- package/dist/cors.js +60 -0
- package/dist/cors.js.map +1 -0
- package/dist/ctx.d.ts +78 -0
- package/dist/ctx.d.ts.map +1 -0
- package/dist/ctx.js +280 -0
- package/dist/ctx.js.map +1 -0
- package/dist/dev-watcher.d.ts +23 -0
- package/dist/dev-watcher.d.ts.map +1 -0
- package/dist/dev-watcher.js +136 -0
- package/dist/dev-watcher.js.map +1 -0
- package/dist/docs-generator.d.ts +69 -0
- package/dist/docs-generator.d.ts.map +1 -0
- package/dist/docs-generator.js +557 -0
- package/dist/docs-generator.js.map +1 -0
- package/dist/docs-page.d.ts +20 -0
- package/dist/docs-page.d.ts.map +1 -0
- package/dist/docs-page.js +1152 -0
- package/dist/docs-page.js.map +1 -0
- package/dist/download.d.ts +78 -0
- package/dist/download.d.ts.map +1 -0
- package/dist/download.js +202 -0
- package/dist/download.js.map +1 -0
- package/dist/env-loader.d.ts +76 -0
- package/dist/env-loader.d.ts.map +1 -0
- package/dist/env-loader.js +213 -0
- package/dist/env-loader.js.map +1 -0
- package/dist/errors.d.ts +146 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +386 -0
- package/dist/errors.js.map +1 -0
- package/dist/head.d.ts +31 -0
- package/dist/head.d.ts.map +1 -0
- package/dist/head.js +245 -0
- package/dist/head.js.map +1 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +30 -0
- package/dist/index.js.map +1 -0
- package/dist/internal-prefixes.d.ts +16 -0
- package/dist/internal-prefixes.d.ts.map +1 -0
- package/dist/internal-prefixes.js +16 -0
- package/dist/internal-prefixes.js.map +1 -0
- package/dist/internal.d.ts +25 -0
- package/dist/internal.d.ts.map +1 -0
- package/dist/internal.js +25 -0
- package/dist/internal.js.map +1 -0
- package/dist/jwt.d.ts +166 -0
- package/dist/jwt.d.ts.map +1 -0
- package/dist/jwt.js +261 -0
- package/dist/jwt.js.map +1 -0
- package/dist/log.d.ts +44 -0
- package/dist/log.d.ts.map +1 -0
- package/dist/log.js +66 -0
- package/dist/log.js.map +1 -0
- package/dist/logger.d.ts +76 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +138 -0
- package/dist/logger.js.map +1 -0
- package/dist/main-runner.d.ts +59 -0
- package/dist/main-runner.d.ts.map +1 -0
- package/dist/main-runner.js +157 -0
- package/dist/main-runner.js.map +1 -0
- package/dist/mates-auth.d.ts +82 -0
- package/dist/mates-auth.d.ts.map +1 -0
- package/dist/mates-auth.js +323 -0
- package/dist/mates-auth.js.map +1 -0
- package/dist/middleware.d.ts +30 -0
- package/dist/middleware.d.ts.map +1 -0
- package/dist/middleware.js +67 -0
- package/dist/middleware.js.map +1 -0
- package/dist/project-resolver.d.ts +102 -0
- package/dist/project-resolver.d.ts.map +1 -0
- package/dist/project-resolver.js +271 -0
- package/dist/project-resolver.js.map +1 -0
- package/dist/rate-limit.d.ts +37 -0
- package/dist/rate-limit.d.ts.map +1 -0
- package/dist/rate-limit.js +109 -0
- package/dist/rate-limit.js.map +1 -0
- package/dist/redirect.d.ts +84 -0
- package/dist/redirect.d.ts.map +1 -0
- package/dist/redirect.js +105 -0
- package/dist/redirect.js.map +1 -0
- package/dist/renderer.d.ts +91 -0
- package/dist/renderer.d.ts.map +1 -0
- package/dist/renderer.js +630 -0
- package/dist/renderer.js.map +1 -0
- package/dist/request-logger.d.ts +12 -0
- package/dist/request-logger.d.ts.map +1 -0
- package/dist/request-logger.js +55 -0
- package/dist/request-logger.js.map +1 -0
- package/dist/rest.d.ts +25 -0
- package/dist/rest.d.ts.map +1 -0
- package/dist/rest.js +93 -0
- package/dist/rest.js.map +1 -0
- package/dist/router.d.ts +71 -0
- package/dist/router.d.ts.map +1 -0
- package/dist/router.js +222 -0
- package/dist/router.js.map +1 -0
- package/dist/rpc-registry.d.ts +84 -0
- package/dist/rpc-registry.d.ts.map +1 -0
- package/dist/rpc-registry.js +271 -0
- package/dist/rpc-registry.js.map +1 -0
- package/dist/rpc-runner.d.ts +82 -0
- package/dist/rpc-runner.d.ts.map +1 -0
- package/dist/rpc-runner.js +564 -0
- package/dist/rpc-runner.js.map +1 -0
- package/dist/sanitize.d.ts +61 -0
- package/dist/sanitize.d.ts.map +1 -0
- package/dist/sanitize.js +193 -0
- package/dist/sanitize.js.map +1 -0
- package/dist/security-headers.d.ts +114 -0
- package/dist/security-headers.d.ts.map +1 -0
- package/dist/security-headers.js +121 -0
- package/dist/security-headers.js.map +1 -0
- package/dist/server-fn.d.ts +323 -0
- package/dist/server-fn.d.ts.map +1 -0
- package/dist/server-fn.js +373 -0
- package/dist/server-fn.js.map +1 -0
- package/dist/server-public.d.ts +13 -0
- package/dist/server-public.d.ts.map +1 -0
- package/dist/server-public.js +12 -0
- package/dist/server-public.js.map +1 -0
- package/dist/server-timeout.d.ts +38 -0
- package/dist/server-timeout.d.ts.map +1 -0
- package/dist/server-timeout.js +46 -0
- package/dist/server-timeout.js.map +1 -0
- package/dist/server.d.ts +100 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +1218 -0
- package/dist/server.js.map +1 -0
- package/dist/socket-router.d.ts +153 -0
- package/dist/socket-router.d.ts.map +1 -0
- package/dist/socket-router.js +612 -0
- package/dist/socket-router.js.map +1 -0
- package/dist/sso.d.ts +90 -0
- package/dist/sso.d.ts.map +1 -0
- package/dist/sso.js +261 -0
- package/dist/sso.js.map +1 -0
- package/dist/ssr-context.d.ts +49 -0
- package/dist/ssr-context.d.ts.map +1 -0
- package/dist/ssr-context.js +85 -0
- package/dist/ssr-context.js.map +1 -0
- package/dist/ssr-globals.d.ts +32 -0
- package/dist/ssr-globals.d.ts.map +1 -0
- package/dist/ssr-globals.js +1010 -0
- package/dist/ssr-globals.js.map +1 -0
- package/dist/ssr-template.d.ts +73 -0
- package/dist/ssr-template.d.ts.map +1 -0
- package/dist/ssr-template.js +507 -0
- package/dist/ssr-template.js.map +1 -0
- package/dist/stack-mapper.d.ts +25 -0
- package/dist/stack-mapper.d.ts.map +1 -0
- package/dist/stack-mapper.js +139 -0
- package/dist/stack-mapper.js.map +1 -0
- package/dist/stream.d.ts +89 -0
- package/dist/stream.d.ts.map +1 -0
- package/dist/stream.js +299 -0
- package/dist/stream.js.map +1 -0
- package/dist/upload.d.ts +69 -0
- package/dist/upload.d.ts.map +1 -0
- package/dist/upload.js +110 -0
- package/dist/upload.js.map +1 -0
- package/dist/validate.d.ts +58 -0
- package/dist/validate.d.ts.map +1 -0
- package/dist/validate.js +89 -0
- package/dist/validate.js.map +1 -0
- package/dist/verify-package.d.ts +3 -0
- package/dist/verify-package.d.ts.map +1 -0
- package/dist/verify-package.js +128 -0
- package/dist/verify-package.js.map +1 -0
- package/package.json +79 -0
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* mates-fullstack — rpc-registry.ts
|
|
3
|
+
*
|
|
4
|
+
* Scans server/api/ and registers every exported async function as an RPC endpoint.
|
|
5
|
+
*
|
|
6
|
+
* URL derivation:
|
|
7
|
+
* server/api/users.ts + getUsers → POST /api/users/getUsers
|
|
8
|
+
* server/api/posts/index.ts + getPosts → POST /api/posts/getPosts
|
|
9
|
+
* server/api/auth.ts + login → POST /api/auth/login
|
|
10
|
+
*
|
|
11
|
+
* The URL is also the test/Postman endpoint:
|
|
12
|
+
* POST /api/users/getUsers
|
|
13
|
+
* Content-Type: application/json
|
|
14
|
+
* { "page": 0 }
|
|
15
|
+
*
|
|
16
|
+
* Rules for what gets registered:
|
|
17
|
+
* ✅ Exported async functions
|
|
18
|
+
* ✅ Plain exported functions (warned but registered)
|
|
19
|
+
* ❌ default export (page component convention)
|
|
20
|
+
* ❌ Non-function exports (types, constants)
|
|
21
|
+
* ❌ Reserved names: loader, meta, layout, staticPaths, onConnect, onDisconnect
|
|
22
|
+
* ❌ Functions named "then" or "catch" (conflicts with Promise protocol)
|
|
23
|
+
* ❌ Files starting with _ or containing .test. / .spec.
|
|
24
|
+
*
|
|
25
|
+
* Dev mode:
|
|
26
|
+
* Files are re-imported with a cache-busting timestamp on every rescan.
|
|
27
|
+
* The watcher triggers a rescan on file add/remove/rename.
|
|
28
|
+
* Content edits are picked up because the cache-bust forces a fresh import.
|
|
29
|
+
*/
|
|
30
|
+
import fs from "node:fs";
|
|
31
|
+
import path from "node:path";
|
|
32
|
+
import { devError, devWarn } from "./log.js";
|
|
33
|
+
// ─── Reserved export names ────────────────────────────────────────────────────
|
|
34
|
+
/**
|
|
35
|
+
* Export names that must never be registered as RPC functions.
|
|
36
|
+
* These are framework-level exports consumed by the SSR runtime or
|
|
37
|
+
* WebSocket handlers.
|
|
38
|
+
*/
|
|
39
|
+
const RESERVED_NAMES = new Set([
|
|
40
|
+
"default", // page component / module default
|
|
41
|
+
"loader", // SSR data loader
|
|
42
|
+
"meta", // page <head> metadata
|
|
43
|
+
"layout", // page layout wrapper
|
|
44
|
+
"staticPaths", // SSG static path list
|
|
45
|
+
"onConnect", // WebSocket lifecycle
|
|
46
|
+
"onDisconnect", // WebSocket lifecycle
|
|
47
|
+
"then", // conflicts with Promise protocol
|
|
48
|
+
"catch", // conflicts with Promise protocol
|
|
49
|
+
"finally", // conflicts with Promise protocol
|
|
50
|
+
]);
|
|
51
|
+
// ─── Registry ─────────────────────────────────────────────────────────────────
|
|
52
|
+
/** url → RpcEntry */
|
|
53
|
+
const _registry = new Map();
|
|
54
|
+
/** Absolute path of the currently scanned apiDir */
|
|
55
|
+
let _apiDir = null;
|
|
56
|
+
// ─── Public API ───────────────────────────────────────────────────────────────
|
|
57
|
+
/**
|
|
58
|
+
* Scan server/api/ and populate the registry.
|
|
59
|
+
* Call once at startup. In dev mode, call again after file changes
|
|
60
|
+
* or use watchRpcFunctions() for automatic rescanning.
|
|
61
|
+
*/
|
|
62
|
+
export async function scanRpcFunctions(apiDir, dev = false) {
|
|
63
|
+
if (!fs.existsSync(apiDir))
|
|
64
|
+
return;
|
|
65
|
+
_apiDir = apiDir;
|
|
66
|
+
_registry.clear();
|
|
67
|
+
const files = _collectFiles(apiDir);
|
|
68
|
+
for (const filePath of files) {
|
|
69
|
+
// Security: ensure resolved path stays inside apiDir
|
|
70
|
+
const absApi = path.resolve(apiDir);
|
|
71
|
+
const absFile = path.resolve(filePath);
|
|
72
|
+
if (!absFile.startsWith(absApi + path.sep) && absFile !== absApi) {
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
await _registerFile(apiDir, filePath, dev);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Look up a registered RPC function by its URL.
|
|
80
|
+
* Returns null if not found.
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* lookupRpcFn("/api/users/getUsers")
|
|
84
|
+
*/
|
|
85
|
+
export function lookupRpcFn(url) {
|
|
86
|
+
// Normalize: strip query string if present
|
|
87
|
+
const pathname = url.split("?")[0];
|
|
88
|
+
return _registry.get(pathname) ?? null;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Returns all registered RPC entries.
|
|
92
|
+
* Used by the docs generator and startup logging.
|
|
93
|
+
*/
|
|
94
|
+
export function listRpcFunctions() {
|
|
95
|
+
return Array.from(_registry.values());
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Returns the number of registered RPC functions.
|
|
99
|
+
*/
|
|
100
|
+
export function rpcRegistrySize() {
|
|
101
|
+
return _registry.size;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Clear the registry. Used before a rescan or in tests.
|
|
105
|
+
*/
|
|
106
|
+
export function clearRpcRegistry() {
|
|
107
|
+
_registry.clear();
|
|
108
|
+
_apiDir = null;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Watch server/api/ for file changes and trigger a rescan.
|
|
112
|
+
* Returns a cleanup function that stops the watcher.
|
|
113
|
+
*
|
|
114
|
+
* Only responds to file add/remove/rename events — content edits are
|
|
115
|
+
* handled by the cache-bust import in dev mode.
|
|
116
|
+
*/
|
|
117
|
+
export function watchRpcFunctions(apiDir, onChange) {
|
|
118
|
+
if (!fs.existsSync(apiDir))
|
|
119
|
+
return () => { };
|
|
120
|
+
let debounce = null;
|
|
121
|
+
const watcher = fs.watch(apiDir, { recursive: true }, (event, filename) => {
|
|
122
|
+
if (!filename)
|
|
123
|
+
return;
|
|
124
|
+
if (!_isApiFile(path.basename(filename)))
|
|
125
|
+
return;
|
|
126
|
+
if (debounce)
|
|
127
|
+
clearTimeout(debounce);
|
|
128
|
+
debounce = setTimeout(async () => {
|
|
129
|
+
await scanRpcFunctions(apiDir, true);
|
|
130
|
+
onChange(event, filename);
|
|
131
|
+
}, 50);
|
|
132
|
+
});
|
|
133
|
+
return () => {
|
|
134
|
+
if (debounce)
|
|
135
|
+
clearTimeout(debounce);
|
|
136
|
+
watcher.close();
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
// ─── URL derivation ───────────────────────────────────────────────────────────
|
|
140
|
+
/**
|
|
141
|
+
* Derive the RPC URL for a function exported from a file.
|
|
142
|
+
*
|
|
143
|
+
* Examples (apiDir = /project/server/api):
|
|
144
|
+
* /project/server/api/users.ts + getUsers → /api/users/getUsers
|
|
145
|
+
* /project/server/api/posts/index.ts + getPosts → /api/posts/getPosts
|
|
146
|
+
* /project/server/api/auth.ts + login → /api/auth/login
|
|
147
|
+
*/
|
|
148
|
+
export function deriveRpcUrl(apiDir, filePath, fnName) {
|
|
149
|
+
const rel = path.relative(apiDir, filePath);
|
|
150
|
+
const withoutExt = rel.replace(/\.(ts|js|tsx|jsx)$/, "");
|
|
151
|
+
// Normalize path separators to forward slash
|
|
152
|
+
let modulePath = withoutExt.split(path.sep).join("/");
|
|
153
|
+
// Drop trailing "index" — posts/index → posts
|
|
154
|
+
if (modulePath.endsWith("/index")) {
|
|
155
|
+
modulePath = modulePath.slice(0, -6);
|
|
156
|
+
}
|
|
157
|
+
else if (modulePath === "index") {
|
|
158
|
+
modulePath = "";
|
|
159
|
+
}
|
|
160
|
+
// Build: /api/{modulePath}/{fnName}
|
|
161
|
+
const parts = ["api"];
|
|
162
|
+
if (modulePath)
|
|
163
|
+
parts.push(modulePath);
|
|
164
|
+
parts.push(fnName);
|
|
165
|
+
return "/" + parts.join("/");
|
|
166
|
+
}
|
|
167
|
+
// ─── Internal ─────────────────────────────────────────────────────────────────
|
|
168
|
+
async function _registerFile(apiDir, filePath, dev) {
|
|
169
|
+
// In dev mode, cache-bust so updated implementations are picked up
|
|
170
|
+
const importSpecifier = dev ? `${filePath}?t=${Date.now()}` : filePath;
|
|
171
|
+
let mod;
|
|
172
|
+
try {
|
|
173
|
+
mod = await import(importSpecifier);
|
|
174
|
+
}
|
|
175
|
+
catch (err) {
|
|
176
|
+
const message = `failed to import ${path.relative(apiDir, filePath)}: ${err?.message ?? err}`;
|
|
177
|
+
if (!dev)
|
|
178
|
+
throw new Error(message);
|
|
179
|
+
// In dev, log and keep the server alive so the developer can fix the file.
|
|
180
|
+
devError(message);
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
let registered = 0;
|
|
184
|
+
const urlsSeen = new Set();
|
|
185
|
+
for (const [exportName, exportValue] of Object.entries(mod)) {
|
|
186
|
+
// Skip reserved names
|
|
187
|
+
if (RESERVED_NAMES.has(exportName))
|
|
188
|
+
continue;
|
|
189
|
+
// Skip non-functions
|
|
190
|
+
if (typeof exportValue !== "function")
|
|
191
|
+
continue;
|
|
192
|
+
// Skip non-async functions with a warning
|
|
193
|
+
// (async check: constructor.name === "AsyncFunction")
|
|
194
|
+
const isAsync = exportValue.constructor?.name === "AsyncFunction";
|
|
195
|
+
if (!isAsync) {
|
|
196
|
+
devWarn(`${path.relative(apiDir, filePath)}: ` +
|
|
197
|
+
`export "${exportName}" is not async — skipped. ` +
|
|
198
|
+
`RPC functions must be async.`);
|
|
199
|
+
continue;
|
|
200
|
+
}
|
|
201
|
+
const url = deriveRpcUrl(apiDir, filePath, exportName);
|
|
202
|
+
// Collision detection: two functions mapping to the same URL
|
|
203
|
+
if (_registry.has(url)) {
|
|
204
|
+
const existing = _registry.get(url);
|
|
205
|
+
if (existing.filePath !== filePath) {
|
|
206
|
+
// Different files, same URL — warn, first one wins
|
|
207
|
+
devWarn(`URL collision: ${url} is registered by both ` +
|
|
208
|
+
`"${path.relative(apiDir, existing.filePath)}" and ` +
|
|
209
|
+
`"${path.relative(apiDir, filePath)}" — ` +
|
|
210
|
+
`first registration wins.`);
|
|
211
|
+
continue;
|
|
212
|
+
}
|
|
213
|
+
// Same file, same URL — shouldn't happen but skip silently
|
|
214
|
+
continue;
|
|
215
|
+
}
|
|
216
|
+
urlsSeen.add(url);
|
|
217
|
+
_registry.set(url, {
|
|
218
|
+
url,
|
|
219
|
+
filePath,
|
|
220
|
+
fnName: exportName,
|
|
221
|
+
fn: exportValue,
|
|
222
|
+
});
|
|
223
|
+
registered++;
|
|
224
|
+
}
|
|
225
|
+
// Warn if file only has HTTP method exports (GET/POST/etc.) — wrong folder
|
|
226
|
+
if (registered === 0) {
|
|
227
|
+
const httpMethods = ["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD"];
|
|
228
|
+
const hasHttpExports = Object.keys(mod).some((k) => httpMethods.includes(k));
|
|
229
|
+
if (hasHttpExports) {
|
|
230
|
+
devWarn(`${path.relative(apiDir, filePath)} exports HTTP methods ` +
|
|
231
|
+
`(GET/POST/etc.) but no RPC functions. ` +
|
|
232
|
+
`mates-fullstack only exposes RPC functions from server/api/.`);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Recursively collect all api files under a directory.
|
|
238
|
+
*/
|
|
239
|
+
function _collectFiles(dir) {
|
|
240
|
+
const results = [];
|
|
241
|
+
_walk(dir, results);
|
|
242
|
+
return results;
|
|
243
|
+
}
|
|
244
|
+
function _walk(dir, out) {
|
|
245
|
+
let entries;
|
|
246
|
+
try {
|
|
247
|
+
entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
248
|
+
}
|
|
249
|
+
catch {
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
for (const entry of entries) {
|
|
253
|
+
const full = path.join(dir, entry.name);
|
|
254
|
+
if (entry.isDirectory()) {
|
|
255
|
+
_walk(full, out);
|
|
256
|
+
}
|
|
257
|
+
else if (_isApiFile(entry.name)) {
|
|
258
|
+
out.push(full);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
function _isApiFile(filename) {
|
|
263
|
+
if (filename.startsWith("_"))
|
|
264
|
+
return false;
|
|
265
|
+
if (filename.startsWith("."))
|
|
266
|
+
return false;
|
|
267
|
+
if (filename.includes(".test.") || filename.includes(".spec."))
|
|
268
|
+
return false;
|
|
269
|
+
return /\.(ts|js|tsx|jsx)$/.test(filename);
|
|
270
|
+
}
|
|
271
|
+
//# sourceMappingURL=rpc-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rpc-registry.js","sourceRoot":"","sources":["../src/rpc-registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* mates-fullstack — rpc-runner.ts
|
|
3
|
+
*
|
|
4
|
+
* Executes a registered RPC function for an incoming HTTP request.
|
|
5
|
+
*
|
|
6
|
+
* Execution pipeline per request:
|
|
7
|
+
* 1. Read + size-check request body
|
|
8
|
+
* 2. Parse payload (JSON or multipart/form-data)
|
|
9
|
+
* 3. Create Context from request headers
|
|
10
|
+
* 4. Run onRequest hooks (registered in server/main.ts)
|
|
11
|
+
* - throws → error response sent, onResponse SKIPPED
|
|
12
|
+
* - returns Response → that response sent, onResponse RUNS
|
|
13
|
+
* - returns nothing → continue
|
|
14
|
+
* 5. Run entry.fn(payload, ctx)
|
|
15
|
+
* - throws → error response sent, onResponse SKIPPED
|
|
16
|
+
* - returns data → onResponse hooks run, then response sent
|
|
17
|
+
* 6. Detect return type → route to correct response writer:
|
|
18
|
+
* - StreamResponse → SSE
|
|
19
|
+
* - Download → binary attachment
|
|
20
|
+
* - void/null/undefined → {} 200
|
|
21
|
+
* - anything else → JSON 200
|
|
22
|
+
* 7. Run onResponse hooks (with data + ctx)
|
|
23
|
+
* 8. Apply ctx.resHeaders to the response
|
|
24
|
+
*
|
|
25
|
+
* Error handling:
|
|
26
|
+
* - Redirect throw → 302 JSON { __type: "Redirect", url, status }
|
|
27
|
+
* - ServerError throw → 4xx/5xx JSON { __type, message, status, code, ...}
|
|
28
|
+
* - Plain Error throw → 500, message hidden in production
|
|
29
|
+
* - Unknown throw → 500, "Internal Server Error"
|
|
30
|
+
*
|
|
31
|
+
* Body limits:
|
|
32
|
+
* - JSON: 1MB default (MAX_JSON_BYTES)
|
|
33
|
+
* - Multipart: 10MB default (MAX_UPLOAD_BYTES)
|
|
34
|
+
*/
|
|
35
|
+
/// <reference types="node" />
|
|
36
|
+
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
37
|
+
import type { RpcEntry } from "./rpc-registry.js";
|
|
38
|
+
export interface RpcRunnerConfig {
|
|
39
|
+
/** Maximum JSON request body size. Default: 1MB */
|
|
40
|
+
maxJsonBytes?: number;
|
|
41
|
+
/** Maximum allowed object depth in JSON payloads. Default: 50 */
|
|
42
|
+
maxJsonDepth?: number;
|
|
43
|
+
/** Maximum allowed array length in JSON payloads. Default: 10_000 */
|
|
44
|
+
maxArrayLength?: number;
|
|
45
|
+
/** Maximum allowed length for any string value. Default: 100_000 */
|
|
46
|
+
maxStringLength?: number;
|
|
47
|
+
/** Maximum multipart/form-data upload size. Default: 10MB */
|
|
48
|
+
maxUploadBytes?: number;
|
|
49
|
+
/** Maximum number of multipart parts. Default: 200 */
|
|
50
|
+
maxMultipartParts?: number;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Configure RPC runner limits. Call once at startup.
|
|
54
|
+
* All values are optional — only provided values override the defaults.
|
|
55
|
+
*/
|
|
56
|
+
export declare function configureRpcRunner(config: RpcRunnerConfig): void;
|
|
57
|
+
/** Request timeout in milliseconds: 30 seconds */
|
|
58
|
+
export declare const DEFAULT_TIMEOUT_MS = 30000;
|
|
59
|
+
/**
|
|
60
|
+
* Handle a single RPC request end-to-end.
|
|
61
|
+
* Never throws under any circumstances.
|
|
62
|
+
* All errors — including unexpected framework bugs — produce a JSON error response.
|
|
63
|
+
*/
|
|
64
|
+
export declare function runRpcRequest(req: IncomingMessage, res: ServerResponse, entry: RpcEntry, dev: boolean, timeoutMs?: number,
|
|
65
|
+
/** Pre-populated ctx from the outer request handler. When supplied, auth
|
|
66
|
+
* and other middleware state already applied via onRequest are shared. */
|
|
67
|
+
sharedCtx?: import("./ctx.js").Context): Promise<void>;
|
|
68
|
+
/**
|
|
69
|
+
* Read and parse the request body.
|
|
70
|
+
*
|
|
71
|
+
* Handles:
|
|
72
|
+
* - application/json → JSON.parse
|
|
73
|
+
* - multipart/form-data → FormData-like object with File entries
|
|
74
|
+
* - no content-type → attempt JSON parse, fallback to {}
|
|
75
|
+
* - empty body → {}
|
|
76
|
+
*
|
|
77
|
+
* Throws with .status set for:
|
|
78
|
+
* - Body too large (413)
|
|
79
|
+
* - Malformed JSON (400)
|
|
80
|
+
*/
|
|
81
|
+
export declare function parseRpcBody(req: IncomingMessage): Promise<unknown>;
|
|
82
|
+
//# sourceMappingURL=rpc-runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rpc-runner.d.ts","sourceRoot":"","sources":["../src/rpc-runner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAEjE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AA2BlD,MAAM,WAAW,eAAe;IAC9B,mDAAmD;IACnD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iEAAiE;IACjE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,qEAAqE;IACrE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,oEAAoE;IACpE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,6DAA6D;IAC7D,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,sDAAsD;IACtD,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAWD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI,CAahE;AA0CD,kDAAkD;AAClD,eAAO,MAAM,kBAAkB,QAAS,CAAC;AAIzC;;;;GAIG;AACH,wBAAsB,aAAa,CACjC,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,cAAc,EACnB,KAAK,EAAE,QAAQ,EACf,GAAG,EAAE,OAAO,EACZ,SAAS,SAAqB;AAC9B;0EAC0E;AAC1E,SAAS,CAAC,EAAE,OAAO,UAAU,EAAE,OAAO,GACrC,OAAO,CAAC,IAAI,CAAC,CA4Cf;AA0ID;;;;;;;;;;;;GAYG;AACH,wBAAsB,YAAY,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC,CAEzE"}
|