@rudderjs/core 0.0.8

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.
@@ -0,0 +1,147 @@
1
+ // ─── HTTP Status Text Map ──────────────────────────────────
2
+ const HTTP_STATUS_TEXT = {
3
+ 400: 'Bad Request',
4
+ 401: 'Unauthorized',
5
+ 402: 'Payment Required',
6
+ 403: 'Forbidden',
7
+ 404: 'Not Found',
8
+ 405: 'Method Not Allowed',
9
+ 406: 'Not Acceptable',
10
+ 408: 'Request Timeout',
11
+ 409: 'Conflict',
12
+ 410: 'Gone',
13
+ 411: 'Length Required',
14
+ 412: 'Precondition Failed',
15
+ 413: 'Content Too Large',
16
+ 414: 'URI Too Long',
17
+ 415: 'Unsupported Media Type',
18
+ 422: 'Unprocessable Content',
19
+ 423: 'Locked',
20
+ 424: 'Failed Dependency',
21
+ 429: 'Too Many Requests',
22
+ 431: 'Request Header Fields Too Large',
23
+ 451: 'Unavailable For Legal Reasons',
24
+ 500: 'Internal Server Error',
25
+ 501: 'Not Implemented',
26
+ 502: 'Bad Gateway',
27
+ 503: 'Service Unavailable',
28
+ 504: 'Gateway Timeout',
29
+ };
30
+ // ─── HttpException ─────────────────────────────────────────
31
+ export class HttpException extends Error {
32
+ statusCode;
33
+ headers;
34
+ constructor(statusCode, message, headers = {}) {
35
+ super(message ?? HTTP_STATUS_TEXT[statusCode] ?? 'Error');
36
+ this.name = 'HttpException';
37
+ this.statusCode = statusCode;
38
+ this.headers = headers;
39
+ }
40
+ }
41
+ // ─── abort() helpers ──────────────────────────────────────
42
+ export function abort(status, message, headers) {
43
+ throw new HttpException(status, message, headers);
44
+ }
45
+ export function abort_if(condition, status, message, headers) {
46
+ if (condition)
47
+ abort(status, message, headers);
48
+ }
49
+ export function abort_unless(condition, status, message, headers) {
50
+ if (!condition)
51
+ abort(status, message, headers);
52
+ }
53
+ let _reporter = (err) => {
54
+ console.error('[RudderJS]', err);
55
+ };
56
+ /**
57
+ * Override the global exception reporter.
58
+ *
59
+ * Called by `@rudderjs/log`'s service provider automatically when the log
60
+ * package is installed, routing all unhandled exceptions through the log
61
+ * channel. Can also be called in bootstrap/app.ts via `e.reportUsing(fn)`.
62
+ */
63
+ export function setExceptionReporter(fn) {
64
+ _reporter = fn;
65
+ }
66
+ /** Report an exception to the configured reporter (default: console.error). */
67
+ export function report(err) {
68
+ _reporter(err);
69
+ }
70
+ /** Conditionally report an exception. */
71
+ export function report_if(condition, err) {
72
+ if (condition)
73
+ report(err);
74
+ }
75
+ // ─── Internal rendering helpers ───────────────────────────
76
+ function wantsJson(req) {
77
+ const accept = req.headers['accept'] ?? '';
78
+ // Treat as JSON unless Accept explicitly prefers HTML
79
+ if (!accept)
80
+ return true;
81
+ if (accept.includes('application/json'))
82
+ return true;
83
+ if (accept.includes('text/html') && !accept.includes('application/json'))
84
+ return false;
85
+ return true;
86
+ }
87
+ function htmlPage(status, message, detail) {
88
+ return `<!DOCTYPE html>
89
+ <html lang="en">
90
+ <head>
91
+ <meta charset="UTF-8">
92
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
93
+ <title>${status} ${message}</title>
94
+ <style>
95
+ *{box-sizing:border-box;margin:0;padding:0}
96
+ body{font-family:system-ui,-apple-system,sans-serif;background:#f8f9fa;color:#1a1a1a;
97
+ display:flex;align-items:center;justify-content:center;min-height:100vh}
98
+ .card{background:#fff;border:1px solid #e5e7eb;border-radius:12px;padding:56px 48px;
99
+ text-align:center;max-width:520px;width:100%;box-shadow:0 1px 3px rgba(0,0,0,.06)}
100
+ h1{font-size:4.5rem;font-weight:800;color:#e5e7eb;line-height:1;margin-bottom:12px}
101
+ h2{font-size:1.25rem;font-weight:600;color:#374151;margin-bottom:8px}
102
+ p{font-size:.9rem;color:#6b7280;line-height:1.6}
103
+ pre{margin-top:24px;text-align:left;background:#f3f4f6;border-radius:6px;
104
+ padding:16px;font-size:.8rem;color:#374151;overflow:auto;white-space:pre-wrap;word-break:break-word}
105
+ </style>
106
+ </head>
107
+ <body>
108
+ <div class="card">
109
+ <h1>${status}</h1>
110
+ <h2>${message}</h2>
111
+ ${detail ? `<pre>${detail}</pre>` : ''}
112
+ </div>
113
+ </body>
114
+ </html>`;
115
+ }
116
+ /** @internal — render an HttpException as a Response. */
117
+ export function renderHttpException(err, req) {
118
+ const status = err.statusCode;
119
+ const message = err.message;
120
+ const headers = { ...err.headers };
121
+ if (wantsJson(req)) {
122
+ headers['Content-Type'] = 'application/json';
123
+ return new Response(JSON.stringify({ message, status }), { status, headers });
124
+ }
125
+ headers['Content-Type'] = 'text/html; charset=utf-8';
126
+ return new Response(htmlPage(status, message), { status, headers });
127
+ }
128
+ /** @internal — render an unhandled error as a 500 Response. */
129
+ export function renderServerError(req, debug, err) {
130
+ const status = 500;
131
+ const message = 'Internal Server Error';
132
+ const headers = {};
133
+ if (wantsJson(req)) {
134
+ headers['Content-Type'] = 'application/json';
135
+ const body = { message, status };
136
+ if (debug && err instanceof Error) {
137
+ body['exception'] = err.message;
138
+ if (err.stack)
139
+ body['trace'] = err.stack.split('\n').slice(1).map(l => l.trim());
140
+ }
141
+ return new Response(JSON.stringify(body), { status, headers });
142
+ }
143
+ headers['Content-Type'] = 'text/html; charset=utf-8';
144
+ const detail = debug && err instanceof Error && err.stack ? err.stack : undefined;
145
+ return new Response(htmlPage(status, message, detail), { status, headers });
146
+ }
147
+ //# sourceMappingURL=exceptions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exceptions.js","sourceRoot":"","sources":["../src/exceptions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ export { Application, RudderJS, AppBuilder, MiddlewareConfigurator, ExceptionConfigurator, app, resolve, defineConfig, } from './application.js';
2
+ export type { BootConfig, ConfigureOptions, RoutingOptions, ErrorRenderer, ProviderClass } from './application.js';
3
+ export { Container, ContextualBindingBuilder, container, Injectable, Inject } from './di.js';
4
+ export { ServiceProvider, getPublishGroups } from './service-provider.js';
5
+ export type { PublishGroup } from './service-provider.js';
6
+ export { Listener, EventDispatcher, dispatcher, dispatch, events } from './events.js';
7
+ export type { ListenMap } from './events.js';
8
+ export { EventFake } from './events-fake.js';
9
+ export type { DispatchedEvent } from './events-fake.js';
10
+ export { FormRequest, ValidationError, validate, validateWith, z } from './validation.js';
11
+ export { rudder, Rudder, CommandRegistry, CommandBuilder, Command, CancelledError, parseSignature } from '@rudderjs/rudder';
12
+ export type { ConsoleHandler, CommandArgDef, CommandOptDef, ParsedSignature } from '@rudderjs/rudder';
13
+ export { Collection, Env, env, sleep, ucfirst, tap, pick, omit, defineEnv, ConfigRepository, resolveOptionalPeer, dump, dd, } from '@rudderjs/support';
14
+ export { HttpException, abort, abort_if, abort_unless, report, report_if, setExceptionReporter, } from './exceptions.js';
15
+ export { config } from './config.js';
16
+ export type { AppConfig } from './config.js';
17
+ export type { AppRequest, AppResponse, RouteHandler, MiddlewareHandler, HttpMethod, RouteDefinition, ServerAdapter, ServerAdapterFactory, FetchHandler, ServerAdapterProvider, } from '@rudderjs/contracts';
18
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,WAAW,EACX,QAAQ,EACR,UAAU,EACV,sBAAsB,EACtB,qBAAqB,EACrB,GAAG,EACH,OAAO,EACP,YAAY,GACb,MAAM,kBAAkB,CAAA;AACzB,YAAY,EAAE,UAAU,EAAE,gBAAgB,EAAE,cAAc,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAIlH,OAAO,EAAE,SAAS,EAAE,wBAAwB,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAI5F,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AACzE,YAAY,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAIzD,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACrF,YAAY,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAC5C,YAAY,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAIvD,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC,EAAE,MAAM,iBAAiB,CAAA;AAIzF,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,cAAc,EAAE,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAC3H,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAIrG,OAAO,EACL,UAAU,EACV,GAAG,EACH,GAAG,EACH,KAAK,EACL,OAAO,EACP,GAAG,EACH,IAAI,EACJ,IAAI,EACJ,SAAS,EACT,gBAAgB,EAChB,mBAAmB,EACnB,IAAI,EACJ,EAAE,GACH,MAAM,mBAAmB,CAAA;AAI1B,OAAO,EACL,aAAa,EACb,KAAK,EACL,QAAQ,EACR,YAAY,EACZ,MAAM,EACN,SAAS,EACT,oBAAoB,GACrB,MAAM,iBAAiB,CAAA;AAMxB,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,YAAY,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAI5C,YAAY,EACV,UAAU,EACV,WAAW,EACX,YAAY,EACZ,iBAAiB,EACjB,UAAU,EACV,eAAe,EACf,aAAa,EACb,oBAAoB,EACpB,YAAY,EACZ,qBAAqB,GACtB,MAAM,qBAAqB,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,22 @@
1
+ // ─── Application ───────────────────────────────────────────
2
+ export { Application, RudderJS, AppBuilder, MiddlewareConfigurator, ExceptionConfigurator, app, resolve, defineConfig, } from './application.js';
3
+ // ─── DI ────────────────────────────────────────────────────
4
+ export { Container, ContextualBindingBuilder, container, Injectable, Inject } from './di.js';
5
+ // ─── Service Provider ──────────────────────────────────────
6
+ export { ServiceProvider, getPublishGroups } from './service-provider.js';
7
+ // ─── Events ────────────────────────────────────────────────
8
+ export { EventDispatcher, dispatcher, dispatch, events } from './events.js';
9
+ export { EventFake } from './events-fake.js';
10
+ // ─── Validation ────────────────────────────────────────────
11
+ export { FormRequest, ValidationError, validate, validateWith, z } from './validation.js';
12
+ // ─── Rudder ───────────────────────────────────────────────
13
+ export { rudder, Rudder, CommandRegistry, CommandBuilder, Command, CancelledError, parseSignature } from '@rudderjs/rudder';
14
+ // ─── Support ───────────────────────────────────────────────
15
+ export { Collection, Env, env, sleep, ucfirst, tap, pick, omit, defineEnv, ConfigRepository, resolveOptionalPeer, dump, dd, } from '@rudderjs/support';
16
+ // ─── Exceptions ────────────────────────────────────────────
17
+ export { HttpException, abort, abort_if, abort_unless, report, report_if, setExceptionReporter, } from './exceptions.js';
18
+ // ─── Typed config ──────────────────────────────────────────
19
+ // Overrides the untyped config() from @rudderjs/support with a version
20
+ // that infers return types from the augmented AppConfig interface.
21
+ export { config } from './config.js';
22
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAE9D,OAAO,EACL,WAAW,EACX,QAAQ,EACR,UAAU,EACV,sBAAsB,EACtB,qBAAqB,EACrB,GAAG,EACH,OAAO,EACP,YAAY,GACb,MAAM,kBAAkB,CAAA;AAGzB,8DAA8D;AAE9D,OAAO,EAAE,SAAS,EAAE,wBAAwB,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAE5F,8DAA8D;AAE9D,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAGzE,8DAA8D;AAE9D,OAAO,EAAY,eAAe,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAErF,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAG5C,8DAA8D;AAE9D,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC,EAAE,MAAM,iBAAiB,CAAA;AAEzF,6DAA6D;AAE7D,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,cAAc,EAAE,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAG3H,8DAA8D;AAE9D,OAAO,EACL,UAAU,EACV,GAAG,EACH,GAAG,EACH,KAAK,EACL,OAAO,EACP,GAAG,EACH,IAAI,EACJ,IAAI,EACJ,SAAS,EACT,gBAAgB,EAChB,mBAAmB,EACnB,IAAI,EACJ,EAAE,GACH,MAAM,mBAAmB,CAAA;AAE1B,8DAA8D;AAE9D,OAAO,EACL,aAAa,EACb,KAAK,EACL,QAAQ,EACR,YAAY,EACZ,MAAM,EACN,SAAS,EACT,oBAAoB,GACrB,MAAM,iBAAiB,CAAA;AAExB,8DAA8D;AAC9D,uEAAuE;AACvE,mEAAmE;AAEnE,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA"}
@@ -0,0 +1,49 @@
1
+ import type { Application } from './index.js';
2
+ export interface PublishGroup {
3
+ /** Absolute path to the source file or directory to copy. */
4
+ from: string;
5
+ /** Destination path relative to the app root. */
6
+ to: string;
7
+ /** Optional tag for selective publishing (e.g. 'panels-pages'). */
8
+ tag?: string;
9
+ /**
10
+ * Always overwrite existing files — useful for framework-managed pages
11
+ * that users should never customize (e.g. admin panel UI).
12
+ * Auth pages should NOT set this — users may customize them.
13
+ */
14
+ force?: boolean;
15
+ /** If set, only publish when this ORM is detected in the project. */
16
+ orm?: 'prisma' | 'drizzle';
17
+ /** If set, only publish when this database driver is detected. Used with orm='drizzle'. */
18
+ driver?: 'sqlite' | 'postgresql' | 'mysql';
19
+ }
20
+ /** @internal — read by the vendor:publish rudder command */
21
+ export declare function getPublishGroups(): Map<string, PublishGroup[]>;
22
+ export declare abstract class ServiceProvider {
23
+ protected app: Application;
24
+ constructor(app: Application);
25
+ /** Register bindings into the container */
26
+ abstract register(): void;
27
+ /** Called after all providers are registered */
28
+ boot?(): void | Promise<void>;
29
+ /**
30
+ * If defined, this provider is **deferred** — its `register()` and `boot()`
31
+ * are not called during bootstrap but lazily when one of the returned tokens
32
+ * is first resolved from the container.
33
+ *
34
+ * **Constraint**: deferred providers must have a synchronous `boot()` (or none).
35
+ */
36
+ provides?(): string[];
37
+ /**
38
+ * Register assets that can be published to the application with `vendor:publish`.
39
+ *
40
+ * @example
41
+ * this.publishes({
42
+ * from: new URL('../pages', import.meta.url).pathname,
43
+ * to: 'pages/(panels)',
44
+ * tag: 'panels-pages',
45
+ * })
46
+ */
47
+ protected publishes(group: PublishGroup | PublishGroup[]): void;
48
+ }
49
+ //# sourceMappingURL=service-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service-provider.d.ts","sourceRoot":"","sources":["../src/service-provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAI7C,MAAM,WAAW,YAAY;IAC3B,6DAA6D;IAC7D,IAAI,EAAE,MAAM,CAAA;IACZ,iDAAiD;IACjD,EAAE,EAAI,MAAM,CAAA;IACZ,mEAAmE;IACnE,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ;;;;OAIG;IACH,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,qEAAqE;IACrE,GAAG,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAA;IAC1B,2FAA2F;IAC3F,MAAM,CAAC,EAAE,QAAQ,GAAG,YAAY,GAAG,OAAO,CAAA;CAC3C;AAMD,4DAA4D;AAC5D,wBAAgB,gBAAgB,IAAI,GAAG,CAAC,MAAM,EAAE,YAAY,EAAE,CAAC,CAE9D;AAID,8BAAsB,eAAe;IACvB,SAAS,CAAC,GAAG,EAAE,WAAW;gBAAhB,GAAG,EAAE,WAAW;IAEtC,2CAA2C;IAC3C,QAAQ,CAAC,QAAQ,IAAI,IAAI;IAEzB,gDAAgD;IAChD,IAAI,CAAC,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAE7B;;;;;;OAMG;IACH,QAAQ,CAAC,IAAI,MAAM,EAAE;IAErB;;;;;;;;;OASG;IACH,SAAS,CAAC,SAAS,CAAC,KAAK,EAAE,YAAY,GAAG,YAAY,EAAE,GAAG,IAAI;CAgBhE"}
@@ -0,0 +1,42 @@
1
+ const _g = globalThis;
2
+ const _key = '__rudderjs_publish_registry__';
3
+ if (!_g[_key])
4
+ _g[_key] = new Map();
5
+ /** @internal — read by the vendor:publish rudder command */
6
+ export function getPublishGroups() {
7
+ return _g[_key];
8
+ }
9
+ // ─── Service Provider ──────────────────────────────────────
10
+ export class ServiceProvider {
11
+ app;
12
+ constructor(app) {
13
+ this.app = app;
14
+ }
15
+ /**
16
+ * Register assets that can be published to the application with `vendor:publish`.
17
+ *
18
+ * @example
19
+ * this.publishes({
20
+ * from: new URL('../pages', import.meta.url).pathname,
21
+ * to: 'pages/(panels)',
22
+ * tag: 'panels-pages',
23
+ * })
24
+ */
25
+ publishes(group) {
26
+ // Anonymous classes (e.g. from factory functions) have constructor.name === ''.
27
+ // Walk up the prototype chain to find the nearest named class.
28
+ let name = this.constructor.name;
29
+ if (!name) {
30
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
31
+ let proto = Object.getPrototypeOf(this);
32
+ while (proto && !proto.constructor.name) {
33
+ proto = Object.getPrototypeOf(proto);
34
+ }
35
+ name = proto?.constructor.name ?? 'ServiceProvider';
36
+ }
37
+ const items = Array.isArray(group) ? group : [group];
38
+ const registry = getPublishGroups();
39
+ registry.set(name, [...(registry.get(name) ?? []), ...items]);
40
+ }
41
+ }
42
+ //# sourceMappingURL=service-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service-provider.js","sourceRoot":"","sources":["../src/service-provider.ts"],"names":[],"mappings":"AAuBA,MAAM,EAAE,GAAG,UAAqC,CAAA;AAChD,MAAM,IAAI,GAAG,+BAA+B,CAAA;AAC5C,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC;IAAE,EAAE,CAAC,IAAI,CAAC,GAAG,IAAI,GAAG,EAA0B,CAAA;AAE3D,4DAA4D;AAC5D,MAAM,UAAU,gBAAgB;IAC9B,OAAO,EAAE,CAAC,IAAI,CAAgC,CAAA;AAChD,CAAC;AAED,8DAA8D;AAE9D,MAAM,OAAgB,eAAe;IACb;IAAtB,YAAsB,GAAgB;QAAhB,QAAG,GAAH,GAAG,CAAa;IAAG,CAAC;IAiB1C;;;;;;;;;OASG;IACO,SAAS,CAAC,KAAoC;QACtD,gFAAgF;QAChF,+DAA+D;QAC/D,IAAI,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAA;QAChC,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,8DAA8D;YAC9D,IAAI,KAAK,GAAQ,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,CAAA;YAC5C,OAAO,KAAK,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;gBACxC,KAAK,GAAG,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,CAAA;YACtC,CAAC;YACD,IAAI,GAAG,KAAK,EAAE,WAAW,CAAC,IAAI,IAAI,iBAAiB,CAAA;QACrD,CAAC;QACD,MAAM,KAAK,GAAM,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAA;QACvD,MAAM,QAAQ,GAAG,gBAAgB,EAAE,CAAA;QACnC,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,KAAK,CAAC,CAAC,CAAA;IAC/D,CAAC;CACF"}
@@ -0,0 +1,20 @@
1
+ import { z, ZodType } from 'zod';
2
+ import type { AppRequest, AppResponse } from '@rudderjs/contracts';
3
+ export declare class ValidationError extends Error {
4
+ errors: Record<string, string[]>;
5
+ constructor(errors: Record<string, string[]>);
6
+ toJSON(): {
7
+ message: string;
8
+ errors: Record<string, string[]>;
9
+ };
10
+ }
11
+ export declare abstract class FormRequest<T extends ZodType = ZodType> {
12
+ protected req: AppRequest;
13
+ abstract rules(): T;
14
+ authorize(): boolean;
15
+ validate(req: AppRequest): Promise<z.infer<T>>;
16
+ }
17
+ export declare function validate<T extends ZodType>(schema: T, req: AppRequest): Promise<z.infer<T>>;
18
+ export declare function validateWith<T extends ZodType>(schema: T): (req: AppRequest, _res: AppResponse, next: () => Promise<void>) => Promise<void>;
19
+ export { z } from 'zod';
20
+ //# sourceMappingURL=validation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,OAAO,EAAY,MAAM,KAAK,CAAA;AAC1C,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAIlE,qBAAa,eAAgB,SAAQ,KAAK;IACrB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;gBAAhC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;IAKnD,MAAM;;;;CAMP;AAID,8BAAsB,WAAW,CAAC,CAAC,SAAS,OAAO,GAAG,OAAO;IAC3D,SAAS,CAAC,GAAG,EAAG,UAAU,CAAA;IAE1B,QAAQ,CAAC,KAAK,IAAI,CAAC;IAEnB,SAAS,IAAI,OAAO;IAId,QAAQ,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;CA2BrD;AAID,wBAAsB,QAAQ,CAAC,CAAC,SAAS,OAAO,EAC9C,MAAM,EAAE,CAAC,EACT,GAAG,EAAE,UAAU,GACd,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAoBrB;AAID,wBAAgB,YAAY,CAAC,CAAC,SAAS,OAAO,EAAE,MAAM,EAAE,CAAC,IAErD,KAAK,UAAU,EACf,MAAM,WAAW,EACjB,MAAM,MAAM,OAAO,CAAC,IAAI,CAAC,mBAK5B;AAED,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA"}
@@ -0,0 +1,79 @@
1
+ import { ZodError } from 'zod';
2
+ // ─── Validation Error ──────────────────────────────────────
3
+ export class ValidationError extends Error {
4
+ errors;
5
+ constructor(errors) {
6
+ super('Validation failed');
7
+ this.errors = errors;
8
+ this.name = 'ValidationError';
9
+ }
10
+ toJSON() {
11
+ return {
12
+ message: this.message,
13
+ errors: this.errors,
14
+ };
15
+ }
16
+ }
17
+ // ─── Form Request ──────────────────────────────────────────
18
+ export class FormRequest {
19
+ req;
20
+ authorize() {
21
+ return true;
22
+ }
23
+ async validate(req) {
24
+ this.req = req;
25
+ if (!this.authorize()) {
26
+ throw new ValidationError({ auth: ['Unauthorized'] });
27
+ }
28
+ const input = {
29
+ ...(typeof req.body === 'object' && req.body !== null ? req.body : {}),
30
+ ...req.query,
31
+ ...req.params,
32
+ };
33
+ try {
34
+ return this.rules().parse(input);
35
+ }
36
+ catch (err) {
37
+ if (err instanceof ZodError) {
38
+ const errors = {};
39
+ for (const issue of err.issues) {
40
+ const key = issue.path.join('.') || 'root';
41
+ errors[key] = [...(errors[key] ?? []), issue.message];
42
+ }
43
+ throw new ValidationError(errors);
44
+ }
45
+ throw err;
46
+ }
47
+ }
48
+ }
49
+ // ─── validate helper ───────────────────────────────────────
50
+ export async function validate(schema, req) {
51
+ const input = {
52
+ ...(typeof req.body === 'object' && req.body !== null ? req.body : {}),
53
+ ...req.query,
54
+ ...req.params,
55
+ };
56
+ try {
57
+ return schema.parse(input);
58
+ }
59
+ catch (err) {
60
+ if (err instanceof ZodError) {
61
+ const errors = {};
62
+ for (const issue of err.issues) {
63
+ const key = issue.path.join('.') || 'root';
64
+ errors[key] = [...(errors[key] ?? []), issue.message];
65
+ }
66
+ throw new ValidationError(errors);
67
+ }
68
+ throw err;
69
+ }
70
+ }
71
+ // ─── validateWith middleware ───────────────────────────────
72
+ export function validateWith(schema) {
73
+ return async (req, _res, next) => {
74
+ await validate(schema, req);
75
+ await next();
76
+ };
77
+ }
78
+ export { z } from 'zod';
79
+ //# sourceMappingURL=validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.js","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@rudderjs/core",
3
+ "version": "0.0.8",
4
+ "license": "MIT",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "https://github.com/rudderjs/rudder",
8
+ "directory": "packages/core"
9
+ },
10
+ "type": "module",
11
+ "files": [
12
+ "dist",
13
+ "boost"
14
+ ],
15
+ "main": "./dist/index.js",
16
+ "types": "./dist/index.d.ts",
17
+ "sideEffects": [
18
+ "./dist/index.js"
19
+ ],
20
+ "exports": {
21
+ ".": {
22
+ "import": "./dist/index.js",
23
+ "types": "./dist/index.d.ts"
24
+ }
25
+ },
26
+ "dependencies": {
27
+ "reflect-metadata": "^0.2.2",
28
+ "zod": "^4.0.0",
29
+ "@rudderjs/contracts": "0.0.3",
30
+ "@rudderjs/router": "0.0.3",
31
+ "@rudderjs/rudder": "0.0.2",
32
+ "@rudderjs/support": "0.0.3"
33
+ },
34
+ "devDependencies": {
35
+ "@types/node": "^20.0.0",
36
+ "typescript": "^5.4.0",
37
+ "tsx": "^4.0.0"
38
+ },
39
+ "author": "Suleiman Shahbari",
40
+ "scripts": {
41
+ "build": "tsc -p tsconfig.build.json",
42
+ "dev": "tsc -p tsconfig.build.json --watch",
43
+ "typecheck": "tsc --noEmit",
44
+ "lint": "eslint src",
45
+ "clean": "rm -rf dist",
46
+ "test": "tsc -p tsconfig.test.json && node --test dist-test/*.test.js; EXIT=$?; rm -rf dist-test; exit $EXIT"
47
+ }
48
+ }