vovk 3.0.0-draft.206 → 3.0.0-draft.207

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 (104) hide show
  1. package/bin/index.mjs +2 -0
  2. package/cjs/HttpException.js +11 -11
  3. package/cjs/JSONLinesResponse.d.ts +1 -1
  4. package/cjs/JSONLinesResponse.js +53 -51
  5. package/cjs/VovkApp.js +177 -187
  6. package/cjs/client/createRPC.d.ts +2 -2
  7. package/cjs/client/createRPC.js +5 -11
  8. package/cjs/client/defaultHandler.js +17 -20
  9. package/cjs/client/defaultStreamHandler.js +71 -69
  10. package/cjs/client/fetcher.d.ts +8 -3
  11. package/cjs/client/fetcher.js +83 -85
  12. package/cjs/client/types.d.ts +35 -42
  13. package/cjs/createVovkApp.d.ts +1 -0
  14. package/cjs/createVovkApp.js +116 -122
  15. package/cjs/index.d.ts +37 -35
  16. package/cjs/index.js +34 -32
  17. package/cjs/openapi/error.js +90 -90
  18. package/cjs/openapi/generateFnName.d.ts +3 -9
  19. package/cjs/openapi/generateFnName.js +49 -61
  20. package/cjs/openapi/index.d.ts +2 -3
  21. package/cjs/openapi/index.js +17 -28
  22. package/cjs/openapi/openAPIToVovkSchema.d.ts +2 -15
  23. package/cjs/openapi/openAPIToVovkSchema.js +85 -26
  24. package/cjs/openapi/vovkSchemaToOpenAPI.js +227 -239
  25. package/cjs/types.d.ts +58 -30
  26. package/cjs/types.js +62 -62
  27. package/cjs/utils/camelCase.d.ts +6 -0
  28. package/cjs/utils/camelCase.js +37 -0
  29. package/cjs/utils/createCodeExamples.js +52 -67
  30. package/cjs/utils/createDecorator.js +40 -41
  31. package/cjs/utils/createLLMFunctions.js +89 -97
  32. package/cjs/utils/generateStaticAPI.js +26 -26
  33. package/cjs/utils/getSchema.d.ts +1 -0
  34. package/cjs/utils/getSchema.js +35 -34
  35. package/cjs/utils/multitenant.d.ts +19 -21
  36. package/cjs/utils/multitenant.js +112 -112
  37. package/cjs/utils/parseQuery.js +110 -101
  38. package/cjs/utils/reqForm.js +27 -23
  39. package/cjs/utils/reqMeta.js +9 -8
  40. package/cjs/utils/reqQuery.d.ts +2 -2
  41. package/cjs/utils/reqQuery.js +7 -9
  42. package/cjs/utils/serializeQuery.js +40 -39
  43. package/cjs/utils/setHandlerSchema.js +12 -14
  44. package/cjs/utils/shim.js +13 -13
  45. package/cjs/utils/withStandard.d.ts +51 -0
  46. package/cjs/utils/withStandard.js +30 -0
  47. package/cjs/utils/{withValidation.d.ts → withValidationLibrary.d.ts} +4 -3
  48. package/cjs/utils/{withValidation.js → withValidationLibrary.js} +12 -11
  49. package/mjs/HttpException.js +11 -11
  50. package/mjs/JSONLinesResponse.d.ts +1 -1
  51. package/mjs/JSONLinesResponse.js +53 -51
  52. package/mjs/VovkApp.js +177 -187
  53. package/mjs/client/createRPC.d.ts +2 -2
  54. package/mjs/client/createRPC.js +5 -11
  55. package/mjs/client/defaultHandler.js +17 -20
  56. package/mjs/client/defaultStreamHandler.js +71 -69
  57. package/mjs/client/fetcher.d.ts +8 -3
  58. package/mjs/client/fetcher.js +1 -1
  59. package/mjs/client/types.d.ts +35 -42
  60. package/mjs/createVovkApp.d.ts +1 -0
  61. package/mjs/createVovkApp.js +116 -122
  62. package/mjs/index.d.ts +37 -35
  63. package/mjs/index.js +34 -32
  64. package/mjs/openapi/error.js +90 -90
  65. package/mjs/openapi/generateFnName.d.ts +3 -9
  66. package/mjs/openapi/generateFnName.js +49 -61
  67. package/mjs/openapi/index.d.ts +2 -3
  68. package/mjs/openapi/index.js +17 -28
  69. package/mjs/openapi/openAPIToVovkSchema.d.ts +2 -15
  70. package/mjs/openapi/openAPIToVovkSchema.js +85 -26
  71. package/mjs/openapi/vovkSchemaToOpenAPI.js +227 -239
  72. package/mjs/types.d.ts +58 -30
  73. package/mjs/types.js +62 -62
  74. package/mjs/utils/camelCase.d.ts +6 -0
  75. package/mjs/utils/camelCase.js +37 -0
  76. package/mjs/utils/createCodeExamples.js +52 -67
  77. package/mjs/utils/createDecorator.js +40 -41
  78. package/mjs/utils/createLLMFunctions.js +89 -97
  79. package/mjs/utils/generateStaticAPI.js +26 -26
  80. package/mjs/utils/getSchema.d.ts +1 -0
  81. package/mjs/utils/getSchema.js +35 -34
  82. package/mjs/utils/multitenant.d.ts +19 -21
  83. package/mjs/utils/multitenant.js +112 -112
  84. package/mjs/utils/parseQuery.js +110 -101
  85. package/mjs/utils/reqForm.js +27 -23
  86. package/mjs/utils/reqMeta.js +9 -8
  87. package/mjs/utils/reqQuery.d.ts +2 -2
  88. package/mjs/utils/reqQuery.js +7 -9
  89. package/mjs/utils/serializeQuery.js +40 -39
  90. package/mjs/utils/setHandlerSchema.js +12 -14
  91. package/mjs/utils/shim.js +14 -14
  92. package/mjs/utils/withStandard.d.ts +51 -0
  93. package/mjs/utils/withStandard.js +30 -0
  94. package/mjs/utils/{withValidation.d.ts → withValidationLibrary.d.ts} +4 -3
  95. package/mjs/utils/{withValidation.js → withValidationLibrary.js} +12 -11
  96. package/package.json +12 -4
  97. package/cjs/openapi/openAPIToSchema.d.ts +0 -24
  98. package/cjs/openapi/openAPIToSchema.js +0 -136
  99. package/cjs/openapi/schemaToOpenAPI.d.ts +0 -14
  100. package/cjs/openapi/schemaToOpenAPI.js +0 -249
  101. package/mjs/openapi/openAPIToSchema.d.ts +0 -24
  102. package/mjs/openapi/openAPIToSchema.js +0 -136
  103. package/mjs/openapi/schemaToOpenAPI.d.ts +0 -14
  104. package/mjs/openapi/schemaToOpenAPI.js +0 -249
