@naturalcycles/backend-lib 9.14.0 → 9.16.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.
Files changed (112) hide show
  1. package/dist/admin/adminMiddleware.js +7 -6
  2. package/dist/admin/base.admin.service.js +2 -2
  3. package/dist/admin/firebase.shared.service.js +1 -1
  4. package/dist/admin/index.d.ts +4 -0
  5. package/dist/admin/index.js +4 -0
  6. package/dist/admin/secureHeaderMiddleware.js +1 -1
  7. package/dist/db/httpDB.d.ts +3 -1
  8. package/dist/db/httpDB.js +1 -1
  9. package/dist/db/httpDBRequestHandler.d.ts +1 -1
  10. package/dist/db/httpDBRequestHandler.js +4 -3
  11. package/dist/deploy/backend.cfg.util.d.ts +1 -1
  12. package/dist/deploy/backend.cfg.util.js +3 -2
  13. package/dist/deploy/deploy.model.d.ts +1 -1
  14. package/dist/deploy/deploy.util.js +11 -6
  15. package/dist/deploy/deployGae.js +6 -3
  16. package/dist/deploy/deployHealthCheck.js +6 -2
  17. package/dist/deploy/deployInfo.util.d.ts +2 -0
  18. package/dist/{server → deploy}/deployInfo.util.js +3 -2
  19. package/dist/deploy/deployPrepare.js +3 -2
  20. package/dist/deploy/index.d.ts +1 -0
  21. package/dist/deploy/index.js +1 -0
  22. package/dist/env/env.shared.service.d.ts +1 -1
  23. package/dist/env/env.shared.service.js +3 -2
  24. package/dist/{server/createDefaultApp.model.d.ts → express/createDefaultApp.d.ts} +3 -2
  25. package/dist/{server → express}/createDefaultApp.js +10 -10
  26. package/dist/{server → express}/getDefaultRouter.d.ts +1 -1
  27. package/dist/{server/startServer.model.d.ts → express/startServer.d.ts} +17 -2
  28. package/dist/{server → express}/startServer.js +4 -3
  29. package/dist/index.d.ts +0 -15
  30. package/dist/index.js +0 -15
  31. package/dist/onFinished.d.ts +2 -0
  32. package/dist/onFinished.js +2 -0
  33. package/dist/sentry/sentry.shared.service.d.ts +2 -1
  34. package/dist/sentry/sentry.shared.service.js +2 -2
  35. package/dist/server/asyncLocalStorageMiddleware.d.ts +1 -1
  36. package/dist/server/basicAuthMiddleware.d.ts +1 -1
  37. package/dist/server/basicAuthMiddleware.js +1 -1
  38. package/dist/server/bodyParserTimeoutMiddleware.d.ts +1 -1
  39. package/dist/server/bodyParserTimeoutMiddleware.js +2 -2
  40. package/dist/server/genericErrorMiddleware.d.ts +1 -1
  41. package/dist/server/genericErrorMiddleware.js +2 -2
  42. package/dist/server/logMiddleware.d.ts +1 -1
  43. package/dist/server/logMiddleware.js +2 -1
  44. package/dist/server/request.log.util.js +1 -1
  45. package/dist/server/requestLoggerMiddleware.d.ts +1 -1
  46. package/dist/server/requestLoggerMiddleware.js +2 -2
  47. package/dist/server/requestTimeoutMiddleware.d.ts +2 -2
  48. package/dist/server/requestTimeoutMiddleware.js +5 -2
  49. package/dist/server/safeJsonMiddleware.js +1 -1
  50. package/dist/server/server.model.d.ts +2 -1
  51. package/dist/server/serverStatsMiddleware.d.ts +1 -1
  52. package/dist/server/serverStatsMiddleware.js +6 -2
  53. package/dist/server/serverStatusMiddleware.js +3 -2
  54. package/dist/server/simpleRequestLoggerMiddleware.d.ts +1 -1
  55. package/dist/server/simpleRequestLoggerMiddleware.js +3 -3
  56. package/dist/testing/express.test.service.d.ts +3 -3
  57. package/dist/testing/express.test.service.js +3 -2
  58. package/dist/{server/validation → validation/ajv}/ajvValidateRequest.d.ts +2 -2
  59. package/dist/{server/validation → validation/ajv}/ajvValidateRequest.js +2 -1
  60. package/dist/{server/validation/validateRequest.d.ts → validation/joi/joiValidateRequest.d.ts} +1 -1
  61. package/dist/{server/validation/validateRequest.js → validation/joi/joiValidateRequest.js} +2 -1
  62. package/dist/{server/validation → validation/zod}/zodValidateRequest.d.ts +2 -2
  63. package/dist/{server/validation → validation/zod}/zodValidateRequest.js +2 -1
  64. package/package.json +11 -2
  65. package/src/admin/adminMiddleware.ts +7 -6
  66. package/src/admin/base.admin.service.ts +2 -2
  67. package/src/admin/firebase.shared.service.ts +1 -1
  68. package/src/admin/index.ts +4 -0
  69. package/src/admin/secureHeaderMiddleware.ts +1 -1
  70. package/src/db/httpDB.ts +4 -7
  71. package/src/db/httpDBRequestHandler.ts +5 -4
  72. package/src/deploy/backend.cfg.util.ts +4 -3
  73. package/src/deploy/deploy.model.ts +1 -1
  74. package/src/deploy/deploy.util.ts +11 -6
  75. package/src/deploy/deployGae.ts +6 -3
  76. package/src/deploy/deployHealthCheck.ts +7 -3
  77. package/src/{server → deploy}/deployInfo.util.ts +4 -3
  78. package/src/deploy/deployPrepare.ts +3 -2
  79. package/src/deploy/index.ts +2 -0
  80. package/src/env/env.shared.service.ts +4 -3
  81. package/src/{server → express}/createDefaultApp.ts +54 -16
  82. package/src/{server → express}/getDefaultRouter.ts +1 -1
  83. package/src/{server → express}/startServer.ts +46 -4
  84. package/src/index.ts +0 -16
  85. package/src/onFinished.ts +3 -0
  86. package/src/sentry/sentry.shared.service.ts +4 -3
  87. package/src/server/asyncLocalStorageMiddleware.ts +1 -1
  88. package/src/server/basicAuthMiddleware.ts +2 -2
  89. package/src/server/bodyParserTimeoutMiddleware.ts +3 -3
  90. package/src/server/genericErrorMiddleware.ts +3 -6
  91. package/src/server/logMiddleware.ts +4 -2
  92. package/src/server/request.log.util.ts +2 -2
  93. package/src/server/requestLoggerMiddleware.ts +4 -4
  94. package/src/server/requestTimeoutMiddleware.ts +7 -4
  95. package/src/server/safeJsonMiddleware.ts +1 -1
  96. package/src/server/server.model.ts +2 -1
  97. package/src/server/server.util.ts +1 -1
  98. package/src/server/serverStatsMiddleware.ts +7 -15
  99. package/src/server/serverStatusMiddleware.ts +3 -2
  100. package/src/server/simpleRequestLoggerMiddleware.ts +5 -5
  101. package/src/testing/express.test.service.ts +9 -5
  102. package/src/{server/validation → validation/ajv}/ajvValidateRequest.ts +4 -3
  103. package/src/{server/validation/validateRequest.ts → validation/joi/joiValidateRequest.ts} +3 -2
  104. package/src/{server/validation → validation/zod}/zodValidateRequest.ts +4 -3
  105. package/dist/server/createDefaultApp.d.ts +0 -3
  106. package/dist/server/createDefaultApp.model.js +0 -1
  107. package/dist/server/deployInfo.util.d.ts +0 -2
  108. package/dist/server/startServer.d.ts +0 -17
  109. package/dist/server/startServer.model.js +0 -1
  110. package/src/server/createDefaultApp.model.ts +0 -41
  111. package/src/server/startServer.model.ts +0 -44
  112. /package/dist/{server → express}/getDefaultRouter.js +0 -0
