@naturalcycles/backend-lib 9.51.1 → 9.53.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/express/createDefaultApp.d.ts +1 -1
- package/dist/express/createDefaultApp.js +1 -1
- package/dist/express/startServer.d.ts +1 -1
- package/dist/sentry/sentry.shared.service.d.ts +2 -2
- package/dist/server/compressionMiddleware.js +3 -0
- package/dist/testing/express.test.service.d.ts +1 -1
- package/dist/testing/express.test.service.js +1 -1
- package/dist/validation/ajv/validateRequest.d.ts +6 -6
- package/dist/validation/ajv/validateRequest.js +2 -2
- package/dist/validation/zod/zodValidateRequest.d.ts +2 -2
- package/dist/validation/zod/zodValidateRequest.js +3 -1
- package/package.json +4 -4
- package/readme.md +4 -0
- package/src/deploy/backend.cfg.util.ts +2 -1
- package/src/deploy/deploy.util.ts +10 -13
- package/src/express/createDefaultApp.ts +2 -4
- package/src/express/startServer.ts +2 -1
- package/src/sentry/sentry.shared.service.ts +2 -2
- package/src/server/compressionMiddleware.ts +3 -0
- package/src/server/logMiddleware.ts +2 -1
- package/src/server/serverStatsMiddleware.ts +2 -1
- package/src/testing/express.test.service.ts +2 -5
- package/src/validation/ajv/validateRequest.ts +16 -19
- package/src/validation/zod/zodValidateRequest.ts +4 -2
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Options, OptionsJson, OptionsUrlencoded } from 'body-parser';
|
|
2
2
|
import type { CorsOptions } from 'cors';
|
|
3
3
|
import type { SentrySharedService } from '../sentry/sentry.shared.service.js';
|
|
4
|
-
import {
|
|
4
|
+
import type { GenericErrorMiddlewareCfg } from '../server/genericErrorMiddleware.js';
|
|
5
5
|
import type { BackendApplication, BackendRequestHandler } from '../server/server.model.js';
|
|
6
6
|
export declare function createDefaultApp(cfg: DefaultAppCfg): Promise<BackendApplication>;
|
|
7
7
|
/**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { asyncLocalStorageMiddleware } from '../server/asyncLocalStorageMiddleware.js';
|
|
2
2
|
import { compressionMiddleware } from '../server/compressionMiddleware.js';
|
|
3
|
-
import { genericErrorMiddleware
|
|
3
|
+
import { genericErrorMiddleware } from '../server/genericErrorMiddleware.js';
|
|
4
4
|
import { logMiddleware } from '../server/logMiddleware.js';
|
|
5
5
|
import { methodOverrideMiddleware } from '../server/methodOverrideMiddleware.js';
|
|
6
6
|
import { notFoundMiddleware } from '../server/notFoundMiddleware.js';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Server } from 'node:http';
|
|
2
2
|
import type { SentrySharedService } from '../sentry/sentry.shared.service.js';
|
|
3
3
|
import type { BackendApplication } from '../server/server.model.js';
|
|
4
|
-
import {
|
|
4
|
+
import type { DefaultAppCfg } from './createDefaultApp.js';
|
|
5
5
|
export declare class BackendServer {
|
|
6
6
|
private cfg;
|
|
7
7
|
constructor(cfg: StartServerCfg);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { CommonLogger } from '@naturalcycles/js-lib/log';
|
|
2
2
|
import type { Primitive, StringMap } from '@naturalcycles/js-lib/types';
|
|
3
|
-
import type { Breadcrumb, SeverityLevel } from '@sentry/node';
|
|
4
|
-
import type * as SentryLib from '@sentry/node';
|
|
3
|
+
import type { Breadcrumb, SeverityLevel } from '@sentry/node-core/light';
|
|
4
|
+
import type * as SentryLib from '@sentry/node-core/light';
|
|
5
5
|
export interface SentrySharedServiceCfg {
|
|
6
6
|
sentry: typeof SentryLib;
|
|
7
7
|
}
|
|
@@ -64,8 +64,11 @@ export function compressionMiddleware(options) {
|
|
|
64
64
|
let length;
|
|
65
65
|
let listeners = [];
|
|
66
66
|
let stream;
|
|
67
|
+
// oxlint-disable-next-line typescript/unbound-method -- monkey-patching, rebound via .call()
|
|
67
68
|
const _end = res.end;
|
|
69
|
+
// oxlint-disable-next-line typescript/unbound-method -- monkey-patching, rebound via .call()
|
|
68
70
|
const _on = res.on;
|
|
71
|
+
// oxlint-disable-next-line typescript/unbound-method -- monkey-patching, rebound via .call()
|
|
69
72
|
const _write = res.write;
|
|
70
73
|
res.flush = function flush() {
|
|
71
74
|
if (stream) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Fetcher, FetcherOptions } from '@naturalcycles/js-lib/http';
|
|
2
|
-
import {
|
|
2
|
+
import type { BackendRequestHandlerCfg, DefaultAppCfg } from '../express/createDefaultApp.js';
|
|
3
3
|
import type { BackendApplication } from '../server/server.model.js';
|
|
4
4
|
export interface ExpressApp extends Fetcher, AsyncDisposable {
|
|
5
5
|
close: () => Promise<void>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { getFetcher } from '@naturalcycles/js-lib/http';
|
|
2
2
|
import { pDelay } from '@naturalcycles/js-lib/promise/pDelay.js';
|
|
3
|
-
import { createDefaultApp
|
|
3
|
+
import { createDefaultApp } from '../express/createDefaultApp.js';
|
|
4
4
|
const nativeFetchFn = async (url, init) => await globalThis.fetch(url, init);
|
|
5
5
|
// Example:
|
|
6
6
|
// const app = expressTestService.createApp([ debugResource ])
|
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { AjvValidationError, SchemaHandledByAjv } from '@naturalcycles/nodejs-lib/ajv';
|
|
2
2
|
import type { BackendRequest } from '../../server/server.model.js';
|
|
3
|
-
import {
|
|
3
|
+
import type { ReqValidationOptions } from '../validateRequest.util.js';
|
|
4
4
|
declare class AjvValidateRequest {
|
|
5
|
-
body<
|
|
5
|
+
body<OUT>(req: BackendRequest, schema: SchemaHandledByAjv<OUT>, opt?: ReqValidationOptions<AjvValidationError>): OUT;
|
|
6
6
|
/**
|
|
7
7
|
* Query validation uses type coercion (unlike body validation),
|
|
8
8
|
* so the passed in schemas do not need to specify only string values.
|
|
9
9
|
*
|
|
10
10
|
* Coercion mutates the input, even if the end result is that the input failed the validation.
|
|
11
11
|
*/
|
|
12
|
-
query<
|
|
12
|
+
query<OUT>(req: BackendRequest, schema: SchemaHandledByAjv<OUT>, opt?: ReqValidationOptions<AjvValidationError>): OUT;
|
|
13
13
|
/**
|
|
14
14
|
* Params validation uses type coercion (unlike body validation),
|
|
15
15
|
* so the passed in schemas do not need to specify only string values.
|
|
16
16
|
*
|
|
17
17
|
* Coercion mutates the input, even if the end result is that the input failed the validation.
|
|
18
18
|
*/
|
|
19
|
-
params<
|
|
19
|
+
params<OUT>(req: BackendRequest, schema: SchemaHandledByAjv<OUT>, opt?: ReqValidationOptions<AjvValidationError>): OUT;
|
|
20
20
|
/**
|
|
21
21
|
* Does NOT mutate `req.headers`,
|
|
22
22
|
* but returns validated/transformed headers.
|
|
@@ -25,7 +25,7 @@ declare class AjvValidateRequest {
|
|
|
25
25
|
* We want to non-mutate the `req.headers`, because we anticipate that
|
|
26
26
|
* there may be additional consumers for `req.headers` (e.g middlewares, etc).
|
|
27
27
|
*/
|
|
28
|
-
headers<
|
|
28
|
+
headers<OUT>(req: BackendRequest, schema: SchemaHandledByAjv<OUT>, opt?: ReqValidationOptions<AjvValidationError>): OUT;
|
|
29
29
|
private validate;
|
|
30
30
|
}
|
|
31
31
|
export declare const validateRequest: AjvValidateRequest;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AjvSchema, getCoercingAjv
|
|
1
|
+
import { AjvSchema, getCoercingAjv } from '@naturalcycles/nodejs-lib/ajv';
|
|
2
2
|
import { handleValidationError } from '../validateRequest.util.js';
|
|
3
3
|
class AjvValidateRequest {
|
|
4
4
|
body(req, schema, opt = {}) {
|
|
@@ -45,7 +45,7 @@ class AjvValidateRequest {
|
|
|
45
45
|
});
|
|
46
46
|
}
|
|
47
47
|
validate(req, reqProperty, schema, getOriginalInput, opt = {}) {
|
|
48
|
-
const input =
|
|
48
|
+
const input = req[reqProperty] || {};
|
|
49
49
|
const { coerceTypes, mutateInput } = opt;
|
|
50
50
|
const ajv = coerceTypes ? getCoercingAjv() : undefined;
|
|
51
51
|
const ajvSchema = AjvSchema.create(schema, { ajv });
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { ZodType, ZodValidationError } from '@naturalcycles/js-lib/zod';
|
|
2
2
|
import type { BackendRequest } from '../../server/server.model.js';
|
|
3
|
-
import {
|
|
3
|
+
import type { ReqValidationOptions } from '../validateRequest.util.js';
|
|
4
4
|
declare class ZodValidateRequest {
|
|
5
5
|
body<T>(req: BackendRequest, schema: ZodType<T>, opt?: ReqValidationOptions<ZodValidationError>): T;
|
|
6
6
|
query<T>(req: BackendRequest, schema: ZodType<T>, opt?: ReqValidationOptions<ZodValidationError>): T;
|
|
@@ -25,7 +25,9 @@ class ZodValidateRequest {
|
|
|
25
25
|
validate(req, reqProperty, schema, opt = {}) {
|
|
26
26
|
const originalProperty = (req[reqProperty] || {});
|
|
27
27
|
// Zod does not mutate the input
|
|
28
|
-
const [error, data] = zSafeValidate(originalProperty, schema
|
|
28
|
+
const [error, data] = zSafeValidate(originalProperty, schema
|
|
29
|
+
// opt2?.itemName,
|
|
30
|
+
);
|
|
29
31
|
if (error) {
|
|
30
32
|
handleValidationError(error, originalProperty, opt);
|
|
31
33
|
}
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@naturalcycles/backend-lib",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "9.
|
|
4
|
+
"version": "9.53.0",
|
|
5
5
|
"peerDependencies": {
|
|
6
|
-
"@sentry/node": "^10"
|
|
6
|
+
"@sentry/node-core": "^10"
|
|
7
7
|
},
|
|
8
8
|
"dependencies": {
|
|
9
9
|
"@naturalcycles/db-lib": "^10",
|
|
@@ -32,8 +32,8 @@
|
|
|
32
32
|
"vary": "^1"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
|
-
"@sentry/node": "^10",
|
|
36
|
-
"@
|
|
35
|
+
"@sentry/node-core": "^10",
|
|
36
|
+
"@typescript/native-preview": "7.0.0-dev.20260201.1",
|
|
37
37
|
"fastify": "^5",
|
|
38
38
|
"@naturalcycles/dev-lib": "18.4.2"
|
|
39
39
|
},
|
package/readme.md
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { _lazyValue } from '@naturalcycles/js-lib'
|
|
2
2
|
import type { StringMap } from '@naturalcycles/js-lib/types'
|
|
3
|
-
import { AjvSchema
|
|
3
|
+
import { AjvSchema } from '@naturalcycles/nodejs-lib/ajv'
|
|
4
|
+
import type { JsonSchema } from '@naturalcycles/nodejs-lib/ajv'
|
|
4
5
|
import { fs2 } from '@naturalcycles/nodejs-lib/fs2'
|
|
5
6
|
import { yaml2 } from '@naturalcycles/nodejs-lib/yaml2'
|
|
6
7
|
import { resourcesDir } from '../paths.cnst.js'
|
|
@@ -162,19 +162,16 @@ export function createAppYaml(
|
|
|
162
162
|
.split(',')
|
|
163
163
|
.filter(Boolean)
|
|
164
164
|
// oxlint-disable-next-line unicorn/no-array-reduce
|
|
165
|
-
.reduce(
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
},
|
|
176
|
-
{} as Record<string, string>,
|
|
177
|
-
)
|
|
165
|
+
.reduce<Record<string, string>>((map, key) => {
|
|
166
|
+
const v = process.env[key]
|
|
167
|
+
if (!v) {
|
|
168
|
+
throw new Error(
|
|
169
|
+
`appYamlPassEnv.${key} is requested, but process.env.${key} is not defined!`,
|
|
170
|
+
)
|
|
171
|
+
}
|
|
172
|
+
map[key] = v
|
|
173
|
+
return map
|
|
174
|
+
}, {})
|
|
178
175
|
|
|
179
176
|
if (Object.keys(passEnv).length) {
|
|
180
177
|
console.log(
|
|
@@ -3,10 +3,8 @@ import type { CorsOptions } from 'cors'
|
|
|
3
3
|
import type { SentrySharedService } from '../sentry/sentry.shared.service.js'
|
|
4
4
|
import { asyncLocalStorageMiddleware } from '../server/asyncLocalStorageMiddleware.js'
|
|
5
5
|
import { compressionMiddleware } from '../server/compressionMiddleware.js'
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
type GenericErrorMiddlewareCfg,
|
|
9
|
-
} from '../server/genericErrorMiddleware.js'
|
|
6
|
+
import { genericErrorMiddleware } from '../server/genericErrorMiddleware.js'
|
|
7
|
+
import type { GenericErrorMiddlewareCfg } from '../server/genericErrorMiddleware.js'
|
|
10
8
|
import { logMiddleware } from '../server/logMiddleware.js'
|
|
11
9
|
import { methodOverrideMiddleware } from '../server/methodOverrideMiddleware.js'
|
|
12
10
|
import { notFoundMiddleware } from '../server/notFoundMiddleware.js'
|
|
@@ -5,7 +5,8 @@ import { _Memo } from '@naturalcycles/js-lib/decorators/memo.decorator.js'
|
|
|
5
5
|
import { boldGrey, dimGrey, white } from '@naturalcycles/nodejs-lib/colors'
|
|
6
6
|
import type { SentrySharedService } from '../sentry/sentry.shared.service.js'
|
|
7
7
|
import type { BackendApplication } from '../server/server.model.js'
|
|
8
|
-
import { createDefaultApp
|
|
8
|
+
import { createDefaultApp } from './createDefaultApp.js'
|
|
9
|
+
import type { DefaultAppCfg } from './createDefaultApp.js'
|
|
9
10
|
|
|
10
11
|
const { NODE_OPTIONS, APP_ENV } = process.env
|
|
11
12
|
|
|
@@ -3,8 +3,8 @@ import type { CommonLogger, CommonLogLevel } from '@naturalcycles/js-lib/log'
|
|
|
3
3
|
import type { Primitive, StringMap } from '@naturalcycles/js-lib/types'
|
|
4
4
|
import type { InspectAnyOptions } from '@naturalcycles/nodejs-lib'
|
|
5
5
|
import { _inspect } from '@naturalcycles/nodejs-lib'
|
|
6
|
-
import type { Breadcrumb, SeverityLevel } from '@sentry/node'
|
|
7
|
-
import type * as SentryLib from '@sentry/node'
|
|
6
|
+
import type { Breadcrumb, SeverityLevel } from '@sentry/node-core/light'
|
|
7
|
+
import type * as SentryLib from '@sentry/node-core/light'
|
|
8
8
|
import { getRequestLogger } from '../server/asyncLocalStorageMiddleware.js'
|
|
9
9
|
|
|
10
10
|
export interface SentrySharedServiceCfg {
|
|
@@ -114,8 +114,11 @@ export function compressionMiddleware(options?: CompressionOptions): BackendRequ
|
|
|
114
114
|
let listeners: [string, (...args: any[]) => void][] | null = []
|
|
115
115
|
let stream: zlib.Gzip | zlib.Deflate | zlib.BrotliCompress | zlib.ZstdCompress | undefined
|
|
116
116
|
|
|
117
|
+
// oxlint-disable-next-line typescript/unbound-method -- monkey-patching, rebound via .call()
|
|
117
118
|
const _end = res.end
|
|
119
|
+
// oxlint-disable-next-line typescript/unbound-method -- monkey-patching, rebound via .call()
|
|
118
120
|
const _on = res.on
|
|
121
|
+
// oxlint-disable-next-line typescript/unbound-method -- monkey-patching, rebound via .call()
|
|
119
122
|
const _write = res.write
|
|
120
123
|
|
|
121
124
|
// flush
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { inspect } from 'node:util'
|
|
2
2
|
import type { CommonLogger } from '@naturalcycles/js-lib/log'
|
|
3
|
-
import { _objectAssign
|
|
3
|
+
import { _objectAssign } from '@naturalcycles/js-lib/types'
|
|
4
|
+
import type { AnyObject } from '@naturalcycles/js-lib/types'
|
|
4
5
|
import { _inspect } from '@naturalcycles/nodejs-lib'
|
|
5
6
|
import { dimGrey } from '@naturalcycles/nodejs-lib/colors'
|
|
6
7
|
import type { BackendRequestHandler } from './server.model.js'
|
|
@@ -5,7 +5,8 @@ import { _ms } from '@naturalcycles/js-lib/datetime/time.util.js'
|
|
|
5
5
|
import { _percentile } from '@naturalcycles/js-lib/math/math.util.js'
|
|
6
6
|
import { NumberStack } from '@naturalcycles/js-lib/math/stack.util.js'
|
|
7
7
|
import { _get, _mapValues } from '@naturalcycles/js-lib/object/object.util.js'
|
|
8
|
-
import { _stringMapEntries, _stringMapValues
|
|
8
|
+
import { _stringMapEntries, _stringMapValues } from '@naturalcycles/js-lib/types'
|
|
9
|
+
import type { StringMap } from '@naturalcycles/js-lib/types'
|
|
9
10
|
import { onFinished } from '../onFinished.js'
|
|
10
11
|
import { getRequestEndpoint } from './request.util.js'
|
|
11
12
|
import type { BackendRequestHandler } from './server.model.js'
|
|
@@ -3,11 +3,8 @@ import type { AddressInfo } from 'node:net'
|
|
|
3
3
|
import type { Fetcher, FetcherOptions, FetchFunction } from '@naturalcycles/js-lib/http'
|
|
4
4
|
import { getFetcher } from '@naturalcycles/js-lib/http'
|
|
5
5
|
import { pDelay } from '@naturalcycles/js-lib/promise/pDelay.js'
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
createDefaultApp,
|
|
9
|
-
type DefaultAppCfg,
|
|
10
|
-
} from '../express/createDefaultApp.js'
|
|
6
|
+
import { createDefaultApp } from '../express/createDefaultApp.js'
|
|
7
|
+
import type { BackendRequestHandlerCfg, DefaultAppCfg } from '../express/createDefaultApp.js'
|
|
11
8
|
import type { BackendApplication } from '../server/server.model.js'
|
|
12
9
|
|
|
13
10
|
const nativeFetchFn: FetchFunction = async (url, init) => await globalThis.fetch(url, init)
|
|
@@ -1,16 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
type AjvValidationError,
|
|
4
|
-
getCoercingAjv,
|
|
5
|
-
type SchemaHandledByAjv,
|
|
6
|
-
} from '@naturalcycles/nodejs-lib/ajv'
|
|
1
|
+
import { AjvSchema, getCoercingAjv } from '@naturalcycles/nodejs-lib/ajv'
|
|
2
|
+
import type { AjvValidationError, SchemaHandledByAjv } from '@naturalcycles/nodejs-lib/ajv'
|
|
7
3
|
import type { BackendRequest } from '../../server/server.model.js'
|
|
8
|
-
import { handleValidationError
|
|
4
|
+
import { handleValidationError } from '../validateRequest.util.js'
|
|
5
|
+
import type { ReqValidationOptions } from '../validateRequest.util.js'
|
|
9
6
|
|
|
10
7
|
class AjvValidateRequest {
|
|
11
|
-
body<
|
|
8
|
+
body<OUT>(
|
|
12
9
|
req: BackendRequest,
|
|
13
|
-
schema: SchemaHandledByAjv<
|
|
10
|
+
schema: SchemaHandledByAjv<OUT>,
|
|
14
11
|
opt: ReqValidationOptions<AjvValidationError> = {},
|
|
15
12
|
): OUT {
|
|
16
13
|
return this.validate(
|
|
@@ -28,9 +25,9 @@ class AjvValidateRequest {
|
|
|
28
25
|
*
|
|
29
26
|
* Coercion mutates the input, even if the end result is that the input failed the validation.
|
|
30
27
|
*/
|
|
31
|
-
query<
|
|
28
|
+
query<OUT>(
|
|
32
29
|
req: BackendRequest,
|
|
33
|
-
schema: SchemaHandledByAjv<
|
|
30
|
+
schema: SchemaHandledByAjv<OUT>,
|
|
34
31
|
opt: ReqValidationOptions<AjvValidationError> = {},
|
|
35
32
|
): OUT {
|
|
36
33
|
const originalQuery = JSON.stringify(req.query)
|
|
@@ -46,9 +43,9 @@ class AjvValidateRequest {
|
|
|
46
43
|
*
|
|
47
44
|
* Coercion mutates the input, even if the end result is that the input failed the validation.
|
|
48
45
|
*/
|
|
49
|
-
params<
|
|
46
|
+
params<OUT>(
|
|
50
47
|
req: BackendRequest,
|
|
51
|
-
schema: SchemaHandledByAjv<
|
|
48
|
+
schema: SchemaHandledByAjv<OUT>,
|
|
52
49
|
opt: ReqValidationOptions<AjvValidationError> = {},
|
|
53
50
|
): OUT {
|
|
54
51
|
const originalParams = JSON.stringify(req.params)
|
|
@@ -66,9 +63,9 @@ class AjvValidateRequest {
|
|
|
66
63
|
* We want to non-mutate the `req.headers`, because we anticipate that
|
|
67
64
|
* there may be additional consumers for `req.headers` (e.g middlewares, etc).
|
|
68
65
|
*/
|
|
69
|
-
headers<
|
|
66
|
+
headers<OUT>(
|
|
70
67
|
req: BackendRequest,
|
|
71
|
-
schema: SchemaHandledByAjv<
|
|
68
|
+
schema: SchemaHandledByAjv<OUT>,
|
|
72
69
|
opt: ReqValidationOptions<AjvValidationError> = {},
|
|
73
70
|
): OUT {
|
|
74
71
|
return this.validate(req, 'headers', schema, undefined, {
|
|
@@ -77,14 +74,14 @@ class AjvValidateRequest {
|
|
|
77
74
|
})
|
|
78
75
|
}
|
|
79
76
|
|
|
80
|
-
private validate<
|
|
77
|
+
private validate<OUT>(
|
|
81
78
|
req: BackendRequest,
|
|
82
79
|
reqProperty: 'body' | 'params' | 'query' | 'headers',
|
|
83
|
-
schema: SchemaHandledByAjv<
|
|
84
|
-
getOriginalInput?: () =>
|
|
80
|
+
schema: SchemaHandledByAjv<OUT>,
|
|
81
|
+
getOriginalInput?: () => unknown,
|
|
85
82
|
opt: ReqValidationOptions<AjvValidationError> = {},
|
|
86
83
|
): OUT {
|
|
87
|
-
const input =
|
|
84
|
+
const input = req[reqProperty] || {}
|
|
88
85
|
|
|
89
86
|
const { coerceTypes, mutateInput } = opt
|
|
90
87
|
const ajv = coerceTypes ? getCoercingAjv() : undefined
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { zSafeValidate } from '@naturalcycles/js-lib/zod'
|
|
2
|
+
import type { ZodType, ZodValidationError } from '@naturalcycles/js-lib/zod'
|
|
2
3
|
import type { BackendRequest } from '../../server/server.model.js'
|
|
3
|
-
import { handleValidationError
|
|
4
|
+
import { handleValidationError } from '../validateRequest.util.js'
|
|
5
|
+
import type { ReqValidationOptions } from '../validateRequest.util.js'
|
|
4
6
|
|
|
5
7
|
class ZodValidateRequest {
|
|
6
8
|
body<T>(
|