sleepy-serv 0.6.1 → 0.7.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023-2026 Travis J True
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -315,7 +315,7 @@ export default [
315
315
  This function returns a middleware function that validates request data against provided schemas. The returned middleware function has the signature `(req, res, next)` and forwards `res` via `next(res)` after successful validation.
316
316
 
317
317
  The `schemas` object can contain these optional properties:
318
- - `headers`: takes a string formatter schema to evaluate `req.headers`
318
+ - `headers`: takes a string formatter schema to evaluate `req.headers`. Header names are case-insensitive, so schema keys are lowercased to match; validation errors report the lowercased name (e.g. `headers.userid`).
319
319
  - `params`: takes a string formatter schema to evaluate `req.params`
320
320
  - `query`: takes a string formatter schema to evaluate `req.query`
321
321
  - `body`: takes a JSON validation schema to evaluate `res` (the body value passed in via `next`)
@@ -0,0 +1,173 @@
1
+ import { StatusCode } from './utils';
2
+ import type { FormattedError } from './utils';
3
+ export type ErrorOutput = {
4
+ message: string;
5
+ } | FormattedError[] | null;
6
+ export declare class RequestError extends Error {
7
+ static get status(): StatusCode;
8
+ get output(): ErrorOutput;
9
+ constructor(message: string);
10
+ }
11
+ export declare class BadRequestError extends RequestError {
12
+ static get status(): StatusCode;
13
+ constructor(message: string);
14
+ }
15
+ export declare class UnauthorizedError extends RequestError {
16
+ static get status(): StatusCode;
17
+ constructor(message: string);
18
+ }
19
+ export declare class PaymentRequiredError extends RequestError {
20
+ static get status(): StatusCode;
21
+ constructor(message: string);
22
+ }
23
+ export declare class ForbiddenError extends RequestError {
24
+ static get status(): StatusCode;
25
+ constructor(message: string);
26
+ }
27
+ export declare class NotFoundError extends RequestError {
28
+ static get status(): StatusCode;
29
+ constructor();
30
+ }
31
+ export declare class MethodNotAllowedError extends RequestError {
32
+ static get status(): StatusCode;
33
+ constructor();
34
+ }
35
+ export declare class NotAcceptableError extends RequestError {
36
+ static get status(): StatusCode;
37
+ constructor(message: string);
38
+ }
39
+ export declare class ProxyAuthenticationRequiredError extends RequestError {
40
+ static get status(): StatusCode;
41
+ constructor(message: string);
42
+ }
43
+ export declare class RequestTimeoutError extends RequestError {
44
+ static get status(): StatusCode;
45
+ constructor(message: string);
46
+ }
47
+ export declare class ConflictError extends RequestError {
48
+ static get status(): StatusCode;
49
+ constructor(message: string);
50
+ }
51
+ export declare class GoneError extends RequestError {
52
+ static get status(): StatusCode;
53
+ constructor(message: string);
54
+ }
55
+ export declare class LengthRequiredError extends RequestError {
56
+ static get status(): StatusCode;
57
+ constructor(message: string);
58
+ }
59
+ export declare class PreconditionFailedError extends RequestError {
60
+ static get status(): StatusCode;
61
+ constructor(message: string);
62
+ }
63
+ export declare class PayloadTooLargeError extends RequestError {
64
+ static get status(): StatusCode;
65
+ constructor(message: string);
66
+ }
67
+ export declare class UriTooLongError extends RequestError {
68
+ static get status(): StatusCode;
69
+ constructor(message: string);
70
+ }
71
+ export declare class UnsupportedMediaTypeError extends RequestError {
72
+ static get status(): StatusCode;
73
+ constructor(subject: string);
74
+ }
75
+ export declare class RangeNotSatisfiableError extends RequestError {
76
+ static get status(): StatusCode;
77
+ constructor(message: string);
78
+ }
79
+ export declare class ExpectationFailedError extends RequestError {
80
+ static get status(): StatusCode;
81
+ constructor(message: string);
82
+ }
83
+ export declare class ImATeapotError extends RequestError {
84
+ static get status(): StatusCode;
85
+ constructor(message: string);
86
+ }
87
+ export declare class MisdirectedRequestError extends RequestError {
88
+ static get status(): StatusCode;
89
+ constructor(message: string);
90
+ }
91
+ export declare class UnprocessableContentError extends RequestError {
92
+ static get status(): StatusCode;
93
+ get output(): ErrorOutput;
94
+ constructor(errors: FormattedError[]);
95
+ }
96
+ export declare class LockedError extends RequestError {
97
+ static get status(): StatusCode;
98
+ constructor(message: string);
99
+ }
100
+ export declare class FailedDependencyError extends RequestError {
101
+ static get status(): StatusCode;
102
+ constructor(message: string);
103
+ }
104
+ export declare class TooEarlyError extends RequestError {
105
+ static get status(): StatusCode;
106
+ constructor(message: string);
107
+ }
108
+ export declare class UpgradeRequiredError extends RequestError {
109
+ static get status(): StatusCode;
110
+ constructor(message: string);
111
+ }
112
+ export declare class PreconditionRequiredError extends RequestError {
113
+ static get status(): StatusCode;
114
+ constructor(message: string);
115
+ }
116
+ export declare class TooManyRequestsError extends RequestError {
117
+ static get status(): StatusCode;
118
+ constructor(message: string);
119
+ }
120
+ export declare class RequestHeaderFieldsTooLargeError extends RequestError {
121
+ static get status(): StatusCode;
122
+ constructor(message: string);
123
+ }
124
+ export declare class UnavailableForLegalReasonsError extends RequestError {
125
+ static get status(): StatusCode;
126
+ constructor(message: string);
127
+ }
128
+ export declare class InternalServerError extends RequestError {
129
+ static get status(): StatusCode;
130
+ ctx: unknown;
131
+ constructor(message: string, ctx?: unknown);
132
+ }
133
+ export declare class NotImplementedError extends RequestError {
134
+ static get status(): StatusCode;
135
+ constructor();
136
+ }
137
+ export declare class BadGatewayError extends RequestError {
138
+ static get status(): StatusCode;
139
+ constructor(message: string);
140
+ }
141
+ export declare class ServiceUnavailableError extends RequestError {
142
+ static get status(): StatusCode;
143
+ constructor(message: string);
144
+ }
145
+ export declare class GatewayTimeoutError extends RequestError {
146
+ static get status(): StatusCode;
147
+ constructor();
148
+ }
149
+ export declare class HTTPVersionNotSupportedError extends RequestError {
150
+ static get status(): StatusCode;
151
+ constructor(message: string);
152
+ }
153
+ export declare class VariantAlsoNegotiatesError extends RequestError {
154
+ static get status(): StatusCode;
155
+ constructor(message: string);
156
+ }
157
+ export declare class InsufficientStorageError extends RequestError {
158
+ static get status(): StatusCode;
159
+ constructor(message: string);
160
+ }
161
+ export declare class LoopDetectedError extends RequestError {
162
+ static get status(): StatusCode;
163
+ constructor(message: string);
164
+ }
165
+ export declare class NotExtendedError extends RequestError {
166
+ static get status(): StatusCode;
167
+ constructor(message: string);
168
+ }
169
+ export declare class NetworkAuthenticationRequiredError extends RequestError {
170
+ static get status(): StatusCode;
171
+ constructor(message: string);
172
+ }
173
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { AppOptions, Server } from './utils';
2
+ import type { SocketCommands } from './socket';
3
+ export * from './errors';
4
+ export { parseJsonBody, setValidationFormats, validateSchemas, } from './middleware';
5
+ export { HttpMethod, StatusCode } from './utils';
6
+ export type { AppOptions, EndpointRequest, FormattedError, Middleware, NextFn, Request, Server, SocketOptions, WebSocketRequest, } from './utils';
7
+ export type { FormatterField, FormatterSchema, ValidationSchemas, } from './middleware';
8
+ export type { SocketCommands } from './socket';
9
+ type OutputRoutes = Record<string, string[]>;
10
+ export type App = {
11
+ server: Server;
12
+ commands: SocketCommands;
13
+ routes: OutputRoutes;
14
+ };
15
+ export declare function createApp(port: number, rootPath: string, opts?: AppOptions): Promise<App>;
16
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAIV,UAAU,EACV,MAAM,EACP,MAAM,SAAS,CAAA;AAEhB,OAAO,KAAK,EAGV,cAAc,EACf,MAAM,UAAU,CAAA;AAEjB,cAAc,UAAU,CAAA;AAExB,OAAO,EACL,aAAa,EACb,oBAAoB,EACpB,eAAe,GAChB,MAAM,cAAc,CAAA;AAErB,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAEhD,YAAY,EACV,UAAU,EACV,eAAe,EACf,cAAc,EACd,UAAU,EACV,MAAM,EACN,OAAO,EACP,MAAM,EACN,aAAa,EACb,gBAAgB,GACjB,MAAM,SAAS,CAAA;AAEhB,YAAY,EACV,cAAc,EACd,eAAe,EACf,iBAAiB,GAClB,MAAM,cAAc,CAAA;AAErB,YAAY,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAE9C,KAAK,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;AA4C5C,MAAM,MAAM,GAAG,GAAG;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,cAAc,CAAA;IACxB,MAAM,EAAE,YAAY,CAAA;CACrB,CAAA;AA6YD,wBAAsB,SAAS,CAC7B,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,IAAI,GAAE,UAAe,GACpB,OAAO,CAAC,GAAG,CAAC,CAad"}
@@ -0,0 +1,63 @@
1
+ import type { HttpMethod } from './utils';
2
+ export declare const MessageType: {
3
+ readonly Request: "request";
4
+ readonly Response: "response";
5
+ readonly Welcome: "welcome";
6
+ readonly Heartbeat: "heartbeat";
7
+ readonly Notification: "notification";
8
+ };
9
+ export type MessageType = typeof MessageType[keyof typeof MessageType];
10
+ export declare const RECEIVED_MESSAGE_TYPES: string[];
11
+ export type BaseMessage = {
12
+ id: string;
13
+ clientId: string;
14
+ type: MessageType;
15
+ timestamp: string;
16
+ };
17
+ export type HeartbeatMessage = BaseMessage & {
18
+ type: typeof MessageType.Heartbeat;
19
+ };
20
+ export type RequestMessage = BaseMessage & {
21
+ type: typeof MessageType.Request;
22
+ method: HttpMethod;
23
+ route: string;
24
+ headers: Bun.HeadersInit;
25
+ query: Record<string, unknown>;
26
+ body: unknown;
27
+ };
28
+ export type ResponseMessage = BaseMessage & {
29
+ type: typeof MessageType.Response;
30
+ status: number;
31
+ headers: Headers;
32
+ body: unknown;
33
+ };
34
+ export type WelcomeMessage = BaseMessage & {
35
+ type: typeof MessageType.Welcome;
36
+ headers: Headers;
37
+ body: {
38
+ heartbeatInterval: number;
39
+ token: string;
40
+ };
41
+ };
42
+ export type NotificationMessage = BaseMessage & {
43
+ type: typeof MessageType.Notification;
44
+ event: string;
45
+ headers: Headers;
46
+ body: unknown;
47
+ };
48
+ export type Message = HeartbeatMessage | RequestMessage | ResponseMessage | WelcomeMessage | NotificationMessage;
49
+ export type RawMessage = {
50
+ type?: string;
51
+ [key: string]: unknown;
52
+ };
53
+ export type IncomingMessage = HeartbeatMessage | RequestMessage;
54
+ export type MessageContent<T extends MessageType = MessageType> = Partial<Pick<Extract<Message, {
55
+ type: T;
56
+ }>, 'id'>> & Omit<Extract<Message, {
57
+ type: T;
58
+ }>, keyof BaseMessage>;
59
+ export declare function createMessage<T extends MessageType>(clientId: string, type: T, content: MessageContent<T>): Extract<Message, {
60
+ type: T;
61
+ }>;
62
+ export declare function validateMessage(message: RawMessage): IncomingMessage;
63
+ //# sourceMappingURL=messages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../src/messages.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAEzC,eAAO,MAAM,WAAW;;;;;;CAMd,CAAA;AAEV,MAAM,MAAM,WAAW,GAAG,OAAO,WAAW,CAAC,MAAM,OAAO,WAAW,CAAC,CAAA;AAEtE,eAAO,MAAM,sBAAsB,EAAE,MAAM,EAG1C,CAAA;AAED,MAAM,MAAM,WAAW,GAAG;IACxB,EAAE,EAAE,MAAM,CAAA;IACV,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,WAAW,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG,WAAW,GAAG;IAC3C,IAAI,EAAE,OAAO,WAAW,CAAC,SAAS,CAAA;CACnC,CAAA;AAED,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG;IACzC,IAAI,EAAE,OAAO,WAAW,CAAC,OAAO,CAAA;IAChC,MAAM,EAAE,UAAU,CAAA;IAClB,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,GAAG,CAAC,WAAW,CAAA;IACxB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC9B,IAAI,EAAE,OAAO,CAAA;CACd,CAAA;AAED,MAAM,MAAM,eAAe,GAAG,WAAW,GAAG;IAC1C,IAAI,EAAE,OAAO,WAAW,CAAC,QAAQ,CAAA;IACjC,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,OAAO,CAAA;IAChB,IAAI,EAAE,OAAO,CAAA;CACd,CAAA;AAED,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG;IACzC,IAAI,EAAE,OAAO,WAAW,CAAC,OAAO,CAAA;IAChC,OAAO,EAAE,OAAO,CAAA;IAChB,IAAI,EAAE;QACJ,iBAAiB,EAAE,MAAM,CAAA;QACzB,KAAK,EAAE,MAAM,CAAA;KACd,CAAA;CACF,CAAA;AAED,MAAM,MAAM,mBAAmB,GAAG,WAAW,GAAG;IAC9C,IAAI,EAAE,OAAO,WAAW,CAAC,YAAY,CAAA;IACrC,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,OAAO,CAAA;IAChB,IAAI,EAAE,OAAO,CAAA;CACd,CAAA;AAED,MAAM,MAAM,OAAO,GACf,gBAAgB,GAChB,cAAc,GACd,eAAe,GACf,cAAc,GACd,mBAAmB,CAAA;AAEvB,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB,CAAA;AAED,MAAM,MAAM,eAAe,GAAG,gBAAgB,GAAG,cAAc,CAAA;AAE/D,MAAM,MAAM,cAAc,CAAC,CAAC,SAAS,WAAW,GAAG,WAAW,IAC5D,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE;IAAE,IAAI,EAAE,CAAC,CAAA;CAAE,CAAC,EAAE,IAAI,CAAC,CAAC,GAC9C,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE;IAAE,IAAI,EAAE,CAAC,CAAA;CAAE,CAAC,EAAE,MAAM,WAAW,CAAC,CAAA;AAwG5D,wBAAgB,aAAa,CAAC,CAAC,SAAS,WAAW,EACjD,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,CAAC,EACP,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC,GACzB,OAAO,CAAC,OAAO,EAAE;IAAE,IAAI,EAAE,CAAC,CAAA;CAAE,CAAC,CAe/B;AAED,wBAAgB,eAAe,CAAE,OAAO,EAAE,UAAU,GAAG,eAAe,CA4BrE"}
@@ -0,0 +1,19 @@
1
+ import type { Format, Schema } from 'ajv';
2
+ import type { Middleware } from './utils';
3
+ export type FormatterField = {
4
+ type: string;
5
+ value: unknown;
6
+ };
7
+ export type FormatterSchema = Record<string, FormatterField>;
8
+ export type ValidationSchemas = {
9
+ headers?: FormatterSchema;
10
+ params?: FormatterSchema;
11
+ query?: FormatterSchema;
12
+ body?: Schema;
13
+ };
14
+ export type SchemaKey = keyof ValidationSchemas;
15
+ export declare function parseJsonBody(): Middleware;
16
+ export declare function setValidationFormats(formats: Record<string, Format>): void;
17
+ export declare function resetValidationFormatsState(): void;
18
+ export declare function validateSchemas(schemas: ValidationSchemas): Middleware;
19
+ //# sourceMappingURL=middleware.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAAoB,MAAM,KAAK,CAAA;AAC3D,OAAO,KAAK,EAAkB,UAAU,EAAmB,MAAM,SAAS,CAAA;AAE1E,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,OAAO,CAAA;CACf,CAAA;AAED,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAA;AAE5D,MAAM,MAAM,iBAAiB,GAAG;IAC9B,OAAO,CAAC,EAAE,eAAe,CAAA;IACzB,MAAM,CAAC,EAAE,eAAe,CAAA;IACxB,KAAK,CAAC,EAAE,eAAe,CAAA;IACvB,IAAI,CAAC,EAAE,MAAM,CAAA;CACd,CAAA;AAED,MAAM,MAAM,SAAS,GAAG,MAAM,iBAAiB,CAAA;AA2F/C,wBAAgB,aAAa,IAAK,UAAU,CAoB3C;AAED,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC9B,IAAI,CAUN;AAID,wBAAgB,2BAA2B,IAAK,IAAI,CAGnD;AAcD,wBAAgB,eAAe,CAC7B,OAAO,EAAE,iBAAiB,GACzB,UAAU,CAgCZ"}
@@ -0,0 +1,50 @@
1
+ import type { WebSocketHandler } from 'bun';
2
+ import type { HttpMethod, Request, Middleware, SocketData, AppOptions } from './utils';
3
+ export type Ticket = {
4
+ clientId: string;
5
+ expiresAt: number;
6
+ };
7
+ export type SocketConnection = {
8
+ data: SocketData;
9
+ send: (data: string) => unknown;
10
+ close: () => void;
11
+ };
12
+ export type ActiveSession = {
13
+ token: string;
14
+ ws: SocketConnection;
15
+ };
16
+ export type InactiveSession = {
17
+ token: string;
18
+ expiresAt: number;
19
+ };
20
+ export type Session = ActiveSession | InactiveSession;
21
+ export type SocketState = {
22
+ disconnectThreshold: number;
23
+ heartbeatInterval: number;
24
+ maxTickets: number;
25
+ reclaimTtl: number;
26
+ ticketTtl: number;
27
+ tickets: Map<string, Ticket>;
28
+ activeSessions: Map<string, ActiveSession>;
29
+ inactiveSessions: Map<string, InactiveSession>;
30
+ };
31
+ export type SocketRoute = {
32
+ method: HttpMethod;
33
+ path: string;
34
+ segments: string[];
35
+ chain: Middleware[];
36
+ };
37
+ export type SocketEndpoint = {
38
+ method: HttpMethod;
39
+ path: string;
40
+ handler: (req: Request, res: unknown) => Response;
41
+ };
42
+ export type SocketCommands = {
43
+ send: (clientId: string, event: string, body: unknown) => void;
44
+ broadcast: (event: string, body: unknown) => void;
45
+ };
46
+ export declare function buildSocketState(opts?: AppOptions): SocketState;
47
+ export declare function buildSocketServer(routes: SocketRoute[], state: SocketState): WebSocketHandler<SocketData>;
48
+ export declare function buildSocketHandlers(state: SocketState): SocketEndpoint[];
49
+ export declare function buildSocketCommands(state: SocketState): SocketCommands;
50
+ //# sourceMappingURL=socket.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"socket.d.ts","sourceRoot":"","sources":["../src/socket.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,KAAK,CAAA;AAG3C,OAAO,KAAK,EACV,UAAU,EACV,OAAO,EAEP,UAAU,EACV,UAAU,EACV,UAAU,EACX,MAAM,SAAS,CAAA;AAShB,MAAM,MAAM,MAAM,GAAG;IACnB,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,UAAU,CAAA;IAChB,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAA;IAC/B,KAAK,EAAE,MAAM,IAAI,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,KAAK,EAAE,MAAM,CAAA;IACb,EAAE,EAAE,gBAAgB,CAAA;CACrB,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,OAAO,GAAG,aAAa,GAAG,eAAe,CAAA;AAErD,MAAM,MAAM,WAAW,GAAG;IACxB,mBAAmB,EAAE,MAAM,CAAA;IAC3B,iBAAiB,EAAE,MAAM,CAAA;IACzB,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC5B,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAA;IAC1C,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAAA;CAC/C,CAAA;AAED,MAAM,MAAM,WAAW,GAAG;IACxB,MAAM,EAAE,UAAU,CAAA;IAClB,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,KAAK,EAAE,UAAU,EAAE,CAAA;CACpB,CAAA;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,UAAU,CAAA;IAClB,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,KAAK,QAAQ,CAAA;CAClD,CAAA;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,KAAK,IAAI,CAAA;IAC9D,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,KAAK,IAAI,CAAA;CAClD,CAAA;AAmTD,wBAAgB,gBAAgB,CAAE,IAAI,GAAE,UAAe,GAAG,WAAW,CAWpE;AAED,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,WAAW,EAAE,EACrB,KAAK,EAAE,WAAW,GACjB,gBAAgB,CAAC,UAAU,CAAC,CAuH9B;AAED,wBAAgB,mBAAmB,CAAE,KAAK,EAAE,WAAW,GAAG,cAAc,EAAE,CAqIzE;AAED,wBAAgB,mBAAmB,CAAE,KAAK,EAAE,WAAW,GAAG,cAAc,CA+BvE"}
@@ -0,0 +1,125 @@
1
+ import type { ErrorObject } from 'ajv';
2
+ import type { BunRequest, Server as BunServer } from 'bun';
3
+ export declare const HttpMethod: {
4
+ readonly Head: "HEAD";
5
+ readonly Get: "GET";
6
+ readonly Post: "POST";
7
+ readonly Put: "PUT";
8
+ readonly Patch: "PATCH";
9
+ readonly Delete: "DELETE";
10
+ };
11
+ export type HttpMethod = typeof HttpMethod[keyof typeof HttpMethod];
12
+ export declare const StatusCode: {
13
+ readonly Continue: 100;
14
+ readonly SwitchingProtocols: 101;
15
+ readonly Processing: 102;
16
+ readonly EarlyHints: 103;
17
+ readonly Ok: 200;
18
+ readonly Created: 201;
19
+ readonly Accepted: 202;
20
+ readonly NonAuthoritativeInformation: 203;
21
+ readonly NoContent: 204;
22
+ readonly ResetContent: 205;
23
+ readonly PartialContent: 206;
24
+ readonly MultiStatus: 207;
25
+ readonly AlreadyReported: 208;
26
+ readonly ImUsed: 226;
27
+ readonly MultipleChoices: 300;
28
+ readonly MovedPermanently: 301;
29
+ readonly Found: 302;
30
+ readonly SeeOther: 303;
31
+ readonly NotModified: 304;
32
+ readonly UseProxy: 305;
33
+ readonly TemporaryRedirect: 307;
34
+ readonly PermanentRedirect: 308;
35
+ readonly BadRequest: 400;
36
+ readonly Unauthorized: 401;
37
+ readonly PaymentRequired: 402;
38
+ readonly Forbidden: 403;
39
+ readonly NotFound: 404;
40
+ readonly MethodNotAllowed: 405;
41
+ readonly NotAcceptable: 406;
42
+ readonly ProxyAuthenticationRequired: 407;
43
+ readonly RequestTimeout: 408;
44
+ readonly Conflict: 409;
45
+ readonly Gone: 410;
46
+ readonly LengthRequired: 411;
47
+ readonly PreconditionFailed: 412;
48
+ readonly PayloadTooLarge: 413;
49
+ readonly UriTooLong: 414;
50
+ readonly UnsupportedMediaType: 415;
51
+ readonly RangeNotSatisfiable: 416;
52
+ readonly ExpectationFailed: 417;
53
+ readonly ImATeapot: 418;
54
+ readonly MisdirectedRequest: 421;
55
+ readonly UnprocessableContent: 422;
56
+ readonly Locked: 423;
57
+ readonly FailedDependency: 424;
58
+ readonly TooEarly: 425;
59
+ readonly UpgradeRequired: 426;
60
+ readonly PreconditionRequired: 428;
61
+ readonly TooManyRequests: 429;
62
+ readonly RequestHeaderFieldsTooLarge: 431;
63
+ readonly UnavailableForLegalReasons: 451;
64
+ readonly InternalServerError: 500;
65
+ readonly NotImplemented: 501;
66
+ readonly BadGateway: 502;
67
+ readonly ServiceUnavailable: 503;
68
+ readonly GatewayTimeout: 504;
69
+ readonly HTTPVersionNotSupported: 505;
70
+ readonly VariantAlsoNegotiates: 506;
71
+ readonly InsufficientStorage: 507;
72
+ readonly LoopDetected: 508;
73
+ readonly NotExtended: 510;
74
+ readonly NetworkAuthenticationRequired: 511;
75
+ };
76
+ export type StatusCode = typeof StatusCode[keyof typeof StatusCode];
77
+ export type ValidationError = Partial<ErrorObject>;
78
+ export type FormattedError = {
79
+ path: string;
80
+ message: string;
81
+ };
82
+ export type NextFn = (data?: unknown) => Response | Promise<Response>;
83
+ export type BaseRequest = {
84
+ method: HttpMethod;
85
+ route: string;
86
+ headers: Headers;
87
+ params: Record<string, string>;
88
+ query: Record<string, unknown>;
89
+ json: () => Promise<unknown>;
90
+ };
91
+ export type EndpointRequest = BaseRequest & {
92
+ raw: BunRequest;
93
+ server: Server;
94
+ };
95
+ export type WebSocketRequest = BaseRequest & {
96
+ id: string;
97
+ clientId: string;
98
+ };
99
+ export type Request = EndpointRequest | WebSocketRequest;
100
+ export type Middleware = (req: Request, res: unknown, next: NextFn | null) => unknown;
101
+ export type SocketOptions = {
102
+ disconnectThreshold?: number;
103
+ heartbeatInterval?: number;
104
+ maxTickets?: number;
105
+ reclaimTtl?: number;
106
+ ticketTtl?: number;
107
+ };
108
+ export type SocketData = {
109
+ clientId: string;
110
+ superseded: boolean;
111
+ reaped: boolean;
112
+ reaperHandle: ReturnType<typeof setTimeout> | null;
113
+ };
114
+ export type Server = BunServer<SocketData>;
115
+ export type AppOptions = {
116
+ hostname?: string;
117
+ mountPath?: string;
118
+ middleware?: Middleware[];
119
+ ws?: SocketOptions;
120
+ onClose?: () => Promise<void> | void;
121
+ };
122
+ export declare function toSegments(pathString: string): string[];
123
+ export declare function formatError(prefix: string, input: ValidationError): FormattedError;
124
+ export declare function executeMiddlewareChain(req: Request, chain: Middleware[]): Promise<Response>;
125
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -2,9 +2,21 @@
2
2
  "name": "sleepy-serv",
3
3
  "description": "A more opinionated web server for building REST-ful applications",
4
4
  "author": "Travis J True",
5
- "version": "0.6.1",
6
- "exports": "./src/index.js",
5
+ "license": "MIT",
6
+ "version": "0.7.0",
7
7
  "type": "module",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "bun": "./src/index.ts",
12
+ "default": "./src/index.ts"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "src",
18
+ "!src/**/*.test.*"
19
+ ],
8
20
  "repository": {
9
21
  "type": "git",
10
22
  "url": "git+https://github.com/travistrue2008/sleepy-serv.git",
@@ -17,7 +29,10 @@
17
29
  "web server",
18
30
  "www"
19
31
  ],
20
- "scripts": {},
32
+ "scripts": {
33
+ "build": "tsc -p tsconfig.build.json",
34
+ "typecheck": "tsc --noEmit -p tsconfig.json"
35
+ },
21
36
  "dependencies": {
22
37
  "ajv": "^8.20.0",
23
38
  "ajv-formats": "^3.0.1"