@naturalcycles/backend-lib 4.18.8 → 4.19.1
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/cfg/tsconfig.json +16 -12
- package/dist/admin/adminMiddleware.js +5 -4
- package/dist/admin/base.admin.service.d.ts +1 -1
- package/dist/admin/firebase.shared.service.d.ts +1 -1
- package/dist/admin/login.html +1 -1
- package/dist/bin/deploy-gae.js +3 -2
- package/dist/bin/deploy-health-check.js +3 -2
- package/dist/bin/deploy-prepare.js +3 -2
- package/dist/db/httpDB.d.ts +1 -1
- package/dist/db/httpDB.js +1 -1
- package/dist/deploy/backend.cfg.util.js +3 -2
- package/dist/deploy/deploy.util.js +9 -8
- package/dist/deploy/deployHealthCheck.js +5 -6
- package/dist/deploy/deployPrepare.js +4 -6
- package/dist/paths.cnst.js +3 -2
- package/dist/server/appEngineLogMiddleware.js +2 -3
- package/dist/server/createDefaultApp.js +1 -1
- package/dist/server/createDefaultApp.model.d.ts +1 -1
- package/dist/server/deployInfo.util.js +3 -2
- package/dist/server/getDefaultRouter.js +2 -1
- package/dist/server/validateMiddleware.d.ts +1 -1
- package/dist/server/zodValidateMiddleware.d.ts +1 -1
- package/dist/testing/express.test.service.js +6 -4
- package/package.json +2 -5
- package/readme.md +1 -1
- package/src/admin/adminMiddleware.ts +2 -2
- package/src/admin/base.admin.service.ts +5 -2
- package/src/admin/firebase.shared.service.ts +1 -1
- package/src/admin/login.html +1 -1
- package/src/bin/deploy-gae.ts +1 -1
- package/src/bin/deploy-health-check.ts +1 -1
- package/src/bin/deploy-prepare.ts +1 -1
- package/src/db/httpDB.ts +7 -7
- package/src/deploy/backend.cfg.util.ts +1 -1
- package/src/deploy/deploy.util.ts +15 -12
- package/src/deploy/deployHealthCheck.ts +1 -2
- package/src/deploy/deployPrepare.ts +1 -3
- package/src/paths.cnst.ts +1 -1
- package/src/sentry/sentry.shared.service.ts +2 -0
- package/src/server/appEngineLogMiddleware.ts +1 -2
- package/src/server/asyncLocalStorageMiddleware.ts +1 -1
- package/src/server/createDefaultApp.model.ts +1 -1
- package/src/server/createDefaultApp.ts +2 -2
- package/src/server/deployInfo.util.ts +1 -1
- package/src/server/validateMiddleware.ts +1 -1
- package/src/server/zodValidateMiddleware.ts +1 -1
- package/src/testing/express.test.service.ts +7 -12
package/cfg/tsconfig.json
CHANGED
|
@@ -8,13 +8,27 @@
|
|
|
8
8
|
// Target/module
|
|
9
9
|
"target": "es2022",
|
|
10
10
|
"lib": ["esnext"], // add "dom" if needed
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
// module `nodenext` is a modern mode that auto-detects cjs/esm
|
|
12
|
+
// it also defaults `esModuleInterop` and `allowSyntheticDefaultImports` to true
|
|
13
|
+
"module": "nodenext",
|
|
14
|
+
"moduleResolution": "nodenext",
|
|
13
15
|
"moduleDetection": "force",
|
|
16
|
+
// specifying these explicitly for better IDE compatibility (but they're on by default with module=nodenext)
|
|
17
|
+
"esModuleInterop": true,
|
|
18
|
+
"allowSyntheticDefaultImports": true,
|
|
19
|
+
// Faster compilation in general
|
|
20
|
+
// Support for external compilers (e.g esbuild)
|
|
21
|
+
// Speedup in Jest by using "isolatedModules" in 'ts-jest' config
|
|
22
|
+
"isolatedModules": true,
|
|
14
23
|
|
|
15
24
|
// Emit
|
|
16
25
|
"sourceMap": false,
|
|
17
26
|
"declaration": false,
|
|
27
|
+
// Otherwise since es2022 it defaults to true
|
|
28
|
+
// and starts to produce different/unexpected behavior
|
|
29
|
+
// https://angular.schule/blog/2022-11-use-define-for-class-fields
|
|
30
|
+
"useDefineForClassFields": false,
|
|
31
|
+
"importHelpers": true,
|
|
18
32
|
|
|
19
33
|
// Strictness
|
|
20
34
|
"strict": true,
|
|
@@ -25,19 +39,10 @@
|
|
|
25
39
|
"noImplicitOverride": true,
|
|
26
40
|
"noUncheckedIndexedAccess": true,
|
|
27
41
|
"noPropertyAccessFromIndexSignature": true,
|
|
28
|
-
// Otherwise since es2022 it defaults to true
|
|
29
|
-
// and starts to produce different/unexpected behavior
|
|
30
|
-
// https://angular.schule/blog/2022-11-use-define-for-class-fields
|
|
31
|
-
"useDefineForClassFields": false,
|
|
32
42
|
|
|
33
43
|
// Enabled should be faster, but will catch less errors
|
|
34
44
|
// "skipLibCheck": true,
|
|
35
45
|
|
|
36
|
-
// Faster compilation in general
|
|
37
|
-
// Support for external compilers (e.g esbuild)
|
|
38
|
-
// Speedup in Jest by using "isolatedModules" in 'ts-jest' config
|
|
39
|
-
"isolatedModules": true,
|
|
40
|
-
|
|
41
46
|
// Disabled because of https://github.com/Microsoft/TypeScript/issues/29172
|
|
42
47
|
// Need to be specified in the project tsconfig
|
|
43
48
|
// "outDir": "dist",
|
|
@@ -54,7 +59,6 @@
|
|
|
54
59
|
// Other
|
|
55
60
|
"pretty": true,
|
|
56
61
|
"newLine": "lf",
|
|
57
|
-
"importHelpers": true,
|
|
58
62
|
"experimentalDecorators": true
|
|
59
63
|
}
|
|
60
64
|
// Need to be specified in the project tsconfig
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getLoginHtmlRedirect = exports.loginHtml = exports.requireAdminPermissions = exports.createAdminMiddleware = void 0;
|
|
4
|
-
const
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const node_fs_1 = tslib_1.__importDefault(require("node:fs"));
|
|
5
6
|
const js_lib_1 = require("@naturalcycles/js-lib");
|
|
6
|
-
const
|
|
7
|
+
const ejs_1 = tslib_1.__importDefault(require("ejs"));
|
|
7
8
|
function createAdminMiddleware(adminService, cfgDefaults = {}) {
|
|
8
9
|
return (reqPermissions, cfg) => requireAdminPermissions(adminService, reqPermissions, {
|
|
9
10
|
...cfgDefaults,
|
|
@@ -52,8 +53,8 @@ function loginHtml(firebaseServiceCfg) {
|
|
|
52
53
|
exports.loginHtml = loginHtml;
|
|
53
54
|
const getLoginHtml = (0, js_lib_1._memoFn)((cfg) => {
|
|
54
55
|
console.log(`reading login.html`);
|
|
55
|
-
const tmpl =
|
|
56
|
-
return
|
|
56
|
+
const tmpl = node_fs_1.default.readFileSync(`${__dirname}/login.html`, 'utf8');
|
|
57
|
+
return ejs_1.default.render(tmpl, cfg);
|
|
57
58
|
});
|
|
58
59
|
function getLoginHtmlRedirect(href) {
|
|
59
60
|
return `
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AppOptions, ServiceAccount } from 'firebase-admin';
|
|
2
|
-
import type
|
|
2
|
+
import type FirebaseAdmin from 'firebase-admin';
|
|
3
3
|
export interface FirebaseSharedServiceCfg {
|
|
4
4
|
/**
|
|
5
5
|
* If undefined - will try to use credential.applicationDefault()
|
package/dist/admin/login.html
CHANGED
package/dist/bin/deploy-gae.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
"use strict";
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
4
5
|
const nodejs_lib_1 = require("@naturalcycles/nodejs-lib");
|
|
5
|
-
const
|
|
6
|
+
const yargs_1 = tslib_1.__importDefault(require("yargs"));
|
|
6
7
|
const deployGae_1 = require("../deploy/deployGae");
|
|
7
8
|
const deployHealthCheck_1 = require("../deploy/deployHealthCheck");
|
|
8
9
|
const deployPrepare_1 = require("../deploy/deployPrepare");
|
|
9
10
|
(0, nodejs_lib_1.runScript)(async () => {
|
|
10
|
-
const opt =
|
|
11
|
+
const opt = yargs_1.default.options({
|
|
11
12
|
...deployPrepare_1.deployPrepareYargsOptions,
|
|
12
13
|
...deployHealthCheck_1.deployHealthCheckYargsOptions,
|
|
13
14
|
}).argv;
|
|
@@ -9,11 +9,12 @@ yarn deploy-health-check --url https://service-dot-yourproject.appspot.com
|
|
|
9
9
|
|
|
10
10
|
*/
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const tslib_1 = require("tslib");
|
|
12
13
|
const nodejs_lib_1 = require("@naturalcycles/nodejs-lib");
|
|
13
|
-
const
|
|
14
|
+
const yargs_1 = tslib_1.__importDefault(require("yargs"));
|
|
14
15
|
const deployHealthCheck_1 = require("../deploy/deployHealthCheck");
|
|
15
16
|
(0, nodejs_lib_1.runScript)(async () => {
|
|
16
|
-
const { url, ...opt } =
|
|
17
|
+
const { url, ...opt } = yargs_1.default.options({
|
|
17
18
|
...deployHealthCheck_1.deployHealthCheckYargsOptions,
|
|
18
19
|
url: {
|
|
19
20
|
type: 'string',
|
|
@@ -6,11 +6,12 @@ yarn deploy-prepare
|
|
|
6
6
|
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
const tslib_1 = require("tslib");
|
|
9
10
|
const nodejs_lib_1 = require("@naturalcycles/nodejs-lib");
|
|
10
|
-
const
|
|
11
|
+
const yargs_1 = tslib_1.__importDefault(require("yargs"));
|
|
11
12
|
const deployPrepare_1 = require("../deploy/deployPrepare");
|
|
12
13
|
(0, nodejs_lib_1.runScript)(async () => {
|
|
13
|
-
const opt =
|
|
14
|
+
const opt = yargs_1.default.options(deployPrepare_1.deployPrepareYargsOptions).argv;
|
|
14
15
|
await (0, deployPrepare_1.deployPrepare)(opt);
|
|
15
16
|
});
|
|
16
17
|
// deploy strategy
|
package/dist/db/httpDB.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { FetcherOptions, JsonSchemaRootObject, ObjectWithId } from '@naturalcycles/js-lib';
|
|
2
1
|
import { BaseCommonDB, CommonDB, CommonDBOptions, CommonDBSaveOptions, CommonDBStreamOptions, DBQuery, RunQueryResult } from '@naturalcycles/db-lib';
|
|
2
|
+
import { FetcherOptions, JsonSchemaRootObject, ObjectWithId } from '@naturalcycles/js-lib';
|
|
3
3
|
import { ReadableTyped } from '@naturalcycles/nodejs-lib';
|
|
4
4
|
export interface HttpDBCfg extends FetcherOptions {
|
|
5
5
|
baseUrl: string;
|
package/dist/db/httpDB.js
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.HttpDB = void 0;
|
|
4
4
|
const node_stream_1 = require("node:stream");
|
|
5
|
-
const js_lib_1 = require("@naturalcycles/js-lib");
|
|
6
5
|
const db_lib_1 = require("@naturalcycles/db-lib");
|
|
6
|
+
const js_lib_1 = require("@naturalcycles/js-lib");
|
|
7
7
|
/**
|
|
8
8
|
* Implementation of CommonDB that proxies all requests via HTTP to "httpDBRequestHandler".
|
|
9
9
|
*/
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getBackendCfg = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
4
5
|
const nodejs_lib_1 = require("@naturalcycles/nodejs-lib");
|
|
5
|
-
const
|
|
6
|
+
const js_yaml_1 = tslib_1.__importDefault(require("js-yaml"));
|
|
6
7
|
const paths_cnst_1 = require("../paths.cnst");
|
|
7
8
|
const backendCfgSchema = nodejs_lib_1.AjvSchema.readJsonSync(`${paths_cnst_1.resourcesDir}/backendCfg.schema.json`, {
|
|
8
9
|
objectName: 'backend.cfg.yaml',
|
|
@@ -12,7 +13,7 @@ function getBackendCfg(projectDir = '.') {
|
|
|
12
13
|
(0, nodejs_lib_1.requireFileToExist)(backendCfgYamlPath);
|
|
13
14
|
const backendCfg = {
|
|
14
15
|
serviceWithBranchName: true,
|
|
15
|
-
...
|
|
16
|
+
...js_yaml_1.default.load((0, nodejs_lib_1._readFileSync)(backendCfgYamlPath)),
|
|
16
17
|
};
|
|
17
18
|
backendCfgSchema.validate(backendCfg);
|
|
18
19
|
return backendCfg;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.validateGAEServiceName = exports.createAppYaml = exports.createAndSaveAppYaml = exports.createDeployInfo = exports.createAndSaveDeployInfo = void 0;
|
|
4
|
-
const
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const node_fs_1 = tslib_1.__importDefault(require("node:fs"));
|
|
5
6
|
const js_lib_1 = require("@naturalcycles/js-lib");
|
|
6
7
|
const nodejs_lib_1 = require("@naturalcycles/nodejs-lib");
|
|
7
|
-
const
|
|
8
|
+
const js_yaml_1 = tslib_1.__importDefault(require("js-yaml"));
|
|
8
9
|
const APP_YAML_DEFAULT = () => ({
|
|
9
10
|
runtime: 'nodejs18',
|
|
10
11
|
service: 'default',
|
|
@@ -26,7 +27,7 @@ const APP_YAML_DEFAULT = () => ({
|
|
|
26
27
|
async function createAndSaveDeployInfo(backendCfg, targetDir) {
|
|
27
28
|
const deployInfo = await createDeployInfo(backendCfg);
|
|
28
29
|
const deployInfoPath = `${targetDir}/deployInfo.json`;
|
|
29
|
-
|
|
30
|
+
node_fs_1.default.writeFileSync(deployInfoPath, JSON.stringify(deployInfo, null, 2));
|
|
30
31
|
console.log(`saved ${(0, nodejs_lib_1.dimGrey)(deployInfoPath)}`);
|
|
31
32
|
return deployInfo;
|
|
32
33
|
}
|
|
@@ -73,7 +74,7 @@ exports.createDeployInfo = createDeployInfo;
|
|
|
73
74
|
function createAndSaveAppYaml(backendCfg, deployInfo, projectDir, targetDir, appYamlPassEnv = '') {
|
|
74
75
|
const appYaml = createAppYaml(backendCfg, deployInfo, projectDir, appYamlPassEnv);
|
|
75
76
|
const appYamlPath = `${targetDir}/app.yaml`;
|
|
76
|
-
|
|
77
|
+
node_fs_1.default.writeFileSync(appYamlPath, js_yaml_1.default.dump(appYaml));
|
|
77
78
|
console.log(`saved ${(0, nodejs_lib_1.dimGrey)(appYamlPath)}`);
|
|
78
79
|
return appYaml;
|
|
79
80
|
}
|
|
@@ -89,14 +90,14 @@ function createAppYaml(backendCfg, deployInfo, projectDir, appYamlPassEnv = '')
|
|
|
89
90
|
const appYaml = APP_YAML_DEFAULT();
|
|
90
91
|
// Check existing app.yaml
|
|
91
92
|
const appYamlPath = `${projectDir}/app.yaml`;
|
|
92
|
-
if (
|
|
93
|
+
if (node_fs_1.default.existsSync(appYamlPath)) {
|
|
93
94
|
console.log(`merging-in ${(0, nodejs_lib_1.dimGrey)(appYamlPath)}`);
|
|
94
|
-
(0, js_lib_1._merge)(appYaml,
|
|
95
|
+
(0, js_lib_1._merge)(appYaml, js_yaml_1.default.load(node_fs_1.default.readFileSync(appYamlPath, 'utf8')));
|
|
95
96
|
}
|
|
96
97
|
const appEnvYamlPath = `${projectDir}/app.${APP_ENV}.yaml`;
|
|
97
|
-
if (
|
|
98
|
+
if (node_fs_1.default.existsSync(appEnvYamlPath)) {
|
|
98
99
|
console.log(`merging-in ${(0, nodejs_lib_1.dimGrey)(appEnvYamlPath)}`);
|
|
99
|
-
(0, js_lib_1._merge)(appYaml,
|
|
100
|
+
(0, js_lib_1._merge)(appYaml, js_yaml_1.default.load(node_fs_1.default.readFileSync(appEnvYamlPath, 'utf8')));
|
|
100
101
|
}
|
|
101
102
|
// appYamlPassEnv
|
|
102
103
|
require('dotenv').config(); // ensure .env is read
|
|
@@ -2,9 +2,8 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.deployHealthCheck = exports.deployHealthCheckYargsOptions = void 0;
|
|
4
4
|
const node_util_1 = require("node:util");
|
|
5
|
-
const nodejs_lib_1 = require("@naturalcycles/nodejs-lib");
|
|
6
5
|
const js_lib_1 = require("@naturalcycles/js-lib");
|
|
7
|
-
const
|
|
6
|
+
const nodejs_lib_1 = require("@naturalcycles/nodejs-lib");
|
|
8
7
|
const request_log_util_1 = require("../server/request.log.util");
|
|
9
8
|
exports.deployHealthCheckYargsOptions = {
|
|
10
9
|
thresholdHealthy: {
|
|
@@ -70,7 +69,7 @@ async function deployHealthCheck(url, opt = {}) {
|
|
|
70
69
|
await makeAttempt();
|
|
71
70
|
}
|
|
72
71
|
if (failed) {
|
|
73
|
-
console.log((0,
|
|
72
|
+
console.log((0, nodejs_lib_1.red)(`Health check failed!`));
|
|
74
73
|
if (logOnFailure) {
|
|
75
74
|
try {
|
|
76
75
|
(0, nodejs_lib_1.execVoidCommandSync)(`gcloud app logs read --project ${gaeProject} --service ${gaeService} --version ${gaeVersion}`, [], { shell: true });
|
|
@@ -87,7 +86,7 @@ async function deployHealthCheck(url, opt = {}) {
|
|
|
87
86
|
}
|
|
88
87
|
async function makeAttempt() {
|
|
89
88
|
attempt++;
|
|
90
|
-
console.log([`>>`, (0,
|
|
89
|
+
console.log([`>>`, (0, nodejs_lib_1.dimGrey)(url), (0, node_util_1.inspect)({ attempt }, inspectOpt)].join(' '));
|
|
91
90
|
const started = Date.now();
|
|
92
91
|
const { err, statusCode = 0 } = await fetcher.doFetch({
|
|
93
92
|
url,
|
|
@@ -123,7 +122,7 @@ async function deployHealthCheck(url, opt = {}) {
|
|
|
123
122
|
console.log([
|
|
124
123
|
`<< HTTP`,
|
|
125
124
|
(0, request_log_util_1.coloredHttpCode)(statusCode),
|
|
126
|
-
(0,
|
|
125
|
+
(0, nodejs_lib_1.dimGrey)((0, js_lib_1._since)(started)),
|
|
127
126
|
(0, node_util_1.inspect)((0, js_lib_1._filterFalsyValues)({ countHealthy, countUnhealthy }), inspectOpt),
|
|
128
127
|
].join(' '));
|
|
129
128
|
if (attempt >= maxTries) {
|
|
@@ -135,7 +134,7 @@ async function deployHealthCheck(url, opt = {}) {
|
|
|
135
134
|
console.log(doneReason);
|
|
136
135
|
}
|
|
137
136
|
else {
|
|
138
|
-
console.log((0,
|
|
137
|
+
console.log((0, nodejs_lib_1.dimGrey)(`... waiting ${(0, js_lib_1._ms)(currentInterval)} ...`));
|
|
139
138
|
await (0, js_lib_1.pDelay)(currentInterval);
|
|
140
139
|
}
|
|
141
140
|
}
|
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.deployPrepare = exports.deployPrepareYargsOptions = void 0;
|
|
4
4
|
const nodejs_lib_1 = require("@naturalcycles/nodejs-lib");
|
|
5
|
-
const nodejs_lib_2 = require("@naturalcycles/nodejs-lib");
|
|
6
|
-
const nodejs_lib_3 = require("@naturalcycles/nodejs-lib");
|
|
7
5
|
const paths_cnst_1 = require("../paths.cnst");
|
|
8
6
|
const backend_cfg_util_1 = require("./backend.cfg.util");
|
|
9
7
|
const deploy_util_1 = require("./deploy.util");
|
|
@@ -58,15 +56,15 @@ async function deployPrepare(opt = {}) {
|
|
|
58
56
|
const backendCfg = (0, backend_cfg_util_1.getBackendCfg)(projectDir);
|
|
59
57
|
const inputPatterns = backendCfg.files || DEFAULT_FILES;
|
|
60
58
|
const appYamlPassEnv = opt.appYamlPassEnv || backendCfg.appYamlPassEnv;
|
|
61
|
-
console.log(`1. Copy files to ${(0,
|
|
59
|
+
console.log(`1. Copy files to ${(0, nodejs_lib_1.dimGrey)(targetDir)}`);
|
|
62
60
|
// Clean targetDir
|
|
63
61
|
(0, nodejs_lib_1._emptyDirSync)(targetDir);
|
|
64
|
-
(0,
|
|
62
|
+
(0, nodejs_lib_1.kpySync)({
|
|
65
63
|
baseDir: defaultFilesDir,
|
|
66
64
|
outputDir: targetDir,
|
|
67
65
|
dotfiles: true,
|
|
68
66
|
});
|
|
69
|
-
(0,
|
|
67
|
+
(0, nodejs_lib_1.kpySync)({
|
|
70
68
|
baseDir: projectDir,
|
|
71
69
|
inputPatterns,
|
|
72
70
|
outputDir: targetDir,
|
|
@@ -78,7 +76,7 @@ async function deployPrepare(opt = {}) {
|
|
|
78
76
|
const npmrc = `//registry.npmjs.org/:_authToken=${NPM_TOKEN}`;
|
|
79
77
|
(0, nodejs_lib_1._writeFileSync)(npmrcPath, npmrc);
|
|
80
78
|
}
|
|
81
|
-
console.log(`2. Generate ${(0,
|
|
79
|
+
console.log(`2. Generate ${(0, nodejs_lib_1.dimGrey)('deployInfo.json')} and ${(0, nodejs_lib_1.dimGrey)('app.yaml')} in targetDir`);
|
|
82
80
|
const deployInfo = await (0, deploy_util_1.createAndSaveDeployInfo)(backendCfg, targetDir);
|
|
83
81
|
(0, deploy_util_1.createAndSaveAppYaml)(backendCfg, deployInfo, projectDir, targetDir, appYamlPassEnv);
|
|
84
82
|
return deployInfo;
|
package/dist/paths.cnst.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.testDir = exports.srcDir = exports.resourcesDir = exports.projectDir = void 0;
|
|
4
|
-
const
|
|
5
|
-
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const node_path_1 = tslib_1.__importDefault(require("node:path"));
|
|
6
|
+
exports.projectDir = node_path_1.default.join(__dirname, '/..');
|
|
6
7
|
exports.resourcesDir = `${exports.projectDir}/resources`;
|
|
7
8
|
exports.srcDir = `${exports.projectDir}/src`;
|
|
8
9
|
exports.testDir = `${exports.srcDir}/test`;
|
|
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.appEngineLogMiddleware = exports.ciLogger = exports.devLogger = exports.gaeLogger = void 0;
|
|
4
4
|
const node_util_1 = require("node:util");
|
|
5
5
|
const nodejs_lib_1 = require("@naturalcycles/nodejs-lib");
|
|
6
|
-
const nodejs_lib_2 = require("@naturalcycles/nodejs-lib");
|
|
7
6
|
const { GOOGLE_CLOUD_PROJECT, GAE_INSTANCE } = process.env;
|
|
8
7
|
const isGAE = !!GAE_INSTANCE;
|
|
9
8
|
// Simple "request counter" (poor man's "correlation id") counter, to use on dev machine (not in the cloud)
|
|
@@ -45,7 +44,7 @@ function logToDev(requestId, args) {
|
|
|
45
44
|
// Run on local machine
|
|
46
45
|
console.log([
|
|
47
46
|
requestId ? [(0, nodejs_lib_1.dimGrey)(`[${requestId}]`)] : [],
|
|
48
|
-
...args.map(a => (0,
|
|
47
|
+
...args.map(a => (0, nodejs_lib_1.inspectAny)(a, { includeErrorStack: true, colors: true })),
|
|
49
48
|
].join(' '));
|
|
50
49
|
}
|
|
51
50
|
/**
|
|
@@ -53,7 +52,7 @@ function logToDev(requestId, args) {
|
|
|
53
52
|
* This is to not confuse e.g Sentry when it picks up messages with colors
|
|
54
53
|
*/
|
|
55
54
|
function logToCI(args) {
|
|
56
|
-
console.log(args.map(a => (0,
|
|
55
|
+
console.log(args.map(a => (0, nodejs_lib_1.inspectAny)(a, { includeErrorStack: true, colors: false })).join(' '));
|
|
57
56
|
}
|
|
58
57
|
function appEngineLogMiddleware() {
|
|
59
58
|
if (!isGAE || !GOOGLE_CLOUD_PROJECT) {
|
|
@@ -5,8 +5,8 @@ const cookieParser = require("cookie-parser");
|
|
|
5
5
|
const cors = require("cors");
|
|
6
6
|
const express = require("express");
|
|
7
7
|
const __1 = require("..");
|
|
8
|
-
const asyncLocalStorageMiddleware_1 = require("./asyncLocalStorageMiddleware");
|
|
9
8
|
const appEngineLogMiddleware_1 = require("./appEngineLogMiddleware");
|
|
9
|
+
const asyncLocalStorageMiddleware_1 = require("./asyncLocalStorageMiddleware");
|
|
10
10
|
const genericErrorMiddleware_1 = require("./genericErrorMiddleware");
|
|
11
11
|
const notFoundMiddleware_1 = require("./notFoundMiddleware");
|
|
12
12
|
const requestTimeoutMiddleware_1 = require("./requestTimeoutMiddleware");
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Options, OptionsJson, OptionsUrlencoded } from 'body-parser';
|
|
2
2
|
import { CorsOptions } from 'cors';
|
|
3
3
|
import { SentrySharedService } from '../sentry/sentry.shared.service';
|
|
4
|
-
import { BackendRequestHandler } from './server.model';
|
|
5
4
|
import { GenericErrorMiddlewareCfg } from './genericErrorMiddleware';
|
|
5
|
+
import { BackendRequestHandler } from './server.model';
|
|
6
6
|
/**
|
|
7
7
|
* Plain RequestHandler can be provided - then it's mounted to /
|
|
8
8
|
* Otherwise `path` can be provided to specify mounting point.
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getDeployInfo = void 0;
|
|
4
|
-
const
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const node_fs_1 = tslib_1.__importDefault(require("node:fs"));
|
|
5
6
|
const js_lib_1 = require("@naturalcycles/js-lib");
|
|
6
7
|
exports.getDeployInfo = (0, js_lib_1._memoFn)((projectDir) => {
|
|
7
8
|
const deployInfoPath = `${projectDir}/deployInfo.json`;
|
|
8
9
|
try {
|
|
9
|
-
return JSON.parse(
|
|
10
|
+
return JSON.parse(node_fs_1.default.readFileSync(deployInfoPath, 'utf8'));
|
|
10
11
|
}
|
|
11
12
|
catch {
|
|
12
13
|
// console.error(`cannot read ${deployInfoPath}, returning empty version`)
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getDefaultRouter = void 0;
|
|
4
|
-
const
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const express_promise_router_1 = tslib_1.__importDefault(require("express-promise-router"));
|
|
5
6
|
/**
|
|
6
7
|
* Convenience method.
|
|
7
8
|
*/
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { JsonSchema, JsonSchemaBuilder } from '@naturalcycles/js-lib';
|
|
2
2
|
import { AjvSchema, AjvValidationError } from '@naturalcycles/nodejs-lib';
|
|
3
|
-
import { BackendRequestHandler } from './server.model';
|
|
4
3
|
import { ReqValidationOptions } from './reqValidationMiddleware';
|
|
4
|
+
import { BackendRequestHandler } from './server.model';
|
|
5
5
|
export declare function validateBody(schema: JsonSchema | JsonSchemaBuilder | AjvSchema, opt?: ReqValidationOptions<AjvValidationError>): BackendRequestHandler;
|
|
6
6
|
export declare function validateParams(schema: JsonSchema | JsonSchemaBuilder | AjvSchema, opt?: ReqValidationOptions<AjvValidationError>): BackendRequestHandler;
|
|
7
7
|
export declare function validateQuery(schema: JsonSchema | JsonSchemaBuilder | AjvSchema, opt?: ReqValidationOptions<AjvValidationError>): BackendRequestHandler;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ZodSchema, ZodValidationError } from '@naturalcycles/js-lib';
|
|
2
|
-
import { BackendRequestHandler } from './server.model';
|
|
3
2
|
import { ReqValidationOptions } from './reqValidationMiddleware';
|
|
3
|
+
import { BackendRequestHandler } from './server.model';
|
|
4
4
|
/**
|
|
5
5
|
* Validates req property (body, params or query).
|
|
6
6
|
* Supports Joi schema or AjvSchema (from nodejs-lib).
|
|
@@ -42,11 +42,13 @@ class ExpressTestService {
|
|
|
42
42
|
await (0, js_lib_1.pDelay)();
|
|
43
43
|
});
|
|
44
44
|
fetcher.close = async () => {
|
|
45
|
-
const started = Date.now()
|
|
46
|
-
await new Promise(resolve => server.close(resolve))
|
|
47
|
-
console.log(`close took ${
|
|
45
|
+
// const started = Date.now()
|
|
46
|
+
// await new Promise(resolve => server.close(resolve))
|
|
47
|
+
// console.log(`close took ${_since(started)}`) // todo: investigate why it takes ~5 seconds!
|
|
48
|
+
// Kirill: not awaiting the server-close, otherwise it takes significant waiting time
|
|
49
|
+
// to "teardown" server after it's been hit by Fetcher
|
|
50
|
+
server.close();
|
|
48
51
|
// server.destroy()
|
|
49
|
-
// await pDelay(1000)
|
|
50
52
|
};
|
|
51
53
|
return fetcher;
|
|
52
54
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@naturalcycles/backend-lib",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.19.1",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"prepare": "husky install",
|
|
6
6
|
"serve": "APP_ENV=dev nodemon",
|
|
@@ -46,10 +46,7 @@
|
|
|
46
46
|
"@types/yargs": "^16.0.0",
|
|
47
47
|
"fastify": "^4.0.0",
|
|
48
48
|
"jest": "^29.0.1",
|
|
49
|
-
"nodemon": "^3.0.1"
|
|
50
|
-
"vue-class-component": "^7.2.6",
|
|
51
|
-
"vuepress": "^1.7.1",
|
|
52
|
-
"vuepress-plugin-typescript": "^0.3.1"
|
|
49
|
+
"nodemon": "^3.0.1"
|
|
53
50
|
},
|
|
54
51
|
"files": [
|
|
55
52
|
"dist",
|
package/readme.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
[](https://codeclimate.com/github/NaturalCycles/backend-lib/maintainability)
|
|
7
7
|
[](https://codeclimate.com/github/NaturalCycles/backend-lib/test_coverage)
|
|
8
8
|
[](https://github.com/prettier/prettier)
|
|
9
|
-
[](https://github.com/NaturalCycles/backend-lib/actions)
|
|
10
10
|
|
|
11
11
|
# [Documentation](https://naturalcycles.github.io/backend-lib/)
|
|
12
12
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import fs from 'node:fs'
|
|
2
2
|
import { _memoFn, AppError } from '@naturalcycles/js-lib'
|
|
3
|
-
import
|
|
3
|
+
import ejs from 'ejs'
|
|
4
4
|
import { BackendRequestHandler } from '../server/server.model'
|
|
5
5
|
import { BaseAdminService } from './base.admin.service'
|
|
6
6
|
import { FirebaseSharedServiceCfg } from './firebase.shared.service'
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { _assert, AppError } from '@naturalcycles/js-lib'
|
|
2
2
|
import { dimGrey, green, red } from '@naturalcycles/nodejs-lib'
|
|
3
|
-
import type
|
|
3
|
+
import type FirebaseAdmin from 'firebase-admin'
|
|
4
4
|
import { BackendRequest, BackendRequestHandler } from '../server/server.model'
|
|
5
5
|
|
|
6
6
|
export interface AdminServiceCfg {
|
|
@@ -31,7 +31,10 @@ const adminInfoDisabled = (): AdminInfo => ({
|
|
|
31
31
|
* Base implementation based on Firebase Auth tokens passed as 'admin_token' cookie.
|
|
32
32
|
*/
|
|
33
33
|
export class BaseAdminService {
|
|
34
|
-
constructor(
|
|
34
|
+
constructor(
|
|
35
|
+
private firebaseAuth: FirebaseAdmin.auth.Auth,
|
|
36
|
+
cfg: AdminServiceCfg,
|
|
37
|
+
) {
|
|
35
38
|
this.cfg = {
|
|
36
39
|
adminTokenKey: 'admin_token',
|
|
37
40
|
authEnabled: true,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { _Memo } from '@naturalcycles/js-lib'
|
|
2
2
|
import type { AppOptions, ServiceAccount } from 'firebase-admin'
|
|
3
|
-
import type
|
|
3
|
+
import type FirebaseAdmin from 'firebase-admin'
|
|
4
4
|
|
|
5
5
|
export interface FirebaseSharedServiceCfg {
|
|
6
6
|
/**
|
package/src/admin/login.html
CHANGED
package/src/bin/deploy-gae.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
import { runScript } from '@naturalcycles/nodejs-lib'
|
|
4
|
-
import
|
|
4
|
+
import yargs from 'yargs'
|
|
5
5
|
import { deployGae } from '../deploy/deployGae'
|
|
6
6
|
import { deployHealthCheckYargsOptions } from '../deploy/deployHealthCheck'
|
|
7
7
|
import { deployPrepareYargsOptions } from '../deploy/deployPrepare'
|
|
@@ -10,7 +10,7 @@ yarn deploy-health-check --url https://service-dot-yourproject.appspot.com
|
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
import { runScript } from '@naturalcycles/nodejs-lib'
|
|
13
|
-
import
|
|
13
|
+
import yargs from 'yargs'
|
|
14
14
|
import { deployHealthCheck, deployHealthCheckYargsOptions } from '../deploy/deployHealthCheck'
|
|
15
15
|
|
|
16
16
|
runScript(async () => {
|
package/src/db/httpDB.ts
CHANGED
|
@@ -1,11 +1,4 @@
|
|
|
1
1
|
import { Readable } from 'node:stream'
|
|
2
|
-
import {
|
|
3
|
-
Fetcher,
|
|
4
|
-
FetcherOptions,
|
|
5
|
-
getFetcher,
|
|
6
|
-
JsonSchemaRootObject,
|
|
7
|
-
ObjectWithId,
|
|
8
|
-
} from '@naturalcycles/js-lib'
|
|
9
2
|
import {
|
|
10
3
|
BaseCommonDB,
|
|
11
4
|
CommonDB,
|
|
@@ -15,6 +8,13 @@ import {
|
|
|
15
8
|
DBQuery,
|
|
16
9
|
RunQueryResult,
|
|
17
10
|
} from '@naturalcycles/db-lib'
|
|
11
|
+
import {
|
|
12
|
+
Fetcher,
|
|
13
|
+
FetcherOptions,
|
|
14
|
+
getFetcher,
|
|
15
|
+
JsonSchemaRootObject,
|
|
16
|
+
ObjectWithId,
|
|
17
|
+
} from '@naturalcycles/js-lib'
|
|
18
18
|
import { ReadableTyped } from '@naturalcycles/nodejs-lib'
|
|
19
19
|
|
|
20
20
|
export interface HttpDBCfg extends FetcherOptions {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { StringMap } from '@naturalcycles/js-lib'
|
|
2
2
|
import { _readFileSync, AjvSchema, requireFileToExist } from '@naturalcycles/nodejs-lib'
|
|
3
|
-
import
|
|
3
|
+
import yaml from 'js-yaml'
|
|
4
4
|
import { resourcesDir } from '../paths.cnst'
|
|
5
5
|
|
|
6
6
|
export interface BackendCfg {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import
|
|
1
|
+
import fs from 'node:fs'
|
|
2
2
|
import { _mapValues, _merge, _truncate, localTime } from '@naturalcycles/js-lib'
|
|
3
3
|
import { dimGrey, white } from '@naturalcycles/nodejs-lib'
|
|
4
|
-
import
|
|
4
|
+
import yaml from 'js-yaml'
|
|
5
5
|
import { BackendCfg } from './backend.cfg.util'
|
|
6
6
|
import { AppYaml, DeployInfo } from './deploy.model'
|
|
7
7
|
|
|
@@ -151,16 +151,19 @@ export function createAppYaml(
|
|
|
151
151
|
.split(',')
|
|
152
152
|
.filter(Boolean)
|
|
153
153
|
// eslint-disable-next-line unicorn/no-array-reduce
|
|
154
|
-
.reduce(
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
154
|
+
.reduce(
|
|
155
|
+
(map, key) => {
|
|
156
|
+
const v = process.env[key]
|
|
157
|
+
if (!v) {
|
|
158
|
+
throw new Error(
|
|
159
|
+
`appYamlPassEnv.${key} is requested, but process.env.${key} is not defined!`,
|
|
160
|
+
)
|
|
161
|
+
}
|
|
162
|
+
map[key] = v
|
|
163
|
+
return map
|
|
164
|
+
},
|
|
165
|
+
{} as Record<string, string>,
|
|
166
|
+
)
|
|
164
167
|
|
|
165
168
|
if (Object.keys(passEnv).length) {
|
|
166
169
|
console.log(
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { inspect, InspectOptions } from 'node:util'
|
|
2
|
-
import { execVoidCommandSync } from '@naturalcycles/nodejs-lib'
|
|
3
2
|
import { pDelay, _filterFalsyValues, _ms, _since, getFetcher } from '@naturalcycles/js-lib'
|
|
4
|
-
import { dimGrey, red } from '@naturalcycles/nodejs-lib'
|
|
3
|
+
import { execVoidCommandSync, dimGrey, red } from '@naturalcycles/nodejs-lib'
|
|
5
4
|
import { coloredHttpCode } from '../server/request.log.util'
|
|
6
5
|
|
|
7
6
|
export interface DeployHealthCheckOptions {
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import { _emptyDirSync, _writeFileSync } from '@naturalcycles/nodejs-lib'
|
|
2
|
-
import { dimGrey } from '@naturalcycles/nodejs-lib'
|
|
3
|
-
import { kpySync } from '@naturalcycles/nodejs-lib'
|
|
1
|
+
import { _emptyDirSync, _writeFileSync, dimGrey, kpySync } from '@naturalcycles/nodejs-lib'
|
|
4
2
|
import { srcDir } from '../paths.cnst'
|
|
5
3
|
import { getBackendCfg } from './backend.cfg.util'
|
|
6
4
|
import { DeployInfo } from './deploy.model'
|
package/src/paths.cnst.ts
CHANGED
|
@@ -6,7 +6,9 @@ import {
|
|
|
6
6
|
CommonLogLevel,
|
|
7
7
|
} from '@naturalcycles/js-lib'
|
|
8
8
|
import { inspectAny, InspectAnyOptions } from '@naturalcycles/nodejs-lib'
|
|
9
|
+
// eslint-disable-next-line import/no-duplicates
|
|
9
10
|
import type { Breadcrumb, NodeOptions, SeverityLevel } from '@sentry/node'
|
|
11
|
+
// eslint-disable-next-line import/no-duplicates
|
|
10
12
|
import type * as SentryLib from '@sentry/node'
|
|
11
13
|
import { BackendErrorRequestHandler, BackendRequestHandler, getRequestLogger } from '../index'
|
|
12
14
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { inspect } from 'node:util'
|
|
2
|
-
import { dimGrey } from '@naturalcycles/nodejs-lib'
|
|
3
|
-
import { inspectAny } from '@naturalcycles/nodejs-lib'
|
|
4
2
|
import { AnyObject, CommonLogger } from '@naturalcycles/js-lib'
|
|
3
|
+
import { dimGrey, inspectAny } from '@naturalcycles/nodejs-lib'
|
|
5
4
|
import { BackendRequestHandler } from './server.model'
|
|
6
5
|
|
|
7
6
|
const { GOOGLE_CLOUD_PROJECT, GAE_INSTANCE } = process.env
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { AsyncLocalStorage } from 'node:async_hooks'
|
|
2
2
|
import { _lazyValue, CommonLogger } from '@naturalcycles/js-lib'
|
|
3
|
-
import { BackendRequest, BackendRequestHandler } from './server.model'
|
|
4
3
|
import { gaeLogger, devLogger, ciLogger } from './appEngineLogMiddleware'
|
|
4
|
+
import { BackendRequest, BackendRequestHandler } from './server.model'
|
|
5
5
|
|
|
6
6
|
const { GAE_INSTANCE, CI } = process.env
|
|
7
7
|
const isGAE = !!GAE_INSTANCE
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Options, OptionsJson, OptionsUrlencoded } from 'body-parser'
|
|
2
2
|
import { CorsOptions } from 'cors'
|
|
3
3
|
import { SentrySharedService } from '../sentry/sentry.shared.service'
|
|
4
|
-
import { BackendRequestHandler } from './server.model'
|
|
5
4
|
import { GenericErrorMiddlewareCfg } from './genericErrorMiddleware'
|
|
5
|
+
import { BackendRequestHandler } from './server.model'
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Plain RequestHandler can be provided - then it's mounted to /
|
|
@@ -2,13 +2,13 @@ import cookieParser = require('cookie-parser')
|
|
|
2
2
|
import cors = require('cors')
|
|
3
3
|
import express = require('express')
|
|
4
4
|
import { BackendApplication, isGAE, methodOverrideMiddleware } from '..'
|
|
5
|
+
import { appEngineLogMiddleware } from './appEngineLogMiddleware'
|
|
6
|
+
import { asyncLocalStorageMiddleware } from './asyncLocalStorageMiddleware'
|
|
5
7
|
import {
|
|
6
8
|
DefaultAppCfg,
|
|
7
9
|
BackendRequestHandlerCfg,
|
|
8
10
|
BackendRequestHandlerWithPath,
|
|
9
11
|
} from './createDefaultApp.model'
|
|
10
|
-
import { asyncLocalStorageMiddleware } from './asyncLocalStorageMiddleware'
|
|
11
|
-
import { appEngineLogMiddleware } from './appEngineLogMiddleware'
|
|
12
12
|
import { genericErrorMiddleware } from './genericErrorMiddleware'
|
|
13
13
|
import { notFoundMiddleware } from './notFoundMiddleware'
|
|
14
14
|
import { requestTimeoutMiddleware } from './requestTimeoutMiddleware'
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { JsonSchema, JsonSchemaBuilder, _get, AppError } from '@naturalcycles/js-lib'
|
|
2
2
|
import { AjvSchema, AjvValidationError } from '@naturalcycles/nodejs-lib'
|
|
3
|
-
import { BackendRequestHandler } from './server.model'
|
|
4
3
|
import { ReqValidationOptions } from './reqValidationMiddleware'
|
|
4
|
+
import { BackendRequestHandler } from './server.model'
|
|
5
5
|
|
|
6
6
|
const REDACTED = 'REDACTED'
|
|
7
7
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { _get, AppError, ZodSchema, ZodValidationError, zSafeValidate } from '@naturalcycles/js-lib'
|
|
2
|
-
import { BackendRequestHandler } from './server.model'
|
|
3
2
|
import { ReqValidationOptions } from './reqValidationMiddleware'
|
|
3
|
+
import { BackendRequestHandler } from './server.model'
|
|
4
4
|
|
|
5
5
|
const REDACTED = 'REDACTED'
|
|
6
6
|
|
|
@@ -1,13 +1,6 @@
|
|
|
1
1
|
import { Server } from 'node:http'
|
|
2
2
|
import { AddressInfo } from 'node:net'
|
|
3
|
-
import {
|
|
4
|
-
_since,
|
|
5
|
-
Fetcher,
|
|
6
|
-
FetcherOptions,
|
|
7
|
-
FetchFunction,
|
|
8
|
-
getFetcher,
|
|
9
|
-
pDelay,
|
|
10
|
-
} from '@naturalcycles/js-lib'
|
|
3
|
+
import { Fetcher, FetcherOptions, FetchFunction, getFetcher, pDelay } from '@naturalcycles/js-lib'
|
|
11
4
|
import { BackendApplication, createDefaultApp, DefaultAppCfg } from '../index'
|
|
12
5
|
import { BackendRequestHandlerCfg } from '../server/createDefaultApp.model'
|
|
13
6
|
|
|
@@ -70,11 +63,13 @@ class ExpressTestService {
|
|
|
70
63
|
}) as ExpressApp
|
|
71
64
|
|
|
72
65
|
fetcher.close = async () => {
|
|
73
|
-
const started = Date.now()
|
|
74
|
-
await new Promise(resolve => server.close(resolve))
|
|
75
|
-
console.log(`close took ${_since(started)}`) // todo: investigate why it takes ~5 seconds!
|
|
66
|
+
// const started = Date.now()
|
|
67
|
+
// await new Promise(resolve => server.close(resolve))
|
|
68
|
+
// console.log(`close took ${_since(started)}`) // todo: investigate why it takes ~5 seconds!
|
|
69
|
+
// Kirill: not awaiting the server-close, otherwise it takes significant waiting time
|
|
70
|
+
// to "teardown" server after it's been hit by Fetcher
|
|
71
|
+
server.close()
|
|
76
72
|
// server.destroy()
|
|
77
|
-
// await pDelay(1000)
|
|
78
73
|
}
|
|
79
74
|
|
|
80
75
|
return fetcher
|