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
package/dist/upload.d.ts
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* mates-ssr — upload.ts
|
|
3
|
+
*
|
|
4
|
+
* Multipart/form-data parsing for file uploads.
|
|
5
|
+
*
|
|
6
|
+
* Uses Bun's native req.formData() for parsing.
|
|
7
|
+
* Validates non-file fields using the same ValidatorFn system as validate().
|
|
8
|
+
* File validation (type, content) is left to the developer.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* export async function POST(req: Request) {
|
|
12
|
+
* const { fields, files } = await parseUpload(req);
|
|
13
|
+
*
|
|
14
|
+
* // fields — validated form text fields
|
|
15
|
+
* // files — raw File objects, validate yourself
|
|
16
|
+
*
|
|
17
|
+
* await Bun.write(`./uploads/${files.photo.name}`, files.photo);
|
|
18
|
+
* return Response.json({ ok: true });
|
|
19
|
+
* }
|
|
20
|
+
*/
|
|
21
|
+
import { ServerError } from "./server-fn.js";
|
|
22
|
+
import type { ValidatorFn } from "./validate.js";
|
|
23
|
+
export interface UploadOptions {
|
|
24
|
+
/**
|
|
25
|
+
* Maximum total upload size in bytes.
|
|
26
|
+
* Defaults to server.maxUploadSize from config (10mb).
|
|
27
|
+
*/
|
|
28
|
+
maxSize?: number;
|
|
29
|
+
/**
|
|
30
|
+
* Validate non-file form fields.
|
|
31
|
+
* Keys are field names, values are arrays of ValidatorFn.
|
|
32
|
+
* Files are never validated here — that's up to you.
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* fieldValidators: {
|
|
36
|
+
* title: [isRequired, maxLength(100)],
|
|
37
|
+
* description: [maxLength(500)],
|
|
38
|
+
* }
|
|
39
|
+
*/
|
|
40
|
+
fieldValidators?: Record<string, ValidatorFn[]>;
|
|
41
|
+
/**
|
|
42
|
+
* Required file fields — throw 400 if any are missing.
|
|
43
|
+
*/
|
|
44
|
+
requiredFiles?: string[];
|
|
45
|
+
}
|
|
46
|
+
export interface ParsedUpload {
|
|
47
|
+
/** Text form fields */
|
|
48
|
+
fields: Record<string, string>;
|
|
49
|
+
/** File objects keyed by field name — validate and store yourself */
|
|
50
|
+
files: Record<string, File>;
|
|
51
|
+
/** Multiple files with the same field name */
|
|
52
|
+
multiFiles: Record<string, File[]>;
|
|
53
|
+
}
|
|
54
|
+
export declare class UploadError extends ServerError {
|
|
55
|
+
constructor(message: string, status?: number, code?: string);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Parse a multipart/form-data request.
|
|
59
|
+
*
|
|
60
|
+
* Separates text fields from files.
|
|
61
|
+
* Validates text fields if fieldValidators are provided.
|
|
62
|
+
* Never validates files — that's the developer's responsibility.
|
|
63
|
+
*
|
|
64
|
+
* @throws UploadError if Content-Type is not multipart/form-data or url-encoded
|
|
65
|
+
* @throws UploadError if required files are missing
|
|
66
|
+
* @throws ValidationError if field validation fails
|
|
67
|
+
*/
|
|
68
|
+
export declare function parseUpload(req: Request, options?: UploadOptions): Promise<ParsedUpload>;
|
|
69
|
+
//# sourceMappingURL=upload.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../src/upload.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD,MAAM,WAAW,aAAa;IAC5B;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;;;;;;;;OAUG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC;IAEhD;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,YAAY;IAC3B,uBAAuB;IACvB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,qEAAqE;IACrE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC5B,8CAA8C;IAC9C,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;CACpC;AAED,qBAAa,WAAY,SAAQ,WAAW;gBAC9B,OAAO,EAAE,MAAM,EAAE,MAAM,SAAM,EAAE,IAAI,SAAiB;CAIjE;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,WAAW,CAC/B,GAAG,EAAE,OAAO,EACZ,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,YAAY,CAAC,CAwFvB"}
|
package/dist/upload.js
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* mates-ssr — upload.ts
|
|
3
|
+
*
|
|
4
|
+
* Multipart/form-data parsing for file uploads.
|
|
5
|
+
*
|
|
6
|
+
* Uses Bun's native req.formData() for parsing.
|
|
7
|
+
* Validates non-file fields using the same ValidatorFn system as validate().
|
|
8
|
+
* File validation (type, content) is left to the developer.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* export async function POST(req: Request) {
|
|
12
|
+
* const { fields, files } = await parseUpload(req);
|
|
13
|
+
*
|
|
14
|
+
* // fields — validated form text fields
|
|
15
|
+
* // files — raw File objects, validate yourself
|
|
16
|
+
*
|
|
17
|
+
* await Bun.write(`./uploads/${files.photo.name}`, files.photo);
|
|
18
|
+
* return Response.json({ ok: true });
|
|
19
|
+
* }
|
|
20
|
+
*/
|
|
21
|
+
import { ServerError } from "./server-fn.js";
|
|
22
|
+
import { validate } from "./validate.js";
|
|
23
|
+
export class UploadError extends ServerError {
|
|
24
|
+
constructor(message, status = 400, code = "UPLOAD_ERROR") {
|
|
25
|
+
super(status, message, { code });
|
|
26
|
+
this.name = "UploadError";
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Parse a multipart/form-data request.
|
|
31
|
+
*
|
|
32
|
+
* Separates text fields from files.
|
|
33
|
+
* Validates text fields if fieldValidators are provided.
|
|
34
|
+
* Never validates files — that's the developer's responsibility.
|
|
35
|
+
*
|
|
36
|
+
* @throws UploadError if Content-Type is not multipart/form-data or url-encoded
|
|
37
|
+
* @throws UploadError if required files are missing
|
|
38
|
+
* @throws ValidationError if field validation fails
|
|
39
|
+
*/
|
|
40
|
+
export async function parseUpload(req, options = {}) {
|
|
41
|
+
const contentType = req.headers.get("content-type") ?? "";
|
|
42
|
+
if (!contentType.includes("multipart/form-data") &&
|
|
43
|
+
!contentType.includes("application/x-www-form-urlencoded")) {
|
|
44
|
+
throw new UploadError("Expected multipart/form-data or application/x-www-form-urlencoded", 415, "UNSUPPORTED_MEDIA_TYPE");
|
|
45
|
+
}
|
|
46
|
+
// Check content-length against maxSize if provided
|
|
47
|
+
if (options.maxSize !== undefined) {
|
|
48
|
+
const contentLength = req.headers.get("content-length");
|
|
49
|
+
if (contentLength && parseInt(contentLength, 10) > options.maxSize) {
|
|
50
|
+
throw new UploadError(`Upload too large. Maximum size is ${formatBytes(options.maxSize)}`, 413, "UPLOAD_TOO_LARGE");
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
let formData;
|
|
54
|
+
try {
|
|
55
|
+
formData = await req.formData();
|
|
56
|
+
}
|
|
57
|
+
catch (err) {
|
|
58
|
+
throw new UploadError(`Failed to parse form data: ${err?.message ?? String(err)}`, 400, "PARSE_ERROR");
|
|
59
|
+
}
|
|
60
|
+
const fields = {};
|
|
61
|
+
const files = {};
|
|
62
|
+
const multiFiles = {};
|
|
63
|
+
for (const [key, value] of formData.entries()) {
|
|
64
|
+
if (typeof value === "object" &&
|
|
65
|
+
value !== null &&
|
|
66
|
+
"size" in value &&
|
|
67
|
+
"type" in value) {
|
|
68
|
+
// File — store as-is, no validation here
|
|
69
|
+
const file = value;
|
|
70
|
+
if (!files[key]) {
|
|
71
|
+
files[key] = file;
|
|
72
|
+
multiFiles[key] = [file];
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
multiFiles[key].push(file);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
// Text field — collect for validation
|
|
80
|
+
fields[key] = String(value);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
// Check required files
|
|
84
|
+
if (options.requiredFiles?.length) {
|
|
85
|
+
for (const name of options.requiredFiles) {
|
|
86
|
+
if (!files[name]) {
|
|
87
|
+
throw new UploadError(`Missing required file: "${name}"`, 400, "MISSING_FILE");
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
// Validate text fields using the ValidatorFn system
|
|
92
|
+
if (options.fieldValidators) {
|
|
93
|
+
for (const [fieldName, validators] of Object.entries(options.fieldValidators)) {
|
|
94
|
+
if (validators.length > 0) {
|
|
95
|
+
// validate() throws ValidationError (status 400) on failure
|
|
96
|
+
validate(fields[fieldName], validators, fieldName);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return { fields, files, multiFiles };
|
|
101
|
+
}
|
|
102
|
+
// ─── Internal helpers ─────────────────────────────────────────────────────────
|
|
103
|
+
function formatBytes(bytes) {
|
|
104
|
+
if (bytes < 1024)
|
|
105
|
+
return `${bytes}B`;
|
|
106
|
+
if (bytes < 1024 * 1024)
|
|
107
|
+
return `${(bytes / 1024).toFixed(1)}KB`;
|
|
108
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=upload.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upload.js","sourceRoot":"","sources":["../src/upload.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* mates-ssr — validate.ts
|
|
3
|
+
*
|
|
4
|
+
* Server-side validation helper. Uses the same ValidatorFn type as mates'
|
|
5
|
+
* client-side formAtom validators — same rule, runs on both ends.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* import { validate } from "mates-ssr";
|
|
9
|
+
* import { isRequired, isEmail, minLength } from "mates";
|
|
10
|
+
*
|
|
11
|
+
* export async function POST(req: Request) {
|
|
12
|
+
* const body = await req.json();
|
|
13
|
+
* validate(body.email, [isRequired, isEmail]);
|
|
14
|
+
* validate(body.name, [isRequired, minLength(2)]);
|
|
15
|
+
* // ... proceed knowing data is valid
|
|
16
|
+
* }
|
|
17
|
+
*/
|
|
18
|
+
import { ServerError } from "./server-fn.js";
|
|
19
|
+
export type ValidatorFn<T = any> = (value: T) => string | null;
|
|
20
|
+
/**
|
|
21
|
+
* Thrown when validate() finds errors. Has status=400 for the server
|
|
22
|
+
* error handler to map to an HTTP 400 response.
|
|
23
|
+
*/
|
|
24
|
+
export declare class ValidationError extends ServerError {
|
|
25
|
+
readonly errors: string[];
|
|
26
|
+
readonly field?: string;
|
|
27
|
+
fieldErrors?: Record<string, string[]>;
|
|
28
|
+
constructor(errors: string[], field?: string);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Validate a single value against an array of validators.
|
|
32
|
+
* Throws ValidationError (status 400) if any validator fails.
|
|
33
|
+
* Returns cleanly if all pass.
|
|
34
|
+
*
|
|
35
|
+
* Uses the same ValidatorFn type as mates formAtom — import validators
|
|
36
|
+
* from "mates" and reuse them on the server.
|
|
37
|
+
*
|
|
38
|
+
* @param value The value to validate
|
|
39
|
+
* @param validators Array of validator functions
|
|
40
|
+
* @param field Optional field name for error context
|
|
41
|
+
*/
|
|
42
|
+
export declare function validate<T>(value: T, validators: ValidatorFn<T>[], field?: string): void;
|
|
43
|
+
/**
|
|
44
|
+
* Validate multiple fields at once.
|
|
45
|
+
* Collects ALL errors across all fields before throwing — unlike validate()
|
|
46
|
+
* which throws on the first failing field.
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* validateAll({
|
|
50
|
+
* email: { value: body.email, validators: [isRequired, isEmail] },
|
|
51
|
+
* password: { value: body.password, validators: [isRequired, isStrongPassword()] },
|
|
52
|
+
* });
|
|
53
|
+
*/
|
|
54
|
+
export declare function validateAll(fields: Record<string, {
|
|
55
|
+
value: any;
|
|
56
|
+
validators: ValidatorFn[];
|
|
57
|
+
}>): void;
|
|
58
|
+
//# sourceMappingURL=validate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,MAAM,MAAM,WAAW,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,MAAM,GAAG,IAAI,CAAC;AAE/D;;;GAGG;AACH,qBAAa,eAAgB,SAAQ,WAAW;IAC9C,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;IAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;gBAE3B,MAAM,EAAE,MAAM,EAAE,EAAE,KAAK,CAAC,EAAE,MAAM;CAS7C;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EACxB,KAAK,EAAE,CAAC,EACR,UAAU,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,EAC5B,KAAK,CAAC,EAAE,MAAM,GACb,IAAI,CAQN;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE;IAAE,KAAK,EAAE,GAAG,CAAC;IAAC,UAAU,EAAE,WAAW,EAAE,CAAA;CAAE,CAAC,GAChE,IAAI,CAuBN"}
|
package/dist/validate.js
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* mates-ssr — validate.ts
|
|
3
|
+
*
|
|
4
|
+
* Server-side validation helper. Uses the same ValidatorFn type as mates'
|
|
5
|
+
* client-side formAtom validators — same rule, runs on both ends.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* import { validate } from "mates-ssr";
|
|
9
|
+
* import { isRequired, isEmail, minLength } from "mates";
|
|
10
|
+
*
|
|
11
|
+
* export async function POST(req: Request) {
|
|
12
|
+
* const body = await req.json();
|
|
13
|
+
* validate(body.email, [isRequired, isEmail]);
|
|
14
|
+
* validate(body.name, [isRequired, minLength(2)]);
|
|
15
|
+
* // ... proceed knowing data is valid
|
|
16
|
+
* }
|
|
17
|
+
*/
|
|
18
|
+
import { ServerError } from "./server-fn.js";
|
|
19
|
+
/**
|
|
20
|
+
* Thrown when validate() finds errors. Has status=400 for the server
|
|
21
|
+
* error handler to map to an HTTP 400 response.
|
|
22
|
+
*/
|
|
23
|
+
export class ValidationError extends ServerError {
|
|
24
|
+
errors;
|
|
25
|
+
field;
|
|
26
|
+
fieldErrors;
|
|
27
|
+
constructor(errors, field) {
|
|
28
|
+
super(400, errors.join("; "), {
|
|
29
|
+
code: "VALIDATION_ERROR",
|
|
30
|
+
...(field ? { field } : {}),
|
|
31
|
+
});
|
|
32
|
+
this.name = "ValidationError";
|
|
33
|
+
this.errors = errors;
|
|
34
|
+
this.field = field;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Validate a single value against an array of validators.
|
|
39
|
+
* Throws ValidationError (status 400) if any validator fails.
|
|
40
|
+
* Returns cleanly if all pass.
|
|
41
|
+
*
|
|
42
|
+
* Uses the same ValidatorFn type as mates formAtom — import validators
|
|
43
|
+
* from "mates" and reuse them on the server.
|
|
44
|
+
*
|
|
45
|
+
* @param value The value to validate
|
|
46
|
+
* @param validators Array of validator functions
|
|
47
|
+
* @param field Optional field name for error context
|
|
48
|
+
*/
|
|
49
|
+
export function validate(value, validators, field) {
|
|
50
|
+
const errors = validators
|
|
51
|
+
.map((fn) => fn(value))
|
|
52
|
+
.filter((e) => typeof e === "string" && e.length > 0);
|
|
53
|
+
if (errors.length > 0) {
|
|
54
|
+
throw new ValidationError(errors, field);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Validate multiple fields at once.
|
|
59
|
+
* Collects ALL errors across all fields before throwing — unlike validate()
|
|
60
|
+
* which throws on the first failing field.
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* validateAll({
|
|
64
|
+
* email: { value: body.email, validators: [isRequired, isEmail] },
|
|
65
|
+
* password: { value: body.password, validators: [isRequired, isStrongPassword()] },
|
|
66
|
+
* });
|
|
67
|
+
*/
|
|
68
|
+
export function validateAll(fields) {
|
|
69
|
+
const allErrors = {};
|
|
70
|
+
let hasErrors = false;
|
|
71
|
+
for (const [field, { value, validators }] of Object.entries(fields)) {
|
|
72
|
+
const errors = validators
|
|
73
|
+
.map((fn) => fn(value))
|
|
74
|
+
.filter((e) => typeof e === "string" && e.length > 0);
|
|
75
|
+
if (errors.length > 0) {
|
|
76
|
+
allErrors[field] = errors;
|
|
77
|
+
hasErrors = true;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (hasErrors) {
|
|
81
|
+
const messages = Object.entries(allErrors)
|
|
82
|
+
.map(([f, errs]) => `${f}: ${errs.join(", ")}`)
|
|
83
|
+
.join("; ");
|
|
84
|
+
const err = new ValidationError([messages]);
|
|
85
|
+
err.fieldErrors = allErrors;
|
|
86
|
+
throw err;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAI7C;;;GAGG;AACH,MAAM,OAAO,eAAgB,SAAQ,WAAW;IACrC,MAAM,CAAW;IACjB,KAAK,CAAU;IACxB,WAAW,CAA4B;IAEvC,YAAY,MAAgB,EAAE,KAAc;QAC1C,KAAK,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;YAC5B,IAAI,EAAE,kBAAkB;YACxB,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC5B,CAAC,CAAC;QACH,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;QAC9B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;CACF;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,QAAQ,CACtB,KAAQ,EACR,UAA4B,EAC5B,KAAc;IAEd,MAAM,MAAM,GAAG,UAAU;SACtB,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;SACtB,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAErE,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,eAAe,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAC3C,CAAC;AACH,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,WAAW,CACzB,MAAiE;IAEjE,MAAM,SAAS,GAA6B,EAAE,CAAC;IAC/C,IAAI,SAAS,GAAG,KAAK,CAAC;IAEtB,KAAK,MAAM,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QACpE,MAAM,MAAM,GAAG,UAAU;aACtB,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;aACtB,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAErE,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtB,SAAS,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC;YAC1B,SAAS,GAAG,IAAI,CAAC;QACnB,CAAC;IACH,CAAC;IAED,IAAI,SAAS,EAAE,CAAC;QACd,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC;aACvC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;aAC9C,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,MAAM,GAAG,GAAG,IAAI,eAAe,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC5C,GAAG,CAAC,WAAW,GAAG,SAAS,CAAC;QAC5B,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify-package.d.ts","sourceRoot":"","sources":["../src/verify-package.ts"],"names":[],"mappings":";AA4BA,wBAAgB,aAAa,CAAC,WAAW,SAAoB,GAAG,MAAM,EAAE,CAmDvE"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
const LEGACY_OUTPUTS = [
|
|
6
|
+
"api-router",
|
|
7
|
+
"auth",
|
|
8
|
+
"auth-routes",
|
|
9
|
+
"cli",
|
|
10
|
+
"env",
|
|
11
|
+
"fn-registry",
|
|
12
|
+
"oauth-providers",
|
|
13
|
+
"rest-router",
|
|
14
|
+
"route-guard",
|
|
15
|
+
"routes-router",
|
|
16
|
+
"ws-router",
|
|
17
|
+
"ws-publish",
|
|
18
|
+
];
|
|
19
|
+
export function verifyPackage(projectRoot = findPackageRoot()) {
|
|
20
|
+
const errors = [];
|
|
21
|
+
const pkgPath = path.join(projectRoot, "package.json");
|
|
22
|
+
const pkg = readPackageJson(pkgPath, errors);
|
|
23
|
+
if (!pkg)
|
|
24
|
+
return errors;
|
|
25
|
+
const files = pkg.files ?? [];
|
|
26
|
+
if (!files.includes("dist")) {
|
|
27
|
+
errors.push(`package.json files[] must include "dist".`);
|
|
28
|
+
}
|
|
29
|
+
if (files.includes("src")) {
|
|
30
|
+
errors.push(`package.json files[] must not include "src".`);
|
|
31
|
+
}
|
|
32
|
+
if (!fs.existsSync(path.join(projectRoot, "dist"))) {
|
|
33
|
+
errors.push(`dist/ is missing. Run npm run build before publishing.`);
|
|
34
|
+
}
|
|
35
|
+
checkPackagePath(projectRoot, pkg.main, "main", errors);
|
|
36
|
+
checkPackagePath(projectRoot, pkg.types, "types", errors);
|
|
37
|
+
if (!pkg.exports || typeof pkg.exports !== "object") {
|
|
38
|
+
errors.push(`package.json exports is missing or invalid.`);
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
for (const [exportName, target] of Object.entries(pkg.exports)) {
|
|
42
|
+
for (const rel of collectExportTargets(target)) {
|
|
43
|
+
checkPackagePath(projectRoot, rel, `exports[${exportName}]`, errors);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
if (!pkg.bin) {
|
|
48
|
+
errors.push(`package.json bin is missing.`);
|
|
49
|
+
}
|
|
50
|
+
else if (typeof pkg.bin === "string") {
|
|
51
|
+
checkBinPath(projectRoot, pkg.bin, "bin", errors);
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
for (const [name, rel] of Object.entries(pkg.bin)) {
|
|
55
|
+
checkBinPath(projectRoot, rel, `bin[${name}]`, errors);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
for (const stem of LEGACY_OUTPUTS) {
|
|
59
|
+
for (const ext of [".js", ".d.ts", ".js.map", ".d.ts.map"]) {
|
|
60
|
+
const rel = `dist/${stem}${ext}`;
|
|
61
|
+
if (fs.existsSync(path.join(projectRoot, rel))) {
|
|
62
|
+
errors.push(`legacy output must not be published: ${rel}`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return errors;
|
|
67
|
+
}
|
|
68
|
+
function readPackageJson(pkgPath, errors) {
|
|
69
|
+
try {
|
|
70
|
+
return JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
|
|
71
|
+
}
|
|
72
|
+
catch (err) {
|
|
73
|
+
errors.push(`Unable to read package.json: ${formatError(err)}`);
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
function collectExportTargets(value) {
|
|
78
|
+
if (typeof value === "string")
|
|
79
|
+
return [value];
|
|
80
|
+
if (!value || typeof value !== "object")
|
|
81
|
+
return [];
|
|
82
|
+
const targets = [];
|
|
83
|
+
for (const nested of Object.values(value)) {
|
|
84
|
+
targets.push(...collectExportTargets(nested));
|
|
85
|
+
}
|
|
86
|
+
return targets;
|
|
87
|
+
}
|
|
88
|
+
function checkPackagePath(projectRoot, rel, label, errors) {
|
|
89
|
+
if (!rel) {
|
|
90
|
+
errors.push(`package.json ${label} is missing.`);
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
if (!rel.startsWith("./")) {
|
|
94
|
+
errors.push(`package.json ${label} must be a relative package path: ${rel}`);
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
if (!fs.existsSync(path.resolve(projectRoot, rel))) {
|
|
98
|
+
errors.push(`package.json ${label} points to missing file: ${rel}`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
function checkBinPath(projectRoot, rel, label, errors) {
|
|
102
|
+
checkPackagePath(projectRoot, rel, label, errors);
|
|
103
|
+
const fullPath = path.resolve(projectRoot, rel);
|
|
104
|
+
if (!fs.existsSync(fullPath))
|
|
105
|
+
return;
|
|
106
|
+
const firstLine = fs.readFileSync(fullPath, "utf-8").split(/\r?\n/, 1)[0];
|
|
107
|
+
if (!firstLine.startsWith("#!")) {
|
|
108
|
+
errors.push(`package.json ${label} target is missing a shebang: ${rel}`);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
function findPackageRoot() {
|
|
112
|
+
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
113
|
+
return path.resolve(here, "..");
|
|
114
|
+
}
|
|
115
|
+
function formatError(err) {
|
|
116
|
+
return err instanceof Error ? err.message : String(err);
|
|
117
|
+
}
|
|
118
|
+
if (process.argv[1] === fileURLToPath(import.meta.url)) {
|
|
119
|
+
const errors = verifyPackage();
|
|
120
|
+
if (errors.length > 0) {
|
|
121
|
+
console.error("[mates-fullstack] package verification failed:");
|
|
122
|
+
for (const error of errors)
|
|
123
|
+
console.error(` - ${error}`);
|
|
124
|
+
process.exit(1);
|
|
125
|
+
}
|
|
126
|
+
console.log("[mates-fullstack] package verification passed");
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=verify-package.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify-package.js","sourceRoot":"","sources":["../src/verify-package.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "mates-fullstack",
|
|
3
|
+
"version": "1.0.0-beta.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Full-stack Node.js framework built on the Mates SPA framework. RPC server functions, SSR, WebSockets, file-system routing.",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist",
|
|
10
|
+
"README.md"
|
|
11
|
+
],
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"import": "./dist/index.js"
|
|
16
|
+
},
|
|
17
|
+
"./browser": {
|
|
18
|
+
"types": "./dist/browser.d.ts",
|
|
19
|
+
"import": "./dist/browser.js"
|
|
20
|
+
},
|
|
21
|
+
"./client": {
|
|
22
|
+
"types": "./dist/client.d.ts",
|
|
23
|
+
"import": "./dist/client.js"
|
|
24
|
+
},
|
|
25
|
+
"./server": {
|
|
26
|
+
"types": "./dist/server-public.d.ts",
|
|
27
|
+
"import": "./dist/server-public.js"
|
|
28
|
+
},
|
|
29
|
+
"./internal": {
|
|
30
|
+
"types": "./dist/internal.d.ts",
|
|
31
|
+
"import": "./dist/internal.js"
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"bin": {
|
|
35
|
+
"mates-fullstack": "./dist/cli-new.js"
|
|
36
|
+
},
|
|
37
|
+
"scripts": {
|
|
38
|
+
"clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"",
|
|
39
|
+
"prebuild": "npm run clean",
|
|
40
|
+
"build": "tsc -p tsconfig.build.json",
|
|
41
|
+
"prepack": "npm run build",
|
|
42
|
+
"verify:package": "npm run build && node ./dist/verify-package.js",
|
|
43
|
+
"pack:smoke": "npm run verify:package && npm pack --dry-run",
|
|
44
|
+
"test": "vitest run --config vitest.config.ts",
|
|
45
|
+
"test:watch": "vitest --config vitest.config.ts",
|
|
46
|
+
"test:coverage": "vitest run --config vitest.config.ts --coverage"
|
|
47
|
+
},
|
|
48
|
+
"keywords": [
|
|
49
|
+
"mates",
|
|
50
|
+
"fullstack",
|
|
51
|
+
"ssr",
|
|
52
|
+
"ssg",
|
|
53
|
+
"rpc",
|
|
54
|
+
"server-functions",
|
|
55
|
+
"node",
|
|
56
|
+
"framework"
|
|
57
|
+
],
|
|
58
|
+
"license": "MIT",
|
|
59
|
+
"dependencies": {
|
|
60
|
+
"@jridgewell/trace-mapping": "0.3.31",
|
|
61
|
+
"arctic": "^3.7.0",
|
|
62
|
+
"chokidar": "4.0.3",
|
|
63
|
+
"esbuild": "0.24.0",
|
|
64
|
+
"ws": "8.18.0"
|
|
65
|
+
},
|
|
66
|
+
"devDependencies": {
|
|
67
|
+
"@types/node": "20.0.0",
|
|
68
|
+
"@types/ws": "8.5.13",
|
|
69
|
+
"@vitest/coverage-v8": "2.0.0",
|
|
70
|
+
"typescript": "5.3.2",
|
|
71
|
+
"vitest": "2.0.0"
|
|
72
|
+
},
|
|
73
|
+
"peerDependencies": {
|
|
74
|
+
"mates": "^0.4.0-beta.1"
|
|
75
|
+
},
|
|
76
|
+
"engines": {
|
|
77
|
+
"node": ">=20.0.0"
|
|
78
|
+
}
|
|
79
|
+
}
|