@@ -1,4 +1,4 @@
1
- import type { BackendRequestHandler } from '../index.js';
1
+ import type { BackendRequestHandler } from './server.model.js';
2
2
  export interface SimpleRequestLoggerMiddlewareCfg {
3
3
  /**
4
4
  * @default false
@@ -1,6 +1,6 @@
1
- import { _since } from '@naturalcycles/js-lib';
2
- import { boldGrey, dimGrey } from '@naturalcycles/nodejs-lib';
3
- import { onFinished } from '../index.js';
1
+ import { _since } from '@naturalcycles/js-lib/datetime';
2
+ import { boldGrey, dimGrey } from '@naturalcycles/nodejs-lib/colors';
3
+ import { onFinished } from '../onFinished.js';
4
4
  import { logRequestWithColors } from './request.log.util.js';
5
5
  export function simpleRequestLoggerMiddleware(cfg = {}) {
6
6
  const { logStart = false, logFinish = true } = cfg;
@@ -1,6 +1,6 @@
1
- import type { Fetcher, FetcherOptions } from '@naturalcycles/js-lib';
2
- import type { BackendApplication, DefaultAppCfg } from '../index.js';
3
- import type { BackendRequestHandlerCfg } from '../server/createDefaultApp.model.js';
1
+ import type { Fetcher, FetcherOptions } from '@naturalcycles/js-lib/http';
2
+ import { type BackendRequestHandlerCfg, type DefaultAppCfg } from '../express/createDefaultApp.js';
3
+ import type { BackendApplication } from '../server/server.model.js';
4
4
  export interface ExpressApp extends Fetcher, AsyncDisposable {
5
5
  close: () => Promise<void>;
6
6
  }
@@ -1,5 +1,6 @@
1
- import { getFetcher, pDelay } from '@naturalcycles/js-lib';
2
- import { createDefaultApp } from '../index.js';
1
+ import { getFetcher } from '@naturalcycles/js-lib/http';
2
+ import { pDelay } from '@naturalcycles/js-lib/promise';
3
+ import { createDefaultApp, } from '../express/createDefaultApp.js';
3
4
  const nativeFetchFn = async (url, init) => await globalThis.fetch(url, init);
4
5
  // Example:
5
6
  // const app = expressTestService.createApp([ debugResource ])
@@ -1,6 +1,6 @@
1
1
  import type { AjvSchema, AjvValidationError } from '@naturalcycles/nodejs-lib/ajv';
2
- import type { BackendRequest } from '../server.model.js';
3
- import type { ReqValidationOptions } from './validateRequest.js';
2
+ import type { BackendRequest } from '../../server/server.model.js';
3
+ import type { ReqValidationOptions } from '../joi/joiValidateRequest.js';
4
4
  declare class AjvValidateRequest {
5
5
  body<T>(req: BackendRequest, schema: AjvSchema<T>, opt?: ReqValidationOptions<AjvValidationError>): T;
6
6
  query<T>(req: BackendRequest, schema: AjvSchema<T>, opt?: ReqValidationOptions<AjvValidationError>): T;
@@ -1,4 +1,5 @@
1
- import { _get, AppError } from '@naturalcycles/js-lib';
1
+ import { AppError } from '@naturalcycles/js-lib/error';
2
+ import { _get } from '@naturalcycles/js-lib/object';
2
3
  class AjvValidateRequest {
3
4
  body(req, schema, opt = {}) {
4
5
  return this.validate(req, 'body', schema, opt);
@@ -1,5 +1,5 @@
1
1
  import type { AnySchema, JoiValidationError } from '@naturalcycles/nodejs-lib/joi';
2
- import type { BackendRequest } from '../server.model.js';
2
+ import type { BackendRequest } from '../../server/server.model.js';
3
3
  export interface ReqValidationOptions<ERR extends Error> {
4
4
  /**
5
5
  * Pass a 'dot-paths' (e.g `pw`, or `input.pw`) that needs to be redacted from the output, in case of error.
@@ -1,4 +1,5 @@
1
- import { _get, AppError } from '@naturalcycles/js-lib';
1
+ import { AppError } from '@naturalcycles/js-lib/error';
2
+ import { _get } from '@naturalcycles/js-lib/object';
2
3
  import { getValidationResult } from '@naturalcycles/nodejs-lib/joi';
3
4
  class ValidateRequest {
4
5
  body(req, schema, opt = {}) {
@@ -1,6 +1,6 @@
1
1
  import { type ZodType, type ZodValidationError } from '@naturalcycles/js-lib/zod';
2
- import type { BackendRequest } from '../server.model.js';
3
- import type { ReqValidationOptions } from './validateRequest.js';
2
+ import type { BackendRequest } from '../../server/server.model.js';
3
+ import type { ReqValidationOptions } from '../joi/joiValidateRequest.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;
@@ -1,4 +1,5 @@
1
- import { _get, AppError } from '@naturalcycles/js-lib';
1
+ import { AppError } from '@naturalcycles/js-lib/error';
2
+ import { _get } from '@naturalcycles/js-lib/object';
2
3
  import { zSafeValidate } from '@naturalcycles/js-lib/zod';
3
4
  class ZodValidateRequest {
4
5
  body(req, schema, opt = {}) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@naturalcycles/backend-lib",
3
3
  "type": "module",
4
- "version": "9.14.0",
4
+ "version": "9.16.0",
5
5
  "peerDependencies": {
6
6
  "@sentry/node": "^9"
7
7
  },
@@ -34,7 +34,16 @@
34
34
  "exports": {
35
35
  "./cfg/tsconfig.json": "./cfg/tsconfig.json",
36
36
  ".": "./dist/index.js",
37
- "./db": "./dist/db/index.js"
37
+ "./db": "./dist/db/index.js",
38
+ "./deploy": "./dist/deploy/index.js",
39
+ "./express/createDefaultApp": "./dist/express/createDefaultApp.js",
40
+ "./express/getDefaultRouter": "./dist/express/getDefaultRouter.js",
41
+ "./express/startServer": "./dist/express/startServer.js",
42
+ "./ajvValidateRequest": "./dist/validation/ajv/ajvValidateRequest.js",
43
+ "./joiValidateRequest": "./dist/validation/joi/joiValidateRequest.js",
44
+ "./zodValidateRequest": "./dist/validation/zod/zodValidateRequest.js",
45
+ "./onFinished": "./dist/onFinished.js",
46
+ "./testing": "./dist/testing/index.js"
38
47
  },
39
48
  "files": [
40
49
  "dist",
@@ -1,6 +1,6 @@
1
- import { _memoFn, AppError } from '@naturalcycles/js-lib'
2
- import { fs2 } from '@naturalcycles/nodejs-lib/fs'
3
- import ejs from 'ejs'
1
+ import { _memoFn } from '@naturalcycles/js-lib/decorators'
2
+ import { AppError } from '@naturalcycles/js-lib/error'
3
+ import { fs2 } from '@naturalcycles/nodejs-lib/fs2'
4
4
  import { srcDir } from '../paths.cnst.js'
5
5
  import type { BackendRequestHandler } from '../server/server.model.js'
6
6
  import type { BaseAdminService } from './base.admin.service.js'
@@ -89,9 +89,9 @@ export function loginHtml(firebaseServiceCfg: FirebaseSharedServiceCfg): Backend
89
89
  adminAuthProvider: firebaseAuthProvider = 'GoogleAuthProvider',
90
90
  } = firebaseServiceCfg
91
91
 
92
- return (_req, res) => {
92
+ return async (_req, res) => {
93
93
  res.send(
94
- getLoginHtml({
94
+ await getLoginHtml({
95
95
  firebaseApiKey,
96
96
  firebaseAuthDomain,
97
97
  firebaseAuthProvider,
@@ -100,9 +100,10 @@ export function loginHtml(firebaseServiceCfg: FirebaseSharedServiceCfg): Backend
100
100
  }
101
101
  }
102
102
 
103
- const getLoginHtml = _memoFn((cfg: LoginHtmlCfg) => {
103
+ const getLoginHtml = _memoFn(async (cfg: LoginHtmlCfg) => {
104
104
  console.log(`reading login.html`)
105
105
  const tmpl = fs2.readText(`${srcDir}/admin/login.html`)
106
+ const { default: ejs } = await import('ejs')
106
107
  return ejs.render(tmpl, cfg)
107
108
  })
108
109
 
@@ -1,5 +1,5 @@
1
- import { _assert, AppError } from '@naturalcycles/js-lib'
2
- import { dimGrey, green, red } from '@naturalcycles/nodejs-lib'
1
+ import { _assert, AppError } from '@naturalcycles/js-lib/error'
2
+ import { dimGrey, green, red } from '@naturalcycles/nodejs-lib/colors'
3
3
  import type FirebaseAdmin from 'firebase-admin'
4
4
  import type { BackendRequest, BackendRequestHandler } from '../server/server.model.js'
5
5
 
@@ -1,4 +1,4 @@
1
- import { _Memo } from '@naturalcycles/js-lib'
1
+ import { _Memo } from '@naturalcycles/js-lib/decorators'
2
2
  import type { AppOptions, ServiceAccount } from 'firebase-admin'
3
3
  import type FirebaseAdmin from 'firebase-admin'
4
4
 
@@ -0,0 +1,4 @@
1
+ export * from './adminMiddleware.js'
2
+ export * from './base.admin.service.js'
3
+ export * from './firebase.shared.service.js'
4
+ export * from './secureHeaderMiddleware.js'
@@ -1,4 +1,4 @@
1
- import { AppError } from '@naturalcycles/js-lib'
1
+ import { AppError } from '@naturalcycles/js-lib/error'
2
2
  import { timingSafeStringEqual } from '@naturalcycles/nodejs-lib'
3
3
  import type { BackendRequestHandler } from '../server/server.model.js'
4
4
  import type { AdminMiddleware, RequireAdminCfg } from './adminMiddleware.js'
package/src/db/httpDB.ts CHANGED
@@ -9,13 +9,10 @@ import type {
9
9
  RunQueryResult,
10
10
  } from '@naturalcycles/db-lib'
11
11
  import { BaseCommonDB, commonDBFullSupport } from '@naturalcycles/db-lib'
12
- import type {
13
- Fetcher,
14
- FetcherOptions,
15
- JsonSchemaRootObject,
16
- ObjectWithId,
17
- } from '@naturalcycles/js-lib'
18
- import { getFetcher } from '@naturalcycles/js-lib'
12
+ import type { Fetcher, FetcherOptions } from '@naturalcycles/js-lib/http'
13
+ import { getFetcher } from '@naturalcycles/js-lib/http'
14
+ import type { JsonSchemaRootObject } from '@naturalcycles/js-lib/json-schema'
15
+ import type { ObjectWithId } from '@naturalcycles/js-lib/types'
19
16
  import type { ReadableTyped } from '@naturalcycles/nodejs-lib/stream'
20
17
 
21
18
  export interface HttpDBCfg extends FetcherOptions {
@@ -1,20 +1,21 @@
1
1
  import type { CommonDB, CommonDBOptions, CommonDBSaveOptions } from '@naturalcycles/db-lib'
2
- import { DBQuery, InMemoryDB } from '@naturalcycles/db-lib'
2
+ import { DBQuery } from '@naturalcycles/db-lib'
3
+ import { InMemoryDB } from '@naturalcycles/db-lib/inmemory'
3
4
  import {
4
5
  commonDBOptionsSchema,
5
6
  commonDBSaveOptionsSchema,
6
7
  dbQuerySchema,
7
8
  } from '@naturalcycles/db-lib/validation'
8
- import type { ObjectWithId } from '@naturalcycles/js-lib'
9
+ import type { ObjectWithId } from '@naturalcycles/js-lib/types'
9
10
  import {
10
11
  anyObjectSchema,
11
12
  arraySchema,
12
13
  objectSchema,
13
14
  stringSchema,
14
15
  } from '@naturalcycles/nodejs-lib/joi'
15
- import { getDefaultRouter } from '../server/getDefaultRouter.js'
16
+ import { getDefaultRouter } from '../express/getDefaultRouter.js'
16
17
  import type { BackendRouter } from '../server/server.model.js'
17
- import { validateRequest } from '../server/validation/validateRequest.js'
18
+ import { validateRequest } from '../validation/joi/joiValidateRequest.js'
18
19
 
19
20
  export interface GetByIdsInput {
20
21
  table: string
@@ -1,6 +1,7 @@
1
- import type { StringMap } from '@naturalcycles/js-lib'
1
+ import type { StringMap } from '@naturalcycles/js-lib/types'
2
2
  import { AjvSchema } from '@naturalcycles/nodejs-lib/ajv'
3
- import { fs2 } from '@naturalcycles/nodejs-lib/fs'
3
+ import { fs2 } from '@naturalcycles/nodejs-lib/fs2'
4
+ import { yaml2 } from '@naturalcycles/nodejs-lib/yaml2'
4
5
  import { resourcesDir } from '../paths.cnst.js'
5
6
 
6
7
  export interface BackendCfg {
@@ -50,7 +51,7 @@ export function getBackendCfg(projectDir = '.'): BackendCfg {
50
51
  fs2.requireFileToExist(backendCfgYamlPath)
51
52
 
52
53
  const backendCfg: BackendCfg = {
53
- ...fs2.readYaml(backendCfgYamlPath),
54
+ ...yaml2.readYaml(backendCfgYamlPath),
54
55
  }
55
56
 
56
57
  backendCfgSchema.validate(backendCfg)
@@ -1,4 +1,4 @@
1
- import type { UnixTimestamp } from '@naturalcycles/js-lib'
1
+ import type { UnixTimestamp } from '@naturalcycles/js-lib/types'
2
2
 
3
3
  export interface DeployInfo {
4
4
  gaeProject: string
@@ -1,6 +1,11 @@
1
- import { _assert, _mapValues, _merge, _truncate, localTime } from '@naturalcycles/js-lib'
2
- import { dimGrey, sha256, white } from '@naturalcycles/nodejs-lib'
3
- import { fs2 } from '@naturalcycles/nodejs-lib/fs'
1
+ import { localTime } from '@naturalcycles/js-lib/datetime'
2
+ import { _assert } from '@naturalcycles/js-lib/error'
3
+ import { _mapValues, _merge } from '@naturalcycles/js-lib/object'
4
+ import { _truncate } from '@naturalcycles/js-lib/string'
5
+ import { sha256 } from '@naturalcycles/nodejs-lib'
6
+ import { dimGrey, white } from '@naturalcycles/nodejs-lib/colors'
7
+ import { fs2 } from '@naturalcycles/nodejs-lib/fs2'
8
+ import { yaml2 } from '@naturalcycles/nodejs-lib/yaml2'
4
9
  import type { BackendCfg } from './backend.cfg.util.js'
5
10
  import type { AppYaml, DeployInfo } from './deploy.model.js'
6
11
 
@@ -117,7 +122,7 @@ export function createAndSaveAppYaml(
117
122
  ): AppYaml {
118
123
  const appYaml = createAppYaml(backendCfg, deployInfo, projectDir, appYamlPassEnv)
119
124
  const appYamlPath = `${targetDir}/app.yaml`
120
- fs2.writeYaml(appYamlPath, appYaml)
125
+ yaml2.writeYaml(appYamlPath, appYaml)
121
126
  console.log(`saved ${dimGrey(appYamlPath)}`)
122
127
  return appYaml
123
128
  }
@@ -143,13 +148,13 @@ export function createAppYaml(
143
148
  const appYamlPath = `${projectDir}/app.yaml`
144
149
  if (fs2.pathExists(appYamlPath)) {
145
150
  console.log(`merging-in ${dimGrey(appYamlPath)}`)
146
- _merge(appYaml, fs2.readYaml(appYamlPath))
151
+ _merge(appYaml, yaml2.readYaml(appYamlPath))
147
152
  }
148
153
 
149
154
  const appEnvYamlPath = `${projectDir}/app.${APP_ENV}.yaml`
150
155
  if (fs2.pathExists(appEnvYamlPath)) {
151
156
  console.log(`merging-in ${dimGrey(appEnvYamlPath)}`)
152
- _merge(appYaml, fs2.readYaml(appEnvYamlPath))
157
+ _merge(appYaml, yaml2.readYaml(appEnvYamlPath))
153
158
  }
154
159
 
155
160
  // appYamlPassEnv
@@ -1,6 +1,9 @@
1
- import { _anyToError, _objectAssign, pRetry } from '@naturalcycles/js-lib'
2
- import { exec2 } from '@naturalcycles/nodejs-lib'
3
- import { appendToGithubSummary, fs2 } from '@naturalcycles/nodejs-lib/fs'
1
+ import { _anyToError } from '@naturalcycles/js-lib/error'
2
+ import { pRetry } from '@naturalcycles/js-lib/promise'
3
+ import { _objectAssign } from '@naturalcycles/js-lib/types'
4
+ import { appendToGithubSummary } from '@naturalcycles/nodejs-lib/env'
5
+ import { exec2 } from '@naturalcycles/nodejs-lib/exec2'
6
+ import { fs2 } from '@naturalcycles/nodejs-lib/fs2'
4
7
  import { getBackendCfg } from './backend.cfg.util.js'
5
8
  import { createDeployInfo } from './deploy.util.js'
6
9
  import type { DeployHealthCheckOptions } from './deployHealthCheck.js'
@@ -1,8 +1,12 @@
1
1
  import type { InspectOptions } from 'node:util'
2
2
  import { inspect } from 'node:util'
3
- import type { UnixTimestampMillis } from '@naturalcycles/js-lib'
4
- import { _filterFalsyValues, _ms, _since, getFetcher, pDelay } from '@naturalcycles/js-lib'
5
- import { dimGrey, exec2, red } from '@naturalcycles/nodejs-lib'
3
+ import { _ms, _since } from '@naturalcycles/js-lib/datetime'
4
+ import { getFetcher } from '@naturalcycles/js-lib/http'
5
+ import { _filterFalsyValues } from '@naturalcycles/js-lib/object'
6
+ import { pDelay } from '@naturalcycles/js-lib/promise'
7
+ import type { UnixTimestampMillis } from '@naturalcycles/js-lib/types'
8
+ import { dimGrey, red } from '@naturalcycles/nodejs-lib/colors'
9
+ import { exec2 } from '@naturalcycles/nodejs-lib/exec2'
6
10
  import { coloredHttpCode } from '../server/request.log.util.js'
7
11
 
8
12
  export interface DeployHealthCheckOptions {
@@ -1,6 +1,7 @@
1
- import { _memoFn, localTime } from '@naturalcycles/js-lib'
2
- import { fs2 } from '@naturalcycles/nodejs-lib/fs'
3
- import type { DeployInfo } from '../deploy/index.js'
1
+ import { localTime } from '@naturalcycles/js-lib/datetime'
2
+ import { _memoFn } from '@naturalcycles/js-lib/decorators'
3
+ import { fs2 } from '@naturalcycles/nodejs-lib/fs2'
4
+ import type { DeployInfo } from './deploy.model.js'
4
5
 
5
6
  export const getDeployInfo = _memoFn((projectDir: string): DeployInfo => {
6
7
  const deployInfoPath = `${projectDir}/deployInfo.json`
@@ -1,5 +1,6 @@
1
- import { dimGrey } from '@naturalcycles/nodejs-lib'
2
- import { fs2, kpySync } from '@naturalcycles/nodejs-lib/fs'
1
+ import { dimGrey } from '@naturalcycles/nodejs-lib/colors'
2
+ import { fs2 } from '@naturalcycles/nodejs-lib/fs2'
3
+ import { kpySync } from '@naturalcycles/nodejs-lib/kpy'
3
4
  import { srcDir } from '../paths.cnst.js'
4
5
  import { getBackendCfg } from './backend.cfg.util.js'
5
6
  import type { DeployInfo } from './deploy.model.js'
@@ -17,3 +17,5 @@ export {
17
17
  deployPrepare,
18
18
  getBackendCfg,
19
19
  }
20
+
21
+ export * from './deployInfo.util.js'
@@ -1,6 +1,7 @@
1
- import type { StringMap } from '@naturalcycles/js-lib'
2
- import { _assert, _by } from '@naturalcycles/js-lib'
3
- import { dimGrey } from '@naturalcycles/nodejs-lib'
1
+ import { _by } from '@naturalcycles/js-lib'
2
+ import { _assert } from '@naturalcycles/js-lib/error'
3
+ import type { StringMap } from '@naturalcycles/js-lib/types'
4
+ import { dimGrey } from '@naturalcycles/nodejs-lib/colors'
4
5
 
5
6
  export interface BaseEnv {
6
7
  name: string
@@ -1,19 +1,17 @@
1
- import cookieParser from 'cookie-parser'
2
- import cors from 'cors'
3
- import express from 'express'
4
- import { asyncLocalStorageMiddleware } from './asyncLocalStorageMiddleware.js'
5
- import type {
6
- BackendRequestHandlerCfg,
7
- BackendRequestHandlerWithPath,
8
- DefaultAppCfg,
9
- } from './createDefaultApp.model.js'
10
- import { genericErrorMiddleware } from './genericErrorMiddleware.js'
11
- import { logMiddleware } from './logMiddleware.js'
12
- import { methodOverrideMiddleware } from './methodOverrideMiddleware.js'
13
- import { notFoundMiddleware } from './notFoundMiddleware.js'
14
- import { requestTimeoutMiddleware } from './requestTimeoutMiddleware.js'
15
- import type { BackendApplication } from './server.model.js'
16
- import { simpleRequestLoggerMiddleware } from './simpleRequestLoggerMiddleware.js'
1
+ import type { Options, OptionsJson, OptionsUrlencoded } from 'body-parser'
2
+ import type { CorsOptions } from 'cors'
3
+ import type { SentrySharedService } from '../sentry/sentry.shared.service.js'
4
+ import { asyncLocalStorageMiddleware } from '../server/asyncLocalStorageMiddleware.js'
5
+ import {
6
+ genericErrorMiddleware,
7
+ type GenericErrorMiddlewareCfg,
8
+ } from '../server/genericErrorMiddleware.js'
9
+ import { logMiddleware } from '../server/logMiddleware.js'
10
+ import { methodOverrideMiddleware } from '../server/methodOverrideMiddleware.js'
11
+ import { notFoundMiddleware } from '../server/notFoundMiddleware.js'
12
+ import { requestTimeoutMiddleware } from '../server/requestTimeoutMiddleware.js'
13
+ import type { BackendApplication, BackendRequestHandler } from '../server/server.model.js'
14
+ import { simpleRequestLoggerMiddleware } from '../server/simpleRequestLoggerMiddleware.js'
17
15
 
18
16
  const isTest = process.env['APP_ENV'] === 'test'
19
17
  const isDev = process.env['APP_ENV'] === 'dev'
@@ -21,6 +19,10 @@ const isDev = process.env['APP_ENV'] === 'dev'
21
19
  export async function createDefaultApp(cfg: DefaultAppCfg): Promise<BackendApplication> {
22
20
  const { sentryService } = cfg
23
21
 
22
+ const { default: express } = await import('express')
23
+ const { default: cors } = await import('cors')
24
+ const { default: cookieParser } = await import('cookie-parser')
25
+
24
26
  const app = express()
25
27
 
26
28
  app.disable('etag')
@@ -143,3 +145,39 @@ function useHandlers(app: BackendApplication, handlers: BackendRequestHandlerCfg
143
145
  app.use(cfg.path, cfg.handler)
144
146
  })
145
147
  }
148
+
149
+ /**
150
+ * Plain RequestHandler can be provided - then it's mounted to /
151
+ * Otherwise `path` can be provided to specify mounting point.
152
+ */
153
+ export type BackendRequestHandlerCfg = BackendRequestHandler | BackendRequestHandlerWithPath
154
+
155
+ export interface BackendRequestHandlerWithPath {
156
+ path: string
157
+ handler: BackendRequestHandler
158
+ }
159
+
160
+ /**
161
+ * Handlers are used in this order:
162
+ *
163
+ * 1. preHandlers
164
+ * 2. handlers
165
+ * 3. resources
166
+ * 4. postHandlers
167
+ */
168
+ export interface DefaultAppCfg {
169
+ preHandlers?: BackendRequestHandlerCfg[]
170
+ handlers?: BackendRequestHandlerCfg[]
171
+ resources?: BackendRequestHandlerCfg[]
172
+ postHandlers?: BackendRequestHandlerCfg[]
173
+
174
+ sentryService?: SentrySharedService
175
+
176
+ bodyParserJsonOptions?: OptionsJson
177
+ bodyParserUrlEncodedOptions?: OptionsUrlencoded
178
+ bodyParserRawOptions?: Options
179
+
180
+ corsOptions?: CorsOptions
181
+
182
+ genericErrorMwCfg?: GenericErrorMiddlewareCfg
183
+ }
@@ -1,5 +1,5 @@
1
1
  import { Router } from 'express'
2
- import type { BackendRequestHandler, BackendRouter } from './server.model.js'
2
+ import type { BackendRequestHandler, BackendRouter } from '../server/server.model.js'
3
3
 
4
4
  /**
5
5
  * Convenience method.
@@ -1,9 +1,11 @@
1
1
  import type { Server } from 'node:http'
2
2
  import os from 'node:os'
3
- import { _Memo, _ms } from '@naturalcycles/js-lib'
4
- import { boldGrey, dimGrey, white } from '@naturalcycles/nodejs-lib'
5
- import { createDefaultApp } from '../index.js'
6
- import type { StartServerCfg, StartServerData } from './startServer.model.js'
3
+ import { _ms } from '@naturalcycles/js-lib/datetime'
4
+ import { _Memo } from '@naturalcycles/js-lib/decorators'
5
+ import { boldGrey, dimGrey, white } from '@naturalcycles/nodejs-lib/colors'
6
+ import type { SentrySharedService } from '../sentry/sentry.shared.service.js'
7
+ import type { BackendApplication } from '../server/server.model.js'
8
+ import { createDefaultApp, type DefaultAppCfg } from './createDefaultApp.js'
7
9
 
8
10
  const { NODE_OPTIONS, APP_ENV } = process.env
9
11
 
@@ -124,3 +126,43 @@ export async function startServer(cfg: StartServerCfg): Promise<StartServerData>
124
126
  throw err
125
127
  }
126
128
  }
129
+
130
+ /**
131
+ * If DefaultAppCfg.resources is passed and `expressApp` is not passed - it will call createDefaultApp(cfg).
132
+ */
133
+ export interface StartServerCfg extends DefaultAppCfg {
134
+ /**
135
+ * @default process.env.PORT || 8080
136
+ */
137
+ port?: number
138
+
139
+ expressApp?: BackendApplication
140
+
141
+ /**
142
+ * Server will wait for promise to resolve until shutting down.
143
+ * (with a timeout)
144
+ */
145
+ onShutdown?: () => Promise<void>
146
+
147
+ /**
148
+ * @default 3000
149
+ */
150
+ forceShutdownTimeout?: number
151
+
152
+ sentryService?: SentrySharedService
153
+
154
+ /**
155
+ * Defaults to true.
156
+ * Set to false if you already have your handlers elsewhere and don't need them here.
157
+ */
158
+ registerUncaughtExceptionHandlers?: boolean
159
+ }
160
+
161
+ export interface StartServerData {
162
+ port: number
163
+ server: Server
164
+ /**
165
+ * "Processed" server.address() as a string, ready to Cmd+click in MacOS Terminal
166
+ */
167
+ address: string
168
+ }
package/src/index.ts CHANGED
@@ -1,18 +1,9 @@
1
- import onFinished from 'on-finished'
2
- export * from './admin/adminMiddleware.js'
3
- export * from './admin/base.admin.service.js'
4
- export * from './admin/firebase.shared.service.js'
5
- export * from './admin/secureHeaderMiddleware.js'
6
1
  export * from './env/env.shared.service.js'
7
2
  export * from './sentry/sentry.shared.service.js'
8
3
  export * from './server/asyncLocalStorageMiddleware.js'
9
4
  export * from './server/basicAuthMiddleware.js'
10
5
  export * from './server/bodyParserTimeoutMiddleware.js'
11
- export * from './server/createDefaultApp.js'
12
- export * from './server/createDefaultApp.model.js'
13
- export * from './server/deployInfo.util.js'
14
6
  export * from './server/genericErrorMiddleware.js'
15
- export * from './server/getDefaultRouter.js'
16
7
  export * from './server/logMiddleware.js'
17
8
  export * from './server/methodOverrideMiddleware.js'
18
9
  export * from './server/notFoundMiddleware.js'
@@ -26,11 +17,4 @@ export * from './server/server.model.js'
26
17
  export * from './server/serverStatsMiddleware.js'
27
18
  export * from './server/serverStatusMiddleware.js'
28
19
  export * from './server/simpleRequestLoggerMiddleware.js'
29
- export * from './server/startServer.js'
30
- export * from './server/startServer.model.js'
31
- export * from './server/validation/ajvValidateRequest.js'
32
- export * from './server/validation/validateRequest.js'
33
- export * from './server/validation/zodValidateRequest.js'
34
20
  export * from './util.js'
35
-
36
- export { onFinished }
@@ -0,0 +1,3 @@
1
+ import onFinished from 'on-finished'
2
+
3
+ export { onFinished }
@@ -1,10 +1,11 @@
1
- import type { CommonLogger, CommonLogLevel, Primitive, StringMap } from '@naturalcycles/js-lib'
2
- import { _anyToError, _isErrorObject } from '@naturalcycles/js-lib'
1
+ import { _anyToError, _isErrorObject } from '@naturalcycles/js-lib/error'
2
+ import type { CommonLogger, CommonLogLevel } from '@naturalcycles/js-lib/log'
3
+ import type { Primitive, StringMap } from '@naturalcycles/js-lib/types'
3
4
  import type { InspectAnyOptions } from '@naturalcycles/nodejs-lib'
4
5
  import { _inspect } from '@naturalcycles/nodejs-lib'
5
6
  import type { Breadcrumb, SeverityLevel } from '@sentry/node'
6
7
  import type * as SentryLib from '@sentry/node'
7
- import { getRequestLogger } from '../index.js'
8
+ import { getRequestLogger } from '../server/asyncLocalStorageMiddleware.js'
8
9
 
9
10
  export interface SentrySharedServiceCfg {
10
11
  sentry: typeof SentryLib
@@ -1,6 +1,6 @@
1
1
  import { AsyncLocalStorage } from 'node:async_hooks'
2
- import type { CommonLogger } from '@naturalcycles/js-lib'
3
2
  import { _lazyValue } from '@naturalcycles/js-lib'
3
+ import type { CommonLogger } from '@naturalcycles/js-lib/log'
4
4
  import { ciLogger, devLogger, gcpStructuredLogger } from './logMiddleware.js'
5
5
  import type { BackendRequest, BackendRequestHandler } from './server.model.js'
6
6
 
@@ -1,5 +1,5 @@
1
- import type { StringMap } from '@naturalcycles/js-lib'
2
- import { _split } from '@naturalcycles/js-lib'
1
+ import { _split } from '@naturalcycles/js-lib/string'
2
+ import type { StringMap } from '@naturalcycles/js-lib/types'
3
3
  import { base64ToString, timingSafeStringEqual } from '@naturalcycles/nodejs-lib'
4
4
  import type { BackendRequestHandler } from './server.model.js'
5
5
 
@@ -1,6 +1,6 @@
1
- import { AppError } from '@naturalcycles/js-lib'
2
- import type { BackendRequestHandler } from '../index.js'
3
- import { respondWithError } from '../index.js'
1
+ import { AppError } from '@naturalcycles/js-lib/error'
2
+ import { respondWithError } from './genericErrorMiddleware.js'
3
+ import type { BackendRequestHandler } from './server.model.js'
4
4
 
5
5
  export interface BodyParserTimeoutMiddlewareCfg {
6
6
  /**
@@ -1,9 +1,6 @@
1
- import {
2
- _objectAssign,
3
- type BackendErrorResponseObject,
4
- type ErrorObject,
5
- } from '@naturalcycles/js-lib'
6
- import { _anyToError, _errorLikeToErrorObject } from '@naturalcycles/js-lib'
1
+ import type { BackendErrorResponseObject, ErrorObject } from '@naturalcycles/js-lib/error'
2
+ import { _anyToError, _errorLikeToErrorObject } from '@naturalcycles/js-lib/error'
3
+ import { _objectAssign } from '@naturalcycles/js-lib/types'
7
4
  import type { BackendErrorRequestHandler, BackendRequest, BackendResponse } from './server.model.js'
8
5
 
9
6
  export interface GenericErrorMiddlewareCfg {