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.
- package/bin/index.mjs +2 -0
- package/cjs/HttpException.js +11 -11
- package/cjs/JSONLinesResponse.d.ts +1 -1
- package/cjs/JSONLinesResponse.js +53 -51
- package/cjs/VovkApp.js +177 -187
- package/cjs/client/createRPC.d.ts +2 -2
- package/cjs/client/createRPC.js +5 -11
- package/cjs/client/defaultHandler.js +17 -20
- package/cjs/client/defaultStreamHandler.js +71 -69
- package/cjs/client/fetcher.d.ts +8 -3
- package/cjs/client/fetcher.js +83 -85
- package/cjs/client/types.d.ts +35 -42
- package/cjs/createVovkApp.d.ts +1 -0
- package/cjs/createVovkApp.js +116 -122
- package/cjs/index.d.ts +37 -35
- package/cjs/index.js +34 -32
- package/cjs/openapi/error.js +90 -90
- package/cjs/openapi/generateFnName.d.ts +3 -9
- package/cjs/openapi/generateFnName.js +49 -61
- package/cjs/openapi/index.d.ts +2 -3
- package/cjs/openapi/index.js +17 -28
- package/cjs/openapi/openAPIToVovkSchema.d.ts +2 -15
- package/cjs/openapi/openAPIToVovkSchema.js +85 -26
- package/cjs/openapi/vovkSchemaToOpenAPI.js +227 -239
- package/cjs/types.d.ts +58 -30
- package/cjs/types.js +62 -62
- package/cjs/utils/camelCase.d.ts +6 -0
- package/cjs/utils/camelCase.js +37 -0
- package/cjs/utils/createCodeExamples.js +52 -67
- package/cjs/utils/createDecorator.js +40 -41
- package/cjs/utils/createLLMFunctions.js +89 -97
- package/cjs/utils/generateStaticAPI.js +26 -26
- package/cjs/utils/getSchema.d.ts +1 -0
- package/cjs/utils/getSchema.js +35 -34
- package/cjs/utils/multitenant.d.ts +19 -21
- package/cjs/utils/multitenant.js +112 -112
- package/cjs/utils/parseQuery.js +110 -101
- package/cjs/utils/reqForm.js +27 -23
- package/cjs/utils/reqMeta.js +9 -8
- package/cjs/utils/reqQuery.d.ts +2 -2
- package/cjs/utils/reqQuery.js +7 -9
- package/cjs/utils/serializeQuery.js +40 -39
- package/cjs/utils/setHandlerSchema.js +12 -14
- package/cjs/utils/shim.js +13 -13
- package/cjs/utils/withStandard.d.ts +51 -0
- package/cjs/utils/withStandard.js +30 -0
- package/cjs/utils/{withValidation.d.ts → withValidationLibrary.d.ts} +4 -3
- package/cjs/utils/{withValidation.js → withValidationLibrary.js} +12 -11
- package/mjs/HttpException.js +11 -11
- package/mjs/JSONLinesResponse.d.ts +1 -1
- package/mjs/JSONLinesResponse.js +53 -51
- package/mjs/VovkApp.js +177 -187
- package/mjs/client/createRPC.d.ts +2 -2
- package/mjs/client/createRPC.js +5 -11
- package/mjs/client/defaultHandler.js +17 -20
- package/mjs/client/defaultStreamHandler.js +71 -69
- package/mjs/client/fetcher.d.ts +8 -3
- package/mjs/client/fetcher.js +1 -1
- package/mjs/client/types.d.ts +35 -42
- package/mjs/createVovkApp.d.ts +1 -0
- package/mjs/createVovkApp.js +116 -122
- package/mjs/index.d.ts +37 -35
- package/mjs/index.js +34 -32
- package/mjs/openapi/error.js +90 -90
- package/mjs/openapi/generateFnName.d.ts +3 -9
- package/mjs/openapi/generateFnName.js +49 -61
- package/mjs/openapi/index.d.ts +2 -3
- package/mjs/openapi/index.js +17 -28
- package/mjs/openapi/openAPIToVovkSchema.d.ts +2 -15
- package/mjs/openapi/openAPIToVovkSchema.js +85 -26
- package/mjs/openapi/vovkSchemaToOpenAPI.js +227 -239
- package/mjs/types.d.ts +58 -30
- package/mjs/types.js +62 -62
- package/mjs/utils/camelCase.d.ts +6 -0
- package/mjs/utils/camelCase.js +37 -0
- package/mjs/utils/createCodeExamples.js +52 -67
- package/mjs/utils/createDecorator.js +40 -41
- package/mjs/utils/createLLMFunctions.js +89 -97
- package/mjs/utils/generateStaticAPI.js +26 -26
- package/mjs/utils/getSchema.d.ts +1 -0
- package/mjs/utils/getSchema.js +35 -34
- package/mjs/utils/multitenant.d.ts +19 -21
- package/mjs/utils/multitenant.js +112 -112
- package/mjs/utils/parseQuery.js +110 -101
- package/mjs/utils/reqForm.js +27 -23
- package/mjs/utils/reqMeta.js +9 -8
- package/mjs/utils/reqQuery.d.ts +2 -2
- package/mjs/utils/reqQuery.js +7 -9
- package/mjs/utils/serializeQuery.js +40 -39
- package/mjs/utils/setHandlerSchema.js +12 -14
- package/mjs/utils/shim.js +14 -14
- package/mjs/utils/withStandard.d.ts +51 -0
- package/mjs/utils/withStandard.js +30 -0
- package/mjs/utils/{withValidation.d.ts → withValidationLibrary.d.ts} +4 -3
- package/mjs/utils/{withValidation.js → withValidationLibrary.js} +12 -11
- package/package.json +12 -4
- package/cjs/openapi/openAPIToSchema.d.ts +0 -24
- package/cjs/openapi/openAPIToSchema.js +0 -136
- package/cjs/openapi/schemaToOpenAPI.d.ts +0 -14
- package/cjs/openapi/schemaToOpenAPI.js +0 -249
- package/mjs/openapi/openAPIToSchema.d.ts +0 -24
- package/mjs/openapi/openAPIToSchema.js +0 -136
- package/mjs/openapi/schemaToOpenAPI.d.ts +0 -14
- 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
|
});
|
package/cjs/HttpException.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports,
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.HttpException = void 0;
|
|
4
4
|
class HttpException extends Error {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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;
|
package/cjs/JSONLinesResponse.js
CHANGED
|
@@ -1,57 +1,59 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports,
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.JSONLinesResponse = void 0;
|
|
4
|
-
require(
|
|
4
|
+
require("./utils/shim.js");
|
|
5
5
|
class JSONLinesResponse extends Response {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
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
|
-
|
|
2
|
-
var __importDefault =
|
|
3
|
-
|
|
4
|
-
|
|
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,
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
7
|
exports.VovkApp = void 0;
|
|
10
|
-
const types_js_1 = require(
|
|
11
|
-
const HttpException_js_1 = require(
|
|
12
|
-
const JSONLinesResponse_js_1 = require(
|
|
13
|
-
const reqQuery_js_1 = __importDefault(require(
|
|
14
|
-
const reqMeta_js_1 = __importDefault(require(
|
|
15
|
-
const reqForm_js_1 = __importDefault(require(
|
|
16
|
-
const headers_1 = require(
|
|
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
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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
|
-
|
|
26
|
-
|
|
27
|
-
|
|
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
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
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
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
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
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
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
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
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
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
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>;
|
package/cjs/client/createRPC.js
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
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
|
-
|
|
2
|
-
Object.defineProperty(exports,
|
|
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(
|
|
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
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
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;
|