@datadog/datadog-ci 0.17.7 → 0.17.11
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/LICENSE-3rdparty.csv +2 -0
- package/README.md +3 -1
- package/dist/{commands/dependencies/index.d.ts → cli.d.ts} +0 -0
- package/dist/cli.js +34 -0
- package/dist/commands/{dsyms/index.d.ts → dependencies/cli.d.ts} +0 -0
- package/dist/commands/dependencies/{index.js → cli.js} +0 -0
- package/dist/commands/dependencies/upload.d.ts +1 -1
- package/dist/commands/{git-metadata/index.d.ts → dsyms/cli.d.ts} +0 -0
- package/dist/commands/dsyms/{index.js → cli.js} +0 -0
- package/dist/commands/dsyms/upload.d.ts +1 -1
- package/dist/commands/{junit/index.d.ts → git-metadata/cli.d.ts} +0 -0
- package/dist/commands/git-metadata/{index.js → cli.js} +0 -0
- package/dist/commands/git-metadata/upload.d.ts +1 -1
- package/dist/commands/git-metadata/upload.js +6 -1
- package/dist/commands/{lambda/__tests__/function.test.d.ts → junit/cli.d.ts} +0 -0
- package/dist/commands/junit/{index.js → cli.js} +0 -0
- package/dist/commands/junit/upload.d.ts +1 -1
- package/dist/commands/lambda/__tests__/fixtures.d.ts +42 -0
- package/dist/commands/lambda/__tests__/fixtures.js +73 -0
- package/dist/commands/lambda/{index.d.ts → __tests__/functions/commons.test.d.ts} +0 -0
- package/dist/commands/lambda/__tests__/functions/commons.test.js +350 -0
- package/dist/commands/{sourcemaps/index.d.ts → lambda/__tests__/functions/instrument.test.d.ts} +0 -0
- package/dist/commands/lambda/__tests__/{function.test.js → functions/instrument.test.js} +504 -476
- package/dist/commands/{trace/index.d.ts → lambda/__tests__/functions/uninstrument.test.d.ts} +0 -0
- package/dist/commands/lambda/__tests__/functions/uninstrument.test.js +371 -0
- package/dist/commands/lambda/__tests__/instrument.test.js +351 -234
- package/dist/commands/lambda/__tests__/loggroup.test.js +98 -34
- package/dist/commands/lambda/__tests__/tags.test.js +107 -31
- package/dist/commands/lambda/__tests__/uninstrument.test.d.ts +1 -0
- package/dist/commands/lambda/__tests__/uninstrument.test.js +281 -0
- package/dist/commands/lambda/cli.d.ts +1 -0
- package/dist/commands/lambda/cli.js +5 -0
- package/dist/commands/lambda/constants.d.ts +18 -6
- package/dist/commands/lambda/constants.js +30 -6
- package/dist/commands/lambda/functions/commons.d.ts +101 -0
- package/dist/commands/lambda/functions/commons.js +258 -0
- package/dist/commands/lambda/functions/instrument.d.ts +7 -0
- package/dist/commands/lambda/functions/instrument.js +186 -0
- package/dist/commands/lambda/functions/uninstrument.d.ts +7 -0
- package/dist/commands/lambda/functions/uninstrument.js +121 -0
- package/dist/commands/lambda/instrument.d.ts +4 -4
- package/dist/commands/lambda/instrument.js +103 -57
- package/dist/commands/lambda/interfaces.d.ts +53 -0
- package/dist/commands/lambda/loggroup.d.ts +4 -7
- package/dist/commands/lambda/loggroup.js +30 -5
- package/dist/commands/lambda/tags.d.ts +3 -4
- package/dist/commands/lambda/tags.js +19 -3
- package/dist/commands/lambda/uninstrument.d.ts +12 -0
- package/dist/commands/lambda/uninstrument.js +166 -0
- package/dist/commands/sourcemaps/cli.d.ts +1 -0
- package/dist/commands/sourcemaps/{index.js → cli.js} +0 -0
- package/dist/commands/sourcemaps/upload.d.ts +1 -1
- package/dist/commands/synthetics/__tests__/cli.test.js +13 -13
- package/dist/commands/synthetics/__tests__/fixtures.js +0 -1
- package/dist/commands/synthetics/__tests__/reporters/default.test.js +3 -2
- package/dist/commands/synthetics/__tests__/run-test.test.js +6 -6
- package/dist/commands/synthetics/__tests__/utils.test.js +9 -5
- package/dist/commands/synthetics/__tests__/websocket.test.js +3 -3
- package/dist/commands/synthetics/cli.d.ts +1 -26
- package/dist/commands/synthetics/cli.js +2 -227
- package/dist/commands/synthetics/command.d.ts +26 -0
- package/dist/commands/synthetics/command.js +229 -0
- package/dist/commands/synthetics/index.d.ts +5 -1
- package/dist/commands/synthetics/index.js +31 -2
- package/dist/commands/synthetics/interfaces.d.ts +1 -1
- package/dist/commands/synthetics/reporters/default.d.ts +3 -3
- package/dist/commands/synthetics/reporters/default.js +4 -3
- package/dist/commands/synthetics/utils.d.ts +1 -3
- package/dist/commands/synthetics/utils.js +14 -15
- package/dist/commands/trace/cli.d.ts +1 -0
- package/dist/commands/trace/{index.js → cli.js} +0 -0
- package/dist/commands/trace/trace.d.ts +1 -1
- package/dist/helpers/__tests__/ci.test.js +51 -114
- package/dist/helpers/__tests__/user-provided-git.test.js +14 -2
- package/dist/helpers/__tests__/utils.test.js +4 -0
- package/dist/helpers/ci.js +62 -96
- package/dist/helpers/interfaces.d.ts +28 -2
- package/dist/helpers/user-provided-git.js +11 -2
- package/dist/helpers/utils.d.ts +4 -0
- package/dist/helpers/utils.js +18 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +23 -31
- package/package.json +8 -6
- package/dist/commands/lambda/function.d.ts +0 -43
- package/dist/commands/lambda/function.js +0 -273
- package/dist/commands/lambda/index.js +0 -4
|
@@ -1,229 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
-
};
|
|
14
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const clipanion_1 = require("clipanion");
|
|
18
|
-
const deep_extend_1 = __importDefault(require("deep-extend"));
|
|
19
|
-
const utils_1 = require("../../helpers/utils");
|
|
20
|
-
const errors_1 = require("./errors");
|
|
21
|
-
const interfaces_1 = require("./interfaces");
|
|
22
|
-
const default_1 = require("./reporters/default");
|
|
23
|
-
const junit_1 = require("./reporters/junit");
|
|
24
|
-
const run_test_1 = require("./run-test");
|
|
25
|
-
const utils_2 = require("./utils");
|
|
26
|
-
exports.DEFAULT_COMMAND_CONFIG = {
|
|
27
|
-
apiKey: '',
|
|
28
|
-
appKey: '',
|
|
29
|
-
configPath: 'datadog-ci.json',
|
|
30
|
-
datadogSite: 'datadoghq.com',
|
|
31
|
-
failOnCriticalErrors: false,
|
|
32
|
-
failOnTimeout: true,
|
|
33
|
-
files: ['{,!(node_modules)/**/}*.synthetics.json'],
|
|
34
|
-
global: {},
|
|
35
|
-
locations: [],
|
|
36
|
-
pollingTimeout: 2 * 60 * 1000,
|
|
37
|
-
proxy: { protocol: 'http' },
|
|
38
|
-
publicIds: [],
|
|
39
|
-
subdomain: 'app',
|
|
40
|
-
tunnel: false,
|
|
41
|
-
};
|
|
42
|
-
class RunTestCommand extends clipanion_1.Command {
|
|
43
|
-
constructor() {
|
|
44
|
-
super(...arguments);
|
|
45
|
-
this.config = JSON.parse(JSON.stringify(exports.DEFAULT_COMMAND_CONFIG)); // Deep copy to avoid mutation during unit tests
|
|
46
|
-
}
|
|
47
|
-
execute() {
|
|
48
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
49
|
-
const reporters = [new default_1.DefaultReporter(this)];
|
|
50
|
-
this.reporter = utils_2.getReporter(reporters);
|
|
51
|
-
if (this.jUnitReport) {
|
|
52
|
-
reporters.push(new junit_1.JUnitReporter(this));
|
|
53
|
-
}
|
|
54
|
-
yield this.resolveConfig();
|
|
55
|
-
const startTime = Date.now();
|
|
56
|
-
if (this.config.tunnel) {
|
|
57
|
-
this.reporter.log('You are using tunnel option, the chosen location(s) will be overridden by a location in your account region.\n');
|
|
58
|
-
}
|
|
59
|
-
let results;
|
|
60
|
-
let summary;
|
|
61
|
-
let tests;
|
|
62
|
-
let triggers;
|
|
63
|
-
try {
|
|
64
|
-
;
|
|
65
|
-
({ results, summary, tests, triggers } = yield run_test_1.executeTests(this.reporter, this.config));
|
|
66
|
-
}
|
|
67
|
-
catch (error) {
|
|
68
|
-
if (error instanceof errors_1.CiError) {
|
|
69
|
-
this.reportCiError(error, this.reporter);
|
|
70
|
-
if (error instanceof errors_1.CriticalError && this.config.failOnCriticalErrors) {
|
|
71
|
-
return 1;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
return 0;
|
|
75
|
-
}
|
|
76
|
-
return this.renderResults(results, summary, tests, triggers, startTime);
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
getAppBaseURL() {
|
|
80
|
-
return `https://${this.config.subdomain}.${this.config.datadogSite}/`;
|
|
81
|
-
}
|
|
82
|
-
renderResults(results, summary, tests, triggers, startTime) {
|
|
83
|
-
var _a, _b, _c, _d;
|
|
84
|
-
// Sort tests to show success first then non blocking failures and finally blocking failures.
|
|
85
|
-
tests.sort(this.sortTestsByOutcome(results));
|
|
86
|
-
// Rendering the results.
|
|
87
|
-
(_a = this.reporter) === null || _a === void 0 ? void 0 : _a.reportStart({ startTime });
|
|
88
|
-
const locationNames = triggers.locations.reduce((mapping, location) => {
|
|
89
|
-
mapping[location.id] = location.display_name;
|
|
90
|
-
return mapping;
|
|
91
|
-
}, {});
|
|
92
|
-
let hasSucceeded = true; // Determine if all the tests have succeeded
|
|
93
|
-
for (const test of tests) {
|
|
94
|
-
const testResults = results[test.public_id];
|
|
95
|
-
if (!this.config.failOnTimeout) {
|
|
96
|
-
if (!summary.timedOut) {
|
|
97
|
-
summary.timedOut = 0;
|
|
98
|
-
}
|
|
99
|
-
const hasTimeout = testResults.some((pollResult) => pollResult.result.error === interfaces_1.ERRORS.TIMEOUT);
|
|
100
|
-
if (hasTimeout) {
|
|
101
|
-
summary.timedOut++;
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
if (!this.config.failOnCriticalErrors) {
|
|
105
|
-
if (!summary.criticalErrors) {
|
|
106
|
-
summary.criticalErrors = 0;
|
|
107
|
-
}
|
|
108
|
-
const hasCriticalErrors = testResults.some((pollResult) => utils_2.isCriticalError(pollResult.result));
|
|
109
|
-
if (hasCriticalErrors) {
|
|
110
|
-
summary.criticalErrors++;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
const passed = utils_2.hasTestSucceeded(testResults, this.config.failOnCriticalErrors, this.config.failOnTimeout);
|
|
114
|
-
if (passed) {
|
|
115
|
-
summary.passed++;
|
|
116
|
-
}
|
|
117
|
-
else {
|
|
118
|
-
summary.failed++;
|
|
119
|
-
if (((_b = test.options.ci) === null || _b === void 0 ? void 0 : _b.executionRule) !== interfaces_1.ExecutionRule.NON_BLOCKING) {
|
|
120
|
-
hasSucceeded = false;
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
(_c = this.reporter) === null || _c === void 0 ? void 0 : _c.testEnd(test, testResults, this.getAppBaseURL(), locationNames, this.config.failOnCriticalErrors, this.config.failOnTimeout);
|
|
124
|
-
}
|
|
125
|
-
(_d = this.reporter) === null || _d === void 0 ? void 0 : _d.runEnd(summary);
|
|
126
|
-
return hasSucceeded ? 0 : 1;
|
|
127
|
-
}
|
|
128
|
-
reportCiError(error, reporter) {
|
|
129
|
-
switch (error.code) {
|
|
130
|
-
case 'NO_RESULTS_TO_POLL':
|
|
131
|
-
reporter.log('No results to poll.\n');
|
|
132
|
-
break;
|
|
133
|
-
case 'NO_TESTS_TO_RUN':
|
|
134
|
-
reporter.log('No test to run.\n');
|
|
135
|
-
break;
|
|
136
|
-
case 'MISSING_APP_KEY':
|
|
137
|
-
reporter.error(`Missing ${chalk_1.default.red.bold('DATADOG_APP_KEY')} in your environment.\n`);
|
|
138
|
-
break;
|
|
139
|
-
case 'MISSING_API_KEY':
|
|
140
|
-
reporter.error(`Missing ${chalk_1.default.red.bold('DATADOG_API_KEY')} in your environment.\n`);
|
|
141
|
-
break;
|
|
142
|
-
case 'POLL_RESULTS_FAILED':
|
|
143
|
-
reporter.error(`\n${chalk_1.default.bgRed.bold(' ERROR: unable to poll test results ')}\n${error.message}\n\n`);
|
|
144
|
-
break;
|
|
145
|
-
case 'TUNNEL_START_FAILED':
|
|
146
|
-
reporter.error(`\n${chalk_1.default.bgRed.bold(' ERROR: unable to start tunnel')}\n${error.message}\n\n`);
|
|
147
|
-
break;
|
|
148
|
-
case 'TRIGGER_TESTS_FAILED':
|
|
149
|
-
reporter.error(`\n${chalk_1.default.bgRed.bold(' ERROR: unable to trigger tests')}\n${error.message}\n\n`);
|
|
150
|
-
break;
|
|
151
|
-
case 'UNAVAILABLE_TEST_CONFIG':
|
|
152
|
-
reporter.error(`\n${chalk_1.default.bgRed.bold(' ERROR: unable to obtain test configurations with search query ')}\n${error.message}\n\n`);
|
|
153
|
-
break;
|
|
154
|
-
case 'UNAVAILABLE_TUNNEL_CONFIG':
|
|
155
|
-
reporter.error(`\n${chalk_1.default.bgRed.bold(' ERROR: unable to get tunnel configuration')}\n${error.message}\n\n`);
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
resolveConfig() {
|
|
159
|
-
var _a, _b;
|
|
160
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
161
|
-
// Default < file < ENV < CLI
|
|
162
|
-
// Override with file config variables
|
|
163
|
-
try {
|
|
164
|
-
this.config = yield utils_1.parseConfigFile(this.config, (_a = this.configPath) !== null && _a !== void 0 ? _a : this.config.configPath);
|
|
165
|
-
}
|
|
166
|
-
catch (error) {
|
|
167
|
-
if (this.configPath) {
|
|
168
|
-
throw error;
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
// Override with ENV variables
|
|
172
|
-
this.config = deep_extend_1.default(this.config, utils_2.removeUndefinedValues({
|
|
173
|
-
apiKey: process.env.DATADOG_API_KEY,
|
|
174
|
-
appKey: process.env.DATADOG_APP_KEY,
|
|
175
|
-
datadogSite: process.env.DATADOG_SITE,
|
|
176
|
-
locations: (_b = process.env.DATADOG_SYNTHETICS_LOCATIONS) === null || _b === void 0 ? void 0 : _b.split(';'),
|
|
177
|
-
subdomain: process.env.DATADOG_SUBDOMAIN,
|
|
178
|
-
}));
|
|
179
|
-
// Override with CLI parameters
|
|
180
|
-
this.config = deep_extend_1.default(this.config, utils_2.removeUndefinedValues({
|
|
181
|
-
apiKey: this.apiKey,
|
|
182
|
-
appKey: this.appKey,
|
|
183
|
-
configPath: this.configPath,
|
|
184
|
-
datadogSite: this.datadogSite,
|
|
185
|
-
failOnCriticalErrors: this.failOnCriticalErrors,
|
|
186
|
-
failOnTimeout: this.failOnTimeout,
|
|
187
|
-
files: this.files,
|
|
188
|
-
publicIds: this.publicIds,
|
|
189
|
-
subdomain: this.subdomain,
|
|
190
|
-
testSearchQuery: this.testSearchQuery,
|
|
191
|
-
tunnel: this.tunnel,
|
|
192
|
-
}));
|
|
193
|
-
if (typeof this.config.files === 'string') {
|
|
194
|
-
this.reporter.log('[DEPRECATED] "files" should be an array of string instead of a string.\n');
|
|
195
|
-
this.config.files = [this.config.files];
|
|
196
|
-
}
|
|
197
|
-
});
|
|
198
|
-
}
|
|
199
|
-
sortTestsByOutcome(results) {
|
|
200
|
-
return (t1, t2) => {
|
|
201
|
-
var _a, _b;
|
|
202
|
-
const success1 = utils_2.hasTestSucceeded(results[t1.public_id], this.config.failOnCriticalErrors, this.config.failOnTimeout);
|
|
203
|
-
const success2 = utils_2.hasTestSucceeded(results[t2.public_id], this.config.failOnCriticalErrors, this.config.failOnTimeout);
|
|
204
|
-
const isNonBlockingTest1 = ((_a = t1.options.ci) === null || _a === void 0 ? void 0 : _a.executionRule) === interfaces_1.ExecutionRule.NON_BLOCKING;
|
|
205
|
-
const isNonBlockingTest2 = ((_b = t2.options.ci) === null || _b === void 0 ? void 0 : _b.executionRule) === interfaces_1.ExecutionRule.NON_BLOCKING;
|
|
206
|
-
if (success1 === success2) {
|
|
207
|
-
if (isNonBlockingTest1 === isNonBlockingTest2) {
|
|
208
|
-
return 0;
|
|
209
|
-
}
|
|
210
|
-
return isNonBlockingTest1 ? -1 : 1;
|
|
211
|
-
}
|
|
212
|
-
return success1 ? -1 : 1;
|
|
213
|
-
};
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
exports.RunTestCommand = RunTestCommand;
|
|
217
|
-
RunTestCommand.addPath('synthetics', 'run-tests');
|
|
218
|
-
RunTestCommand.addOption('apiKey', clipanion_1.Command.String('--apiKey'));
|
|
219
|
-
RunTestCommand.addOption('appKey', clipanion_1.Command.String('--appKey'));
|
|
220
|
-
RunTestCommand.addOption('failOnCriticalErrors', clipanion_1.Command.Boolean('--failOnCriticalErrors'));
|
|
221
|
-
RunTestCommand.addOption('configPath', clipanion_1.Command.String('--config'));
|
|
222
|
-
RunTestCommand.addOption('datadogSite', clipanion_1.Command.String('--datadogSite'));
|
|
223
|
-
RunTestCommand.addOption('files', clipanion_1.Command.Array('-f,--files'));
|
|
224
|
-
RunTestCommand.addOption('failOnTimeout', clipanion_1.Command.Boolean('--failOnTimeout'));
|
|
225
|
-
RunTestCommand.addOption('publicIds', clipanion_1.Command.Array('-p,--public-id'));
|
|
226
|
-
RunTestCommand.addOption('testSearchQuery', clipanion_1.Command.String('-s,--search'));
|
|
227
|
-
RunTestCommand.addOption('subdomain', clipanion_1.Command.Boolean('--subdomain'));
|
|
228
|
-
RunTestCommand.addOption('tunnel', clipanion_1.Command.Boolean('-t,--tunnel'));
|
|
229
|
-
RunTestCommand.addOption('runName', clipanion_1.Command.String('-n,--runName'));
|
|
3
|
+
const command_1 = require("./command");
|
|
4
|
+
module.exports = [command_1.RunTestCommand];
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Command } from 'clipanion';
|
|
2
|
+
import { CommandConfig } from './interfaces';
|
|
3
|
+
export declare const DEFAULT_COMMAND_CONFIG: CommandConfig;
|
|
4
|
+
export declare class RunTestCommand extends Command {
|
|
5
|
+
jUnitReport?: string;
|
|
6
|
+
runName?: string;
|
|
7
|
+
private apiKey?;
|
|
8
|
+
private appKey?;
|
|
9
|
+
private config;
|
|
10
|
+
private configPath?;
|
|
11
|
+
private datadogSite?;
|
|
12
|
+
private failOnCriticalErrors?;
|
|
13
|
+
private failOnTimeout?;
|
|
14
|
+
private files?;
|
|
15
|
+
private publicIds?;
|
|
16
|
+
private reporter?;
|
|
17
|
+
private subdomain?;
|
|
18
|
+
private testSearchQuery?;
|
|
19
|
+
private tunnel?;
|
|
20
|
+
execute(): Promise<1 | 0>;
|
|
21
|
+
private getAppBaseURL;
|
|
22
|
+
private renderResults;
|
|
23
|
+
private reportCiError;
|
|
24
|
+
private resolveConfig;
|
|
25
|
+
private sortTestsByOutcome;
|
|
26
|
+
}
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.RunTestCommand = exports.DEFAULT_COMMAND_CONFIG = void 0;
|
|
16
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
17
|
+
const clipanion_1 = require("clipanion");
|
|
18
|
+
const deep_extend_1 = __importDefault(require("deep-extend"));
|
|
19
|
+
const utils_1 = require("../../helpers/utils");
|
|
20
|
+
const errors_1 = require("./errors");
|
|
21
|
+
const interfaces_1 = require("./interfaces");
|
|
22
|
+
const default_1 = require("./reporters/default");
|
|
23
|
+
const junit_1 = require("./reporters/junit");
|
|
24
|
+
const run_test_1 = require("./run-test");
|
|
25
|
+
const utils_2 = require("./utils");
|
|
26
|
+
exports.DEFAULT_COMMAND_CONFIG = {
|
|
27
|
+
apiKey: '',
|
|
28
|
+
appKey: '',
|
|
29
|
+
configPath: 'datadog-ci.json',
|
|
30
|
+
datadogSite: 'datadoghq.com',
|
|
31
|
+
failOnCriticalErrors: false,
|
|
32
|
+
failOnTimeout: true,
|
|
33
|
+
files: ['{,!(node_modules)/**/}*.synthetics.json'],
|
|
34
|
+
global: {},
|
|
35
|
+
locations: [],
|
|
36
|
+
pollingTimeout: 2 * 60 * 1000,
|
|
37
|
+
proxy: { protocol: 'http' },
|
|
38
|
+
publicIds: [],
|
|
39
|
+
subdomain: 'app',
|
|
40
|
+
tunnel: false,
|
|
41
|
+
};
|
|
42
|
+
class RunTestCommand extends clipanion_1.Command {
|
|
43
|
+
constructor() {
|
|
44
|
+
super(...arguments);
|
|
45
|
+
this.config = JSON.parse(JSON.stringify(exports.DEFAULT_COMMAND_CONFIG)); // Deep copy to avoid mutation during unit tests
|
|
46
|
+
}
|
|
47
|
+
execute() {
|
|
48
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
49
|
+
const reporters = [new default_1.DefaultReporter(this)];
|
|
50
|
+
this.reporter = utils_2.getReporter(reporters);
|
|
51
|
+
if (this.jUnitReport) {
|
|
52
|
+
reporters.push(new junit_1.JUnitReporter(this));
|
|
53
|
+
}
|
|
54
|
+
yield this.resolveConfig();
|
|
55
|
+
const startTime = Date.now();
|
|
56
|
+
if (this.config.tunnel) {
|
|
57
|
+
this.reporter.log('You are using tunnel option, the chosen location(s) will be overridden by a location in your account region.\n');
|
|
58
|
+
}
|
|
59
|
+
let results;
|
|
60
|
+
let summary;
|
|
61
|
+
let tests;
|
|
62
|
+
let triggers;
|
|
63
|
+
try {
|
|
64
|
+
;
|
|
65
|
+
({ results, summary, tests, triggers } = yield run_test_1.executeTests(this.reporter, this.config));
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
if (error instanceof errors_1.CiError) {
|
|
69
|
+
this.reportCiError(error, this.reporter);
|
|
70
|
+
if (error instanceof errors_1.CriticalError && this.config.failOnCriticalErrors) {
|
|
71
|
+
return 1;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return 0;
|
|
75
|
+
}
|
|
76
|
+
return this.renderResults(results, summary, tests, triggers, startTime);
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
getAppBaseURL() {
|
|
80
|
+
return `https://${this.config.subdomain}.${this.config.datadogSite}/`;
|
|
81
|
+
}
|
|
82
|
+
renderResults(results, summary, tests, triggers, startTime) {
|
|
83
|
+
var _a, _b, _c, _d;
|
|
84
|
+
// Sort tests to show success first then non blocking failures and finally blocking failures.
|
|
85
|
+
tests.sort(this.sortTestsByOutcome(results));
|
|
86
|
+
// Rendering the results.
|
|
87
|
+
(_a = this.reporter) === null || _a === void 0 ? void 0 : _a.reportStart({ startTime });
|
|
88
|
+
const locationNames = triggers.locations.reduce((mapping, location) => {
|
|
89
|
+
mapping[location.id] = location.display_name;
|
|
90
|
+
return mapping;
|
|
91
|
+
}, {});
|
|
92
|
+
let hasSucceeded = true; // Determine if all the tests have succeeded
|
|
93
|
+
for (const test of tests) {
|
|
94
|
+
const testResults = results[test.public_id];
|
|
95
|
+
if (!this.config.failOnTimeout) {
|
|
96
|
+
if (!summary.timedOut) {
|
|
97
|
+
summary.timedOut = 0;
|
|
98
|
+
}
|
|
99
|
+
const hasTimeout = testResults.some((pollResult) => pollResult.result.error === interfaces_1.ERRORS.TIMEOUT);
|
|
100
|
+
if (hasTimeout) {
|
|
101
|
+
summary.timedOut++;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
if (!this.config.failOnCriticalErrors) {
|
|
105
|
+
if (!summary.criticalErrors) {
|
|
106
|
+
summary.criticalErrors = 0;
|
|
107
|
+
}
|
|
108
|
+
const hasCriticalErrors = testResults.some((pollResult) => utils_2.isCriticalError(pollResult.result));
|
|
109
|
+
if (hasCriticalErrors) {
|
|
110
|
+
summary.criticalErrors++;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
const passed = utils_2.hasTestSucceeded(testResults, this.config.failOnCriticalErrors, this.config.failOnTimeout);
|
|
114
|
+
if (passed) {
|
|
115
|
+
summary.passed++;
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
summary.failed++;
|
|
119
|
+
if (((_b = test.options.ci) === null || _b === void 0 ? void 0 : _b.executionRule) !== interfaces_1.ExecutionRule.NON_BLOCKING) {
|
|
120
|
+
hasSucceeded = false;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
(_c = this.reporter) === null || _c === void 0 ? void 0 : _c.testEnd(test, testResults, this.getAppBaseURL(), locationNames, this.config.failOnCriticalErrors, this.config.failOnTimeout);
|
|
124
|
+
}
|
|
125
|
+
(_d = this.reporter) === null || _d === void 0 ? void 0 : _d.runEnd(summary);
|
|
126
|
+
return hasSucceeded ? 0 : 1;
|
|
127
|
+
}
|
|
128
|
+
reportCiError(error, reporter) {
|
|
129
|
+
switch (error.code) {
|
|
130
|
+
case 'NO_RESULTS_TO_POLL':
|
|
131
|
+
reporter.log('No results to poll.\n');
|
|
132
|
+
break;
|
|
133
|
+
case 'NO_TESTS_TO_RUN':
|
|
134
|
+
reporter.log('No test to run.\n');
|
|
135
|
+
break;
|
|
136
|
+
case 'MISSING_APP_KEY':
|
|
137
|
+
reporter.error(`Missing ${chalk_1.default.red.bold('DATADOG_APP_KEY')} in your environment.\n`);
|
|
138
|
+
break;
|
|
139
|
+
case 'MISSING_API_KEY':
|
|
140
|
+
reporter.error(`Missing ${chalk_1.default.red.bold('DATADOG_API_KEY')} in your environment.\n`);
|
|
141
|
+
break;
|
|
142
|
+
case 'POLL_RESULTS_FAILED':
|
|
143
|
+
reporter.error(`\n${chalk_1.default.bgRed.bold(' ERROR: unable to poll test results ')}\n${error.message}\n\n`);
|
|
144
|
+
break;
|
|
145
|
+
case 'TUNNEL_START_FAILED':
|
|
146
|
+
reporter.error(`\n${chalk_1.default.bgRed.bold(' ERROR: unable to start tunnel')}\n${error.message}\n\n`);
|
|
147
|
+
break;
|
|
148
|
+
case 'TRIGGER_TESTS_FAILED':
|
|
149
|
+
reporter.error(`\n${chalk_1.default.bgRed.bold(' ERROR: unable to trigger tests')}\n${error.message}\n\n`);
|
|
150
|
+
break;
|
|
151
|
+
case 'UNAVAILABLE_TEST_CONFIG':
|
|
152
|
+
reporter.error(`\n${chalk_1.default.bgRed.bold(' ERROR: unable to obtain test configurations with search query ')}\n${error.message}\n\n`);
|
|
153
|
+
break;
|
|
154
|
+
case 'UNAVAILABLE_TUNNEL_CONFIG':
|
|
155
|
+
reporter.error(`\n${chalk_1.default.bgRed.bold(' ERROR: unable to get tunnel configuration')}\n${error.message}\n\n`);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
resolveConfig() {
|
|
159
|
+
var _a, _b;
|
|
160
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
161
|
+
// Default < file < ENV < CLI
|
|
162
|
+
// Override with file config variables
|
|
163
|
+
try {
|
|
164
|
+
this.config = yield utils_1.parseConfigFile(this.config, (_a = this.configPath) !== null && _a !== void 0 ? _a : this.config.configPath);
|
|
165
|
+
}
|
|
166
|
+
catch (error) {
|
|
167
|
+
if (this.configPath) {
|
|
168
|
+
throw error;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
// Override with ENV variables
|
|
172
|
+
this.config = deep_extend_1.default(this.config, utils_1.removeUndefinedValues({
|
|
173
|
+
apiKey: process.env.DATADOG_API_KEY,
|
|
174
|
+
appKey: process.env.DATADOG_APP_KEY,
|
|
175
|
+
datadogSite: process.env.DATADOG_SITE,
|
|
176
|
+
locations: (_b = process.env.DATADOG_SYNTHETICS_LOCATIONS) === null || _b === void 0 ? void 0 : _b.split(';'),
|
|
177
|
+
subdomain: process.env.DATADOG_SUBDOMAIN,
|
|
178
|
+
}));
|
|
179
|
+
// Override with CLI parameters
|
|
180
|
+
this.config = deep_extend_1.default(this.config, utils_1.removeUndefinedValues({
|
|
181
|
+
apiKey: this.apiKey,
|
|
182
|
+
appKey: this.appKey,
|
|
183
|
+
configPath: this.configPath,
|
|
184
|
+
datadogSite: this.datadogSite,
|
|
185
|
+
failOnCriticalErrors: this.failOnCriticalErrors,
|
|
186
|
+
failOnTimeout: this.failOnTimeout,
|
|
187
|
+
files: this.files,
|
|
188
|
+
publicIds: this.publicIds,
|
|
189
|
+
subdomain: this.subdomain,
|
|
190
|
+
testSearchQuery: this.testSearchQuery,
|
|
191
|
+
tunnel: this.tunnel,
|
|
192
|
+
}));
|
|
193
|
+
if (typeof this.config.files === 'string') {
|
|
194
|
+
this.reporter.log('[DEPRECATED] "files" should be an array of string instead of a string.\n');
|
|
195
|
+
this.config.files = [this.config.files];
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
sortTestsByOutcome(results) {
|
|
200
|
+
return (t1, t2) => {
|
|
201
|
+
var _a, _b;
|
|
202
|
+
const success1 = utils_2.hasTestSucceeded(results[t1.public_id], this.config.failOnCriticalErrors, this.config.failOnTimeout);
|
|
203
|
+
const success2 = utils_2.hasTestSucceeded(results[t2.public_id], this.config.failOnCriticalErrors, this.config.failOnTimeout);
|
|
204
|
+
const isNonBlockingTest1 = ((_a = t1.options.ci) === null || _a === void 0 ? void 0 : _a.executionRule) === interfaces_1.ExecutionRule.NON_BLOCKING;
|
|
205
|
+
const isNonBlockingTest2 = ((_b = t2.options.ci) === null || _b === void 0 ? void 0 : _b.executionRule) === interfaces_1.ExecutionRule.NON_BLOCKING;
|
|
206
|
+
if (success1 === success2) {
|
|
207
|
+
if (isNonBlockingTest1 === isNonBlockingTest2) {
|
|
208
|
+
return 0;
|
|
209
|
+
}
|
|
210
|
+
return isNonBlockingTest1 ? -1 : 1;
|
|
211
|
+
}
|
|
212
|
+
return success1 ? -1 : 1;
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
exports.RunTestCommand = RunTestCommand;
|
|
217
|
+
RunTestCommand.addPath('synthetics', 'run-tests');
|
|
218
|
+
RunTestCommand.addOption('apiKey', clipanion_1.Command.String('--apiKey'));
|
|
219
|
+
RunTestCommand.addOption('appKey', clipanion_1.Command.String('--appKey'));
|
|
220
|
+
RunTestCommand.addOption('failOnCriticalErrors', clipanion_1.Command.Boolean('--failOnCriticalErrors'));
|
|
221
|
+
RunTestCommand.addOption('configPath', clipanion_1.Command.String('--config'));
|
|
222
|
+
RunTestCommand.addOption('datadogSite', clipanion_1.Command.String('--datadogSite'));
|
|
223
|
+
RunTestCommand.addOption('files', clipanion_1.Command.Array('-f,--files'));
|
|
224
|
+
RunTestCommand.addOption('failOnTimeout', clipanion_1.Command.Boolean('--failOnTimeout'));
|
|
225
|
+
RunTestCommand.addOption('publicIds', clipanion_1.Command.Array('-p,--public-id'));
|
|
226
|
+
RunTestCommand.addOption('testSearchQuery', clipanion_1.Command.String('-s,--search'));
|
|
227
|
+
RunTestCommand.addOption('subdomain', clipanion_1.Command.Boolean('--subdomain'));
|
|
228
|
+
RunTestCommand.addOption('tunnel', clipanion_1.Command.Boolean('-t,--tunnel'));
|
|
229
|
+
RunTestCommand.addOption('runName', clipanion_1.Command.String('-n,--runName'));
|
|
@@ -1,4 +1,33 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
10
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
11
|
+
}) : function(o, v) {
|
|
12
|
+
o["default"] = v;
|
|
13
|
+
});
|
|
14
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
15
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
16
|
+
};
|
|
17
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
18
|
+
if (mod && mod.__esModule) return mod;
|
|
19
|
+
var result = {};
|
|
20
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
21
|
+
__setModuleDefault(result, mod);
|
|
22
|
+
return result;
|
|
23
|
+
};
|
|
2
24
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
|
|
4
|
-
|
|
25
|
+
exports.utils = exports.executeTests = exports.DefaultReporter = exports.CiError = void 0;
|
|
26
|
+
var errors_1 = require("./errors");
|
|
27
|
+
Object.defineProperty(exports, "CiError", { enumerable: true, get: function () { return errors_1.CiError; } });
|
|
28
|
+
__exportStar(require("./interfaces"), exports);
|
|
29
|
+
var default_1 = require("./reporters/default");
|
|
30
|
+
Object.defineProperty(exports, "DefaultReporter", { enumerable: true, get: function () { return default_1.DefaultReporter; } });
|
|
31
|
+
var run_test_1 = require("./run-test");
|
|
32
|
+
Object.defineProperty(exports, "executeTests", { enumerable: true, get: function () { return run_test_1.executeTests; } });
|
|
33
|
+
exports.utils = __importStar(require("./utils"));
|
|
@@ -292,9 +292,9 @@ export interface Suite {
|
|
|
292
292
|
export interface Summary {
|
|
293
293
|
criticalErrors: number;
|
|
294
294
|
failed: number;
|
|
295
|
-
notFound: number;
|
|
296
295
|
passed: number;
|
|
297
296
|
skipped: number;
|
|
297
|
+
testsNotFound: Set<string>;
|
|
298
298
|
timedOut: number;
|
|
299
299
|
}
|
|
300
300
|
export interface TestSearchResult {
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { BaseContext } from 'clipanion';
|
|
2
|
-
import { ConfigOverride, ExecutionRule, LocationsMapping,
|
|
3
|
-
export declare class DefaultReporter implements
|
|
2
|
+
import { ConfigOverride, ExecutionRule, LocationsMapping, MainReporter, PollResult, Summary, Test } from '../interfaces';
|
|
3
|
+
export declare class DefaultReporter implements MainReporter {
|
|
4
4
|
private write;
|
|
5
5
|
constructor({ context }: {
|
|
6
6
|
context: BaseContext;
|
|
7
7
|
});
|
|
8
8
|
error(error: string): void;
|
|
9
|
-
|
|
9
|
+
initErrors(errors: string[]): void;
|
|
10
10
|
log(log: string): void;
|
|
11
11
|
reportStart(timings: {
|
|
12
12
|
startTime: number;
|
|
@@ -190,7 +190,7 @@ class DefaultReporter {
|
|
|
190
190
|
error(error) {
|
|
191
191
|
this.write(error);
|
|
192
192
|
}
|
|
193
|
-
|
|
193
|
+
initErrors(errors) {
|
|
194
194
|
this.write(errors.join('\n'));
|
|
195
195
|
}
|
|
196
196
|
log(log) {
|
|
@@ -208,8 +208,9 @@ class DefaultReporter {
|
|
|
208
208
|
if (summary.skipped) {
|
|
209
209
|
summaries.push(`${chalk_1.default.bold(summary.skipped)} skipped`);
|
|
210
210
|
}
|
|
211
|
-
if (summary.
|
|
212
|
-
|
|
211
|
+
if (summary.testsNotFound.size > 0) {
|
|
212
|
+
const testsNotFoundStr = chalk_1.default.gray(`(${[...summary.testsNotFound].join(', ')})`);
|
|
213
|
+
summaries.push(`${chalk_1.default.yellow(`${chalk_1.default.bold(summary.testsNotFound.size)} not found`)} ${testsNotFoundStr}`);
|
|
213
214
|
}
|
|
214
215
|
const extraInfo = [];
|
|
215
216
|
if (summary.timedOut) {
|
|
@@ -12,6 +12,7 @@ export declare const waitForResults: (api: APIHelper, triggerResponses: TriggerR
|
|
|
12
12
|
[key: string]: PollResult[];
|
|
13
13
|
}>;
|
|
14
14
|
export declare const createTriggerResultMap: (triggerResponses: TriggerResponse[], defaultTimeout: number, triggerConfigs: TriggerConfig[]) => Map<string, TriggerResult>;
|
|
15
|
+
export declare const createSummary: () => Summary;
|
|
15
16
|
export declare const getResultDuration: (result: Result) => number;
|
|
16
17
|
export declare const getReporter: (reporters: Reporter[]) => MainReporter;
|
|
17
18
|
export declare const getTestsToTrigger: (api: APIHelper, triggerConfigs: TriggerConfig[], reporter: MainReporter) => Promise<{
|
|
@@ -21,6 +22,3 @@ export declare const getTestsToTrigger: (api: APIHelper, triggerConfigs: Trigger
|
|
|
21
22
|
}>;
|
|
22
23
|
export declare const runTests: (api: APIHelper, testsToTrigger: TestPayload[]) => Promise<Trigger>;
|
|
23
24
|
export declare const retry: <T, E extends Error>(func: () => Promise<T>, shouldRetryAfterWait: (retries: number, error: E) => number | undefined) => Promise<T>;
|
|
24
|
-
export declare const removeUndefinedValues: <T extends {
|
|
25
|
-
[key: string]: any;
|
|
26
|
-
}>(object: T) => T;
|
|
@@ -31,7 +31,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
31
31
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
32
32
|
};
|
|
33
33
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
34
|
-
exports.
|
|
34
|
+
exports.retry = exports.runTests = exports.getTestsToTrigger = exports.getReporter = exports.getResultDuration = exports.createSummary = exports.createTriggerResultMap = exports.waitForResults = exports.wait = exports.getSuites = exports.hasTestSucceeded = exports.hasResultPassed = exports.isCriticalError = exports.getStrictestExecutionRule = exports.getExecutionRule = exports.handleConfig = void 0;
|
|
35
35
|
const fs = __importStar(require("fs"));
|
|
36
36
|
const path = __importStar(require("path"));
|
|
37
37
|
const url_1 = require("url");
|
|
@@ -284,12 +284,21 @@ const createFailingResult = (errorMessage, resultId, deviceId, dcId, tunnel) =>
|
|
|
284
284
|
resultID: resultId,
|
|
285
285
|
timestamp: 0,
|
|
286
286
|
});
|
|
287
|
+
const createSummary = () => ({
|
|
288
|
+
criticalErrors: 0,
|
|
289
|
+
failed: 0,
|
|
290
|
+
passed: 0,
|
|
291
|
+
skipped: 0,
|
|
292
|
+
testsNotFound: new Set(),
|
|
293
|
+
timedOut: 0,
|
|
294
|
+
});
|
|
295
|
+
exports.createSummary = createSummary;
|
|
287
296
|
const getResultDuration = (result) => {
|
|
288
297
|
if ('duration' in result) {
|
|
289
|
-
return result.duration;
|
|
298
|
+
return Math.round(result.duration);
|
|
290
299
|
}
|
|
291
300
|
if ('timings' in result) {
|
|
292
|
-
return result.timings.total;
|
|
301
|
+
return Math.round(result.timings.total);
|
|
293
302
|
}
|
|
294
303
|
return 0;
|
|
295
304
|
};
|
|
@@ -356,7 +365,7 @@ exports.getReporter = getReporter;
|
|
|
356
365
|
const getTestsToTrigger = (api, triggerConfigs, reporter) => __awaiter(void 0, void 0, void 0, function* () {
|
|
357
366
|
const overriddenTestsToTrigger = [];
|
|
358
367
|
const errorMessages = [];
|
|
359
|
-
const summary =
|
|
368
|
+
const summary = exports.createSummary();
|
|
360
369
|
const tests = yield Promise.all(triggerConfigs.map(({ config, id, suite }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
361
370
|
let test;
|
|
362
371
|
id = PUBLIC_ID_REGEX.test(id) ? id : id.substr(id.lastIndexOf('/') + 1);
|
|
@@ -367,7 +376,7 @@ const getTestsToTrigger = (api, triggerConfigs, reporter) => __awaiter(void 0, v
|
|
|
367
376
|
if (api_1.is5xxError(e)) {
|
|
368
377
|
throw e;
|
|
369
378
|
}
|
|
370
|
-
summary.
|
|
379
|
+
summary.testsNotFound.add(id);
|
|
371
380
|
const errorMessage = api_1.formatBackendErrors(e);
|
|
372
381
|
errorMessages.push(`[${chalk_1.default.bold.dim(id)}] ${chalk_1.default.yellow.bold('Test not found')}: ${errorMessage}\n`);
|
|
373
382
|
return;
|
|
@@ -426,13 +435,3 @@ const retry = (func, shouldRetryAfterWait) => __awaiter(void 0, void 0, void 0,
|
|
|
426
435
|
return trier();
|
|
427
436
|
});
|
|
428
437
|
exports.retry = retry;
|
|
429
|
-
const removeUndefinedValues = (object) => {
|
|
430
|
-
const newObject = Object.assign({}, object);
|
|
431
|
-
for (const [key, value] of Object.entries(newObject)) {
|
|
432
|
-
if (value === undefined) {
|
|
433
|
-
delete newObject[key];
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
|
-
return newObject;
|
|
437
|
-
};
|
|
438
|
-
exports.removeUndefinedValues = removeUndefinedValues;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
File without changes
|