package/bin/index.mjs CHANGED
@@ -1,6 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import { spawn } from 'child_process';
3
3
 
4
+ console.warn(`Vovk CLI requires vovk-cli package. Running "npx vovk-cli ${process.argv.slice(2).join(' ')}" instead.`);
5
+
4
6
  spawn('npx', ['vovk-cli', ...process.argv.slice(2)], { stdio: 'inherit' }).on('exit', (code) => {
5
7
  process.exit(code);
6
8
  });
@@ -1,15 +1,15 @@
1
- 'use strict';
2
- Object.defineProperty(exports, '__esModule', { value: true });
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.HttpException = void 0;
4
4
  class HttpException extends Error {
5
- statusCode;
6
- message;
7
- cause;
8
- constructor(statusCode, message, cause) {
9
- super(message);
10
- this.statusCode = statusCode;
11
- this.message = message;
12
- this.cause = cause;
13
- }
5
+ statusCode;
6
+ message;
7
+ cause;
8
+ constructor(statusCode, message, cause) {
9
+ super(message);
10
+ this.statusCode = statusCode;
11
+ this.message = message;
12
+ this.cause = cause;
13
+ }
14
14
  }
15
15
  exports.HttpException = HttpException;
@@ -1,4 +1,4 @@
1
- import type { headers } from 'next/headers';
1
+ import { headers } from 'next/headers';
2
2
  import type { KnownAny, StreamAbortMessage } from './types.js';
3
3
  import './utils/shim.js';
