vovk 3.0.0-draft.13 → 3.0.0-draft.130

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 (82) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +8 -96
  3. package/{HttpException.d.ts → dist/HttpException.d.ts} +2 -2
  4. package/{HttpException.js → dist/HttpException.js} +3 -3
  5. package/dist/JSONLinesResponse.d.ts +14 -0
  6. package/{StreamResponse.js → dist/JSONLinesResponse.js} +15 -9
  7. package/{Segment.d.ts → dist/VovkApp.d.ts} +11 -10
  8. package/dist/VovkApp.js +189 -0
  9. package/dist/client/createRPC.d.ts +3 -0
  10. package/dist/client/createRPC.js +86 -0
  11. package/{client → dist/client}/defaultHandler.d.ts +1 -1
  12. package/dist/client/defaultHandler.js +22 -0
  13. package/dist/client/defaultStreamHandler.d.ts +4 -0
  14. package/{client → dist/client}/defaultStreamHandler.js +8 -8
  15. package/dist/client/fetcher.d.ts +8 -0
  16. package/dist/client/fetcher.js +88 -0
  17. package/dist/client/index.d.ts +3 -0
  18. package/dist/client/index.js +8 -0
  19. package/dist/client/types.d.ts +113 -0
  20. package/dist/createDecorator.d.ts +6 -0
  21. package/{createDecorator.js → dist/createDecorator.js} +21 -16
  22. package/{createSegment.d.ts → dist/createVovkApp.d.ts} +10 -10
  23. package/dist/createVovkApp.js +129 -0
  24. package/dist/index.d.ts +60 -0
  25. package/dist/index.js +25 -0
  26. package/dist/types.d.ts +276 -0
  27. package/dist/types.js +72 -0
  28. package/dist/utils/generateStaticAPI.d.ts +4 -0
  29. package/dist/utils/generateStaticAPI.js +30 -0
  30. package/dist/utils/getSchema.d.ts +20 -0
  31. package/dist/utils/getSchema.js +35 -0
  32. package/dist/utils/parseQuery.d.ts +25 -0
  33. package/dist/utils/parseQuery.js +156 -0
  34. package/dist/utils/reqForm.d.ts +2 -0
  35. package/dist/utils/reqForm.js +32 -0
  36. package/{utils → dist/utils}/reqMeta.d.ts +1 -2
  37. package/{utils → dist/utils}/reqQuery.d.ts +1 -2
  38. package/dist/utils/reqQuery.js +10 -0
  39. package/dist/utils/serializeQuery.d.ts +13 -0
  40. package/dist/utils/serializeQuery.js +65 -0
  41. package/dist/utils/setHandlerSchema.d.ts +4 -0
  42. package/dist/utils/setHandlerSchema.js +15 -0
  43. package/dist/utils/withValidation.d.ts +21 -0
  44. package/dist/utils/withValidation.js +88 -0
  45. package/package.json +10 -4
  46. package/.npmignore +0 -2
  47. package/Segment.js +0 -182
  48. package/StreamResponse.d.ts +0 -16
  49. package/client/clientizeController.d.ts +0 -4
  50. package/client/clientizeController.js +0 -93
  51. package/client/defaultFetcher.d.ts +0 -4
  52. package/client/defaultFetcher.js +0 -49
  53. package/client/defaultHandler.js +0 -21
  54. package/client/defaultStreamHandler.d.ts +0 -4
  55. package/client/index.d.ts +0 -4
  56. package/client/index.js +0 -5
  57. package/client/types.d.ts +0 -100
  58. package/createDecorator.d.ts +0 -4
  59. package/createSegment.js +0 -118
  60. package/generateStaticAPI.d.ts +0 -4
  61. package/generateStaticAPI.js +0 -18
  62. package/index.d.ts +0 -60
  63. package/index.js +0 -20
  64. package/types.d.ts +0 -186
  65. package/types.js +0 -65
  66. package/utils/getSchema.d.ts +0 -8
  67. package/utils/getSchema.js +0 -38
  68. package/utils/reqQuery.js +0 -25
  69. package/utils/setClientValidatorsForHandler.d.ts +0 -5
  70. package/utils/setClientValidatorsForHandler.js +0 -28
  71. package/worker/index.d.ts +0 -3
  72. package/worker/index.js +0 -7
  73. package/worker/promisifyWorker.d.ts +0 -2
  74. package/worker/promisifyWorker.js +0 -143
  75. package/worker/types.d.ts +0 -31
  76. package/worker/types.js +0 -2
  77. package/worker/worker.d.ts +0 -1
  78. package/worker/worker.js +0 -44
  79. /package/{client → dist/client}/types.js +0 -0
  80. /package/{utils → dist/utils}/reqMeta.js +0 -0
  81. /package/{utils → dist/utils}/shim.d.ts +0 -0
  82. /package/{utils → dist/utils}/shim.js +0 -0
