@naturalcycles/backend-lib 9.13.0 → 9.15.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 (84) hide show
  1. package/dist/admin/adminMiddleware.js +5 -5
  2. package/dist/admin/base.admin.service.js +1 -1
  3. package/dist/admin/index.d.ts +4 -0
  4. package/dist/admin/index.js +4 -0
  5. package/dist/db/httpDBRequestHandler.js +2 -2
  6. package/dist/deploy/backend.cfg.util.js +3 -2
  7. package/dist/deploy/deploy.util.js +7 -5
  8. package/dist/deploy/deployGae.js +3 -2
  9. package/dist/deploy/deployHealthCheck.js +2 -1
  10. package/dist/{server → deploy}/deployInfo.util.d.ts +1 -1
  11. package/dist/{server → deploy}/deployInfo.util.js +1 -1
  12. package/dist/deploy/deployPrepare.js +3 -2
  13. package/dist/deploy/index.d.ts +1 -0
  14. package/dist/deploy/index.js +1 -0
  15. package/dist/env/env.shared.service.js +1 -1
  16. package/dist/{server/createDefaultApp.model.d.ts → express/createDefaultApp.d.ts} +3 -2
  17. package/dist/{server → express}/createDefaultApp.js +10 -10
  18. package/dist/{server → express}/getDefaultRouter.d.ts +1 -1
  19. package/dist/{server/startServer.model.d.ts → express/startServer.d.ts} +17 -2
  20. package/dist/{server → express}/startServer.js +2 -2
  21. package/dist/index.d.ts +0 -15
  22. package/dist/index.js +0 -15
  23. package/dist/onFinished.d.ts +2 -0
  24. package/dist/onFinished.js +2 -0
  25. package/dist/sentry/sentry.shared.service.js +1 -1
  26. package/dist/server/bodyParserTimeoutMiddleware.d.ts +1 -1
  27. package/dist/server/bodyParserTimeoutMiddleware.js +1 -1
  28. package/dist/server/logMiddleware.js +2 -1
  29. package/dist/server/request.log.util.js +1 -1
  30. package/dist/server/requestLoggerMiddleware.d.ts +1 -1
  31. package/dist/server/requestLoggerMiddleware.js +1 -1
  32. package/dist/server/requestTimeoutMiddleware.d.ts +1 -1
  33. package/dist/server/requestTimeoutMiddleware.js +3 -1
  34. package/dist/server/serverStatsMiddleware.d.ts +1 -1
  35. package/dist/server/serverStatsMiddleware.js +5 -3
  36. package/dist/server/serverStatusMiddleware.js +1 -1
  37. package/dist/server/simpleRequestLoggerMiddleware.d.ts +1 -1
  38. package/dist/server/simpleRequestLoggerMiddleware.js +2 -2
  39. package/dist/testing/express.test.service.d.ts +2 -2
  40. package/dist/testing/express.test.service.js +1 -1
  41. package/dist/{server/validation → validation/ajv}/ajvValidateRequest.d.ts +2 -2
  42. package/dist/{server/validation/validateRequest.d.ts → validation/joi/joiValidateRequest.d.ts} +1 -1
  43. package/dist/{server/validation → validation/zod}/zodValidateRequest.d.ts +2 -2
  44. package/package.json +11 -2
  45. package/src/admin/adminMiddleware.ts +5 -5
  46. package/src/admin/base.admin.service.ts +1 -1
  47. package/src/admin/index.ts +4 -0
  48. package/src/db/httpDBRequestHandler.ts +2 -2
  49. package/src/deploy/backend.cfg.util.ts +3 -2
  50. package/src/deploy/deploy.util.ts +7 -5
  51. package/src/deploy/deployGae.ts +3 -2
  52. package/src/deploy/deployHealthCheck.ts +2 -1
  53. package/src/{server → deploy}/deployInfo.util.ts +2 -2
  54. package/src/deploy/deployPrepare.ts +3 -2
  55. package/src/deploy/index.ts +2 -0
  56. package/src/env/env.shared.service.ts +1 -1
  57. package/src/{server → express}/createDefaultApp.ts +54 -16
  58. package/src/{server → express}/getDefaultRouter.ts +1 -1
  59. package/src/{server → express}/startServer.ts +44 -3
  60. package/src/index.ts +0 -16
  61. package/src/onFinished.ts +3 -0
  62. package/src/sentry/sentry.shared.service.ts +1 -1
  63. package/src/server/bodyParserTimeoutMiddleware.ts +2 -2
  64. package/src/server/logMiddleware.ts +2 -1
  65. package/src/server/request.log.util.ts +1 -1
  66. package/src/server/requestLoggerMiddleware.ts +2 -2
  67. package/src/server/requestTimeoutMiddleware.ts +4 -2
  68. package/src/server/serverStatsMiddleware.ts +6 -9
  69. package/src/server/serverStatusMiddleware.ts +1 -1
  70. package/src/server/simpleRequestLoggerMiddleware.ts +3 -3
  71. package/src/testing/express.test.service.ts +6 -3
  72. package/src/{server/validation → validation/ajv}/ajvValidateRequest.ts +2 -2
  73. package/src/{server/validation/validateRequest.ts → validation/joi/joiValidateRequest.ts} +1 -1
  74. package/src/{server/validation → validation/zod}/zodValidateRequest.ts +2 -2
  75. package/dist/server/createDefaultApp.d.ts +0 -3
  76. package/dist/server/createDefaultApp.model.js +0 -1
  77. package/dist/server/startServer.d.ts +0 -17
  78. package/dist/server/startServer.model.js +0 -1
  79. package/src/server/createDefaultApp.model.ts +0 -41
  80. package/src/server/startServer.model.ts +0 -44
  81. /package/dist/{server → express}/getDefaultRouter.js +0 -0
  82. /package/dist/{server/validation → validation/ajv}/ajvValidateRequest.js +0 -0
  83. /package/dist/{server/validation/validateRequest.js → validation/joi/joiValidateRequest.js} +0 -0
  84. /package/dist/{server/validation → validation/zod}/zodValidateRequest.js +0 -0