4
4
  export declare class JSONLinesResponse<T> extends Response {
@@ -1,57 +1,59 @@
1
- 'use strict';
2
- Object.defineProperty(exports, '__esModule', { value: true });
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.JSONLinesResponse = void 0;
4
- require('./utils/shim.js');
4
+ require("./utils/shim.js");
5
5
  class JSONLinesResponse extends Response {
6
- isClosed = false;
7
- controller;
8
- encoder;
9
- readableStream;
10
- constructor(requestHeaders, init) {
11
- const encoder = new TextEncoder();
12
- let readableController;
13
- const readableStream = new ReadableStream({
14
- cancel: () => {
6
+ isClosed = false;
7
+ controller;
8
+ encoder;
9
+ readableStream;
10
+ constructor(requestHeaders, init) {
11
+ const encoder = new TextEncoder();
12
+ let readableController;
13
+ const readableStream = new ReadableStream({
14
+ cancel: () => {
15
+ this.isClosed = true;
16
+ },
17
+ start: (controller) => {
18
+ readableController = controller;
19
+ },
20
+ });
21
+ if (!requestHeaders) {
22
+ throw new Error('Request headers are required');
23
+ }
24
+ const accept = requestHeaders.get('accept');
25
+ super(readableStream, {
26
+ ...init,
27
+ headers: {
28
+ ...init?.headers,
29
+ 'Content-Type': accept?.includes('application/jsonl')
30
+ ? 'application/jsonl; charset=utf-8'
31
+ : 'text/plain; charset=utf-8',
32
+ },
33
+ });
34
+ this.readableStream = readableStream;
35
+ this.encoder = encoder;
36
+ this.controller = readableController;
37
+ }
38
+ send(data) {
39
+ const { controller, encoder } = this;
40
+ if (this.isClosed)
41
+ return;
42
+ return controller?.enqueue(encoder.encode(JSON.stringify(data) + '\n'));
43
+ }
44
+ close() {
45
+ const { controller } = this;
46
+ if (this.isClosed)
47
+ return;
15
48
  this.isClosed = true;
16
- },
17
- start: (controller) => {
18
- readableController = controller;
19
- },
20
- });
21
- if (!requestHeaders) {
22
- throw new Error('Request headers are required');
49
+ controller?.close();
50
+ }
51
+ throw(e) {
52
+ this.send({ isError: true, reason: e instanceof Error ? e.message : e });
53
+ return this.close();
54
+ }
55
+ [Symbol.dispose]() {
56
+ this.close();
23
57
  }
24
- const accept = requestHeaders.get('accept');
25
- super(readableStream, {
26
- ...init,
27
- headers: {
28
- ...init?.headers,
29
- 'Content-Type': accept?.includes('application/jsonl')
30
- ? 'application/jsonl; charset=utf-8'
31
- : 'text/plain; charset=utf-8',
32
- },
33
- });
34
- this.readableStream = readableStream;
35
- this.encoder = encoder;
36
- this.controller = readableController;
37
- }
38
- send(data) {
39
- const { controller, encoder } = this;
40
- if (this.isClosed) return;
41
- return controller?.enqueue(encoder.encode(JSON.stringify(data) + '\n'));
42
- }
43
- close() {
44
- const { controller } = this;
45
- if (this.isClosed) return;
46
- this.isClosed = true;
47
- controller?.close();
48
- }
49
- throw(e) {
50
- this.send({ isError: true, reason: e instanceof Error ? e.message : e });
51
- return this.close();
52
- }
53
- [Symbol.dispose]() {
54
- this.close();
55
- }
56
58
  }
57
59
  exports.JSONLinesResponse = JSONLinesResponse;
package/cjs/VovkApp.js CHANGED
@@ -1,199 +1,189 @@
1
- 'use strict';
2
- var __importDefault =
3
- (this && this.__importDefault) ||
4
- function (mod) {
5
- return mod && mod.__esModule ? mod : { default: mod };
6
- };
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
7
5
  var _a;
8
- Object.defineProperty(exports, '__esModule', { value: true });
6
+ Object.defineProperty(exports, "__esModule", { value: true });
9
7
  exports.VovkApp = void 0;
10
- const types_js_1 = require('./types.js');
11
- const HttpException_js_1 = require('./HttpException.js');
12
- const JSONLinesResponse_js_1 = require('./JSONLinesResponse.js');
13
- const reqQuery_js_1 = __importDefault(require('./utils/reqQuery.js'));
14
- const reqMeta_js_1 = __importDefault(require('./utils/reqMeta.js'));
15
- const reqForm_js_1 = __importDefault(require('./utils/reqForm.js'));
16
- const headers_1 = require('next/headers');
8
+ const types_js_1 = require("./types.js");
9
+ const HttpException_js_1 = require("./HttpException.js");
10
+ const JSONLinesResponse_js_1 = require("./JSONLinesResponse.js");
11
+ const reqQuery_js_1 = __importDefault(require("./utils/reqQuery.js"));
12
+ const reqMeta_js_1 = __importDefault(require("./utils/reqMeta.js"));
13
+ const reqForm_js_1 = __importDefault(require("./utils/reqForm.js"));
14
+ const headers_1 = require("next/headers");
17
15
  class VovkApp {
18
- static getHeadersFromOptions(options) {
19
- if (!options) return {};
20
- const corsHeaders = {
21
- 'access-control-allow-origin': '*',
22
- 'access-control-allow-methods': 'GET, POST, PUT, DELETE, OPTIONS, HEAD',
23
- 'access-control-allow-headers': 'content-type, authorization',
16
+ static getHeadersFromOptions(options) {
17
+ if (!options)
18
+ return {};
19
+ const corsHeaders = {
20
+ 'access-control-allow-origin': '*',
21
+ 'access-control-allow-methods': 'GET, POST, PUT, DELETE, OPTIONS, HEAD',
22
+ 'access-control-allow-headers': 'content-type, authorization',
23
+ };
24
+ const headers = {
25
+ ...(options.cors ? corsHeaders : {}),
26
+ ...(options.headers ?? {}),
27
+ };
28
+ return headers;
29
+ }
30
+ routes = {
31
+ GET: new Map(),
32
+ POST: new Map(),
33
+ PUT: new Map(),
34
+ PATCH: new Map(),
35
+ DELETE: new Map(),
36
+ HEAD: new Map(),
37
+ OPTIONS: new Map(),
24
38
  };
25
- const headers = {
26
- ...(options.cors ? corsHeaders : {}),
27
- ...(options.headers ?? {}),
39
+ GET = async (req, data) => this.#callMethod(types_js_1.HttpMethod.GET, req, await data.params);
40
+ POST = async (req, data) => this.#callMethod(types_js_1.HttpMethod.POST, req, await data.params);
41
+ PUT = async (req, data) => this.#callMethod(types_js_1.HttpMethod.PUT, req, await data.params);
42
+ PATCH = async (req, data) => this.#callMethod(types_js_1.HttpMethod.PATCH, req, await data.params);
43
+ DELETE = async (req, data) => this.#callMethod(types_js_1.HttpMethod.DELETE, req, await data.params);
44
+ HEAD = async (req, data) => this.#callMethod(types_js_1.HttpMethod.HEAD, req, await data.params);
45
+ OPTIONS = async (req, data) => this.#callMethod(types_js_1.HttpMethod.OPTIONS, req, await data.params);
46
+ respond = (status, body, options) => {
47
+ return new Response(JSON.stringify(body), {
48
+ status,
49
+ headers: {
50
+ 'content-type': 'application/json',
51
+ ..._a.getHeadersFromOptions(options),
52
+ },
53
+ });
28
54
  };
29
- return headers;
30
- }
31
- routes = {
32
- GET: new Map(),
33
- POST: new Map(),
34
- PUT: new Map(),
35
- PATCH: new Map(),
36
- DELETE: new Map(),
37
- HEAD: new Map(),
38
- OPTIONS: new Map(),
39
- };
40
- GET = async (req, data) => this.#callMethod(types_js_1.HttpMethod.GET, req, await data.params);
41
- POST = async (req, data) => this.#callMethod(types_js_1.HttpMethod.POST, req, await data.params);
42
- PUT = async (req, data) => this.#callMethod(types_js_1.HttpMethod.PUT, req, await data.params);
43
- PATCH = async (req, data) => this.#callMethod(types_js_1.HttpMethod.PATCH, req, await data.params);
44
- DELETE = async (req, data) => this.#callMethod(types_js_1.HttpMethod.DELETE, req, await data.params);
45
- HEAD = async (req, data) => this.#callMethod(types_js_1.HttpMethod.HEAD, req, await data.params);
46
- OPTIONS = async (req, data) => this.#callMethod(types_js_1.HttpMethod.OPTIONS, req, await data.params);
47
- respond = (status, body, options) => {
48
- return new Response(JSON.stringify(body), {
49
- status,
50
- headers: {
51
- 'content-type': 'application/json',
52
- ..._a.getHeadersFromOptions(options),
53
- },
54
- });
55
- };
56
- #respondWithError = (statusCode, message, options, cause) => {
57
- return this.respond(
58
- statusCode,
59
- {
60
- cause,
61
- statusCode,
62
- message,
63
- isError: true,
64
- },
65
- options
66
- );
67
- };
68
- #getHandler = ({ handlers, path, params }) => {
69
- const methodParams = {};
70
- if (Object.keys(params).length === 0) {
71
- return { handler: handlers[''], methodParams };
72
- }
73
- const allMethodKeys = Object.keys(handlers);
74
- let methodKeys = [];
75
- const pathStr = path.join('/');
76
- methodKeys = allMethodKeys
77
- // First, try to match literal routes exactly.
78
- .filter((p) => {
79
- if (p.includes(':')) return false; // Skip parameterized paths
80
- return p === pathStr;
81
- });
82
- if (!methodKeys.length) {
83
- methodKeys = allMethodKeys.filter((p) => {
84
- const routeSegments = p.split('/');
85
- if (routeSegments.length !== path.length) return false;
86
- for (let i = 0; i < routeSegments.length; i++) {
87
- const routeSegment = routeSegments[i];
88
- const pathSegment = path[i];
89
- if (routeSegment.startsWith(':')) {
90
- const parameter = routeSegment.slice(1);
91
- if (parameter in methodParams) {
92
- throw new HttpException_js_1.HttpException(
93
- types_js_1.HttpStatus.INTERNAL_SERVER_ERROR,
94
- `Duplicate parameter "${parameter}" at ${p}`
95
- );
96
- }
97
- // If it's a parameterized segment, capture the parameter value.
98
- methodParams[parameter] = pathSegment;
99
- } else if (routeSegment !== pathSegment) {
100
- // If it's a literal segment and it does not match the corresponding path segment, return false.
101
- return false;
102
- }
55
+ #respondWithError = (statusCode, message, options, cause) => {
56
+ return this.respond(statusCode, {
57
+ cause,
58
+ statusCode,
59
+ message,
60
+ isError: true,
61
+ }, options);
62
+ };
63
+ #getHandler = ({ handlers, path, params, }) => {
64
+ const methodParams = {};
65
+ if (Object.keys(params).length === 0) {
66
+ return { handler: handlers[''], methodParams };
103
67
  }
104
- return true;
105
- });
106
- }
107
- if (methodKeys.length > 1) {
108
- throw new HttpException_js_1.HttpException(
109
- types_js_1.HttpStatus.INTERNAL_SERVER_ERROR,
110
- `Conflicting routes found: ${methodKeys.join(', ')}`
111
- );
112
- }
113
- const [methodKey] = methodKeys;
114
- if (methodKey) {
115
- return { handler: handlers[methodKey], methodParams };
116
- }
117
- return { handler: null, methodParams };
118
- };
119
- #callMethod = async (httpMethod, nextReq, params) => {
120
- const req = nextReq;
121
- const controllers = this.routes[httpMethod];
122
- const path = params[Object.keys(params)[0]];
123
- const handlers = {};
124
- controllers.forEach((staticMethods, controller) => {
125
- const prefix = controller._prefix ?? '';
126
- if (!controller._activated) {
127
- throw new HttpException_js_1.HttpException(
128
- types_js_1.HttpStatus.INTERNAL_SERVER_ERROR,
129
- `Controller "${controller.name}" found but not activated`
130
- );
131
- }
132
- Object.entries(staticMethods ?? {}).forEach(([path, staticMethod]) => {
133
- const fullPath = [prefix, path].filter(Boolean).join('/');
134
- handlers[fullPath] = { staticMethod, controller };
135
- });
136
- });
137
- const { handler, methodParams } = this.#getHandler({ handlers, path, params });
138
- if (!handler) {
139
- return this.#respondWithError(
140
- types_js_1.HttpStatus.NOT_FOUND,
141
- `${Object.keys(handlers)} - Route ${path.join('/')} is not found`
142
- );
143
- }
144
- const { staticMethod, controller } = handler;
145
- req.vovk = {
146
- body: () => req.json(),
147
- query: () => (0, reqQuery_js_1.default)(req),
148
- meta: (meta) => (0, reqMeta_js_1.default)(req, meta),
149
- form: () => (0, reqForm_js_1.default)(req),
150
- params: () => methodParams,
68
+ const allMethodKeys = Object.keys(handlers);
69
+ let methodKeys = [];
70
+ const pathStr = path.join('/');
71
+ methodKeys = allMethodKeys
72
+ // First, try to match literal routes exactly.
73
+ .filter((p) => {
74
+ if (p.includes(':'))
75
+ return false; // Skip parameterized paths
76
+ return p === pathStr;
77
+ });
78
+ if (!methodKeys.length) {
79
+ methodKeys = allMethodKeys.filter((p) => {
80
+ const routeSegments = p.split('/');
81
+ if (routeSegments.length !== path.length)
82
+ return false;
83
+ for (let i = 0; i < routeSegments.length; i++) {
84
+ const routeSegment = routeSegments[i];
85
+ const pathSegment = path[i];
86
+ if (routeSegment.startsWith(':')) {
87
+ const parameter = routeSegment.slice(1);
88
+ if (parameter in methodParams) {
89
+ throw new HttpException_js_1.HttpException(types_js_1.HttpStatus.INTERNAL_SERVER_ERROR, `Duplicate parameter "${parameter}" at ${p}`);
90
+ }
91
+ // If it's a parameterized segment, capture the parameter value.
92
+ methodParams[parameter] = pathSegment;
93
+ }
94
+ else if (routeSegment !== pathSegment) {
95
+ // If it's a literal segment and it does not match the corresponding path segment, return false.
96
+ return false;
97
+ }
98
+ }
99
+ return true;
100
+ });
101
+ }
102
+ if (methodKeys.length > 1) {
103
+ throw new HttpException_js_1.HttpException(types_js_1.HttpStatus.INTERNAL_SERVER_ERROR, `Conflicting routes found: ${methodKeys.join(', ')}`);
104
+ }
105
+ const [methodKey] = methodKeys;
106
+ if (methodKey) {
107
+ return { handler: handlers[methodKey], methodParams };
108
+ }
109
+ return { handler: null, methodParams };
151
110
  };
152
- try {
153
- await staticMethod._options?.before?.call(controller, req);
154
- const result = await staticMethod.call(controller, req, methodParams);
155
- const isIterator =
156
- typeof result === 'object' &&
157
- !!result &&
158
- ((Reflect.has(result, Symbol.iterator) && typeof result[Symbol.iterator] === 'function') ||
159
- (Reflect.has(result, Symbol.asyncIterator) && typeof result[Symbol.asyncIterator] === 'function'));
160
- if (isIterator && !(result instanceof Array)) {
161
- const streamResponse = new JSONLinesResponse_js_1.JSONLinesResponse(await (0, headers_1.headers)(), {
162
- headers: {
163
- ..._a.getHeadersFromOptions(staticMethod._options),
164
- },
111
+ #callMethod = async (httpMethod, nextReq, params) => {
112
+ const req = nextReq;
113
+ const controllers = this.routes[httpMethod];
114
+ const path = params[Object.keys(params)[0]];
115
+ const handlers = {};
116
+ controllers.forEach((staticMethods, controller) => {
117
+ const prefix = controller._prefix ?? '';
118
+ if (!controller._activated) {
119
+ throw new HttpException_js_1.HttpException(types_js_1.HttpStatus.INTERNAL_SERVER_ERROR, `Controller "${controller.name}" found but not activated`);
120
+ }
121
+ Object.entries(staticMethods ?? {}).forEach(([path, staticMethod]) => {
122
+ const fullPath = [prefix, path].filter(Boolean).join('/');
123
+ handlers[fullPath] = { staticMethod, controller };
124
+ });
165
125
  });
166
- void (async () => {
167
- try {
168
- for await (const chunk of result) {
169
- streamResponse.send(chunk);
126
+ const { handler, methodParams } = this.#getHandler({ handlers, path, params });
127
+ if (!handler) {
128
+ return this.#respondWithError(types_js_1.HttpStatus.NOT_FOUND, `${Object.keys(handlers)} - Route ${path.join('/')} is not found`);
129
+ }
130
+ const { staticMethod, controller } = handler;
131
+ req.vovk = {
132
+ body: () => req.json(),
133
+ query: () => (0, reqQuery_js_1.default)(req),
134
+ meta: (meta) => (0, reqMeta_js_1.default)(req, meta),
135
+ form: () => (0, reqForm_js_1.default)(req),
136
+ params: () => methodParams,
137
+ };
138
+ try {
139
+ await staticMethod._options?.before?.call(controller, req);
140
+ const result = await staticMethod.call(controller, req, methodParams);
141
+ const isIterator = typeof result === 'object' &&
142
+ !!result &&
143
+ ((Reflect.has(result, Symbol.iterator) &&
144
+ typeof result[Symbol.iterator] === 'function') ||
145
+ (Reflect.has(result, Symbol.asyncIterator) &&
146
+ typeof result[Symbol.asyncIterator] === 'function'));
147
+ if (isIterator && !(result instanceof Array)) {
148
+ const streamResponse = new JSONLinesResponse_js_1.JSONLinesResponse(await (0, headers_1.headers)(), {
149
+ headers: {
150
+ ..._a.getHeadersFromOptions(staticMethod._options),
151
+ },
152
+ });
153
+ void (async () => {
154
+ try {
155
+ for await (const chunk of result) {
156
+ streamResponse.send(chunk);
157
+ }
158
+ }
159
+ catch (e) {
160
+ return streamResponse.throw(e);
161
+ }
162
+ return streamResponse.close();
163
+ })();
164
+ return streamResponse;
170
165
  }
171
- } catch (e) {
172
- return streamResponse.throw(e);
173
- }
174
- return streamResponse.close();
175
- })();
176
- return streamResponse;
177
- }
178
- if (result instanceof Response) {
179
- return result;
180
- }
181
- return this.respond(200, result ?? null, staticMethod._options);
182
- } catch (e) {
183
- const err = e;
184
- try {
185
- await controller._onError?.(err, req);
186
- } catch (onErrorError) {
187
- // eslint-disable-next-line no-console
188
- console.error(onErrorError);
189
- }
190
- if (err.message !== 'NEXT_REDIRECT' && err.message !== 'NEXT_NOT_FOUND') {
191
- const statusCode = err.statusCode || types_js_1.HttpStatus.INTERNAL_SERVER_ERROR;
192
- return this.#respondWithError(statusCode, err.message, staticMethod._options, err.cause);
193
- }
194
- throw e; // if NEXT_REDIRECT or NEXT_NOT_FOUND, rethrow it
195
- }
196
- };
166
+ if (result instanceof Response) {
167
+ return result;
168
+ }
169
+ return this.respond(200, result ?? null, staticMethod._options);
170
+ }
171
+ catch (e) {
172
+ const err = e;
173
+ try {
174
+ await controller._onError?.(err, req);
175
+ }
176
+ catch (onErrorError) {
177
+ // eslint-disable-next-line no-console
178
+ console.error(onErrorError);
179
+ }
180
+ if (err.message !== 'NEXT_REDIRECT' && err.message !== 'NEXT_NOT_FOUND') {
181
+ const statusCode = err.statusCode || types_js_1.HttpStatus.INTERNAL_SERVER_ERROR;
182
+ return this.#respondWithError(statusCode, err.message, staticMethod._options, err.cause);
183
+ }
184
+ throw e; // if NEXT_REDIRECT or NEXT_NOT_FOUND, rethrow it
185
+ }
186
+ };
197
187
  }
198
188
  exports.VovkApp = VovkApp;
199
189
  _a = VovkApp;
@@ -1,3 +1,3 @@
1
1
  import type { KnownAny, VovkSchema } from '../types.js';
2
- import type { VovkClient, VovkDefaultFetcherOptions } from './types.js';
3
- export declare const createRPC: <T, OPTS extends Record<string, KnownAny> = Record<string, never>>(schema: VovkSchema, segmentName: string, rpcModuleName: string, options?: VovkDefaultFetcherOptions<OPTS>) => VovkClient<T, OPTS>;
2
+ import type { VovkClient, VovkClientFetcher, VovkDefaultFetcherOptions } from './types.js';
3
+ export declare const createRPC: <T, OPTS extends Record<string, KnownAny> = Record<string, never>>(schema: VovkSchema, segmentName: string, rpcModuleName: string, fetcher?: VovkClientFetcher<OPTS>, options?: VovkDefaultFetcherOptions<OPTS>) => VovkClient<T, OPTS>;
@@ -17,20 +17,20 @@ const getHandlerPath = (endpoint, params, query) => {
17
17
  }
18
18
  return `${result}${queryStr ? '?' : ''}${queryStr}`;
19
19
  };
20
- const createRPC = (schema, segmentName, rpcModuleName, options) => {
20
+ const createRPC = (schema, segmentName, rpcModuleName, fetcher = fetcher_js_1.fetcher, options) => {
21
21
  const segmentNamePath = options?.segmentNameOverride ?? segmentName;
22
22
  const segmentSchema = schema.segments[segmentName];
23
23
  if (!segmentSchema)
24
- throw new Error(`Unable to create RPC object. Segment schema is missing. Check client template.`);
24
+ throw new Error(`Unable to create RPC module. Segment schema is missing. Check client template.`);
25
25
  const controllerSchema = schema.segments[segmentName]?.controllers[rpcModuleName];
26
26
  const client = {};
27
27
  if (!controllerSchema)
28
- throw new Error(`Unable to create RPC object. Controller schema is missing. Check client template.`);
28
+ throw new Error(`Unable to create RPC module. Controller schema is missing. Check client template.`);
29
29
  const controllerPrefix = trimPath(controllerSchema.prefix ?? '');
30
- const { fetcher: settingsFetcher = fetcher_js_1.fetcher } = options ?? {};
31
30
  for (const [staticMethodName, handlerSchema] of Object.entries(controllerSchema.handlers ?? {})) {
32
31
  const { path, httpMethod, validation } = handlerSchema;
33
32
  const getEndpoint = ({ apiRoot, params, query, }) => {
33
+ apiRoot ??= options?.apiRoot ?? '/api';
34
34
  const endpoint = [
35
35
  apiRoot.startsWith('http://') || apiRoot.startsWith('https://') || apiRoot.startsWith('/') ? '' : '/',
36
36
  apiRoot,
@@ -42,7 +42,6 @@ const createRPC = (schema, segmentName, rpcModuleName, options) => {
42
42
  return endpoint;
43
43
  };
44
44
  const handler = (input = {}) => {
45
- const fetcher = input.fetcher ?? settingsFetcher;
46
45
  const validate = async ({ body, query, params, endpoint, }) => {
47
46
  const validateOnClient = input.validateOnClient ?? options?.validateOnClient;
48
47
  if (validateOnClient && validation) {
@@ -61,17 +60,12 @@ const createRPC = (schema, segmentName, rpcModuleName, options) => {
61
60
  defaultStreamHandler: defaultStreamHandler_js_1.defaultStreamHandler,
62
61
  };
63
62
  const internalInput = {
64
- ...options?.defaultOptions,
63
+ ...options,
65
64
  ...input,
66
65
  body: input.body ?? null,
67
66
  query: input.query ?? {},
68
67
  params: input.params ?? {},
69
- // TS workaround
70
- fetcher: undefined,
71
- validateOnClient: undefined,
72
68
  };
73
- delete internalInput.fetcher;
74
- delete internalInput.validateOnClient;
75
69
  if (!fetcher)
76
70
  throw new Error('Fetcher is not provided');
77
71
  const fetcherPromise = fetcher(internalOptions, internalInput);
@@ -1,25 +1,22 @@
1
- 'use strict';
2
- Object.defineProperty(exports, '__esModule', { value: true });
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.defaultHandler = exports.DEFAULT_ERROR_MESSAGE = void 0;
4
- const HttpException_js_1 = require('../HttpException.js');
4
+ const HttpException_js_1 = require("../HttpException.js");
5
5
  exports.DEFAULT_ERROR_MESSAGE = 'Unknown error at defaultHandler';
6
6
  const defaultHandler = async (response) => {
7
- let result;
8
- try {
9
- result = await response.json();
10
- } catch (e) {
11
- // handle parsing errors
12
- throw new HttpException_js_1.HttpException(response.status, e?.message ?? exports.DEFAULT_ERROR_MESSAGE);
13
- }
14
- if (!response.ok) {
15
- // handle server errors
16
- const errorResponse = result;
17
- throw new HttpException_js_1.HttpException(
18
- response.status,
19
- errorResponse?.message ?? exports.DEFAULT_ERROR_MESSAGE,
20
- errorResponse?.cause
21
- );
22
- }
23
- return result;
7
+ let result;
8
+ try {
9
+ result = await response.json();
10
+ }
11
+ catch (e) {
12
+ // handle parsing errors
13
+ throw new HttpException_js_1.HttpException(response.status, e?.message ?? exports.DEFAULT_ERROR_MESSAGE);
14
+ }
15
+ if (!response.ok) {
16
+ // handle server errors
17
+ const errorResponse = result;
18
+ throw new HttpException_js_1.HttpException(response.status, errorResponse?.message ?? exports.DEFAULT_ERROR_MESSAGE, errorResponse?.cause);
19
+ }
20
+ return result;
24
21
  };
25
22
  exports.defaultHandler = defaultHandler;