@@ -0,0 +1,276 @@
1
+ import type { NextRequest } from 'next/server';
2
+ import type { OperationObject } from 'openapi3-ts/oas31';
3
+ import type { JSONLinesResponse } from './JSONLinesResponse.js';
4
+ import { VovkStreamAsyncIterable } from './client/types.js';
5
+ import type { PackageJson } from 'type-fest';
6
+ export type KnownAny = any;
7
+ export type StaticClass = Function;
8
+ export type VovkHandlerSchema = {
9
+ path: string;
10
+ httpMethod: string;
11
+ validation?: {
12
+ query?: KnownAny;
13
+ body?: KnownAny;
14
+ params?: KnownAny;
15
+ output?: KnownAny;
16
+ iteration?: KnownAny;
17
+ };
18
+ openapi?: OperationObject;
19
+ misc?: Record<string, KnownAny>;
20
+ };
21
+ export type VovkControllerSchema = {
22
+ rpcModuleName: string;
23
+ originalControllerName: string;
24
+ prefix?: string;
25
+ handlers: Record<string, VovkHandlerSchema>;
26
+ };
27
+ export type VovkSegmentSchema = {
28
+ $schema: typeof VovkSchemaIdEnum.SEGMENT | string;
29
+ emitSchema: boolean;
30
+ segmentName: string;
31
+ controllers: Record<string, VovkControllerSchema>;
32
+ };
33
+ export type VovkErrorResponse = {
34
+ cause?: unknown;
35
+ statusCode: HttpStatus;
36
+ message: string;
37
+ isError: true;
38
+ };
39
+ export type VovkControllerInternal = {
40
+ _rpcModuleName?: VovkControllerSchema['rpcModuleName'];
41
+ _prefix?: VovkControllerSchema['prefix'];
42
+ _handlers: VovkControllerSchema['handlers'];
43
+ _handlersMetadata?: Record<string, {
44
+ staticParams?: Record<string, string>[];
45
+ }>;
46
+ _activated?: true;
47
+ _onError?: (err: Error, req: VovkRequest) => void | Promise<void>;
48
+ };
49
+ export type VovkController = StaticClass & VovkControllerInternal & {
50
+ [key: string]: unknown;
51
+ };
52
+ export type DecoratorOptions = {
53
+ cors?: boolean;
54
+ headers?: Record<string, string>;
55
+ staticParams?: Record<string, string>[];
56
+ before?: (this: VovkController, req: VovkRequest) => unknown;
57
+ };
58
+ export type RouteHandler = ((req: VovkRequest, params: Record<string, string>) => Response | Promise<Response> | Iterable<unknown> | AsyncIterable<unknown>) & {
59
+ _options?: DecoratorOptions;
60
+ };
61
+ export interface VovkRequest<BODY extends KnownAny = null, QUERY extends KnownAny = undefined, PARAMS extends KnownAny = undefined> extends Omit<NextRequest, 'json' | 'nextUrl'> {
62
+ json: () => Promise<BODY>;
63
+ nextUrl: Omit<NextRequest['nextUrl'], 'searchParams'> & {
64
+ searchParams: Omit<NextRequest['nextUrl']['searchParams'], 'get' | 'getAll' | 'entries' | 'forEach' | 'keys' | 'values'> & {
65
+ get: <KEY extends keyof QUERY>(key: KEY) => QUERY[KEY] extends readonly (infer ITEM)[] ? ITEM : QUERY[KEY];
66
+ getAll: <KEY extends keyof QUERY>(key: KEY) => QUERY[KEY] extends KnownAny[] ? QUERY[KEY] : QUERY[KEY][];
67
+ entries: () => IterableIterator<[keyof QUERY, QUERY[keyof QUERY]]>;
68
+ forEach: (callbackfn: (value: QUERY[keyof QUERY], key: keyof QUERY, searchParams: NextRequest['nextUrl']['searchParams']) => void) => void;
69
+ keys: () => IterableIterator<keyof QUERY>;
70
+ values: () => IterableIterator<QUERY[keyof QUERY]>;
71
+ };
72
+ };
73
+ vovk: {
74
+ body: () => Promise<BODY>;
75
+ query: () => QUERY;
76
+ meta: <T = Record<KnownAny, KnownAny>>(meta?: T | null) => T;
77
+ form: <T = KnownAny>() => Promise<T>;
78
+ params: () => PARAMS;
79
+ };
80
+ }
81
+ export type ControllerStaticMethod<REQ extends VovkRequest<KnownAny, KnownAny> = VovkRequest<undefined, Record<string, KnownAny>>, PARAMS extends {
82
+ [key: string]: string;
83
+ } = KnownAny> = ((req: REQ, params: PARAMS) => unknown) & {
84
+ _controller?: VovkController;
85
+ };
86
+ export type VovkControllerBody<T extends (...args: KnownAny) => KnownAny> = Awaited<ReturnType<Parameters<T>[0]['vovk']['body']>>;
87
+ export type VovkControllerQuery<T extends (...args: KnownAny) => KnownAny> = ReturnType<Parameters<T>[0]['vovk']['query']>;
88
+ export type VovkControllerParams<T extends (...args: KnownAny) => KnownAny> = Parameters<T>[1] extends object ? Parameters<T>[1] : ReturnType<Parameters<T>[0]['vovk']['params']>;
89
+ export type VovkControllerYieldType<T extends (req: VovkRequest<KnownAny, KnownAny>) => KnownAny> = T extends (...args: KnownAny[]) => AsyncGenerator<infer Y, KnownAny, KnownAny> ? Y : T extends (...args: KnownAny[]) => Generator<infer Y, KnownAny, KnownAny> ? Y : T extends (...args: KnownAny[]) => Promise<JSONLinesResponse<infer Y>> | JSONLinesResponse<infer Y> ? Y : never;
90
+ export type VovkOutput<T extends ((...args: KnownAny) => KnownAny) & {
91
+ __output?: KnownAny;
92
+ }> = T['__output'];
93
+ export type VovkIteration<T extends ((...args: KnownAny) => KnownAny) & {
94
+ __iteration?: KnownAny;
95
+ }> = T['__iteration'];
96
+ export type VovkClientBody<T extends (...args: KnownAny[]) => unknown> = Parameters<T>[0]['body'];
97
+ export type VovkClientQuery<T extends (...args: KnownAny[]) => unknown> = Parameters<T>[0]['query'];
98
+ export type VovkClientParams<T extends (...args: KnownAny[]) => unknown> = Parameters<T>[0]['params'];
99
+ export type VovkClientYieldType<T extends (...args: KnownAny[]) => unknown> = T extends (...args: KnownAny[]) => Promise<VovkStreamAsyncIterable<infer Y>> ? Y : never;
100
+ export type VovkBody<T extends (...args: KnownAny[]) => unknown> = T extends {
101
+ isRPC: true;
102
+ } ? VovkClientBody<T> : VovkControllerBody<T>;
103
+ export type VovkQuery<T extends (...args: KnownAny[]) => unknown> = T extends {
104
+ isRPC: true;
105
+ } ? VovkClientQuery<T> : VovkControllerQuery<T>;
106
+ export type VovkParams<T extends (...args: KnownAny[]) => unknown> = T extends {
107
+ isRPC: true;
108
+ } ? VovkClientParams<T> : VovkControllerParams<T>;
109
+ export type VovkYieldType<T extends (...args: KnownAny[]) => unknown> = T extends {
110
+ isRPC: true;
111
+ } ? VovkClientYieldType<T> : VovkControllerYieldType<T>;
112
+ export type VovkReturnType<T extends (...args: KnownAny) => unknown> = Awaited<ReturnType<T>>;
113
+ export type StreamAbortMessage = {
114
+ isError: true;
115
+ reason: KnownAny;
116
+ };
117
+ export type VovkValidationType = 'body' | 'query' | 'params' | 'output' | 'iteration';
118
+ export type VovkSchema = {
119
+ $schema: typeof VovkSchemaIdEnum.SCHEMA | string;
120
+ config: Partial<VovkStrictConfig>;
121
+ segments: Record<string, VovkSegmentSchema>;
122
+ };
123
+ export declare enum HttpMethod {
124
+ GET = "GET",
125
+ POST = "POST",
126
+ PUT = "PUT",
127
+ PATCH = "PATCH",
128
+ DELETE = "DELETE",
129
+ HEAD = "HEAD",
130
+ OPTIONS = "OPTIONS"
131
+ }
132
+ export declare enum HttpStatus {
133
+ NULL = 0,
134
+ CONTINUE = 100,
135
+ SWITCHING_PROTOCOLS = 101,
136
+ PROCESSING = 102,
137
+ EARLYHINTS = 103,
138
+ OK = 200,
139
+ CREATED = 201,
140
+ ACCEPTED = 202,
141
+ NON_AUTHORITATIVE_INFORMATION = 203,
142
+ NO_CONTENT = 204,
143
+ RESET_CONTENT = 205,
144
+ PARTIAL_CONTENT = 206,
145
+ AMBIGUOUS = 300,
146
+ MOVED_PERMANENTLY = 301,
147
+ FOUND = 302,
148
+ SEE_OTHER = 303,
149
+ NOT_MODIFIED = 304,
150
+ TEMPORARY_REDIRECT = 307,
151
+ PERMANENT_REDIRECT = 308,
152
+ BAD_REQUEST = 400,
153
+ UNAUTHORIZED = 401,
154
+ PAYMENT_REQUIRED = 402,
155
+ FORBIDDEN = 403,
156
+ NOT_FOUND = 404,
157
+ METHOD_NOT_ALLOWED = 405,
158
+ NOT_ACCEPTABLE = 406,
159
+ PROXY_AUTHENTICATION_REQUIRED = 407,
160
+ REQUEST_TIMEOUT = 408,
161
+ CONFLICT = 409,
162
+ GONE = 410,
163
+ LENGTH_REQUIRED = 411,
164
+ PRECONDITION_FAILED = 412,
165
+ PAYLOAD_TOO_LARGE = 413,
166
+ URI_TOO_LONG = 414,
167
+ UNSUPPORTED_MEDIA_TYPE = 415,
168
+ REQUESTED_RANGE_NOT_SATISFIABLE = 416,
169
+ EXPECTATION_FAILED = 417,
170
+ I_AM_A_TEAPOT = 418,
171
+ MISDIRECTED = 421,
172
+ UNPROCESSABLE_ENTITY = 422,
173
+ FAILED_DEPENDENCY = 424,
174
+ PRECONDITION_REQUIRED = 428,
175
+ TOO_MANY_REQUESTS = 429,
176
+ INTERNAL_SERVER_ERROR = 500,
177
+ NOT_IMPLEMENTED = 501,
178
+ BAD_GATEWAY = 502,
179
+ SERVICE_UNAVAILABLE = 503,
180
+ GATEWAY_TIMEOUT = 504,
181
+ HTTP_VERSION_NOT_SUPPORTED = 505
182
+ }
183
+ export declare enum VovkSchemaIdEnum {
184
+ CONFIG = "https://vovk.dev/api/spec/v3/config.json",
185
+ SEGMENT = "https://vovk.dev/api/spec/v3/segment.json",
186
+ SCHEMA = "https://vovk.dev/api/spec/v3/schema.json"
187
+ }
188
+ type ClientConfigCommon = {
189
+ enabled?: boolean;
190
+ outDir?: string;
191
+ fromTemplates?: string[];
192
+ } & ({
193
+ excludeSegments?: never;
194
+ includeSegments?: string[];
195
+ } | {
196
+ excludeSegments?: string[];
197
+ includeSegments?: never;
198
+ });
199
+ type ClientConfigFull = ClientConfigCommon & {
200
+ package?: PackageJson;
201
+ };
202
+ type ClientConfigSegmented = ClientConfigCommon & {
203
+ packages?: Record<string, PackageJson>;
204
+ };
205
+ type BundleConfig = {
206
+ outDir?: string;
207
+ requires?: Record<string, string>;
208
+ tsClientOutDir?: string;
209
+ dontDeleteTsClientOutDirAfter?: boolean;
210
+ sourcemap?: boolean;
211
+ } & ({
212
+ excludeSegments?: never;
213
+ includeSegments?: string[];
214
+ } | {
215
+ excludeSegments?: string[];
216
+ includeSegments?: never;
217
+ });
218
+ export type ClientTemplateDef = {
219
+ extends?: string;
220
+ templatePath?: string | null;
221
+ origin?: string | null;
222
+ composedClient?: Omit<ClientConfigFull, 'fromTemplates' | 'enabled'>;
223
+ segmentedClient?: Omit<ClientConfigSegmented, 'fromTemplates' | 'enabled'>;
224
+ segmentConfig?: false | Record<string, {
225
+ origin?: string;
226
+ rootEntry?: boolean;
227
+ }>;
228
+ requires?: Record<string, string>;
229
+ };
230
+ export type VovkConfig = {
231
+ $schema?: typeof VovkSchemaIdEnum.CONFIG | string;
232
+ emitConfig?: boolean | (keyof VovkStrictConfig)[];
233
+ schemaOutDir?: string;
234
+ composedClient?: ClientConfigFull;
235
+ segmentedClient?: ClientConfigSegmented;
236
+ bundle?: BundleConfig;
237
+ imports?: {
238
+ fetcher?: string | [string, string] | [string];
239
+ validateOnClient?: string | [string, string] | [string];
240
+ createRPC?: string | [string, string] | [string];
241
+ };
242
+ modulesDir?: string;
243
+ rootEntry?: string;
244
+ origin?: string;
245
+ rootSegmentModulesDirName?: string;
246
+ logLevel?: 'error' | 'trace' | 'debug' | 'info' | 'warn';
247
+ prettifyClient?: boolean;
248
+ devHttps?: boolean;
249
+ clientTemplateDefs?: Record<string, ClientTemplateDef>;
250
+ moduleTemplates?: {
251
+ service?: string;
252
+ controller?: string;
253
+ [key: string]: string | undefined;
254
+ };
255
+ libs?: Record<string, KnownAny>;
256
+ /** @todo this is an experimental feature */
257
+ segmentConfig?: false | Record<string, {
258
+ origin?: string;
259
+ rootEntry?: boolean;
260
+ }>;
261
+ };
262
+ export type VovkStrictConfig = Required<Omit<VovkConfig, 'emitConfig' | 'libs' | 'imports' | 'composedClient' | 'segmentedClient' | 'bundle'>> & {
263
+ emitConfig: (keyof VovkStrictConfig)[];
264
+ bundle: RequireAllExcept<Exclude<VovkConfig['bundle'], undefined>, 'includeSegments' | 'excludeSegments'>;
265
+ imports: {
266
+ fetcher: [string, string] | [string];
267
+ validateOnClient: [string, string] | [string] | null;
268
+ createRPC: [string, string] | [string];
269
+ };
270
+ libs: Record<string, KnownAny>;
271
+ composedClient: RequireFields<ClientConfigFull, 'enabled' | 'fromTemplates' | 'outDir'>;
272
+ segmentedClient: RequireFields<ClientConfigSegmented, 'enabled' | 'fromTemplates' | 'outDir'>;
273
+ };
274
+ type RequireFields<T, K extends keyof T> = T & Required<Pick<T, K>>;
275
+ type RequireAllExcept<T, K extends keyof T> = Required<Omit<T, K>> & Pick<T, K>;
276
+ export {};
package/dist/types.js ADDED
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.VovkSchemaIdEnum = exports.HttpStatus = exports.HttpMethod = void 0;
4
+ // Enums
5
+ var HttpMethod;
6
+ (function (HttpMethod) {
7
+ HttpMethod["GET"] = "GET";
8
+ HttpMethod["POST"] = "POST";
9
+ HttpMethod["PUT"] = "PUT";
10
+ HttpMethod["PATCH"] = "PATCH";
11
+ HttpMethod["DELETE"] = "DELETE";
12
+ HttpMethod["HEAD"] = "HEAD";
13
+ HttpMethod["OPTIONS"] = "OPTIONS";
14
+ })(HttpMethod || (exports.HttpMethod = HttpMethod = {}));
15
+ var HttpStatus;
16
+ (function (HttpStatus) {
17
+ HttpStatus[HttpStatus["NULL"] = 0] = "NULL";
18
+ HttpStatus[HttpStatus["CONTINUE"] = 100] = "CONTINUE";
19
+ HttpStatus[HttpStatus["SWITCHING_PROTOCOLS"] = 101] = "SWITCHING_PROTOCOLS";
20
+ HttpStatus[HttpStatus["PROCESSING"] = 102] = "PROCESSING";
21
+ HttpStatus[HttpStatus["EARLYHINTS"] = 103] = "EARLYHINTS";
22
+ HttpStatus[HttpStatus["OK"] = 200] = "OK";
23
+ HttpStatus[HttpStatus["CREATED"] = 201] = "CREATED";
24
+ HttpStatus[HttpStatus["ACCEPTED"] = 202] = "ACCEPTED";
25
+ HttpStatus[HttpStatus["NON_AUTHORITATIVE_INFORMATION"] = 203] = "NON_AUTHORITATIVE_INFORMATION";
26
+ HttpStatus[HttpStatus["NO_CONTENT"] = 204] = "NO_CONTENT";
27
+ HttpStatus[HttpStatus["RESET_CONTENT"] = 205] = "RESET_CONTENT";
28
+ HttpStatus[HttpStatus["PARTIAL_CONTENT"] = 206] = "PARTIAL_CONTENT";
29
+ HttpStatus[HttpStatus["AMBIGUOUS"] = 300] = "AMBIGUOUS";
30
+ HttpStatus[HttpStatus["MOVED_PERMANENTLY"] = 301] = "MOVED_PERMANENTLY";
31
+ HttpStatus[HttpStatus["FOUND"] = 302] = "FOUND";
32
+ HttpStatus[HttpStatus["SEE_OTHER"] = 303] = "SEE_OTHER";
33
+ HttpStatus[HttpStatus["NOT_MODIFIED"] = 304] = "NOT_MODIFIED";
34
+ HttpStatus[HttpStatus["TEMPORARY_REDIRECT"] = 307] = "TEMPORARY_REDIRECT";
35
+ HttpStatus[HttpStatus["PERMANENT_REDIRECT"] = 308] = "PERMANENT_REDIRECT";
36
+ HttpStatus[HttpStatus["BAD_REQUEST"] = 400] = "BAD_REQUEST";
37
+ HttpStatus[HttpStatus["UNAUTHORIZED"] = 401] = "UNAUTHORIZED";
38
+ HttpStatus[HttpStatus["PAYMENT_REQUIRED"] = 402] = "PAYMENT_REQUIRED";
39
+ HttpStatus[HttpStatus["FORBIDDEN"] = 403] = "FORBIDDEN";
40
+ HttpStatus[HttpStatus["NOT_FOUND"] = 404] = "NOT_FOUND";
41
+ HttpStatus[HttpStatus["METHOD_NOT_ALLOWED"] = 405] = "METHOD_NOT_ALLOWED";
42
+ HttpStatus[HttpStatus["NOT_ACCEPTABLE"] = 406] = "NOT_ACCEPTABLE";
43
+ HttpStatus[HttpStatus["PROXY_AUTHENTICATION_REQUIRED"] = 407] = "PROXY_AUTHENTICATION_REQUIRED";
44
+ HttpStatus[HttpStatus["REQUEST_TIMEOUT"] = 408] = "REQUEST_TIMEOUT";
45
+ HttpStatus[HttpStatus["CONFLICT"] = 409] = "CONFLICT";
46
+ HttpStatus[HttpStatus["GONE"] = 410] = "GONE";
47
+ HttpStatus[HttpStatus["LENGTH_REQUIRED"] = 411] = "LENGTH_REQUIRED";
48
+ HttpStatus[HttpStatus["PRECONDITION_FAILED"] = 412] = "PRECONDITION_FAILED";
49
+ HttpStatus[HttpStatus["PAYLOAD_TOO_LARGE"] = 413] = "PAYLOAD_TOO_LARGE";
50
+ HttpStatus[HttpStatus["URI_TOO_LONG"] = 414] = "URI_TOO_LONG";
51
+ HttpStatus[HttpStatus["UNSUPPORTED_MEDIA_TYPE"] = 415] = "UNSUPPORTED_MEDIA_TYPE";
52
+ HttpStatus[HttpStatus["REQUESTED_RANGE_NOT_SATISFIABLE"] = 416] = "REQUESTED_RANGE_NOT_SATISFIABLE";
53
+ HttpStatus[HttpStatus["EXPECTATION_FAILED"] = 417] = "EXPECTATION_FAILED";
54
+ HttpStatus[HttpStatus["I_AM_A_TEAPOT"] = 418] = "I_AM_A_TEAPOT";
55
+ HttpStatus[HttpStatus["MISDIRECTED"] = 421] = "MISDIRECTED";
56
+ HttpStatus[HttpStatus["UNPROCESSABLE_ENTITY"] = 422] = "UNPROCESSABLE_ENTITY";
57
+ HttpStatus[HttpStatus["FAILED_DEPENDENCY"] = 424] = "FAILED_DEPENDENCY";
58
+ HttpStatus[HttpStatus["PRECONDITION_REQUIRED"] = 428] = "PRECONDITION_REQUIRED";
59
+ HttpStatus[HttpStatus["TOO_MANY_REQUESTS"] = 429] = "TOO_MANY_REQUESTS";
60
+ HttpStatus[HttpStatus["INTERNAL_SERVER_ERROR"] = 500] = "INTERNAL_SERVER_ERROR";
61
+ HttpStatus[HttpStatus["NOT_IMPLEMENTED"] = 501] = "NOT_IMPLEMENTED";
62
+ HttpStatus[HttpStatus["BAD_GATEWAY"] = 502] = "BAD_GATEWAY";
63
+ HttpStatus[HttpStatus["SERVICE_UNAVAILABLE"] = 503] = "SERVICE_UNAVAILABLE";
64
+ HttpStatus[HttpStatus["GATEWAY_TIMEOUT"] = 504] = "GATEWAY_TIMEOUT";
65
+ HttpStatus[HttpStatus["HTTP_VERSION_NOT_SUPPORTED"] = 505] = "HTTP_VERSION_NOT_SUPPORTED";
66
+ })(HttpStatus || (exports.HttpStatus = HttpStatus = {}));
67
+ var VovkSchemaIdEnum;
68
+ (function (VovkSchemaIdEnum) {
69
+ VovkSchemaIdEnum["CONFIG"] = "https://vovk.dev/api/spec/v3/config.json";
70
+ VovkSchemaIdEnum["SEGMENT"] = "https://vovk.dev/api/spec/v3/segment.json";
71
+ VovkSchemaIdEnum["SCHEMA"] = "https://vovk.dev/api/spec/v3/schema.json";
72
+ })(VovkSchemaIdEnum || (exports.VovkSchemaIdEnum = VovkSchemaIdEnum = {}));
@@ -0,0 +1,4 @@
1
+ import type { StaticClass } from '../types.js';
2
+ export declare function generateStaticAPI(c: Record<string, StaticClass>, slug?: string): {
3
+ [slug]: string[];
4
+ }[];
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateStaticAPI = generateStaticAPI;
4
+ function generateStaticAPI(c, slug = 'vovk') {
5
+ const controllers = c;
6
+ return [
7
+ { [slug]: ['_schema_'] },
8
+ ...Object.values(controllers)
9
+ .map((controller) => {
10
+ const handlers = controller._handlers;
11
+ const splitPrefix = controller._prefix?.split('/') ?? [];
12
+ return Object.entries(handlers)
13
+ .map(([name, handler]) => {
14
+ const staticParams = controller._handlersMetadata?.[name]?.staticParams;
15
+ if (staticParams?.length) {
16
+ return staticParams.map((paramsItem) => {
17
+ let path = handler.path;
18
+ for (const [key, value] of Object.entries(paramsItem)) {
19
+ path = path.replace(`:${key}`, value);
20
+ }
21
+ return { [slug]: [...splitPrefix, ...path.split('/')].filter(Boolean) };
22
+ });
23
+ }
24
+ return [{ [slug]: [...splitPrefix, ...handler.path.split('/')].filter(Boolean) }];
25
+ })
26
+ .flat();
27
+ })
28
+ .flat(),
29
+ ];
30
+ }
@@ -0,0 +1,20 @@
1
+ import { type VovkSegmentSchema, type VovkController, type StaticClass } from '../types.js';
2
+ export declare function getControllerSchema(controller: VovkController, rpcModuleName: string, exposeValidation: boolean): {
3
+ rpcModuleName: string;
4
+ originalControllerName: string;
5
+ prefix: string;
6
+ handlers: {
7
+ [k: string]: {
8
+ path: string;
9
+ httpMethod: string;
10
+ openapi?: import("openapi3-ts/oas31.js").OperationObject;
11
+ misc?: Record<string, import("../types.js").KnownAny>;
12
+ };
13
+ };
14
+ };
15
+ export default function getSchema(options: {
16
+ emitSchema?: boolean;
17
+ segmentName?: string;
18
+ controllers: Record<string, StaticClass>;
19
+ exposeValidation?: boolean;
20
+ }): VovkSegmentSchema;
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getControllerSchema = getControllerSchema;
4
+ exports.default = getSchema;
5
+ const types_js_1 = require("../types.js");
6
+ function getControllerSchema(controller, rpcModuleName, exposeValidation) {
7
+ return {
8
+ rpcModuleName,
9
+ originalControllerName: controller.name,
10
+ prefix: controller._prefix ?? '',
11
+ handlers: {
12
+ ...(exposeValidation
13
+ ? controller._handlers
14
+ : Object.fromEntries(
15
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
16
+ Object.entries(controller._handlers ?? {}).map(([key, { validation: _v, ...value }]) => [key, value]))),
17
+ },
18
+ };
19
+ }
20
+ function getSchema(options) {
21
+ const exposeValidation = options?.exposeValidation ?? true;
22
+ const emitSchema = options.emitSchema ?? true;
23
+ const schema = {
24
+ $schema: types_js_1.VovkSchemaIdEnum.SEGMENT,
25
+ emitSchema,
26
+ segmentName: options.segmentName ?? '',
27
+ controllers: {},
28
+ };
29
+ if (!emitSchema)
30
+ return schema;
31
+ for (const [rpcModuleName, controller] of Object.entries(options.controllers)) {
32
+ schema.controllers[rpcModuleName] = getControllerSchema(controller, rpcModuleName, exposeValidation);
33
+ }
34
+ return schema;
35
+ }
@@ -0,0 +1,25 @@
1
+ import type { KnownAny } from '../types.js';
2
+ /**
3
+ * Deserialize a bracket-based query string into an object.
4
+ *
5
+ * Supports:
6
+ * - Key/value pairs with nested brackets (e.g. "a[b][0]=value")
7
+ * - Arrays with empty bracket (e.g. "arr[]=1&arr[]=2")
8
+ * - Mixed arrays of objects, etc.
9
+ *
10
+ * @example
11
+ * parseQuery("x=xx&y[0]=yy&y[1]=uu&z[f]=x&z[u][0]=uu&z[u][1]=xx&z[d][x]=ee")
12
+ * => {
13
+ * x: "xx",
14
+ * y: ["yy", "uu"],
15
+ * z: {
16
+ * f: "x",
17
+ * u: ["uu", "xx"],
18
+ * d: { x: "ee" }
19
+ * }
20
+ * }
21
+ *
22
+ * @param queryString - The raw query string (e.g. location.search.slice(1))
23
+ * @returns - A nested object representing the query params
24
+ */
25
+ export default function parseQuery(queryString: string): Record<string, KnownAny>;
@@ -0,0 +1,156 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = parseQuery;
4
+ /**
5
+ * Parse a bracket-based key (e.g. "z[d][0][x]" or "arr[]")
6
+ * into an array of path segments (strings or special push-markers).
7
+ *
8
+ * Example: "z[d][0][x]" => ["z", "d", "0", "x"]
9
+ * Example: "arr[]" => ["arr", "" ] // "" indicates "push" onto array
10
+ */
11
+ function parseKey(key) {
12
+ // The first segment is everything up to the first '[' (or the entire key if no '[')
13
+ const segments = [];
14
+ const topKeyMatch = key.match(/^([^[\]]+)/);
15
+ if (topKeyMatch) {
16
+ segments.push(topKeyMatch[1]);
17
+ }
18
+ else {
19
+ // If it starts with brackets, treat it as empty? (edge case)
20
+ segments.push('');
21
+ }
22
+ // Now capture all bracket parts: [something], [0], []
23
+ const bracketRegex = /\[([^[\]]*)\]/g;
24
+ let match;
25
+ while ((match = bracketRegex.exec(key)) !== null) {
26
+ // match[1] is the content inside the brackets
27
+ segments.push(match[1]);
28
+ }
29
+ return segments;
30
+ }
31
+ /**
32
+ * Recursively set a value in a nested object/array, given a path of segments.
33
+ * - If segment is numeric => treat as array index
34
+ * - If segment is empty "" => push to array
35
+ * - Else => object property
36
+ */
37
+ function setValue(obj, path, value) {
38
+ let current = obj;
39
+ for (let i = 0; i < path.length; i++) {
40
+ const segment = path[i];
41
+ // If we're at the last segment, set the value
42
+ if (i === path.length - 1) {
43
+ if (segment === '') {
44
+ // Empty bracket => push
45
+ if (!Array.isArray(current)) {
46
+ current = [];
47
+ }
48
+ current.push(value);
49
+ }
50
+ else if (!isNaN(Number(segment))) {
51
+ // Numeric segment => array index
52
+ const idx = Number(segment);
53
+ if (!Array.isArray(current)) {
54
+ current = [];
55
+ }
56
+ current[idx] = value;
57
+ }
58
+ else {
59
+ // Object property
60
+ current[segment] = value;
61
+ }
62
+ }
63
+ else {
64
+ // Not the last segment: descend into existing structure or create it
65
+ const nextSegment = path[i + 1];
66
+ if (segment === '') {
67
+ // Empty bracket => push
68
+ if (!Array.isArray(current)) {
69
+ // Convert the current node into an array, if not one
70
+ current = [];
71
+ }
72
+ // If we are not at the last path, we need a placeholder object or array
73
+ // for the next segment. We'll push something and move current to that.
74
+ if (current.length === 0) {
75
+ // nothing in array yet
76
+ current.push(typeof nextSegment === 'string' && !isNaN(Number(nextSegment)) ? [] : {});
77
+ }
78
+ else if (typeof nextSegment === 'string' && !isNaN(Number(nextSegment))) {
79
+ // next is numeric => we want an array
80
+ if (!Array.isArray(current[current.length - 1])) {
81
+ current[current.length - 1] = [];
82
+ }
83
+ }
84
+ else {
85
+ // next is not numeric => we want an object
86
+ if (typeof current[current.length - 1] !== 'object') {
87
+ current[current.length - 1] = {};
88
+ }
89
+ }
90
+ current = current[current.length - 1];
91
+ }
92
+ else if (!isNaN(Number(segment))) {
93
+ // segment is numeric => array index
94
+ const idx = Number(segment);
95
+ if (!Array.isArray(current)) {
96
+ current = [];
97
+ }
98
+ if (current[idx] === undefined) {
99
+ // Create placeholder for next segment
100
+ current[idx] = typeof nextSegment === 'string' && !isNaN(Number(nextSegment)) ? [] : {};
101
+ }
102
+ current = current[idx];
103
+ }
104
+ else {
105
+ // segment is an object key
106
+ if (current[segment] === undefined) {
107
+ // Create placeholder
108
+ current[segment] = typeof nextSegment === 'string' && !isNaN(Number(nextSegment)) ? [] : {};
109
+ }
110
+ current = current[segment];
111
+ }
112
+ }
113
+ }
114
+ }
115
+ /**
116
+ * Deserialize a bracket-based query string into an object.
117
+ *
118
+ * Supports:
119
+ * - Key/value pairs with nested brackets (e.g. "a[b][0]=value")
120
+ * - Arrays with empty bracket (e.g. "arr[]=1&arr[]=2")
121
+ * - Mixed arrays of objects, etc.
122
+ *
123
+ * @example
124
+ * parseQuery("x=xx&y[0]=yy&y[1]=uu&z[f]=x&z[u][0]=uu&z[u][1]=xx&z[d][x]=ee")
125
+ * => {
126
+ * x: "xx",
127
+ * y: ["yy", "uu"],
128
+ * z: {
129
+ * f: "x",
130
+ * u: ["uu", "xx"],
131
+ * d: { x: "ee" }
132
+ * }
133
+ * }
134
+ *
135
+ * @param queryString - The raw query string (e.g. location.search.slice(1))
136
+ * @returns - A nested object representing the query params
137
+ */
138
+ function parseQuery(queryString) {
139
+ const result = {};
140
+ if (!queryString)
141
+ return result;
142
+ // Split into key=value pairs
143
+ const pairs = queryString
144
+ .replace(/^\?/, '') // Remove leading "?" if present
145
+ .split('&');
146
+ for (const pair of pairs) {
147
+ const [rawKey, rawVal = ''] = pair.split('=');
148
+ const decodedKey = decodeURIComponent(rawKey);
149
+ const decodedVal = decodeURIComponent(rawVal);
150
+ // Parse bracket notation
151
+ const pathSegments = parseKey(decodedKey);
152
+ // Insert into the result object
153
+ setValue(result, pathSegments, decodedVal);
154
+ }
155
+ return result;
156
+ }
@@ -0,0 +1,2 @@
1
+ import type { KnownAny, VovkRequest } from '../types.js';
2
+ export default function reqForm<T = KnownAny>(req: VovkRequest<KnownAny, KnownAny>): Promise<T>;
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = reqForm;
4
+ const formMap = new WeakMap();
5
+ async function reqForm(req) {
6
+ if (formMap.has(req)) {
7
+ return formMap.get(req);
8
+ }
9
+ const body = await req.formData();
10
+ const formData = {};
11
+ for (const [key, value] of body.entries()) {
12
+ if (value instanceof File) {
13
+ // If this key already exists, convert to array or append to existing array
14
+ if (formData[key]) {
15
+ if (Array.isArray(formData[key])) {
16
+ formData[key].push(value);
17
+ }
18
+ else {
19
+ formData[key] = [formData[key], value];
20
+ }
21
+ }
22
+ else {
23
+ formData[key] = value;
24
+ }
25
+ }
26
+ else {
27
+ formData[key] = value.toString();
28
+ }
29
+ }
30
+ formMap.set(req, formData);
31
+ return formData;
32
+ }
@@ -1,3 +1,2 @@
1
- import { VovkRequest } from 'vovk';
2
- import { _KnownAny as KnownAny } from '../types';
1
+ import type { KnownAny, VovkRequest } from '../types.js';
3
2
  export default function reqMeta<T = Record<KnownAny, KnownAny>>(req: VovkRequest<KnownAny, KnownAny>, meta?: T | null): T;
@@ -1,3 +1,2 @@
1
- import { _KnownAny as KnownAny } from '../types';
2
- import { VovkRequest } from 'vovk';
1
+ import type { KnownAny, VovkRequest } from '../types.js';
3
2
  export default function reqQuery<T extends object | undefined>(req: VovkRequest<KnownAny, T>): T;