@kosmojs/api 0.0.11 → 0.0.21
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 +21 -0
- package/package.json +15 -18
- package/pkg/debug.d.ts +16 -0
- package/pkg/errors/index.d.ts +21 -0
- package/pkg/errors/index.js +23 -0
- package/pkg/errors/index.js.map +7 -0
- package/pkg/errors/types.d.ts +43 -0
- package/pkg/index.d.ts +3 -0
- package/pkg/index.js +49 -198
- package/pkg/index.js.map +3 -3
- package/pkg/routes.d.ts +5 -0
- package/pkg/types.d.ts +285 -0
- package/pkg/bodyparser/index.js +0 -111
- package/pkg/bodyparser/index.js.map +0 -7
- package/pkg/queryparser/index.js +0 -37
- package/pkg/queryparser/index.js.map +0 -7
- package/pkg/src/app.d.ts +0 -2
- package/pkg/src/bodyparser/config.d.ts +0 -10
- package/pkg/src/bodyparser/index.d.ts +0 -14
- package/pkg/src/bodyparser/types.d.ts +0 -39
- package/pkg/src/debug.d.ts +0 -10
- package/pkg/src/errors.d.ts +0 -19
- package/pkg/src/index.d.ts +0 -5
- package/pkg/src/queryparser/index.d.ts +0 -5
- package/pkg/src/router.d.ts +0 -6
- package/pkg/src/types.d.ts +0 -136
- package/pkg/src/use.d.ts +0 -2
- package/pkg/test/defineRoute.test.d.ts +0 -1
- package/pkg/test/index.d.ts +0 -5
- package/pkg/test/routerRoutesFactory/params.test.d.ts +0 -1
- package/pkg/test/routerRoutesFactory/routeMiddleware.test.d.ts +0 -1
- package/pkg/test/routerRoutesFactory/useWrappers.test.d.ts +0 -1
- package/pkg/test/use.test.d.ts +0 -1
package/pkg/routes.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { CreateRouteMiddleware, MiddlewareDefinition, Route, RouteSource } from "./types";
|
|
2
|
+
export declare const createRoutes: <MiddlewareT, MiddlewareR>(routeSources: Array<RouteSource<MiddlewareT>>, { globalMiddleware, createRouteMiddleware, }: {
|
|
3
|
+
globalMiddleware: Array<MiddlewareDefinition<MiddlewareT>>;
|
|
4
|
+
createRouteMiddleware: CreateRouteMiddleware<MiddlewareT>;
|
|
5
|
+
}) => Array<Route<MiddlewareR>>;
|
package/pkg/types.d.ts
ADDED
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
import type { ValidationErrorEntry } from "./errors/types";
|
|
2
|
+
export declare enum HTTPMethods {
|
|
3
|
+
HEAD = "HEAD",
|
|
4
|
+
OPTIONS = "OPTIONS",
|
|
5
|
+
GET = "GET",
|
|
6
|
+
PUT = "PUT",
|
|
7
|
+
PATCH = "PATCH",
|
|
8
|
+
POST = "POST",
|
|
9
|
+
DELETE = "DELETE"
|
|
10
|
+
}
|
|
11
|
+
export type HTTPMethod = keyof typeof HTTPMethods;
|
|
12
|
+
export type MiddlewareDefinition<MiddlewareT> = {
|
|
13
|
+
kind: "middleware";
|
|
14
|
+
middleware: Array<MiddlewareT>;
|
|
15
|
+
options?: UseOptions | undefined;
|
|
16
|
+
};
|
|
17
|
+
export type HandlerDefinition<MiddlewareT> = {
|
|
18
|
+
kind: "handler";
|
|
19
|
+
middleware: Array<MiddlewareT>;
|
|
20
|
+
method: HTTPMethod;
|
|
21
|
+
};
|
|
22
|
+
export type RouteDefinitionItem<MiddlewareT> = MiddlewareDefinition<MiddlewareT> | HandlerDefinition<MiddlewareT>;
|
|
23
|
+
export interface UseSlots {
|
|
24
|
+
errorHandler: string;
|
|
25
|
+
extendContext: string;
|
|
26
|
+
bodyparser: string;
|
|
27
|
+
"validate:params": string;
|
|
28
|
+
"validate:query": string;
|
|
29
|
+
"validate:headers": string;
|
|
30
|
+
"validate:cookies": string;
|
|
31
|
+
"validate:json": string;
|
|
32
|
+
"validate:form": string;
|
|
33
|
+
"validate:raw": string;
|
|
34
|
+
"validate:response": string;
|
|
35
|
+
}
|
|
36
|
+
export type UseOptions = {
|
|
37
|
+
on?: Array<HTTPMethod>;
|
|
38
|
+
slot?: keyof UseSlots;
|
|
39
|
+
debug?: string | undefined;
|
|
40
|
+
};
|
|
41
|
+
export type RouteSource<MiddlewareT> = {
|
|
42
|
+
name: string;
|
|
43
|
+
path: string;
|
|
44
|
+
pathPattern: string;
|
|
45
|
+
file: string;
|
|
46
|
+
cascadingMiddleware: [...a: Array<MiddlewareDefinition<MiddlewareT>>];
|
|
47
|
+
definitionItems: Array<RouteDefinitionItem<MiddlewareT>>;
|
|
48
|
+
params: Array<string>;
|
|
49
|
+
numericParams: Array<string>;
|
|
50
|
+
validationSchemas: ValidationSchemas;
|
|
51
|
+
meta?: Record<string, unknown>;
|
|
52
|
+
};
|
|
53
|
+
export type Route<MiddlewareT> = {
|
|
54
|
+
name: string;
|
|
55
|
+
path: string;
|
|
56
|
+
file: string;
|
|
57
|
+
methods: Array<string>;
|
|
58
|
+
middleware: Array<MiddlewareT>;
|
|
59
|
+
debug: {
|
|
60
|
+
headline: string;
|
|
61
|
+
methods: string;
|
|
62
|
+
middleware: string;
|
|
63
|
+
handler: string;
|
|
64
|
+
full: string;
|
|
65
|
+
};
|
|
66
|
+
};
|
|
67
|
+
export type DevSetup = {
|
|
68
|
+
/**
|
|
69
|
+
* API request handler for development mode.
|
|
70
|
+
*
|
|
71
|
+
* In dev mode, incoming requests are routed based on URL:
|
|
72
|
+
* - Requests matching apiurl routed to this handler (your API)
|
|
73
|
+
* - All other requests routed to Vite dev server (pages/assets)
|
|
74
|
+
*
|
|
75
|
+
* Returns a function that processes API requests.
|
|
76
|
+
* */
|
|
77
|
+
requestHandler: () => (req: import("node:http").IncomingMessage, res: import("node:http").ServerResponse) => Promise<void>;
|
|
78
|
+
/**
|
|
79
|
+
* Custom function to determine if a request should be handled by the API.
|
|
80
|
+
*
|
|
81
|
+
* By default, requests are routed to the API handler if their URL starts with `apiurl`.
|
|
82
|
+
* Use this to implement custom heuristics for detecting API requests.
|
|
83
|
+
* */
|
|
84
|
+
requestMatcher?: (req: import("node:http").IncomingMessage) => boolean;
|
|
85
|
+
/**
|
|
86
|
+
* In dev mode, perform cleanup operations before reloading the API handler.
|
|
87
|
+
* */
|
|
88
|
+
teardownHandler?: () => void | Promise<void>;
|
|
89
|
+
};
|
|
90
|
+
export type AppFactory<App, AppOptions = unknown> = (factory: (a: {
|
|
91
|
+
createApp: (o?: AppOptions) => App;
|
|
92
|
+
}) => App) => App;
|
|
93
|
+
export type RouterFactory<Router, RouterOptions = unknown> = (factory: (a: {
|
|
94
|
+
createRouter: (o?: RouterOptions) => Router;
|
|
95
|
+
}) => Router) => Router;
|
|
96
|
+
export type CreateRouteMiddleware<MiddlewareT> = (routeSource: RouteSource<MiddlewareT>) => Array<MiddlewareDefinition<MiddlewareT>>;
|
|
97
|
+
export type CreateServer<App, Server> = (app: App, opt?: {
|
|
98
|
+
port?: number;
|
|
99
|
+
sock?: string;
|
|
100
|
+
callback?: () => void | Promise<void>;
|
|
101
|
+
}) => Promise<Server>;
|
|
102
|
+
export type ServerFactory<App, Server> = (factory: (a: {
|
|
103
|
+
createServer: CreateServer<App, Server>;
|
|
104
|
+
}) => void) => void;
|
|
105
|
+
/**
|
|
106
|
+
* Request metadata validation targets.
|
|
107
|
+
* */
|
|
108
|
+
export declare const RequestMetadataTargets: {
|
|
109
|
+
readonly query: "URL query parameters";
|
|
110
|
+
readonly headers: "HTTP request headers";
|
|
111
|
+
readonly cookies: "HTTP cookies";
|
|
112
|
+
};
|
|
113
|
+
/**
|
|
114
|
+
* Request body validation targets.
|
|
115
|
+
*
|
|
116
|
+
* Body formats are mutually exclusive - only one should be specified per handler.
|
|
117
|
+
*
|
|
118
|
+
* **Development behavior:**
|
|
119
|
+
* - If multiple formats are defined, the builder displays a warning and
|
|
120
|
+
* disables validation schemas for the affected handler.
|
|
121
|
+
* - If an unsuitable target is defined (e.g., `json`, `form`)
|
|
122
|
+
* for a method without a body like GET, HEAD), a warning is displayed and
|
|
123
|
+
* validation schemas are disabled for that handler.
|
|
124
|
+
*
|
|
125
|
+
* This ensures misconfigurations are detected during development
|
|
126
|
+
* for runtime to execute without false positive validation failures.
|
|
127
|
+
*
|
|
128
|
+
* Always define exactly one target that is suitable for current handler.
|
|
129
|
+
* */
|
|
130
|
+
export declare const RequestBodyTargets: {
|
|
131
|
+
readonly json: "JSON request body";
|
|
132
|
+
readonly form: "URL-encoded or Multipart form";
|
|
133
|
+
readonly raw: "Raw body format (string/Buffer/ArrayBuffer/Blob)";
|
|
134
|
+
};
|
|
135
|
+
export declare const RequestValidationTargets: {
|
|
136
|
+
readonly json: "JSON request body";
|
|
137
|
+
readonly form: "URL-encoded or Multipart form";
|
|
138
|
+
readonly raw: "Raw body format (string/Buffer/ArrayBuffer/Blob)";
|
|
139
|
+
readonly query: "URL query parameters";
|
|
140
|
+
readonly headers: "HTTP request headers";
|
|
141
|
+
readonly cookies: "HTTP cookies";
|
|
142
|
+
};
|
|
143
|
+
export type RequestMetadataTarget = keyof typeof RequestMetadataTargets;
|
|
144
|
+
export type RequestBodyTarget = keyof typeof RequestBodyTargets;
|
|
145
|
+
export type RequestValidationTarget = keyof typeof RequestValidationTargets;
|
|
146
|
+
export type ValidationTarget = RequestValidationTarget | "params" | "response";
|
|
147
|
+
export type ValidationDefmap = Partial<{
|
|
148
|
+
/**
|
|
149
|
+
* Request metadata targets.
|
|
150
|
+
* */
|
|
151
|
+
query: Record<string, unknown>;
|
|
152
|
+
headers: Record<string, string>;
|
|
153
|
+
cookies: Record<string, unknown>;
|
|
154
|
+
/**
|
|
155
|
+
* Request body targets. One target per handler.
|
|
156
|
+
*
|
|
157
|
+
* POST<
|
|
158
|
+
* json: { id: number }
|
|
159
|
+
* // or form/raw
|
|
160
|
+
* >((ctx) => {})
|
|
161
|
+
* */
|
|
162
|
+
json: unknown;
|
|
163
|
+
form: Record<string, unknown>;
|
|
164
|
+
raw: string | Buffer | ArrayBuffer | Blob;
|
|
165
|
+
/**
|
|
166
|
+
* Response variants.
|
|
167
|
+
* Multiple variants can be specified via unions.
|
|
168
|
+
*
|
|
169
|
+
* POST<
|
|
170
|
+
* response:
|
|
171
|
+
* | [200, "json", User]
|
|
172
|
+
* | [201, "json"]
|
|
173
|
+
* | [301]
|
|
174
|
+
* >((ctx) => {})
|
|
175
|
+
* */
|
|
176
|
+
response: [
|
|
177
|
+
/**
|
|
178
|
+
* HTTP status code to send with the response.
|
|
179
|
+
* Common values: 200 (OK), 400 (Bad Request), 404 (Not Found), 500 (Internal Server Error)
|
|
180
|
+
* */
|
|
181
|
+
status: number,
|
|
182
|
+
/**
|
|
183
|
+
* Content-Type header for the response. Supports shorthand notation that gets
|
|
184
|
+
* resolved via mime-types lookup (e.g., "json" becomes "application/json",
|
|
185
|
+
* "html" becomes "text/html", "png" becomes "image/png")
|
|
186
|
+
* */
|
|
187
|
+
contentType?: string | undefined,
|
|
188
|
+
/** The response body schema */
|
|
189
|
+
body?: unknown
|
|
190
|
+
];
|
|
191
|
+
}>;
|
|
192
|
+
export type ValidationCustomErrors = {
|
|
193
|
+
/**
|
|
194
|
+
* Custom error messages for validation failures.
|
|
195
|
+
*
|
|
196
|
+
* Use `error` to set a general error message for the entire validation target.
|
|
197
|
+
* Use `error.<fieldName>` to set specific error messages for individual fields.
|
|
198
|
+
*
|
|
199
|
+
* @example Override validation error messages
|
|
200
|
+
* POST<{
|
|
201
|
+
* json: {
|
|
202
|
+
* id: number;
|
|
203
|
+
* email: string;
|
|
204
|
+
* age: number;
|
|
205
|
+
* }
|
|
206
|
+
* }, {
|
|
207
|
+
* json: {
|
|
208
|
+
* error: "Invalid user data provided",
|
|
209
|
+
* "error.id": "User ID must be a valid number",
|
|
210
|
+
* "error.email": "Please provide a valid email address",
|
|
211
|
+
* "error.age": "Age must be a number"
|
|
212
|
+
* }
|
|
213
|
+
* }>
|
|
214
|
+
* */
|
|
215
|
+
error?: string;
|
|
216
|
+
} & {
|
|
217
|
+
[E in `error.${string}`]?: string;
|
|
218
|
+
};
|
|
219
|
+
export type ValidationOptions = {
|
|
220
|
+
/**
|
|
221
|
+
* Controls runtime validation for this target.
|
|
222
|
+
*
|
|
223
|
+
* By default, all validation targets are validated at runtime. Set this to
|
|
224
|
+
* `false` if you only need compile-time type checking without runtime validation.
|
|
225
|
+
*
|
|
226
|
+
* @example Disable runtime validation for JSON payload
|
|
227
|
+
* POST<{
|
|
228
|
+
* json: Payload<User>
|
|
229
|
+
* }, {
|
|
230
|
+
* json: {
|
|
231
|
+
* runtimeValidation: false
|
|
232
|
+
* }
|
|
233
|
+
* }>
|
|
234
|
+
* */
|
|
235
|
+
runtimeValidation?: boolean | undefined;
|
|
236
|
+
/**
|
|
237
|
+
* Specifies the request Content-Type for OpenAPI schema generation.
|
|
238
|
+
*
|
|
239
|
+
* When the validation target is `form`, the OpenAPI generator will include
|
|
240
|
+
* both `application/x-www-form-urlencoded` and `multipart/form-data` in the
|
|
241
|
+
* request body content types by default. This indicates the handler accepts
|
|
242
|
+
* either format, which may not be accurate for your use case.
|
|
243
|
+
*
|
|
244
|
+
* Use this option to explicitly declare which content type your handler expects.
|
|
245
|
+
* */
|
|
246
|
+
contentType?: string;
|
|
247
|
+
} & ValidationCustomErrors;
|
|
248
|
+
export type ValidationOptmap = {
|
|
249
|
+
[K in ValidationTarget]?: ValidationOptions;
|
|
250
|
+
};
|
|
251
|
+
export declare const StateKey: unique symbol;
|
|
252
|
+
export type ExtendContext<ParamsT, VDefs extends ValidationDefmap, VOpts extends ValidationOptmap, BodyparserOptions extends Record<RequestBodyTarget, unknown>> = {
|
|
253
|
+
[StateKey]: Map<ValidationTarget, unknown>;
|
|
254
|
+
bodyparser: {
|
|
255
|
+
[T in RequestBodyTarget]: <R = unknown>(opts?: BodyparserOptions[T]) => Promise<R>;
|
|
256
|
+
};
|
|
257
|
+
validated: {
|
|
258
|
+
[K in keyof VDefs as K extends RequestValidationTarget ? VOpts[K] extends {
|
|
259
|
+
runtimeValidation: false;
|
|
260
|
+
} ? never : K : never]: VDefs[K];
|
|
261
|
+
} & {
|
|
262
|
+
params: ParamsT;
|
|
263
|
+
};
|
|
264
|
+
};
|
|
265
|
+
export type ValidationSchema = {
|
|
266
|
+
check: (data: unknown) => boolean;
|
|
267
|
+
errors: (data: unknown) => Array<ValidationErrorEntry>;
|
|
268
|
+
errorMessage: (data: unknown) => string;
|
|
269
|
+
errorSummary: (data: unknown) => string;
|
|
270
|
+
validate: (data: unknown) => void;
|
|
271
|
+
};
|
|
272
|
+
export type ValidationSchemas<Extend = object> = {
|
|
273
|
+
[T in RequestValidationTarget]?: Record<string, ValidationSchema & Extend & {
|
|
274
|
+
runtimeValidation?: boolean;
|
|
275
|
+
customErrors?: ValidationCustomErrors;
|
|
276
|
+
}>;
|
|
277
|
+
} & {
|
|
278
|
+
params?: ValidationSchema & Extend;
|
|
279
|
+
response?: Record<string, Array<ValidationSchema & Extend & {
|
|
280
|
+
status: number;
|
|
281
|
+
contentType?: string;
|
|
282
|
+
runtimeValidation?: boolean;
|
|
283
|
+
customErrors?: ValidationCustomErrors;
|
|
284
|
+
}>>;
|
|
285
|
+
};
|
package/pkg/bodyparser/index.js
DELETED
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
// src/bodyparser/index.ts
|
|
2
|
-
import zlib from "node:zlib";
|
|
3
|
-
import IncomingForm from "formidable";
|
|
4
|
-
import rawParser from "raw-body";
|
|
5
|
-
|
|
6
|
-
// src/bodyparser/config.ts
|
|
7
|
-
var json = {
|
|
8
|
-
limit: 1024 ** 2,
|
|
9
|
-
trim: ["*"]
|
|
10
|
-
};
|
|
11
|
-
var form = {
|
|
12
|
-
limit: 1024 ** 2
|
|
13
|
-
};
|
|
14
|
-
var raw = {
|
|
15
|
-
limit: 1024 ** 2
|
|
16
|
-
};
|
|
17
|
-
var config_default = {
|
|
18
|
-
json,
|
|
19
|
-
form,
|
|
20
|
-
raw
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
// src/bodyparser/index.ts
|
|
24
|
-
var bodyparser_default = { json: json2, form: form2, raw: raw2 };
|
|
25
|
-
function json2(opts = {}) {
|
|
26
|
-
return [
|
|
27
|
-
async function useJSONBodyparser(ctx, next) {
|
|
28
|
-
const form3 = IncomingForm({
|
|
29
|
-
maxFieldsSize: opts.limit || config_default.json.limit,
|
|
30
|
-
...opts
|
|
31
|
-
});
|
|
32
|
-
const trimmer = trimmerFactory(opts.trim);
|
|
33
|
-
ctx.request.body = await new Promise((resolve, reject) => {
|
|
34
|
-
form3.parse(ctx.request.req, (err, fields) => {
|
|
35
|
-
if (err) {
|
|
36
|
-
return reject(err);
|
|
37
|
-
}
|
|
38
|
-
resolve(trimmer ? trimmer(fields) : fields);
|
|
39
|
-
});
|
|
40
|
-
});
|
|
41
|
-
return next();
|
|
42
|
-
}
|
|
43
|
-
];
|
|
44
|
-
}
|
|
45
|
-
function form2(opts = {}) {
|
|
46
|
-
return [
|
|
47
|
-
async function useFormBodyparser(ctx, next) {
|
|
48
|
-
const form3 = IncomingForm({
|
|
49
|
-
maxFieldsSize: opts.limit || config_default.form.limit,
|
|
50
|
-
maxFileSize: opts.limit || config_default.form.limit,
|
|
51
|
-
...opts
|
|
52
|
-
});
|
|
53
|
-
let trimmer = trimmerFactory(opts.trim);
|
|
54
|
-
if (opts.multipart || opts.urlencoded) {
|
|
55
|
-
trimmer = void 0;
|
|
56
|
-
}
|
|
57
|
-
ctx.request.body = await new Promise((resolve, reject) => {
|
|
58
|
-
form3.parse(ctx.request.req, (err, fields, files) => {
|
|
59
|
-
if (err) {
|
|
60
|
-
return reject(err);
|
|
61
|
-
}
|
|
62
|
-
resolve({
|
|
63
|
-
fields: trimmer ? trimmer(fields) : fields,
|
|
64
|
-
files
|
|
65
|
-
});
|
|
66
|
-
});
|
|
67
|
-
});
|
|
68
|
-
return next();
|
|
69
|
-
}
|
|
70
|
-
];
|
|
71
|
-
}
|
|
72
|
-
function raw2(opts = {}) {
|
|
73
|
-
return [
|
|
74
|
-
async function useRawBodyparser(ctx, next) {
|
|
75
|
-
const { chunkSize, ...rawParserOptions } = { ...config_default.raw, ...opts };
|
|
76
|
-
const stream = ctx.request.req.pipe(zlib.createUnzip({ chunkSize }));
|
|
77
|
-
ctx.request.body = await rawParser(stream, rawParserOptions);
|
|
78
|
-
return next();
|
|
79
|
-
}
|
|
80
|
-
];
|
|
81
|
-
}
|
|
82
|
-
function trimmerFactory(trimOption) {
|
|
83
|
-
if (!Array.isArray(trimOption) || !trimOption.length) {
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
|
-
const trimableKeys = trimOption.reduce((m, k) => {
|
|
87
|
-
m[k] = true;
|
|
88
|
-
return m;
|
|
89
|
-
}, {});
|
|
90
|
-
const trim = (key, val) => {
|
|
91
|
-
return typeof val === "string" ? trimableKeys[key] || trimableKeys["*"] ? val.trim() : val : val;
|
|
92
|
-
};
|
|
93
|
-
const reducer = (memo, [key, val]) => {
|
|
94
|
-
memo[key] = trim(key, val);
|
|
95
|
-
return memo;
|
|
96
|
-
};
|
|
97
|
-
return (payload) => Object.entries(payload).reduce(
|
|
98
|
-
reducer,
|
|
99
|
-
// accumulator is set to payload intentionally, to avoid duplication of big strings.
|
|
100
|
-
// if using a new object for accumulator then trimmed strings will be duplicated?
|
|
101
|
-
payload
|
|
102
|
-
);
|
|
103
|
-
}
|
|
104
|
-
export {
|
|
105
|
-
config_default as config,
|
|
106
|
-
bodyparser_default as default,
|
|
107
|
-
form2 as form,
|
|
108
|
-
json2 as json,
|
|
109
|
-
raw2 as raw
|
|
110
|
-
};
|
|
111
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/bodyparser/index.ts", "../../src/bodyparser/config.ts"],
|
|
4
|
-
"sourcesContent": ["import zlib from \"node:zlib\";\n\nimport IncomingForm from \"formidable\";\nimport rawParser from \"raw-body\";\n\nimport type { ParameterizedMiddleware } from \"@kosmojs/api\";\n\nimport config from \"./config\";\nimport type {\n FormOptions,\n JsonOptions,\n RawOptions,\n Trimmer,\n TrimOption,\n} from \"./types\";\n\nexport * from \"./types\";\nexport { config };\nexport default { json, form, raw };\n\nexport function json(opts: JsonOptions = {}): Array<ParameterizedMiddleware> {\n return [\n async function useJSONBodyparser(ctx, next) {\n const form = IncomingForm({\n maxFieldsSize: opts.limit || config.json.limit,\n ...opts,\n });\n\n const trimmer = trimmerFactory(opts.trim);\n\n ctx.request.body = await new Promise((resolve, reject) => {\n form.parse(ctx.request.req, (err, fields) => {\n if (err) {\n return reject(err);\n }\n\n resolve(trimmer ? trimmer(fields) : fields);\n });\n });\n\n return next();\n },\n ];\n}\n\nexport function form(opts: FormOptions = {}): Array<ParameterizedMiddleware> {\n return [\n async function useFormBodyparser(ctx, next) {\n const form = IncomingForm({\n maxFieldsSize: opts.limit || config.form.limit,\n maxFileSize: opts.limit || config.form.limit,\n ...opts,\n });\n\n let trimmer = trimmerFactory(opts.trim);\n\n if (opts.multipart || opts.urlencoded) {\n trimmer = undefined;\n }\n\n ctx.request.body = await new Promise((resolve, reject) => {\n form.parse(ctx.request.req, (err, fields, files) => {\n if (err) {\n return reject(err);\n }\n\n resolve({\n fields: trimmer ? trimmer(fields) : fields,\n files,\n });\n });\n });\n\n return next();\n },\n ];\n}\n\nexport function raw(opts: RawOptions = {}): Array<ParameterizedMiddleware> {\n return [\n async function useRawBodyparser(ctx, next) {\n const { chunkSize, ...rawParserOptions } = { ...config.raw, ...opts };\n\n const stream = ctx.request.req.pipe(zlib.createUnzip({ chunkSize }));\n ctx.request.body = await rawParser(stream, rawParserOptions);\n\n return next();\n },\n ];\n}\n\nfunction trimmerFactory(\n trimOption: TrimOption | undefined,\n): Trimmer | undefined {\n if (!Array.isArray(trimOption) || !trimOption.length) {\n return;\n }\n\n const trimableKeys: {\n [key: string]: boolean;\n } = trimOption.reduce((m: Record<string, boolean>, k) => {\n m[k] = true;\n return m;\n }, {});\n\n const trim = (key: string, val: unknown) => {\n return typeof val === \"string\"\n ? trimableKeys[key] || trimableKeys[\"*\"]\n ? val.trim()\n : val\n : val;\n };\n\n const reducer = (\n memo: Record<string, unknown>,\n [key, val]: [string, unknown],\n ) => {\n memo[key] = trim(key, val);\n return memo;\n };\n\n return (payload) =>\n Object.entries(payload).reduce(\n reducer,\n // accumulator is set to payload intentionally, to avoid duplication of big strings.\n // if using a new object for accumulator then trimmed strings will be duplicated?\n payload,\n );\n}\n", "import type { FormOptions, JsonOptions, RawOptions } from \"./types\";\n\nexport const json: JsonOptions = {\n limit: 1024 ** 2,\n trim: [\"*\"],\n};\n\nexport const form: FormOptions = {\n limit: 1024 ** 2,\n};\n\nexport const raw: RawOptions = {\n limit: 1024 ** 2,\n};\n\nexport default {\n json,\n form,\n raw,\n};\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["json", "form", "raw"]
|
|
7
|
-
}
|
package/pkg/queryparser/index.js
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
// src/queryparser/index.ts
|
|
2
|
-
import { parse, stringify } from "qs";
|
|
3
|
-
var queryparser_default = (app, _parseOptions = {}, _stringifyOptions = {}) => {
|
|
4
|
-
const parseOptions = {
|
|
5
|
-
ignoreQueryPrefix: true,
|
|
6
|
-
parseArrays: true,
|
|
7
|
-
arrayLimit: 100,
|
|
8
|
-
parameterLimit: 100,
|
|
9
|
-
depth: 5,
|
|
10
|
-
..._parseOptions
|
|
11
|
-
};
|
|
12
|
-
const stringifyOptions = {
|
|
13
|
-
encodeValuesOnly: true,
|
|
14
|
-
arrayFormat: "brackets",
|
|
15
|
-
..._stringifyOptions
|
|
16
|
-
};
|
|
17
|
-
const obj = {
|
|
18
|
-
get query() {
|
|
19
|
-
return parse(this.querystring || "", parseOptions);
|
|
20
|
-
},
|
|
21
|
-
set query(obj2) {
|
|
22
|
-
this.querystring = stringify(obj2, stringifyOptions);
|
|
23
|
-
}
|
|
24
|
-
};
|
|
25
|
-
const entries = Object.getOwnPropertyNames(obj).map((name) => [
|
|
26
|
-
name,
|
|
27
|
-
Object.getOwnPropertyDescriptor(obj, name)
|
|
28
|
-
]);
|
|
29
|
-
for (const [name, desc] of entries) {
|
|
30
|
-
Object.defineProperty(app.request, name, desc);
|
|
31
|
-
}
|
|
32
|
-
return app;
|
|
33
|
-
};
|
|
34
|
-
export {
|
|
35
|
-
queryparser_default as default
|
|
36
|
-
};
|
|
37
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/queryparser/index.ts"],
|
|
4
|
-
"sourcesContent": ["import type Koa from \"koa\";\nimport type { IParseOptions, IStringifyOptions } from \"qs\";\nimport { parse, stringify } from \"qs\";\n\nimport type { DefaultContext, DefaultState } from \"@/types\";\n\nexport default <\n T extends InstanceType<typeof Koa<DefaultState, DefaultContext>> = never,\n>(\n app: T,\n _parseOptions: IParseOptions = {},\n _stringifyOptions: IStringifyOptions = {},\n) => {\n const parseOptions = {\n ignoreQueryPrefix: true,\n parseArrays: true,\n arrayLimit: 100,\n parameterLimit: 100,\n depth: 5,\n ..._parseOptions,\n };\n\n const stringifyOptions = {\n encodeValuesOnly: true,\n arrayFormat: \"brackets\",\n ..._stringifyOptions,\n } as const;\n\n const obj = {\n get query() {\n return parse((this as Koa.Request).querystring || \"\", parseOptions);\n },\n\n set query(obj: object) {\n (this as Koa.Request).querystring = stringify(obj, stringifyOptions);\n },\n };\n\n const entries = Object.getOwnPropertyNames(obj).map((name) => [\n name,\n Object.getOwnPropertyDescriptor(obj, name),\n ]) as [name: string, desc: PropertyDescriptor][];\n\n for (const [name, desc] of entries) {\n Object.defineProperty(app.request, name, desc);\n }\n\n return app;\n};\n"],
|
|
5
|
-
"mappings": ";AAEA,SAAS,OAAO,iBAAiB;AAIjC,IAAO,sBAAQ,CAGb,KACA,gBAA+B,CAAC,GAChC,oBAAuC,CAAC,MACrC;AACH,QAAM,eAAe;AAAA,IACnB,mBAAmB;AAAA,IACnB,aAAa;AAAA,IACb,YAAY;AAAA,IACZ,gBAAgB;AAAA,IAChB,OAAO;AAAA,IACP,GAAG;AAAA,EACL;AAEA,QAAM,mBAAmB;AAAA,IACvB,kBAAkB;AAAA,IAClB,aAAa;AAAA,IACb,GAAG;AAAA,EACL;AAEA,QAAM,MAAM;AAAA,IACV,IAAI,QAAQ;AACV,aAAO,MAAO,KAAqB,eAAe,IAAI,YAAY;AAAA,IACpE;AAAA,IAEA,IAAI,MAAMA,MAAa;AACrB,MAAC,KAAqB,cAAc,UAAUA,MAAK,gBAAgB;AAAA,IACrE;AAAA,EACF;AAEA,QAAM,UAAU,OAAO,oBAAoB,GAAG,EAAE,IAAI,CAAC,SAAS;AAAA,IAC5D;AAAA,IACA,OAAO,yBAAyB,KAAK,IAAI;AAAA,EAC3C,CAAC;AAED,aAAW,CAAC,MAAM,IAAI,KAAK,SAAS;AAClC,WAAO,eAAe,IAAI,SAAS,MAAM,IAAI;AAAA,EAC/C;AAEA,SAAO;AACT;",
|
|
6
|
-
"names": ["obj"]
|
|
7
|
-
}
|
package/pkg/src/app.d.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import type { FormOptions, JsonOptions, RawOptions } from "./types";
|
|
2
|
-
export declare const json: JsonOptions;
|
|
3
|
-
export declare const form: FormOptions;
|
|
4
|
-
export declare const raw: RawOptions;
|
|
5
|
-
declare const _default: {
|
|
6
|
-
json: JsonOptions;
|
|
7
|
-
form: FormOptions;
|
|
8
|
-
raw: RawOptions;
|
|
9
|
-
};
|
|
10
|
-
export default _default;
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import type { ParameterizedMiddleware } from "@kosmojs/api";
|
|
2
|
-
import config from "./config";
|
|
3
|
-
import type { FormOptions, JsonOptions, RawOptions } from "./types";
|
|
4
|
-
export * from "./types";
|
|
5
|
-
export { config };
|
|
6
|
-
declare const _default: {
|
|
7
|
-
json: typeof json;
|
|
8
|
-
form: typeof form;
|
|
9
|
-
raw: typeof raw;
|
|
10
|
-
};
|
|
11
|
-
export default _default;
|
|
12
|
-
export declare function json(opts?: JsonOptions): Array<ParameterizedMiddleware>;
|
|
13
|
-
export declare function form(opts?: FormOptions): Array<ParameterizedMiddleware>;
|
|
14
|
-
export declare function raw(opts?: RawOptions): Array<ParameterizedMiddleware>;
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import type { Options as FormidableOptions } from "formidable";
|
|
2
|
-
export type TrimOption = Array<string>;
|
|
3
|
-
export type Trimmer = (fields: Record<string, unknown>) => Record<string, unknown>;
|
|
4
|
-
type GenericOptions = {
|
|
5
|
-
limit?: number;
|
|
6
|
-
trim?: TrimOption;
|
|
7
|
-
};
|
|
8
|
-
export type JsonOptions = FormidableOptions & GenericOptions;
|
|
9
|
-
export type FormOptions = FormidableOptions & GenericOptions & {
|
|
10
|
-
uploadDir?: string;
|
|
11
|
-
multipart?: boolean;
|
|
12
|
-
urlencoded?: boolean;
|
|
13
|
-
};
|
|
14
|
-
export type RawOptions = {
|
|
15
|
-
/**
|
|
16
|
-
* The byte limit of the body.
|
|
17
|
-
* If the body ends up being larger than this limit, a 413 error code is returned.
|
|
18
|
-
* */
|
|
19
|
-
limit?: number;
|
|
20
|
-
/**
|
|
21
|
-
* The length of the stream.
|
|
22
|
-
* If the contents of the stream do not add up to this length,
|
|
23
|
-
* an 400 error code is returned
|
|
24
|
-
* */
|
|
25
|
-
length?: number;
|
|
26
|
-
/**
|
|
27
|
-
* The encoding to use to decode the body into a string.
|
|
28
|
-
* By default, a Buffer instance will be returned when no encoding is specified.
|
|
29
|
-
* utf-8 would decode as plain text.
|
|
30
|
-
* use any encoding supported by iconv-lite.
|
|
31
|
-
* */
|
|
32
|
-
encoding?: string;
|
|
33
|
-
/**
|
|
34
|
-
* zlib options
|
|
35
|
-
* */
|
|
36
|
-
chunkSize?: number;
|
|
37
|
-
};
|
|
38
|
-
export type Options = JsonOptions | FormOptions | RawOptions;
|
|
39
|
-
export {};
|
package/pkg/src/debug.d.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import type { HandlerDefinition, MiddlewareDefinition, RouterRoute } from "./types";
|
|
2
|
-
declare const _default: (entry: {
|
|
3
|
-
name: string;
|
|
4
|
-
path: string;
|
|
5
|
-
file: string;
|
|
6
|
-
methods: Array<string>;
|
|
7
|
-
middleware: Array<MiddlewareDefinition>;
|
|
8
|
-
handler: HandlerDefinition;
|
|
9
|
-
}) => RouterRoute["debug"];
|
|
10
|
-
export default _default;
|
package/pkg/src/errors.d.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import type { ParameterizedMiddleware, ValidationErrorData, ValidationErrorEntry, ValidationErrorScope } from "./types";
|
|
2
|
-
/**
|
|
3
|
-
* Standardized error wrapper used by validation generators.
|
|
4
|
-
*
|
|
5
|
-
* Instances of this class are thrown whenever validation fails,
|
|
6
|
-
* carrying both the error scope (e.g. `"params"`, `"payload"`)
|
|
7
|
-
* and the list of validation error details.
|
|
8
|
-
*/
|
|
9
|
-
export declare class ValidationError extends Error {
|
|
10
|
-
scope: ValidationErrorScope;
|
|
11
|
-
errors: Array<ValidationErrorEntry>;
|
|
12
|
-
errorMessage: string;
|
|
13
|
-
errorSummary: string;
|
|
14
|
-
constructor([scope, { errors, errorMessage, errorSummary }]: [
|
|
15
|
-
ValidationErrorScope,
|
|
16
|
-
ValidationErrorData
|
|
17
|
-
]);
|
|
18
|
-
}
|
|
19
|
-
export declare const createErrorHandler: (handler: ParameterizedMiddleware) => ParameterizedMiddleware;
|
package/pkg/src/index.d.ts
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import type Koa from "koa";
|
|
2
|
-
import type { IParseOptions, IStringifyOptions } from "qs";
|
|
3
|
-
import type { DefaultContext, DefaultState } from "../types";
|
|
4
|
-
declare const _default: <T extends InstanceType<typeof Koa<DefaultState, DefaultContext>> = never>(app: T, _parseOptions?: IParseOptions, _stringifyOptions?: IStringifyOptions) => T;
|
|
5
|
-
export default _default;
|
package/pkg/src/router.d.ts
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import type { CreateRouter, DefineRoute, MiddlewareDefinition, RouterRoute, RouterRouteSource } from "./types";
|
|
2
|
-
export declare const createRouter: CreateRouter;
|
|
3
|
-
export declare const defineRoute: DefineRoute;
|
|
4
|
-
export declare const routerRoutesFactory: (routeSources: Array<RouterRouteSource>, { coreMiddleware, }: {
|
|
5
|
-
coreMiddleware: Array<MiddlewareDefinition>;
|
|
6
|
-
}) => Array<RouterRoute>;
|