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.
Files changed (202) hide show
  1. package/README.md +311 -0
  2. package/dist/arctic-auth.d.ts +101 -0
  3. package/dist/arctic-auth.d.ts.map +1 -0
  4. package/dist/arctic-auth.js +538 -0
  5. package/dist/arctic-auth.js.map +1 -0
  6. package/dist/asset-manifest.d.ts +14 -0
  7. package/dist/asset-manifest.d.ts.map +1 -0
  8. package/dist/asset-manifest.js +102 -0
  9. package/dist/asset-manifest.js.map +1 -0
  10. package/dist/browser.d.ts +18 -0
  11. package/dist/browser.d.ts.map +1 -0
  12. package/dist/browser.js +25 -0
  13. package/dist/browser.js.map +1 -0
  14. package/dist/build-esbuild.d.ts +29 -0
  15. package/dist/build-esbuild.d.ts.map +1 -0
  16. package/dist/build-esbuild.js +699 -0
  17. package/dist/build-esbuild.js.map +1 -0
  18. package/dist/build-prod.d.ts +126 -0
  19. package/dist/build-prod.d.ts.map +1 -0
  20. package/dist/build-prod.js +1014 -0
  21. package/dist/build-prod.js.map +1 -0
  22. package/dist/cli-new.d.ts +14 -0
  23. package/dist/cli-new.d.ts.map +1 -0
  24. package/dist/cli-new.js +637 -0
  25. package/dist/cli-new.js.map +1 -0
  26. package/dist/client.d.ts +43 -0
  27. package/dist/client.d.ts.map +1 -0
  28. package/dist/client.js +130 -0
  29. package/dist/client.js.map +1 -0
  30. package/dist/cors.d.ts +16 -0
  31. package/dist/cors.d.ts.map +1 -0
  32. package/dist/cors.js +60 -0
  33. package/dist/cors.js.map +1 -0
  34. package/dist/ctx.d.ts +78 -0
  35. package/dist/ctx.d.ts.map +1 -0
  36. package/dist/ctx.js +280 -0
  37. package/dist/ctx.js.map +1 -0
  38. package/dist/dev-watcher.d.ts +23 -0
  39. package/dist/dev-watcher.d.ts.map +1 -0
  40. package/dist/dev-watcher.js +136 -0
  41. package/dist/dev-watcher.js.map +1 -0
  42. package/dist/docs-generator.d.ts +69 -0
  43. package/dist/docs-generator.d.ts.map +1 -0
  44. package/dist/docs-generator.js +557 -0
  45. package/dist/docs-generator.js.map +1 -0
  46. package/dist/docs-page.d.ts +20 -0
  47. package/dist/docs-page.d.ts.map +1 -0
  48. package/dist/docs-page.js +1152 -0
  49. package/dist/docs-page.js.map +1 -0
  50. package/dist/download.d.ts +78 -0
  51. package/dist/download.d.ts.map +1 -0
  52. package/dist/download.js +202 -0
  53. package/dist/download.js.map +1 -0
  54. package/dist/env-loader.d.ts +76 -0
  55. package/dist/env-loader.d.ts.map +1 -0
  56. package/dist/env-loader.js +213 -0
  57. package/dist/env-loader.js.map +1 -0
  58. package/dist/errors.d.ts +146 -0
  59. package/dist/errors.d.ts.map +1 -0
  60. package/dist/errors.js +386 -0
  61. package/dist/errors.js.map +1 -0
  62. package/dist/head.d.ts +31 -0
  63. package/dist/head.d.ts.map +1 -0
  64. package/dist/head.js +245 -0
  65. package/dist/head.js.map +1 -0
  66. package/dist/index.d.ts +30 -0
  67. package/dist/index.d.ts.map +1 -0
  68. package/dist/index.js +30 -0
  69. package/dist/index.js.map +1 -0
  70. package/dist/internal-prefixes.d.ts +16 -0
  71. package/dist/internal-prefixes.d.ts.map +1 -0
  72. package/dist/internal-prefixes.js +16 -0
  73. package/dist/internal-prefixes.js.map +1 -0
  74. package/dist/internal.d.ts +25 -0
  75. package/dist/internal.d.ts.map +1 -0
  76. package/dist/internal.js +25 -0
  77. package/dist/internal.js.map +1 -0
  78. package/dist/jwt.d.ts +166 -0
  79. package/dist/jwt.d.ts.map +1 -0
  80. package/dist/jwt.js +261 -0
  81. package/dist/jwt.js.map +1 -0
  82. package/dist/log.d.ts +44 -0
  83. package/dist/log.d.ts.map +1 -0
  84. package/dist/log.js +66 -0
  85. package/dist/log.js.map +1 -0
  86. package/dist/logger.d.ts +76 -0
  87. package/dist/logger.d.ts.map +1 -0
  88. package/dist/logger.js +138 -0
  89. package/dist/logger.js.map +1 -0
  90. package/dist/main-runner.d.ts +59 -0
  91. package/dist/main-runner.d.ts.map +1 -0
  92. package/dist/main-runner.js +157 -0
  93. package/dist/main-runner.js.map +1 -0
  94. package/dist/mates-auth.d.ts +82 -0
  95. package/dist/mates-auth.d.ts.map +1 -0
  96. package/dist/mates-auth.js +323 -0
  97. package/dist/mates-auth.js.map +1 -0
  98. package/dist/middleware.d.ts +30 -0
  99. package/dist/middleware.d.ts.map +1 -0
  100. package/dist/middleware.js +67 -0
  101. package/dist/middleware.js.map +1 -0
  102. package/dist/project-resolver.d.ts +102 -0
  103. package/dist/project-resolver.d.ts.map +1 -0
  104. package/dist/project-resolver.js +271 -0
  105. package/dist/project-resolver.js.map +1 -0
  106. package/dist/rate-limit.d.ts +37 -0
  107. package/dist/rate-limit.d.ts.map +1 -0
  108. package/dist/rate-limit.js +109 -0
  109. package/dist/rate-limit.js.map +1 -0
  110. package/dist/redirect.d.ts +84 -0
  111. package/dist/redirect.d.ts.map +1 -0
  112. package/dist/redirect.js +105 -0
  113. package/dist/redirect.js.map +1 -0
  114. package/dist/renderer.d.ts +91 -0
  115. package/dist/renderer.d.ts.map +1 -0
  116. package/dist/renderer.js +630 -0
  117. package/dist/renderer.js.map +1 -0
  118. package/dist/request-logger.d.ts +12 -0
  119. package/dist/request-logger.d.ts.map +1 -0
  120. package/dist/request-logger.js +55 -0
  121. package/dist/request-logger.js.map +1 -0
  122. package/dist/rest.d.ts +25 -0
  123. package/dist/rest.d.ts.map +1 -0
  124. package/dist/rest.js +93 -0
  125. package/dist/rest.js.map +1 -0
  126. package/dist/router.d.ts +71 -0
  127. package/dist/router.d.ts.map +1 -0
  128. package/dist/router.js +222 -0
  129. package/dist/router.js.map +1 -0
  130. package/dist/rpc-registry.d.ts +84 -0
  131. package/dist/rpc-registry.d.ts.map +1 -0
  132. package/dist/rpc-registry.js +271 -0
  133. package/dist/rpc-registry.js.map +1 -0
  134. package/dist/rpc-runner.d.ts +82 -0
  135. package/dist/rpc-runner.d.ts.map +1 -0
  136. package/dist/rpc-runner.js +564 -0
  137. package/dist/rpc-runner.js.map +1 -0
  138. package/dist/sanitize.d.ts +61 -0
  139. package/dist/sanitize.d.ts.map +1 -0
  140. package/dist/sanitize.js +193 -0
  141. package/dist/sanitize.js.map +1 -0
  142. package/dist/security-headers.d.ts +114 -0
  143. package/dist/security-headers.d.ts.map +1 -0
  144. package/dist/security-headers.js +121 -0
  145. package/dist/security-headers.js.map +1 -0
  146. package/dist/server-fn.d.ts +323 -0
  147. package/dist/server-fn.d.ts.map +1 -0
  148. package/dist/server-fn.js +373 -0
  149. package/dist/server-fn.js.map +1 -0
  150. package/dist/server-public.d.ts +13 -0
  151. package/dist/server-public.d.ts.map +1 -0
  152. package/dist/server-public.js +12 -0
  153. package/dist/server-public.js.map +1 -0
  154. package/dist/server-timeout.d.ts +38 -0
  155. package/dist/server-timeout.d.ts.map +1 -0
  156. package/dist/server-timeout.js +46 -0
  157. package/dist/server-timeout.js.map +1 -0
  158. package/dist/server.d.ts +100 -0
  159. package/dist/server.d.ts.map +1 -0
  160. package/dist/server.js +1218 -0
  161. package/dist/server.js.map +1 -0
  162. package/dist/socket-router.d.ts +153 -0
  163. package/dist/socket-router.d.ts.map +1 -0
  164. package/dist/socket-router.js +612 -0
  165. package/dist/socket-router.js.map +1 -0
  166. package/dist/sso.d.ts +90 -0
  167. package/dist/sso.d.ts.map +1 -0
  168. package/dist/sso.js +261 -0
  169. package/dist/sso.js.map +1 -0
  170. package/dist/ssr-context.d.ts +49 -0
  171. package/dist/ssr-context.d.ts.map +1 -0
  172. package/dist/ssr-context.js +85 -0
  173. package/dist/ssr-context.js.map +1 -0
  174. package/dist/ssr-globals.d.ts +32 -0
  175. package/dist/ssr-globals.d.ts.map +1 -0
  176. package/dist/ssr-globals.js +1010 -0
  177. package/dist/ssr-globals.js.map +1 -0
  178. package/dist/ssr-template.d.ts +73 -0
  179. package/dist/ssr-template.d.ts.map +1 -0
  180. package/dist/ssr-template.js +507 -0
  181. package/dist/ssr-template.js.map +1 -0
  182. package/dist/stack-mapper.d.ts +25 -0
  183. package/dist/stack-mapper.d.ts.map +1 -0
  184. package/dist/stack-mapper.js +139 -0
  185. package/dist/stack-mapper.js.map +1 -0
  186. package/dist/stream.d.ts +89 -0
  187. package/dist/stream.d.ts.map +1 -0
  188. package/dist/stream.js +299 -0
  189. package/dist/stream.js.map +1 -0
  190. package/dist/upload.d.ts +69 -0
  191. package/dist/upload.d.ts.map +1 -0
  192. package/dist/upload.js +110 -0
  193. package/dist/upload.js.map +1 -0
  194. package/dist/validate.d.ts +58 -0
  195. package/dist/validate.d.ts.map +1 -0
  196. package/dist/validate.js +89 -0
  197. package/dist/validate.js.map +1 -0
  198. package/dist/verify-package.d.ts +3 -0
  199. package/dist/verify-package.d.ts.map +1 -0
  200. package/dist/verify-package.js +128 -0
  201. package/dist/verify-package.js.map +1 -0
  202. package/package.json +79 -0
@@ -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"}
@@ -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,3 @@
1
+ #!/usr/bin/env node
2
+ export declare function verifyPackage(projectRoot?: string): string[];
3
+ //# sourceMappingURL=verify-package.d.ts.map
@@ -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
+ }