@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.
@@ -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 { type GenericErrorMiddlewareCfg } from '../server/genericErrorMiddleware.js';
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, } from '../server/genericErrorMiddleware.js';
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 { type DefaultAppCfg } from './createDefaultApp.js';
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 { type BackendRequestHandlerCfg, type DefaultAppCfg } from '../express/createDefaultApp.js';
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, } from '../express/createDefaultApp.js';
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 { type AjvValidationError, type SchemaHandledByAjv } from '@naturalcycles/nodejs-lib/ajv';
1
+ import type { AjvValidationError, SchemaHandledByAjv } from '@naturalcycles/nodejs-lib/ajv';
2
2
  import type { BackendRequest } from '../../server/server.model.js';
3
- import { type ReqValidationOptions } from '../validateRequest.util.js';
3
+ import type { ReqValidationOptions } from '../validateRequest.util.js';
4
4
  declare class AjvValidateRequest {
5
- body<IN, OUT>(req: BackendRequest, schema: SchemaHandledByAjv<IN, OUT>, opt?: ReqValidationOptions<AjvValidationError>): OUT;
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<IN, OUT>(req: BackendRequest, schema: SchemaHandledByAjv<IN, OUT>, opt?: ReqValidationOptions<AjvValidationError>): OUT;
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<IN, OUT>(req: BackendRequest, schema: SchemaHandledByAjv<IN, OUT>, opt?: ReqValidationOptions<AjvValidationError>): OUT;
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<IN, OUT>(req: BackendRequest, schema: SchemaHandledByAjv<IN, OUT>, opt?: ReqValidationOptions<AjvValidationError>): OUT;
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, } from '@naturalcycles/nodejs-lib/ajv';
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 = (req[reqProperty] || {});
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 { type ZodType, type ZodValidationError } from '@naturalcycles/js-lib/zod';
1
+ import type { ZodType, ZodValidationError } from '@naturalcycles/js-lib/zod';
2
2
  import type { BackendRequest } from '../../server/server.model.js';
3
- import { type ReqValidationOptions } from '../validateRequest.util.js';
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.51.1",
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
- "@types/ejs": "^3",
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
@@ -9,3 +9,7 @@
9
9
  [![Actions](https://github.com/NaturalCycles/backend-lib/workflows/ci/badge.svg)](https://github.com/NaturalCycles/backend-lib/actions)
10
10
 
11
11
  # [Documentation](https://naturalcycles.github.io/backend-lib/)
12
+
13
+ ## chore-counter
14
+
15
+ 1
@@ -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, type JsonSchema } from '@naturalcycles/nodejs-lib/ajv'
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
- (map, key) => {
167
- const v = process.env[key]
168
- if (!v) {
169
- throw new Error(
170
- `appYamlPassEnv.${key} is requested, but process.env.${key} is not defined!`,
171
- )
172
- }
173
- map[key] = v
174
- return map
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
- genericErrorMiddleware,
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, type DefaultAppCfg } from './createDefaultApp.js'
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, type AnyObject } from '@naturalcycles/js-lib/types'
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, type StringMap } from '@naturalcycles/js-lib/types'
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
- type BackendRequestHandlerCfg,
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
- AjvSchema,
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, type ReqValidationOptions } from '../validateRequest.util.js'
4
+ import { handleValidationError } from '../validateRequest.util.js'
5
+ import type { ReqValidationOptions } from '../validateRequest.util.js'
9
6
 
10
7
  class AjvValidateRequest {
11
- body<IN, OUT>(
8
+ body<OUT>(
12
9
  req: BackendRequest,
13
- schema: SchemaHandledByAjv<IN, OUT>,
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<IN, OUT>(
28
+ query<OUT>(
32
29
  req: BackendRequest,
33
- schema: SchemaHandledByAjv<IN, OUT>,
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<IN, OUT>(
46
+ params<OUT>(
50
47
  req: BackendRequest,
51
- schema: SchemaHandledByAjv<IN, OUT>,
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<IN, OUT>(
66
+ headers<OUT>(
70
67
  req: BackendRequest,
71
- schema: SchemaHandledByAjv<IN, OUT>,
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<IN, OUT>(
77
+ private validate<OUT>(
81
78
  req: BackendRequest,
82
79
  reqProperty: 'body' | 'params' | 'query' | 'headers',
83
- schema: SchemaHandledByAjv<IN, OUT>,
84
- getOriginalInput?: () => IN,
80
+ schema: SchemaHandledByAjv<OUT>,
81
+ getOriginalInput?: () => unknown,
85
82
  opt: ReqValidationOptions<AjvValidationError> = {},
86
83
  ): OUT {
87
- const input = (req[reqProperty] || {}) as IN
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 { type ZodType, type ZodValidationError, zSafeValidate } from '@naturalcycles/js-lib/zod'
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, type ReqValidationOptions } from '../validateRequest.util.js'
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>(