@@ -1,6 +1,5 @@
1
1
  import { _memoFn, AppError } from '@naturalcycles/js-lib';
2
- import { fs2 } from '@naturalcycles/nodejs-lib/fs';
3
- import ejs from 'ejs';
2
+ import { fs2 } from '@naturalcycles/nodejs-lib/fs2';
4
3
  import { srcDir } from '../paths.cnst.js';
5
4
  export function createAdminMiddleware(adminService, cfgDefaults = {}) {
6
5
  return (reqPermissions, cfg) => requireAdminPermissions(adminService, reqPermissions, {
@@ -37,17 +36,18 @@ export function requireAdminPermissions(adminService, reqPermissions = [], cfg =
37
36
  }
38
37
  export function loginHtml(firebaseServiceCfg) {
39
38
  const { apiKey: firebaseApiKey, authDomain: firebaseAuthDomain, adminAuthProvider: firebaseAuthProvider = 'GoogleAuthProvider', } = firebaseServiceCfg;
40
- return (_req, res) => {
41
- res.send(getLoginHtml({
39
+ return async (_req, res) => {
40
+ res.send(await getLoginHtml({
42
41
  firebaseApiKey,
43
42
  firebaseAuthDomain,
44
43
  firebaseAuthProvider,
45
44
  }));
46
45
  };
47
46
  }
48
- const getLoginHtml = _memoFn((cfg) => {
47
+ const getLoginHtml = _memoFn(async (cfg) => {
49
48
  console.log(`reading login.html`);
50
49
  const tmpl = fs2.readText(`${srcDir}/admin/login.html`);
50
+ const { default: ejs } = await import('ejs');
51
51
  return ejs.render(tmpl, cfg);
52
52
  });
53
53
  export function getLoginHtmlRedirect(href) {
@@ -1,5 +1,5 @@
1
1
  import { _assert, AppError } from '@naturalcycles/js-lib';
2
- import { dimGrey, green, red } from '@naturalcycles/nodejs-lib';
2
+ import { dimGrey, green, red } from '@naturalcycles/nodejs-lib/colors';
3
3
  const adminInfoDisabled = () => ({
4
4
  email: 'authDisabled',
5
5
  permissions: [],
@@ -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';
@@ -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,8 +1,8 @@
1
1
  import { DBQuery, InMemoryDB } from '@naturalcycles/db-lib';
2
2
  import { commonDBOptionsSchema, commonDBSaveOptionsSchema, dbQuerySchema, } from '@naturalcycles/db-lib/validation';
3
3
  import { anyObjectSchema, arraySchema, objectSchema, stringSchema, } from '@naturalcycles/nodejs-lib/joi';
4
- import { getDefaultRouter } from '../server/getDefaultRouter.js';
5
- import { validateRequest } from '../server/validation/validateRequest.js';
4
+ import { getDefaultRouter } from '../express/getDefaultRouter.js';
5
+ import { validateRequest } from '../validation/joi/joiValidateRequest.js';
6
6
  const getByIdsInputSchema = objectSchema({
7
7
  table: stringSchema,
8
8
  ids: arraySchema(stringSchema),
@@ -1,5 +1,6 @@
1
1
  import { AjvSchema } from '@naturalcycles/nodejs-lib/ajv';
2
- import { fs2 } from '@naturalcycles/nodejs-lib/fs';
2
+ import { fs2 } from '@naturalcycles/nodejs-lib/fs2';
3
+ import { yaml2 } from '@naturalcycles/nodejs-lib/yaml2';
3
4
  import { resourcesDir } from '../paths.cnst.js';
4
5
  const backendCfgSchema = AjvSchema.readJsonSync(`${resourcesDir}/backendCfg.schema.json`, {
5
6
  objectName: 'backend.cfg.yaml',
@@ -8,7 +9,7 @@ export function getBackendCfg(projectDir = '.') {
8
9
  const backendCfgYamlPath = `${projectDir}/backend.cfg.yaml`;
9
10
  fs2.requireFileToExist(backendCfgYamlPath);
10
11
  const backendCfg = {
11
- ...fs2.readYaml(backendCfgYamlPath),
12
+ ...yaml2.readYaml(backendCfgYamlPath),
12
13
  };
13
14
  backendCfgSchema.validate(backendCfg);
14
15
  return backendCfg;
@@ -1,6 +1,8 @@
1
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';
2
+ import { sha256 } from '@naturalcycles/nodejs-lib';
3
+ import { dimGrey, white } from '@naturalcycles/nodejs-lib/colors';
4
+ import { fs2 } from '@naturalcycles/nodejs-lib/fs2';
5
+ import { yaml2 } from '@naturalcycles/nodejs-lib/yaml2';
4
6
  const APP_YAML_DEFAULT = () => ({
5
7
  runtime: 'nodejs22',
6
8
  service: 'default',
@@ -77,7 +79,7 @@ export async function createDeployInfo(backendCfg, overrideBranch) {
77
79
  export function createAndSaveAppYaml(backendCfg, deployInfo, projectDir, targetDir, appYamlPassEnv = '') {
78
80
  const appYaml = createAppYaml(backendCfg, deployInfo, projectDir, appYamlPassEnv);
79
81
  const appYamlPath = `${targetDir}/app.yaml`;
80
- fs2.writeYaml(appYamlPath, appYaml);
82
+ yaml2.writeYaml(appYamlPath, appYaml);
81
83
  console.log(`saved ${dimGrey(appYamlPath)}`);
82
84
  return appYaml;
83
85
  }
@@ -94,12 +96,12 @@ export function createAppYaml(backendCfg, deployInfo, projectDir, appYamlPassEnv
94
96
  const appYamlPath = `${projectDir}/app.yaml`;
95
97
  if (fs2.pathExists(appYamlPath)) {
96
98
  console.log(`merging-in ${dimGrey(appYamlPath)}`);
97
- _merge(appYaml, fs2.readYaml(appYamlPath));
99
+ _merge(appYaml, yaml2.readYaml(appYamlPath));
98
100
  }
99
101
  const appEnvYamlPath = `${projectDir}/app.${APP_ENV}.yaml`;
100
102
  if (fs2.pathExists(appEnvYamlPath)) {
101
103
  console.log(`merging-in ${dimGrey(appEnvYamlPath)}`);
102
- _merge(appYaml, fs2.readYaml(appEnvYamlPath));
104
+ _merge(appYaml, yaml2.readYaml(appEnvYamlPath));
103
105
  }
104
106
  // appYamlPassEnv
105
107
  const passEnv = appYamlPassEnv
@@ -1,6 +1,7 @@
1
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';
2
+ import { appendToGithubSummary } from '@naturalcycles/nodejs-lib/env';
3
+ import { exec2 } from '@naturalcycles/nodejs-lib/exec2';
4
+ import { fs2 } from '@naturalcycles/nodejs-lib/fs2';
4
5
  import { getBackendCfg } from './backend.cfg.util.js';
5
6
  import { createDeployInfo } from './deploy.util.js';
6
7
  import { deployHealthCheck } from './deployHealthCheck.js';
@@ -1,6 +1,7 @@
1
1
  import { inspect } from 'node:util';
2
2
  import { _filterFalsyValues, _ms, _since, getFetcher, pDelay } from '@naturalcycles/js-lib';
3
- import { dimGrey, exec2, red } from '@naturalcycles/nodejs-lib';
3
+ import { dimGrey, red } from '@naturalcycles/nodejs-lib/colors';
4
+ import { exec2 } from '@naturalcycles/nodejs-lib/exec2';
4
5
  import { coloredHttpCode } from '../server/request.log.util.js';
5
6
  export const deployHealthCheckYargsOptions = {
6
7
  thresholdHealthy: {
@@ -1,2 +1,2 @@
1
- import type { DeployInfo } from '../deploy/index.js';
1
+ import type { DeployInfo } from './deploy.model.js';
2
2
  export declare const getDeployInfo: ((projectDir: string) => DeployInfo) & import("@naturalcycles/js-lib").MemoizedFunction;
@@ -1,5 +1,5 @@
1
1
  import { _memoFn, localTime } from '@naturalcycles/js-lib';
2
- import { fs2 } from '@naturalcycles/nodejs-lib/fs';
2
+ import { fs2 } from '@naturalcycles/nodejs-lib/fs2';
3
3
  export const getDeployInfo = _memoFn((projectDir) => {
4
4
  const deployInfoPath = `${projectDir}/deployInfo.json`;
5
5
  try {
@@ -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 { createAndSaveAppYaml, createAndSaveDeployInfo } from './deploy.util.js';
@@ -8,3 +8,4 @@ import { deployHealthCheck } from './deployHealthCheck.js';
8
8
  import { deployPrepare } from './deployPrepare.js';
9
9
  export type { BackendCfg, DeployHealthCheckOptions, DeployInfo };
10
10
  export { createAppYaml, createDeployInfo, deployGae, deployHealthCheck, deployPrepare, getBackendCfg, };
11
+ export * from './deployInfo.util.js';
@@ -4,3 +4,4 @@ import { deployGae } from './deployGae.js';
4
4
  import { deployHealthCheck } from './deployHealthCheck.js';
5
5
  import { deployPrepare } from './deployPrepare.js';
6
6
  export { createAppYaml, createDeployInfo, deployGae, deployHealthCheck, deployPrepare, getBackendCfg, };
7
+ export * from './deployInfo.util.js';
@@ -1,5 +1,5 @@
1
1
  import { _assert, _by } from '@naturalcycles/js-lib';
2
- import { dimGrey } from '@naturalcycles/nodejs-lib';
2
+ import { dimGrey } from '@naturalcycles/nodejs-lib/colors';
3
3
  export class EnvSharedService {
4
4
  constructor(cfg) {
5
5
  this.envMap = _by(cfg.environments, e => e.name);
@@ -1,8 +1,9 @@
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 './genericErrorMiddleware.js';
5
- import type { BackendRequestHandler } from './server.model.js';
4
+ import { type GenericErrorMiddlewareCfg } from '../server/genericErrorMiddleware.js';
5
+ import type { BackendApplication, BackendRequestHandler } from '../server/server.model.js';
6
+ export declare function createDefaultApp(cfg: DefaultAppCfg): Promise<BackendApplication>;
6
7
  /**
7
8
  * Plain RequestHandler can be provided - then it's mounted to /
8
9
  * Otherwise `path` can be provided to specify mounting point.
@@ -1,17 +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 { genericErrorMiddleware } from './genericErrorMiddleware.js';
6
- import { logMiddleware } from './logMiddleware.js';
7
- import { methodOverrideMiddleware } from './methodOverrideMiddleware.js';
8
- import { notFoundMiddleware } from './notFoundMiddleware.js';
9
- import { requestTimeoutMiddleware } from './requestTimeoutMiddleware.js';
10
- import { simpleRequestLoggerMiddleware } from './simpleRequestLoggerMiddleware.js';
1
+ import { asyncLocalStorageMiddleware } from '../server/asyncLocalStorageMiddleware.js';
2
+ import { genericErrorMiddleware, } from '../server/genericErrorMiddleware.js';
3
+ import { logMiddleware } from '../server/logMiddleware.js';
4
+ import { methodOverrideMiddleware } from '../server/methodOverrideMiddleware.js';
5
+ import { notFoundMiddleware } from '../server/notFoundMiddleware.js';
6
+ import { requestTimeoutMiddleware } from '../server/requestTimeoutMiddleware.js';
7
+ import { simpleRequestLoggerMiddleware } from '../server/simpleRequestLoggerMiddleware.js';
11
8
  const isTest = process.env['APP_ENV'] === 'test';
12
9
  const isDev = process.env['APP_ENV'] === 'dev';
13
10
  export async function createDefaultApp(cfg) {
14
11
  const { sentryService } = cfg;
12
+ const { default: express } = await import('express');
13
+ const { default: cors } = await import('cors');
14
+ const { default: cookieParser } = await import('cookie-parser');
15
15
  const app = express();
16
16
  app.disable('etag');
17
17
  app.disable('x-powered-by');
@@ -1,4 +1,4 @@
1
- import type { BackendRequestHandler, BackendRouter } from './server.model.js';
1
+ import type { BackendRequestHandler, BackendRouter } from '../server/server.model.js';
2
2
  /**
3
3
  * Convenience method.
4
4
  */
@@ -1,7 +1,22 @@
1
1
  import type { Server } from 'node:http';
2
2
  import type { SentrySharedService } from '../sentry/sentry.shared.service.js';
3
- import type { DefaultAppCfg } from './createDefaultApp.model.js';
4
- import type { BackendApplication } from './server.model.js';
3
+ import type { BackendApplication } from '../server/server.model.js';
4
+ import { type DefaultAppCfg } from './createDefaultApp.js';
5
+ export declare class BackendServer {
6
+ private cfg;
7
+ constructor(cfg: StartServerCfg);
8
+ server?: Server;
9
+ start(): Promise<StartServerData>;
10
+ /**
11
+ * Gracefully shuts down the server.
12
+ * Does `process.exit()` in the end.
13
+ */
14
+ stop(reason: string): Promise<void>;
15
+ }
16
+ /**
17
+ * Convenience function.
18
+ */
19
+ export declare function startServer(cfg: StartServerCfg): Promise<StartServerData>;
5
20
  /**
6
21
  * If DefaultAppCfg.resources is passed and `expressApp` is not passed - it will call createDefaultApp(cfg).
7
22
  */
@@ -1,8 +1,8 @@
1
1
  import { __decorate } from "tslib";
2
2
  import os from 'node:os';
3
3
  import { _Memo, _ms } from '@naturalcycles/js-lib';
4
- import { boldGrey, dimGrey, white } from '@naturalcycles/nodejs-lib';
5
- import { createDefaultApp } from '../index.js';
4
+ import { boldGrey, dimGrey, white } from '@naturalcycles/nodejs-lib/colors';
5
+ import { createDefaultApp } from './createDefaultApp.js';
6
6
  const { NODE_OPTIONS, APP_ENV } = process.env;
7
7
  export class BackendServer {
8
8
  cfg;
package/dist/index.d.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,10 +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
- export { onFinished };
package/dist/index.js 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,10 +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
- export { onFinished };
@@ -0,0 +1,2 @@
1
+ import onFinished from 'on-finished';
2
+ export { onFinished };
@@ -0,0 +1,2 @@
1
+ import onFinished from 'on-finished';
2
+ export { onFinished };
@@ -1,6 +1,6 @@
1
1
  import { _anyToError, _isErrorObject } from '@naturalcycles/js-lib';
2
2
  import { _inspect } from '@naturalcycles/nodejs-lib';
3
- import { getRequestLogger } from '../index.js';
3
+ import { getRequestLogger } from '../server/asyncLocalStorageMiddleware.js';
4
4
  const sentrySeverityMap = {
5
5
  debug: 'log',
6
6
  info: 'log',
@@ -1,4 +1,4 @@
1
- import type { BackendRequestHandler } from '../index.js';
1
+ import type { BackendRequestHandler } from './server.model.js';
2
2
  export interface BodyParserTimeoutMiddlewareCfg {
3
3
  /**
4
4
  * @default 10
@@ -1,5 +1,5 @@
1
1
  import { AppError } from '@naturalcycles/js-lib';
2
- import { respondWithError } from '../index.js';
2
+ import { respondWithError } from './genericErrorMiddleware.js';
3
3
  const code = 'BODY_PARSER_TIMEOUT';
4
4
  /**
5
5
  * Should be called BEFORE bodyParser
@@ -1,5 +1,6 @@
1
1
  import { inspect } from 'node:util';
2
- import { _inspect, dimGrey } from '@naturalcycles/nodejs-lib';
2
+ import { _inspect } from '@naturalcycles/nodejs-lib';
3
+ import { dimGrey } from '@naturalcycles/nodejs-lib/colors';
3
4
  const { GOOGLE_CLOUD_PROJECT, GAE_INSTANCE, K_SERVICE, APP_ENV } = process.env;
4
5
  const isGAE = !!GAE_INSTANCE;
5
6
  const isCloudRun = !!K_SERVICE;
@@ -1,4 +1,4 @@
1
- import { boldGrey, green, red, yellow } from '@naturalcycles/nodejs-lib';
1
+ import { boldGrey, green, red, yellow } from '@naturalcycles/nodejs-lib/colors';
2
2
  export function logRequestWithColors(req, statusCode, ...tokens) {
3
3
  req[logLevel(statusCode)]([coloredHttpCode(statusCode), req.method, boldGrey(req.url), ...tokens].join(' '));
4
4
  }
@@ -1,4 +1,4 @@
1
- import type { BackendRequest, BackendRequestHandler } from '../index.js';
1
+ import type { BackendRequest, BackendRequestHandler } from './server.model.js';
2
2
  export interface RequestLoggerMiddlewareCfg {
3
3
  /**
4
4
  * If set - this prefix will be removed from the request url before logging.
@@ -1,5 +1,5 @@
1
1
  import { _since } from '@naturalcycles/js-lib';
2
- import { onFinished } from '../index.js';
2
+ import { onFinished } from '../onFinished.js';
3
3
  /**
4
4
  * Experimental request logger for Cloud Run.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  import type { NumberOfSeconds } from '@naturalcycles/js-lib';
2
- import type { BackendRequest, BackendRequestHandler, BackendResponse } from '../index.js';
2
+ import type { BackendRequest, BackendRequestHandler, BackendResponse } from './server.model.js';
3
3
  export interface RequestTimeoutMiddlewareCfg {
4
4
  /**
5
5
  * @default 120
@@ -1,5 +1,7 @@
1
1
  import { _ms, AppError } from '@naturalcycles/js-lib';
2
- import { getRequestEndpoint, onFinished, respondWithError } from '../index.js';
2
+ import { onFinished } from '../onFinished.js';
3
+ import { respondWithError } from './genericErrorMiddleware.js';
4
+ import { getRequestEndpoint } from './request.util.js';
3
5
  const code = 'REQUEST_TIMEOUT';
4
6
  const REQUEST_TIMEOUT_QUERY_KEY = 'requestTimeout';
5
7
  export function requestTimeoutMiddleware(cfg = {}) {
@@ -1,4 +1,4 @@
1
- import type { BackendRequestHandler } from '../index.js';
1
+ import type { BackendRequestHandler } from './server.model.js';
2
2
  /**
3
3
  * Depends on serverStatsMiddleware to work.
4
4
  *
@@ -1,5 +1,5 @@
1
1
  import { _get, _mapValues, _mb, _ms, _percentile, _sortBy, _stringMapEntries, _stringMapValues, _sum, NumberStack, } from '@naturalcycles/js-lib';
2
- import { onFinished } from '../index.js';
2
+ import { onFinished } from '../onFinished.js';
3
3
  import { getRequestEndpoint } from './request.util.js';
4
4
  const { GAE_INSTANCE } = process.env;
5
5
  const serverStatsMap = {};
@@ -20,7 +20,7 @@ export const serverStatsHTMLHandler = (req, res) => {
20
20
  // calc things
21
21
  _stringMapValues(serverStatsMap).forEach(s => {
22
22
  s.total = s['2xx'] + s['4xx'] + s['5xx'];
23
- s.pc = _mapValues(s.stack.percentiles(percentiles), (_k, v) => Math.round(v), true);
23
+ s.pc = _mapValues(s.stack.percentiles(percentiles), (_k, v) => Math.round(v), { mutate: true });
24
24
  });
25
25
  const allLatencies = _stringMapValues(serverStatsMap).flatMap(s => s.stack.items);
26
26
  const all2xx = _sum(_stringMapValues(serverStatsMap).flatMap(s => s['2xx']));
@@ -49,7 +49,9 @@ export const serverStatsHTMLHandler = (req, res) => {
49
49
  `<td align="right"><pre>${all5xx}</pre></td>`,
50
50
  ...percentiles.map(pc => `<td align="right"><pre>${Math.round(_percentile(allLatencies, pc))}</pre></td>`),
51
51
  `</tr>`,
52
- ..._sortBy(_stringMapEntries(serverStatsMap), ([_, stat]) => _get(stat, sortBy), false, asc ? 'asc' : 'desc').map(([endpoint, stat]) => {
52
+ ..._sortBy(_stringMapEntries(serverStatsMap), ([_, stat]) => _get(stat, sortBy), {
53
+ dir: asc ? 'asc' : 'desc',
54
+ }).map(([endpoint, stat]) => {
53
55
  return [
54
56
  '<tr>',
55
57
  `<td><pre>${endpoint}</pre></td>`,
@@ -1,6 +1,6 @@
1
1
  import { _filterNullishValues, localTime } from '@naturalcycles/js-lib';
2
2
  import { memoryUsageFull, processSharedUtil } from '@naturalcycles/nodejs-lib';
3
- import { getDeployInfo } from './deployInfo.util.js';
3
+ import { getDeployInfo } from '../deploy/deployInfo.util.js';
4
4
  const { versions, arch, platform } = process;
5
5
  const { GAE_APPLICATION, GAE_SERVICE, GAE_VERSION, GOOGLE_CLOUD_PROJECT, K_SERVICE, K_REVISION, APP_ENV, NODE_OPTIONS, DEPLOY_BUILD_TIME, } = process.env;
6
6
  export function serverStatusMiddleware(projectDir, extra) {
@@ -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
1
  import { _since } from '@naturalcycles/js-lib';
2
- import { boldGrey, dimGrey } from '@naturalcycles/nodejs-lib';
3
- import { onFinished } from '../index.js';
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
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';
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,5 @@
1
1
  import { getFetcher, pDelay } from '@naturalcycles/js-lib';
2
- import { createDefaultApp } from '../index.js';
2
+ import { createDefaultApp, } from '../express/createDefaultApp.js';
3
3
  const nativeFetchFn = async (url, init) => await globalThis.fetch(url, init);
4
4
  // Example:
5
5
  // 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,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,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;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@naturalcycles/backend-lib",
3
3
  "type": "module",
4
- "version": "9.13.0",
4
+ "version": "9.15.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,5 @@
1
1
  import { _memoFn, AppError } from '@naturalcycles/js-lib'
2
- import { fs2 } from '@naturalcycles/nodejs-lib/fs'
3
- import ejs from 'ejs'
2
+ import { fs2 } from '@naturalcycles/nodejs-lib/fs2'
4
3
  import { srcDir } from '../paths.cnst.js'
5
4
  import type { BackendRequestHandler } from '../server/server.model.js'
6
5
  import type { BaseAdminService } from './base.admin.service.js'
@@ -89,9 +88,9 @@ export function loginHtml(firebaseServiceCfg: FirebaseSharedServiceCfg): Backend
89
88
  adminAuthProvider: firebaseAuthProvider = 'GoogleAuthProvider',
90
89
  } = firebaseServiceCfg
91
90
 
92
- return (_req, res) => {
91
+ return async (_req, res) => {
93
92
  res.send(
94
- getLoginHtml({
93
+ await getLoginHtml({
95
94
  firebaseApiKey,
96
95
  firebaseAuthDomain,
97
96
  firebaseAuthProvider,
@@ -100,9 +99,10 @@ export function loginHtml(firebaseServiceCfg: FirebaseSharedServiceCfg): Backend
100
99
  }
101
100
  }
102
101
 
103
- const getLoginHtml = _memoFn((cfg: LoginHtmlCfg) => {
102
+ const getLoginHtml = _memoFn(async (cfg: LoginHtmlCfg) => {
104
103
  console.log(`reading login.html`)
105
104
  const tmpl = fs2.readText(`${srcDir}/admin/login.html`)
105
+ const { default: ejs } = await import('ejs')
106
106
  return ejs.render(tmpl, cfg)
107
107
  })
108
108
 
@@ -1,5 +1,5 @@
1
1
  import { _assert, AppError } from '@naturalcycles/js-lib'
2
- import { dimGrey, green, red } from '@naturalcycles/nodejs-lib'
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
 
@@ -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'
@@ -12,9 +12,9 @@ import {
12
12
  objectSchema,
13
13
  stringSchema,
14
14
  } from '@naturalcycles/nodejs-lib/joi'
15
- import { getDefaultRouter } from '../server/getDefaultRouter.js'
15
+ import { getDefaultRouter } from '../express/getDefaultRouter.js'
16
16
  import type { BackendRouter } from '../server/server.model.js'
17
- import { validateRequest } from '../server/validation/validateRequest.js'
17
+ import { validateRequest } from '../validation/joi/joiValidateRequest.js'
18
18
 
19
19
  export interface GetByIdsInput {
20
20
  table: string