@naturalcycles/backend-lib 8.0.4 → 9.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin/adminMiddleware.d.ts +3 -3
- package/dist/admin/adminMiddleware.js +11 -18
- package/dist/admin/base.admin.service.d.ts +1 -1
- package/dist/admin/base.admin.service.js +9 -13
- package/dist/admin/firebase.shared.service.d.ts +3 -3
- package/dist/admin/firebase.shared.service.js +12 -15
- package/dist/admin/secureHeaderMiddleware.d.ts +2 -2
- package/dist/admin/secureHeaderMiddleware.js +7 -10
- package/dist/bin/deploy-gae.js +9 -11
- package/dist/bin/deploy-health-check.js +6 -8
- package/dist/bin/deploy-prepare.js +5 -7
- package/dist/bin/undeploy-gae.js +5 -7
- package/dist/db/httpDB.js +7 -11
- package/dist/db/httpDBRequestHandler.d.ts +1 -1
- package/dist/db/httpDBRequestHandler.js +27 -29
- package/dist/db/index.d.ts +3 -3
- package/dist/db/index.js +3 -7
- package/dist/deploy/backend.cfg.util.js +6 -9
- package/dist/deploy/deploy.model.js +1 -2
- package/dist/deploy/deploy.util.d.ts +2 -2
- package/dist/deploy/deploy.util.js +25 -33
- package/dist/deploy/deployGae.d.ts +2 -2
- package/dist/deploy/deployGae.js +23 -27
- package/dist/deploy/deployHealthCheck.js +16 -20
- package/dist/deploy/deployPrepare.d.ts +1 -1
- package/dist/deploy/deployPrepare.js +17 -21
- package/dist/deploy/index.d.ts +8 -8
- package/dist/deploy/index.js +6 -14
- package/dist/env/env.shared.service.js +8 -12
- package/dist/index.d.ts +33 -33
- package/dist/index.js +34 -38
- package/dist/paths.cnst.js +5 -9
- package/dist/sentry/sentry.shared.service.js +11 -15
- package/dist/server/asyncLocalStorageMiddleware.d.ts +1 -1
- package/dist/server/asyncLocalStorageMiddleware.js +9 -15
- package/dist/server/basicAuthMiddleware.d.ts +1 -1
- package/dist/server/basicAuthMiddleware.js +5 -8
- package/dist/server/bodyParserTimeoutMiddleware.d.ts +1 -1
- package/dist/server/bodyParserTimeoutMiddleware.js +5 -9
- package/dist/server/createDefaultApp.d.ts +3 -3
- package/dist/server/createDefaultApp.js +22 -23
- package/dist/server/createDefaultApp.model.d.ts +3 -3
- package/dist/server/createDefaultApp.model.js +1 -2
- package/dist/server/deployInfo.util.d.ts +1 -1
- package/dist/server/deployInfo.util.js +5 -8
- package/dist/server/genericErrorMiddleware.d.ts +2 -2
- package/dist/server/genericErrorMiddleware.js +6 -10
- package/dist/server/getDefaultRouter.d.ts +1 -1
- package/dist/server/getDefaultRouter.js +3 -6
- package/dist/server/logMiddleware.d.ts +1 -1
- package/dist/server/logMiddleware.js +12 -16
- package/dist/server/methodOverrideMiddleware.d.ts +1 -1
- package/dist/server/methodOverrideMiddleware.js +1 -4
- package/dist/server/notFoundMiddleware.d.ts +1 -1
- package/dist/server/notFoundMiddleware.js +3 -6
- package/dist/server/okMiddleware.d.ts +1 -1
- package/dist/server/okMiddleware.js +1 -4
- package/dist/server/request.log.util.d.ts +1 -1
- package/dist/server/request.log.util.js +7 -11
- package/dist/server/request.util.d.ts +1 -1
- package/dist/server/request.util.js +1 -4
- package/dist/server/requestTimeoutMiddleware.d.ts +1 -1
- package/dist/server/requestTimeoutMiddleware.js +9 -13
- package/dist/server/safeJsonMiddleware.d.ts +1 -1
- package/dist/server/safeJsonMiddleware.js +3 -6
- package/dist/server/server.model.js +1 -2
- package/dist/server/server.util.js +1 -4
- package/dist/server/serverStatsMiddleware.d.ts +1 -1
- package/dist/server/serverStatsMiddleware.js +19 -24
- package/dist/server/serverStatusMiddleware.d.ts +1 -1
- package/dist/server/serverStatusMiddleware.js +12 -16
- package/dist/server/simpleRequestLoggerMiddleware.d.ts +1 -1
- package/dist/server/simpleRequestLoggerMiddleware.js +8 -11
- package/dist/server/startServer.d.ts +1 -1
- package/dist/server/startServer.js +18 -22
- package/dist/server/startServer.model.d.ts +3 -3
- package/dist/server/startServer.model.js +1 -2
- package/dist/server/validation/validateMiddleware.d.ts +2 -2
- package/dist/server/validation/validateMiddleware.js +9 -15
- package/dist/server/validation/validateRequest.d.ts +1 -1
- package/dist/server/validation/validateRequest.js +6 -9
- package/dist/server/validation/zodValidateMiddleware.d.ts +2 -2
- package/dist/server/validation/zodValidateMiddleware.js +6 -9
- package/dist/testing/express.test.service.d.ts +5 -5
- package/dist/testing/express.test.service.js +16 -14
- package/dist/testing/index.d.ts +2 -2
- package/dist/testing/index.js +2 -5
- package/dist/util.js +2 -6
- package/package.json +7 -7
- package/src/admin/adminMiddleware.ts +3 -3
- package/src/admin/base.admin.service.ts +1 -1
- package/src/admin/firebase.shared.service.ts +7 -6
- package/src/admin/secureHeaderMiddleware.ts +4 -4
- package/src/bin/deploy-gae.ts +3 -3
- package/src/bin/deploy-health-check.ts +1 -1
- package/src/bin/deploy-prepare.ts +1 -1
- package/src/bin/undeploy-gae.ts +1 -1
- package/src/db/httpDBRequestHandler.ts +4 -3
- package/src/db/index.ts +3 -3
- package/src/deploy/backend.cfg.util.ts +1 -1
- package/src/deploy/deploy.util.ts +3 -4
- package/src/deploy/deployGae.ts +6 -6
- package/src/deploy/deployHealthCheck.ts +1 -1
- package/src/deploy/deployPrepare.ts +6 -5
- package/src/deploy/index.ts +8 -8
- package/src/index.ts +33 -33
- package/src/sentry/sentry.shared.service.ts +1 -1
- package/src/server/asyncLocalStorageMiddleware.ts +2 -2
- package/src/server/basicAuthMiddleware.ts +1 -1
- package/src/server/bodyParserTimeoutMiddleware.ts +2 -2
- package/src/server/createDefaultApp.model.ts +3 -3
- package/src/server/createDefaultApp.ts +16 -14
- package/src/server/deployInfo.util.ts +1 -1
- package/src/server/genericErrorMiddleware.ts +2 -2
- package/src/server/getDefaultRouter.ts +1 -1
- package/src/server/logMiddleware.ts +1 -1
- package/src/server/methodOverrideMiddleware.ts +1 -1
- package/src/server/notFoundMiddleware.ts +2 -2
- package/src/server/okMiddleware.ts +1 -1
- package/src/server/request.log.util.ts +1 -1
- package/src/server/request.util.ts +1 -1
- package/src/server/requestTimeoutMiddleware.ts +2 -2
- package/src/server/safeJsonMiddleware.ts +1 -1
- package/src/server/serverStatsMiddleware.ts +3 -3
- package/src/server/serverStatusMiddleware.ts +2 -2
- package/src/server/simpleRequestLoggerMiddleware.ts +3 -3
- package/src/server/startServer.model.ts +3 -3
- package/src/server/startServer.ts +4 -7
- package/src/server/validation/validateMiddleware.ts +2 -2
- package/src/server/validation/validateRequest.ts +1 -1
- package/src/server/validation/zodValidateMiddleware.ts +2 -2
- package/src/testing/express.test.service.ts +20 -11
- package/src/testing/index.ts +2 -2
|
@@ -1,12 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.createAndSaveDeployInfo = createAndSaveDeployInfo;
|
|
4
|
-
exports.createDeployInfo = createDeployInfo;
|
|
5
|
-
exports.createAndSaveAppYaml = createAndSaveAppYaml;
|
|
6
|
-
exports.createAppYaml = createAppYaml;
|
|
7
|
-
exports.validateGAEServiceName = validateGAEServiceName;
|
|
8
|
-
const js_lib_1 = require("@naturalcycles/js-lib");
|
|
9
|
-
const nodejs_lib_1 = require("@naturalcycles/nodejs-lib");
|
|
1
|
+
import { _assert, _mapValues, _merge, _truncate, localTime } from '@naturalcycles/js-lib';
|
|
2
|
+
import { dimGrey, fs2, sha256, white } from '@naturalcycles/nodejs-lib';
|
|
10
3
|
const APP_YAML_DEFAULT = () => ({
|
|
11
4
|
runtime: 'nodejs22',
|
|
12
5
|
service: 'default',
|
|
@@ -25,17 +18,17 @@ const APP_YAML_DEFAULT = () => ({
|
|
|
25
18
|
TS_NODE_PROJECT: './tsconfig.dist.json',
|
|
26
19
|
},
|
|
27
20
|
});
|
|
28
|
-
async function createAndSaveDeployInfo(backendCfg, targetDir) {
|
|
21
|
+
export async function createAndSaveDeployInfo(backendCfg, targetDir) {
|
|
29
22
|
const deployInfo = await createDeployInfo(backendCfg);
|
|
30
23
|
const deployInfoPath = `${targetDir}/deployInfo.json`;
|
|
31
|
-
|
|
32
|
-
console.log(`saved ${
|
|
24
|
+
fs2.writeJson(deployInfoPath, deployInfo, { spaces: 2 });
|
|
25
|
+
console.log(`saved ${dimGrey(deployInfoPath)}`);
|
|
33
26
|
return deployInfo;
|
|
34
27
|
}
|
|
35
|
-
async function createDeployInfo(backendCfg, overrideBranch) {
|
|
36
|
-
const simpleGit =
|
|
28
|
+
export async function createDeployInfo(backendCfg, overrideBranch) {
|
|
29
|
+
const { simpleGit } = await import('simple-git'); // lazy load
|
|
37
30
|
const git = simpleGit('.');
|
|
38
|
-
const now =
|
|
31
|
+
const now = localTime.now();
|
|
39
32
|
const gitBranch = overrideBranch || (await git.status()).current;
|
|
40
33
|
const gitRev = (await git.revparse(['HEAD'])).slice(0, 7);
|
|
41
34
|
let { gaeProject, gaeProjectByBranch = {}, gaeService, gaeServiceByBranch = {}, branchesWithTimestampVersions = [], } = backendCfg;
|
|
@@ -49,7 +42,7 @@ async function createDeployInfo(backendCfg, overrideBranch) {
|
|
|
49
42
|
// Obfuscates the branch name by hashing it.
|
|
50
43
|
// If there are Jira issue names in the branch name, the first one found will be used as a prefix.
|
|
51
44
|
const jiraIssue = gitBranch.match(/([Dd][Ee][Vv]-\d+)/)?.[0];
|
|
52
|
-
const branchHash =
|
|
45
|
+
const branchHash = sha256(gitBranch).slice(0, 10);
|
|
53
46
|
branchName = [jiraIssue, branchHash].filter(Boolean).join('-');
|
|
54
47
|
}
|
|
55
48
|
gaeService = validateGAEServiceName([branchName, gaeService].join('--'));
|
|
@@ -66,7 +59,7 @@ async function createDeployInfo(backendCfg, overrideBranch) {
|
|
|
66
59
|
const versionUrl = `https://${[gaeVersion, gaeService, gaeProject].join('-dot-')}.appspot.com`;
|
|
67
60
|
// Check the 63-char limit
|
|
68
61
|
const versionUrlString = [gaeVersion, gaeService, gaeProject].join('-dot-');
|
|
69
|
-
|
|
62
|
+
_assert(versionUrlString.length <= 63, `versionUrl length should be <= 63 characters, but it's ${versionUrlString.length} instead: ${versionUrlString}`);
|
|
70
63
|
const serviceUrl = `https://${[gaeService, gaeProject].join('-dot-')}.appspot.com`;
|
|
71
64
|
const deployInfo = {
|
|
72
65
|
gaeProject,
|
|
@@ -81,35 +74,34 @@ async function createDeployInfo(backendCfg, overrideBranch) {
|
|
|
81
74
|
console.log({ deployInfo });
|
|
82
75
|
return deployInfo;
|
|
83
76
|
}
|
|
84
|
-
function createAndSaveAppYaml(backendCfg, deployInfo, projectDir, targetDir, appYamlPassEnv = '') {
|
|
77
|
+
export function createAndSaveAppYaml(backendCfg, deployInfo, projectDir, targetDir, appYamlPassEnv = '') {
|
|
85
78
|
const appYaml = createAppYaml(backendCfg, deployInfo, projectDir, appYamlPassEnv);
|
|
86
79
|
const appYamlPath = `${targetDir}/app.yaml`;
|
|
87
|
-
|
|
88
|
-
console.log(`saved ${
|
|
80
|
+
fs2.writeYaml(appYamlPath, appYaml);
|
|
81
|
+
console.log(`saved ${dimGrey(appYamlPath)}`);
|
|
89
82
|
return appYaml;
|
|
90
83
|
}
|
|
91
|
-
function createAppYaml(backendCfg, deployInfo, projectDir, appYamlPassEnv = '') {
|
|
84
|
+
export function createAppYaml(backendCfg, deployInfo, projectDir, appYamlPassEnv = '') {
|
|
92
85
|
const { appEnvDefault, appEnvByBranch = {} } = backendCfg;
|
|
93
86
|
const { gaeService: service, gitBranch } = deployInfo;
|
|
94
87
|
const { APP_ENV: processAppEnv } = process.env;
|
|
95
88
|
const APP_ENV = processAppEnv || appEnvByBranch[gitBranch] || appEnvDefault;
|
|
96
89
|
if (processAppEnv) {
|
|
97
|
-
console.log(`using APP_ENV=${
|
|
90
|
+
console.log(`using APP_ENV=${dimGrey(processAppEnv)} from process.env`);
|
|
98
91
|
}
|
|
99
92
|
const appYaml = APP_YAML_DEFAULT();
|
|
100
93
|
// Check existing app.yaml
|
|
101
94
|
const appYamlPath = `${projectDir}/app.yaml`;
|
|
102
|
-
if (
|
|
103
|
-
console.log(`merging-in ${
|
|
104
|
-
|
|
95
|
+
if (fs2.pathExists(appYamlPath)) {
|
|
96
|
+
console.log(`merging-in ${dimGrey(appYamlPath)}`);
|
|
97
|
+
_merge(appYaml, fs2.readYaml(appYamlPath));
|
|
105
98
|
}
|
|
106
99
|
const appEnvYamlPath = `${projectDir}/app.${APP_ENV}.yaml`;
|
|
107
|
-
if (
|
|
108
|
-
console.log(`merging-in ${
|
|
109
|
-
|
|
100
|
+
if (fs2.pathExists(appEnvYamlPath)) {
|
|
101
|
+
console.log(`merging-in ${dimGrey(appEnvYamlPath)}`);
|
|
102
|
+
_merge(appYaml, fs2.readYaml(appEnvYamlPath));
|
|
110
103
|
}
|
|
111
104
|
// appYamlPassEnv
|
|
112
|
-
require('dotenv').config(); // ensure .env is read
|
|
113
105
|
const passEnv = appYamlPassEnv
|
|
114
106
|
.split(',')
|
|
115
107
|
.filter(Boolean)
|
|
@@ -123,9 +115,9 @@ function createAppYaml(backendCfg, deployInfo, projectDir, appYamlPassEnv = '')
|
|
|
123
115
|
return map;
|
|
124
116
|
}, {});
|
|
125
117
|
if (Object.keys(passEnv).length) {
|
|
126
|
-
console.log(`will merge ${
|
|
118
|
+
console.log(`will merge ${white(String(Object.keys(passEnv).length))} process.env keys to app.yaml: ${dimGrey(Object.keys(passEnv).join(', '))}`);
|
|
127
119
|
}
|
|
128
|
-
|
|
120
|
+
_merge(appYaml, {
|
|
129
121
|
service,
|
|
130
122
|
env_variables: {
|
|
131
123
|
APP_ENV,
|
|
@@ -141,10 +133,10 @@ function createAppYaml(backendCfg, deployInfo, projectDir, appYamlPassEnv = '')
|
|
|
141
133
|
function redactedAppYaml(appYaml) {
|
|
142
134
|
return {
|
|
143
135
|
...appYaml,
|
|
144
|
-
env_variables:
|
|
136
|
+
env_variables: _mapValues(appYaml.env_variables || {}, (_k, v) => _truncate(String(v), 7)),
|
|
145
137
|
};
|
|
146
138
|
}
|
|
147
|
-
function validateGAEServiceName(serviceName) {
|
|
139
|
+
export function validateGAEServiceName(serviceName) {
|
|
148
140
|
// May only contain lowercase letters, digits, and hyphens. Must begin and end with a letter or digit. Must not exceed 63 characters.
|
|
149
141
|
return serviceName
|
|
150
142
|
.replaceAll('_', '-')
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { DeployHealthCheckOptions } from './deployHealthCheck';
|
|
2
|
-
import type { DeployPrepareOptions } from './deployPrepare';
|
|
1
|
+
import type { DeployHealthCheckOptions } from './deployHealthCheck.js';
|
|
2
|
+
import type { DeployPrepareOptions } from './deployPrepare.js';
|
|
3
3
|
export interface DeployGaeOptions extends DeployPrepareOptions, DeployHealthCheckOptions {
|
|
4
4
|
}
|
|
5
5
|
export declare function deployGae(opt?: DeployGaeOptions): Promise<void>;
|
package/dist/deploy/deployGae.js
CHANGED
|
@@ -1,30 +1,26 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const deploy_util_1 = require("./deploy.util");
|
|
9
|
-
const deployHealthCheck_1 = require("./deployHealthCheck");
|
|
10
|
-
const deployPrepare_1 = require("./deployPrepare");
|
|
11
|
-
async function deployGae(opt = {}) {
|
|
1
|
+
import { _anyToError, _objectAssign, pRetry } from '@naturalcycles/js-lib';
|
|
2
|
+
import { appendToGithubSummary, exec2 } from '@naturalcycles/nodejs-lib';
|
|
3
|
+
import { getBackendCfg } from './backend.cfg.util.js';
|
|
4
|
+
import { createDeployInfo } from './deploy.util.js';
|
|
5
|
+
import { deployHealthCheck } from './deployHealthCheck.js';
|
|
6
|
+
import { deployPrepare } from './deployPrepare.js';
|
|
7
|
+
export async function deployGae(opt = {}) {
|
|
12
8
|
const { logOnFailure, logOnSuccess } = opt;
|
|
13
9
|
// 1. build
|
|
14
|
-
|
|
10
|
+
exec2.spawn('yarn build');
|
|
15
11
|
// 2. deploy-prepare
|
|
16
|
-
const deployInfo = await
|
|
12
|
+
const deployInfo = await deployPrepare();
|
|
17
13
|
const targetDir = './tmp/deploy';
|
|
18
14
|
const appYamlPath = `${targetDir}/app.yaml`;
|
|
19
15
|
const { gaeProject, gaeService, gaeVersion, versionUrl, serviceUrl } = deployInfo;
|
|
20
|
-
|
|
16
|
+
_objectAssign(opt, {
|
|
21
17
|
gaeProject,
|
|
22
18
|
gaeService,
|
|
23
19
|
gaeVersion,
|
|
24
20
|
});
|
|
25
|
-
await
|
|
21
|
+
await pRetry(async () => {
|
|
26
22
|
try {
|
|
27
|
-
|
|
23
|
+
exec2.spawn(`gcloud app deploy ${appYamlPath} --project ${gaeProject} --version ${gaeVersion} --quiet --no-promote`);
|
|
28
24
|
}
|
|
29
25
|
catch (err) {
|
|
30
26
|
if (logOnFailure) {
|
|
@@ -38,21 +34,21 @@ async function deployGae(opt = {}) {
|
|
|
38
34
|
delay: 30_000,
|
|
39
35
|
// todo: this doesn't work, as the error is different from what is logged.
|
|
40
36
|
// We shoud somehow capture the logged text
|
|
41
|
-
predicate: err =>
|
|
37
|
+
predicate: err => _anyToError(err).message.includes('operation is already in progress'),
|
|
42
38
|
});
|
|
43
39
|
// Health check (versionUrl)
|
|
44
40
|
// yarn deploy-health-check --url $deployInfo_versionUrl --repeat 3 --timeoutSec 180 --intervalSec 2
|
|
45
|
-
await
|
|
41
|
+
await deployHealthCheck(versionUrl, opt);
|
|
46
42
|
// Only if "timestamped version" is used ('1' is default)
|
|
47
43
|
if (gaeVersion !== '1') {
|
|
48
44
|
// Rollout (promote versionUrl to serviceUrl)
|
|
49
45
|
// gcloud app services set-traffic $deployInfo_gaeService --project $deployInfo_gaeProject --splits $deployInfo_gaeVersion=1 --quiet
|
|
50
|
-
|
|
46
|
+
exec2.spawn(`gcloud app services set-traffic ${gaeService} --project ${gaeProject} --splits ${gaeVersion}=1 --quiet`);
|
|
51
47
|
// Health check (serviceUrl)
|
|
52
48
|
// yarn deploy-health-check --url $deployInfo_serviceUrl --repeat 3 --timeoutSec 60 --intervalSec 2
|
|
53
|
-
await
|
|
49
|
+
await deployHealthCheck(serviceUrl, opt);
|
|
54
50
|
}
|
|
55
|
-
|
|
51
|
+
appendToGithubSummary(`Deployed ${serviceUrl}`);
|
|
56
52
|
// Logs
|
|
57
53
|
if (logOnSuccess) {
|
|
58
54
|
logs(gaeProject, gaeService, gaeVersion);
|
|
@@ -62,21 +58,21 @@ async function deployGae(opt = {}) {
|
|
|
62
58
|
* Undeploys/removes the GAE service/version, using the same rules as deployGae.
|
|
63
59
|
* Detects the service/version by the same criteria: branch name, backend.cfg.yaml, etc.
|
|
64
60
|
*/
|
|
65
|
-
async function undeployGae(branch) {
|
|
61
|
+
export async function undeployGae(branch) {
|
|
66
62
|
const projectDir = '.';
|
|
67
|
-
const backendCfg =
|
|
68
|
-
const { gaeProject, gaeService, gaeVersion } = await
|
|
63
|
+
const backendCfg = getBackendCfg(projectDir);
|
|
64
|
+
const { gaeProject, gaeService, gaeVersion } = await createDeployInfo(backendCfg, branch);
|
|
69
65
|
// if (prod) {
|
|
70
66
|
// console.log(`undeployGae (branch: ${branch}): not removing prod version (safety check)`)
|
|
71
67
|
// return
|
|
72
68
|
// }
|
|
73
69
|
console.log(`undeployGae (branch: ${branch}): going to remove ${gaeProject}/${gaeService}/${gaeVersion}`);
|
|
74
|
-
|
|
75
|
-
|
|
70
|
+
exec2.spawn(`gcloud app versions delete --project ${gaeProject} --service ${gaeService} ${gaeVersion} --quiet`);
|
|
71
|
+
appendToGithubSummary(`removed ${gaeProject}/${gaeService}/${gaeVersion}`);
|
|
76
72
|
}
|
|
77
73
|
function logs(gaeProject, gaeService, gaeVersion) {
|
|
78
74
|
try {
|
|
79
|
-
|
|
75
|
+
exec2.spawn(`gcloud app logs read --project ${gaeProject} --service ${gaeService} --version ${gaeVersion}`);
|
|
80
76
|
}
|
|
81
77
|
catch { }
|
|
82
78
|
}
|
|
@@ -1,12 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const
|
|
6
|
-
const js_lib_1 = require("@naturalcycles/js-lib");
|
|
7
|
-
const nodejs_lib_1 = require("@naturalcycles/nodejs-lib");
|
|
8
|
-
const request_log_util_1 = require("../server/request.log.util");
|
|
9
|
-
exports.deployHealthCheckYargsOptions = {
|
|
1
|
+
import { inspect } from 'node:util';
|
|
2
|
+
import { _filterFalsyValues, _ms, _since, getFetcher, pDelay } from '@naturalcycles/js-lib';
|
|
3
|
+
import { dimGrey, exec2, red } from '@naturalcycles/nodejs-lib';
|
|
4
|
+
import { coloredHttpCode } from '../server/request.log.util.js';
|
|
5
|
+
export const deployHealthCheckYargsOptions = {
|
|
10
6
|
thresholdHealthy: {
|
|
11
7
|
type: 'number',
|
|
12
8
|
default: 5,
|
|
@@ -56,7 +52,7 @@ const inspectOpt = {
|
|
|
56
52
|
* Fails on up to `unhealthyThreshold` consecutive FAIL responses.
|
|
57
53
|
* Fails after maxTries.
|
|
58
54
|
*/
|
|
59
|
-
async function deployHealthCheck(url, opt = {}) {
|
|
55
|
+
export async function deployHealthCheck(url, opt = {}) {
|
|
60
56
|
const { thresholdHealthy = 5, thresholdUnhealthy = 8, maxTries = 30, timeoutSec = 30, intervalSec = 1, logOnFailure = true, logOnSuccess, gaeProject, gaeService, gaeVersion, } = opt;
|
|
61
57
|
let attempt = 0;
|
|
62
58
|
let countHealthy = 0;
|
|
@@ -65,15 +61,15 @@ async function deployHealthCheck(url, opt = {}) {
|
|
|
65
61
|
let doneReason;
|
|
66
62
|
let failed = false;
|
|
67
63
|
let currentInterval = intervalSec * 1000;
|
|
68
|
-
const fetcher =
|
|
64
|
+
const fetcher = getFetcher();
|
|
69
65
|
while (!done) {
|
|
70
66
|
await makeAttempt();
|
|
71
67
|
}
|
|
72
68
|
if (failed) {
|
|
73
|
-
console.log(
|
|
69
|
+
console.log(red(`Health check failed!`));
|
|
74
70
|
if (logOnFailure) {
|
|
75
71
|
try {
|
|
76
|
-
|
|
72
|
+
exec2.spawn(`gcloud app logs read --project ${gaeProject} --service ${gaeService} --version ${gaeVersion}`);
|
|
77
73
|
}
|
|
78
74
|
catch { }
|
|
79
75
|
}
|
|
@@ -81,13 +77,13 @@ async function deployHealthCheck(url, opt = {}) {
|
|
|
81
77
|
}
|
|
82
78
|
if (logOnSuccess) {
|
|
83
79
|
try {
|
|
84
|
-
|
|
80
|
+
exec2.spawn(`gcloud app logs read --project ${gaeProject} --service ${gaeService} --version ${gaeVersion}`);
|
|
85
81
|
}
|
|
86
82
|
catch { }
|
|
87
83
|
}
|
|
88
84
|
async function makeAttempt() {
|
|
89
85
|
attempt++;
|
|
90
|
-
console.log([`>>`,
|
|
86
|
+
console.log([`>>`, dimGrey(url), inspect({ attempt }, inspectOpt)].join(' '));
|
|
91
87
|
const started = Date.now();
|
|
92
88
|
const { err, statusCode = 0 } = await fetcher.doFetch({
|
|
93
89
|
url,
|
|
@@ -122,9 +118,9 @@ async function deployHealthCheck(url, opt = {}) {
|
|
|
122
118
|
}
|
|
123
119
|
console.log([
|
|
124
120
|
`<< HTTP`,
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
121
|
+
coloredHttpCode(statusCode),
|
|
122
|
+
dimGrey(_since(started)),
|
|
123
|
+
inspect(_filterFalsyValues({ countHealthy, countUnhealthy }), inspectOpt),
|
|
128
124
|
].join(' '));
|
|
129
125
|
if (attempt >= maxTries) {
|
|
130
126
|
doneReason = `reached maxTries of ${maxTries}`;
|
|
@@ -135,8 +131,8 @@ async function deployHealthCheck(url, opt = {}) {
|
|
|
135
131
|
console.log(doneReason);
|
|
136
132
|
}
|
|
137
133
|
else {
|
|
138
|
-
console.log(
|
|
139
|
-
await
|
|
134
|
+
console.log(dimGrey(`... waiting ${_ms(currentInterval)} ...`));
|
|
135
|
+
await pDelay(currentInterval);
|
|
140
136
|
}
|
|
141
137
|
}
|
|
142
138
|
}
|
|
@@ -1,12 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const
|
|
6
|
-
const paths_cnst_1 = require("../paths.cnst");
|
|
7
|
-
const backend_cfg_util_1 = require("./backend.cfg.util");
|
|
8
|
-
const deploy_util_1 = require("./deploy.util");
|
|
9
|
-
exports.deployPrepareYargsOptions = {
|
|
1
|
+
import { dimGrey, fs2, kpySync } from '@naturalcycles/nodejs-lib';
|
|
2
|
+
import { srcDir } from '../paths.cnst.js';
|
|
3
|
+
import { getBackendCfg } from './backend.cfg.util.js';
|
|
4
|
+
import { createAndSaveAppYaml, createAndSaveDeployInfo } from './deploy.util.js';
|
|
5
|
+
export const deployPrepareYargsOptions = {
|
|
10
6
|
projectDir: {
|
|
11
7
|
type: 'string',
|
|
12
8
|
default: '.',
|
|
@@ -50,22 +46,22 @@ const DEFAULT_FILES = [
|
|
|
50
46
|
'patches', // to allow patch-package
|
|
51
47
|
'resources',
|
|
52
48
|
];
|
|
53
|
-
const defaultFilesDir = `${
|
|
54
|
-
async function deployPrepare(opt = {}) {
|
|
55
|
-
|
|
49
|
+
const defaultFilesDir = `${srcDir}/deploy/files-default`;
|
|
50
|
+
export async function deployPrepare(opt = {}) {
|
|
51
|
+
await import('dotenv/config'); // ensure .env is loaded
|
|
56
52
|
const { projectDir = '.', targetDir = './tmp/deploy', createNpmrc = true } = opt;
|
|
57
|
-
const backendCfg =
|
|
53
|
+
const backendCfg = getBackendCfg(projectDir);
|
|
58
54
|
const inputPatterns = backendCfg.files || DEFAULT_FILES;
|
|
59
55
|
const appYamlPassEnv = opt.appYamlPassEnv || backendCfg.appYamlPassEnv;
|
|
60
|
-
console.log(`1. Copy files to ${
|
|
56
|
+
console.log(`1. Copy files to ${dimGrey(targetDir)}`);
|
|
61
57
|
// Clean targetDir
|
|
62
|
-
|
|
63
|
-
|
|
58
|
+
fs2.emptyDir(targetDir);
|
|
59
|
+
kpySync({
|
|
64
60
|
baseDir: defaultFilesDir,
|
|
65
61
|
outputDir: targetDir,
|
|
66
62
|
dotfiles: true,
|
|
67
63
|
});
|
|
68
|
-
|
|
64
|
+
kpySync({
|
|
69
65
|
baseDir: projectDir,
|
|
70
66
|
inputPatterns,
|
|
71
67
|
outputDir: targetDir,
|
|
@@ -75,10 +71,10 @@ async function deployPrepare(opt = {}) {
|
|
|
75
71
|
if (NPM_TOKEN && createNpmrc) {
|
|
76
72
|
const npmrcPath = `${targetDir}/.npmrc`;
|
|
77
73
|
const npmrc = `//registry.npmjs.org/:_authToken=${NPM_TOKEN}`;
|
|
78
|
-
|
|
74
|
+
fs2.writeFile(npmrcPath, npmrc);
|
|
79
75
|
}
|
|
80
|
-
console.log(`2. Generate ${
|
|
81
|
-
const deployInfo = await
|
|
82
|
-
|
|
76
|
+
console.log(`2. Generate ${dimGrey('deployInfo.json')} and ${dimGrey('app.yaml')} in targetDir`);
|
|
77
|
+
const deployInfo = await createAndSaveDeployInfo(backendCfg, targetDir);
|
|
78
|
+
createAndSaveAppYaml(backendCfg, deployInfo, projectDir, targetDir, appYamlPassEnv);
|
|
83
79
|
return deployInfo;
|
|
84
80
|
}
|
package/dist/deploy/index.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import type { BackendCfg } from './backend.cfg.util';
|
|
2
|
-
import { getBackendCfg } from './backend.cfg.util';
|
|
3
|
-
import type { DeployInfo } from './deploy.model';
|
|
4
|
-
import { createAppYaml, createDeployInfo } from './deploy.util';
|
|
5
|
-
import { deployGae } from './deployGae';
|
|
6
|
-
import type { DeployHealthCheckOptions } from './deployHealthCheck';
|
|
7
|
-
import { deployHealthCheck } from './deployHealthCheck';
|
|
8
|
-
import { deployPrepare } from './deployPrepare';
|
|
1
|
+
import type { BackendCfg } from './backend.cfg.util.js';
|
|
2
|
+
import { getBackendCfg } from './backend.cfg.util.js';
|
|
3
|
+
import type { DeployInfo } from './deploy.model.js';
|
|
4
|
+
import { createAppYaml, createDeployInfo } from './deploy.util.js';
|
|
5
|
+
import { deployGae } from './deployGae.js';
|
|
6
|
+
import type { DeployHealthCheckOptions } from './deployHealthCheck.js';
|
|
7
|
+
import { deployHealthCheck } from './deployHealthCheck.js';
|
|
8
|
+
import { deployPrepare } from './deployPrepare.js';
|
|
9
9
|
export type { BackendCfg, DeployHealthCheckOptions, DeployInfo };
|
|
10
10
|
export { createAppYaml, createDeployInfo, deployGae, deployHealthCheck, deployPrepare, getBackendCfg, };
|
package/dist/deploy/index.js
CHANGED
|
@@ -1,14 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
Object.defineProperty(exports, "createAppYaml", { enumerable: true, get: function () { return deploy_util_1.createAppYaml; } });
|
|
8
|
-
Object.defineProperty(exports, "createDeployInfo", { enumerable: true, get: function () { return deploy_util_1.createDeployInfo; } });
|
|
9
|
-
const deployGae_1 = require("./deployGae");
|
|
10
|
-
Object.defineProperty(exports, "deployGae", { enumerable: true, get: function () { return deployGae_1.deployGae; } });
|
|
11
|
-
const deployHealthCheck_1 = require("./deployHealthCheck");
|
|
12
|
-
Object.defineProperty(exports, "deployHealthCheck", { enumerable: true, get: function () { return deployHealthCheck_1.deployHealthCheck; } });
|
|
13
|
-
const deployPrepare_1 = require("./deployPrepare");
|
|
14
|
-
Object.defineProperty(exports, "deployPrepare", { enumerable: true, get: function () { return deployPrepare_1.deployPrepare; } });
|
|
1
|
+
import { getBackendCfg } from './backend.cfg.util.js';
|
|
2
|
+
import { createAppYaml, createDeployInfo } from './deploy.util.js';
|
|
3
|
+
import { deployGae } from './deployGae.js';
|
|
4
|
+
import { deployHealthCheck } from './deployHealthCheck.js';
|
|
5
|
+
import { deployPrepare } from './deployPrepare.js';
|
|
6
|
+
export { createAppYaml, createDeployInfo, deployGae, deployHealthCheck, deployPrepare, getBackendCfg, };
|
|
@@ -1,11 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const js_lib_1 = require("@naturalcycles/js-lib");
|
|
5
|
-
const nodejs_lib_1 = require("@naturalcycles/nodejs-lib");
|
|
6
|
-
class EnvSharedService {
|
|
1
|
+
import { _assert, _by } from '@naturalcycles/js-lib';
|
|
2
|
+
import { dimGrey } from '@naturalcycles/nodejs-lib';
|
|
3
|
+
export class EnvSharedService {
|
|
7
4
|
constructor(cfg) {
|
|
8
|
-
this.envMap =
|
|
5
|
+
this.envMap = _by(cfg.environments, e => e.name);
|
|
9
6
|
}
|
|
10
7
|
envMap;
|
|
11
8
|
env;
|
|
@@ -15,17 +12,16 @@ class EnvSharedService {
|
|
|
15
12
|
getEnv() {
|
|
16
13
|
if (!this.env) {
|
|
17
14
|
const { APP_ENV } = process.env;
|
|
18
|
-
|
|
15
|
+
_assert(APP_ENV, 'APP_ENV should be defined!');
|
|
19
16
|
const env = this.envMap[APP_ENV];
|
|
20
|
-
|
|
17
|
+
_assert(env, `Environment ${APP_ENV} is not defined`);
|
|
21
18
|
this.env = env;
|
|
22
|
-
console.log(`APP_ENV=${
|
|
19
|
+
console.log(`APP_ENV=${dimGrey(APP_ENV)} loaded`);
|
|
23
20
|
}
|
|
24
21
|
return this.env;
|
|
25
22
|
}
|
|
26
23
|
setEnv(env) {
|
|
27
24
|
this.env = env;
|
|
28
|
-
console.log(`setEnv APP_ENV=${
|
|
25
|
+
console.log(`setEnv APP_ENV=${dimGrey(env?.name || 'undefined')}`);
|
|
29
26
|
}
|
|
30
27
|
}
|
|
31
|
-
exports.EnvSharedService = EnvSharedService;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,34 +1,34 @@
|
|
|
1
|
-
import onFinished
|
|
2
|
-
export * from './admin/adminMiddleware';
|
|
3
|
-
export * from './admin/base.admin.service';
|
|
4
|
-
export * from './admin/firebase.shared.service';
|
|
5
|
-
export * from './admin/secureHeaderMiddleware';
|
|
6
|
-
export * from './env/env.shared.service';
|
|
7
|
-
export * from './sentry/sentry.shared.service';
|
|
8
|
-
export * from './server/asyncLocalStorageMiddleware';
|
|
9
|
-
export * from './server/basicAuthMiddleware';
|
|
10
|
-
export * from './server/bodyParserTimeoutMiddleware';
|
|
11
|
-
export * from './server/createDefaultApp';
|
|
12
|
-
export * from './server/createDefaultApp.model';
|
|
13
|
-
export * from './server/deployInfo.util';
|
|
14
|
-
export * from './server/genericErrorMiddleware';
|
|
15
|
-
export * from './server/getDefaultRouter';
|
|
16
|
-
export * from './server/logMiddleware';
|
|
17
|
-
export * from './server/methodOverrideMiddleware';
|
|
18
|
-
export * from './server/notFoundMiddleware';
|
|
19
|
-
export * from './server/okMiddleware';
|
|
20
|
-
export * from './server/request.log.util';
|
|
21
|
-
export * from './server/request.util';
|
|
22
|
-
export * from './server/requestTimeoutMiddleware';
|
|
23
|
-
export * from './server/safeJsonMiddleware';
|
|
24
|
-
export * from './server/server.model';
|
|
25
|
-
export * from './server/serverStatsMiddleware';
|
|
26
|
-
export * from './server/serverStatusMiddleware';
|
|
27
|
-
export * from './server/simpleRequestLoggerMiddleware';
|
|
28
|
-
export * from './server/startServer';
|
|
29
|
-
export * from './server/startServer.model';
|
|
30
|
-
export * from './server/validation/validateMiddleware';
|
|
31
|
-
export * from './server/validation/validateRequest';
|
|
32
|
-
export * from './server/validation/zodValidateMiddleware';
|
|
33
|
-
export * from './util';
|
|
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
|
+
export * from './env/env.shared.service.js';
|
|
7
|
+
export * from './sentry/sentry.shared.service.js';
|
|
8
|
+
export * from './server/asyncLocalStorageMiddleware.js';
|
|
9
|
+
export * from './server/basicAuthMiddleware.js';
|
|
10
|
+
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
|
+
export * from './server/genericErrorMiddleware.js';
|
|
15
|
+
export * from './server/getDefaultRouter.js';
|
|
16
|
+
export * from './server/logMiddleware.js';
|
|
17
|
+
export * from './server/methodOverrideMiddleware.js';
|
|
18
|
+
export * from './server/notFoundMiddleware.js';
|
|
19
|
+
export * from './server/okMiddleware.js';
|
|
20
|
+
export * from './server/request.log.util.js';
|
|
21
|
+
export * from './server/request.util.js';
|
|
22
|
+
export * from './server/requestTimeoutMiddleware.js';
|
|
23
|
+
export * from './server/safeJsonMiddleware.js';
|
|
24
|
+
export * from './server/server.model.js';
|
|
25
|
+
export * from './server/serverStatsMiddleware.js';
|
|
26
|
+
export * from './server/serverStatusMiddleware.js';
|
|
27
|
+
export * from './server/simpleRequestLoggerMiddleware.js';
|
|
28
|
+
export * from './server/startServer.js';
|
|
29
|
+
export * from './server/startServer.model.js';
|
|
30
|
+
export * from './server/validation/validateMiddleware.js';
|
|
31
|
+
export * from './server/validation/validateRequest.js';
|
|
32
|
+
export * from './server/validation/zodValidateMiddleware.js';
|
|
33
|
+
export * from './util.js';
|
|
34
34
|
export { onFinished };
|
package/dist/index.js
CHANGED
|
@@ -1,38 +1,34 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
tslib_1.__exportStar(require("./server/validation/validateMiddleware"), exports);
|
|
36
|
-
tslib_1.__exportStar(require("./server/validation/validateRequest"), exports);
|
|
37
|
-
tslib_1.__exportStar(require("./server/validation/zodValidateMiddleware"), exports);
|
|
38
|
-
tslib_1.__exportStar(require("./util"), exports);
|
|
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
|
+
export * from './env/env.shared.service.js';
|
|
7
|
+
export * from './sentry/sentry.shared.service.js';
|
|
8
|
+
export * from './server/asyncLocalStorageMiddleware.js';
|
|
9
|
+
export * from './server/basicAuthMiddleware.js';
|
|
10
|
+
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
|
+
export * from './server/genericErrorMiddleware.js';
|
|
15
|
+
export * from './server/getDefaultRouter.js';
|
|
16
|
+
export * from './server/logMiddleware.js';
|
|
17
|
+
export * from './server/methodOverrideMiddleware.js';
|
|
18
|
+
export * from './server/notFoundMiddleware.js';
|
|
19
|
+
export * from './server/okMiddleware.js';
|
|
20
|
+
export * from './server/request.log.util.js';
|
|
21
|
+
export * from './server/request.util.js';
|
|
22
|
+
export * from './server/requestTimeoutMiddleware.js';
|
|
23
|
+
export * from './server/safeJsonMiddleware.js';
|
|
24
|
+
export * from './server/server.model.js';
|
|
25
|
+
export * from './server/serverStatsMiddleware.js';
|
|
26
|
+
export * from './server/serverStatusMiddleware.js';
|
|
27
|
+
export * from './server/simpleRequestLoggerMiddleware.js';
|
|
28
|
+
export * from './server/startServer.js';
|
|
29
|
+
export * from './server/startServer.model.js';
|
|
30
|
+
export * from './server/validation/validateMiddleware.js';
|
|
31
|
+
export * from './server/validation/validateRequest.js';
|
|
32
|
+
export * from './server/validation/zodValidateMiddleware.js';
|
|
33
|
+
export * from './util.js';
|
|
34
|
+
export { onFinished };
|