@testomatio/reporter 2.1.2-beta.1-alias → 2.1.3-beta.1-multi-links
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/lib/adapter/codecept.js +3 -4
- package/lib/bin/startTest.js +91 -38
- package/lib/pipe/testomatio.js +2 -1
- package/lib/reporter-functions.d.ts +6 -12
- package/lib/reporter-functions.js +9 -11
- package/lib/reporter.d.ts +8 -8
- package/lib/reporter.js +6 -6
- package/lib/services/links.d.ts +22 -0
- package/lib/services/links.js +71 -0
- package/lib/utils/cli_utils.d.ts +1 -0
- package/lib/utils/cli_utils.js +65552 -0
- package/package.json +1 -1
- package/src/adapter/codecept.js +3 -4
- package/src/bin/startTest.js +114 -43
- package/src/pipe/testomatio.js +2 -1
- package/src/reporter-functions.js +10 -11
- package/src/reporter.js +6 -6
package/lib/adapter/codecept.js
CHANGED
|
@@ -50,18 +50,17 @@ function CodeceptReporter(config) {
|
|
|
50
50
|
};
|
|
51
51
|
output.debug = function (msg) {
|
|
52
52
|
originalOutput.debug(msg);
|
|
53
|
-
data_storage_js_1.dataStorage.putData('log', repeat(this
|
|
53
|
+
data_storage_js_1.dataStorage.putData('log', repeat(this.stepShift) + picocolors_1.default.cyan(msg.toString()));
|
|
54
54
|
};
|
|
55
55
|
output.say = function (message, color = 'cyan') {
|
|
56
56
|
originalOutput.say(message, color);
|
|
57
|
-
const sayMsg = repeat(this
|
|
57
|
+
const sayMsg = repeat(this.stepShift) + ` ${picocolors_1.default.bold(picocolors_1.default[color](message))}`;
|
|
58
58
|
data_storage_js_1.dataStorage.putData('log', sayMsg);
|
|
59
59
|
};
|
|
60
60
|
output.log = function (msg) {
|
|
61
61
|
originalOutput.log(msg);
|
|
62
|
-
data_storage_js_1.dataStorage.putData('log', repeat(this
|
|
62
|
+
data_storage_js_1.dataStorage.putData('log', repeat(this.stepShift) + picocolors_1.default.gray(msg));
|
|
63
63
|
};
|
|
64
|
-
output.stepShift = 0;
|
|
65
64
|
recorder.startUnlessRunning();
|
|
66
65
|
const hookSteps = new Map();
|
|
67
66
|
let currentHook = null;
|
package/lib/bin/startTest.js
CHANGED
|
@@ -4,50 +4,103 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
5
|
};
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const utils_js_1 = require("../utils/utils.js");
|
|
7
|
+
const cross_spawn_1 = require("cross-spawn");
|
|
8
|
+
const commander_1 = require("commander");
|
|
10
9
|
const picocolors_1 = __importDefault(require("picocolors"));
|
|
11
|
-
|
|
12
|
-
const
|
|
10
|
+
const client_js_1 = __importDefault(require("../client.js"));
|
|
11
|
+
const constants_js_1 = require("../constants.js");
|
|
12
|
+
const utils_js_1 = require("../utils/utils.js");
|
|
13
|
+
const config_js_1 = require("../config.js");
|
|
14
|
+
const dotenv_1 = __importDefault(require("dotenv"));
|
|
13
15
|
const version = (0, utils_js_1.getPackageVersion)();
|
|
14
16
|
console.log(picocolors_1.default.cyan(picocolors_1.default.bold(` 🤩 Testomat.io Reporter v${version}`)));
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
17
|
+
const program = new commander_1.Command();
|
|
18
|
+
program
|
|
19
|
+
.option('-c, --command <cmd>', 'Test runner command')
|
|
20
|
+
.option('--launch', 'Start a new run and return its ID')
|
|
21
|
+
.option('--finish', 'Finish Run by its ID')
|
|
22
|
+
.option('--env-file <envfile>', 'Load environment variables from env file')
|
|
23
|
+
.option('--filter <filter>', 'Additional execution filter')
|
|
24
|
+
.action(async (opts) => {
|
|
25
|
+
const { launch, finish, filter } = opts;
|
|
26
|
+
let { command } = opts;
|
|
27
|
+
if (opts.envFile)
|
|
28
|
+
dotenv_1.default.config({ path: opts.envFile });
|
|
29
|
+
const apiKey = process.env['INPUT_TESTOMATIO-KEY'] || config_js_1.config.TESTOMATIO;
|
|
30
|
+
const title = process.env.TESTOMATIO_TITLE;
|
|
31
|
+
if (launch) {
|
|
32
|
+
console.log('Starting a new Run on Testomat.io...');
|
|
33
|
+
const client = new client_js_1.default({ apiKey });
|
|
34
|
+
client.createRun().then(() => {
|
|
35
|
+
console.log(process.env.runId);
|
|
36
|
+
process.exit(0);
|
|
37
|
+
});
|
|
38
|
+
return;
|
|
27
39
|
}
|
|
28
|
-
|
|
29
|
-
//
|
|
30
|
-
|
|
31
|
-
|
|
40
|
+
if (finish) {
|
|
41
|
+
// TODO: add error in case of TESTOMATIO environment variable is not set
|
|
42
|
+
// because command is fine in console, but actually (on testomat.io) run is not finished
|
|
43
|
+
if (!process.env.TESTOMATIO_RUN) {
|
|
44
|
+
console.log('TESTOMATIO_RUN environment variable must be set.');
|
|
45
|
+
return process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
console.log('Finishing Run on Testomat.io...');
|
|
48
|
+
const client = new client_js_1.default({ apiKey });
|
|
49
|
+
// @ts-ignore
|
|
50
|
+
client.updateRunStatus(constants_js_1.STATUS.FINISHED).then(() => {
|
|
51
|
+
console.log(picocolors_1.default.yellow(`Run ${process.env.TESTOMATIO_RUN} was finished`));
|
|
52
|
+
process.exit(0);
|
|
53
|
+
});
|
|
54
|
+
return;
|
|
32
55
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
56
|
+
let exitCode = 0;
|
|
57
|
+
if (!command.split) {
|
|
58
|
+
process.exitCode = 255;
|
|
59
|
+
console.log(constants_js_1.APP_PREFIX, `No command provided. Use -c option to launch a test runner.`);
|
|
60
|
+
return;
|
|
36
61
|
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
62
|
+
const client = new client_js_1.default({ apiKey, title, parallel: true });
|
|
63
|
+
if (filter) {
|
|
64
|
+
const [pipe, ...optsArray] = filter.split(':');
|
|
65
|
+
const pipeOptions = optsArray.join(':');
|
|
66
|
+
try {
|
|
67
|
+
const tests = await client.prepareRun({ pipe, pipeOptions });
|
|
68
|
+
if (!tests || tests.length === 0) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
const grep = ` --grep (${tests.join('|')})`;
|
|
72
|
+
command += grep;
|
|
73
|
+
}
|
|
74
|
+
catch (err) {
|
|
75
|
+
console.log(constants_js_1.APP_PREFIX, err);
|
|
76
|
+
}
|
|
40
77
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
78
|
+
const testCmds = command.split(' ');
|
|
79
|
+
console.log(constants_js_1.APP_PREFIX, `🚀 Running`, picocolors_1.default.green(command));
|
|
80
|
+
if (!apiKey) {
|
|
81
|
+
const cmd = (0, cross_spawn_1.spawn)(testCmds[0], testCmds.slice(1), { stdio: 'inherit' });
|
|
82
|
+
cmd.on('close', code => {
|
|
83
|
+
console.log(constants_js_1.APP_PREFIX, '⚠️ ', `Runner exited with ${picocolors_1.default.bold(code)}, report is ignored`);
|
|
84
|
+
if (code > exitCode)
|
|
85
|
+
exitCode = code;
|
|
86
|
+
process.exitCode = exitCode;
|
|
87
|
+
});
|
|
88
|
+
return;
|
|
44
89
|
}
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
90
|
+
client.createRun().then(() => {
|
|
91
|
+
const cmd = (0, cross_spawn_1.spawn)(testCmds[0], testCmds.slice(1), { stdio: 'inherit' });
|
|
92
|
+
cmd.on('close', code => {
|
|
93
|
+
const emoji = code === 0 ? '🟢' : '🔴';
|
|
94
|
+
console.log(constants_js_1.APP_PREFIX, emoji, `Runner exited with ${picocolors_1.default.bold(code)}`);
|
|
95
|
+
const status = code === 0 ? 'passed' : 'failed';
|
|
96
|
+
client.updateRunStatus(status, true);
|
|
97
|
+
if (code > exitCode)
|
|
98
|
+
exitCode = code;
|
|
99
|
+
process.exitCode = exitCode;
|
|
100
|
+
});
|
|
101
|
+
});
|
|
53
102
|
});
|
|
103
|
+
if (process.argv.length <= 2) {
|
|
104
|
+
program.outputHelp();
|
|
105
|
+
}
|
|
106
|
+
program.parse(process.argv);
|
package/lib/pipe/testomatio.js
CHANGED
|
@@ -113,7 +113,8 @@ class TestomatioPipe {
|
|
|
113
113
|
const resp = await this.client.request({
|
|
114
114
|
method: 'GET',
|
|
115
115
|
url: '/api/test_grep',
|
|
116
|
-
|
|
116
|
+
params: q.params,
|
|
117
|
+
responseType: q.responseType
|
|
117
118
|
});
|
|
118
119
|
if (Array.isArray(resp.data?.tests) && resp.data?.tests?.length > 0) {
|
|
119
120
|
(0, utils_js_1.foundedTestLog)(constants_js_1.APP_PREFIX, resp.data.tests);
|
|
@@ -9,8 +9,6 @@ export default _default;
|
|
|
9
9
|
/**
|
|
10
10
|
* Stores path to file as artifact and uploads it to the S3 storage
|
|
11
11
|
* @param {string | {path: string, type: string, name: string}} data - path to file or object with path, type and name
|
|
12
|
-
* @param {any} [context=null] - optional context parameter
|
|
13
|
-
* @returns {void}
|
|
14
12
|
*/
|
|
15
13
|
declare function saveArtifact(data: string | {
|
|
16
14
|
path: string;
|
|
@@ -19,21 +17,18 @@ declare function saveArtifact(data: string | {
|
|
|
19
17
|
}, context?: any): void;
|
|
20
18
|
/**
|
|
21
19
|
* Attach log message(s) to the test report
|
|
22
|
-
* @param
|
|
23
|
-
* @returns {void}
|
|
20
|
+
* @param string
|
|
24
21
|
*/
|
|
25
22
|
declare function logMessage(...args: any[]): void;
|
|
26
23
|
/**
|
|
27
24
|
* Similar to "log" function but marks message in report as a step
|
|
28
|
-
* @param {string} message
|
|
29
|
-
* @returns {void}
|
|
25
|
+
* @param {string} message
|
|
30
26
|
*/
|
|
31
27
|
declare function addStep(message: string): void;
|
|
32
28
|
/**
|
|
33
29
|
* Add key-value pair(s) to the test report
|
|
34
|
-
* @param {{[key: string]: string} | string} keyValue
|
|
35
|
-
* @param {string
|
|
36
|
-
* @returns {void}
|
|
30
|
+
* @param {{[key: string]: string} | string} keyValue object { key: value } (multiple props allowed) or key (string)
|
|
31
|
+
* @param {string?} value
|
|
37
32
|
*/
|
|
38
33
|
declare function setKeyValue(keyValue: {
|
|
39
34
|
[key: string]: string;
|
|
@@ -41,7 +36,6 @@ declare function setKeyValue(keyValue: {
|
|
|
41
36
|
/**
|
|
42
37
|
* Add a single label to the test report
|
|
43
38
|
* @param {string} key - label key (e.g. 'severity', 'feature', or just 'smoke' for labels without values)
|
|
44
|
-
* @param {string
|
|
45
|
-
* @returns {void}
|
|
39
|
+
* @param {string} [value] - optional label value (e.g. 'high', 'login')
|
|
46
40
|
*/
|
|
47
|
-
declare function setLabel(key: string, value?: string
|
|
41
|
+
declare function setLabel(key: string, value?: string): void;
|
|
@@ -4,8 +4,6 @@ const index_js_1 = require("./services/index.js");
|
|
|
4
4
|
/**
|
|
5
5
|
* Stores path to file as artifact and uploads it to the S3 storage
|
|
6
6
|
* @param {string | {path: string, type: string, name: string}} data - path to file or object with path, type and name
|
|
7
|
-
* @param {any} [context=null] - optional context parameter
|
|
8
|
-
* @returns {void}
|
|
9
7
|
*/
|
|
10
8
|
function saveArtifact(data, context = null) {
|
|
11
9
|
if (process.env.IS_PLAYWRIGHT)
|
|
@@ -17,8 +15,7 @@ function saveArtifact(data, context = null) {
|
|
|
17
15
|
}
|
|
18
16
|
/**
|
|
19
17
|
* Attach log message(s) to the test report
|
|
20
|
-
* @param
|
|
21
|
-
* @returns {void}
|
|
18
|
+
* @param string
|
|
22
19
|
*/
|
|
23
20
|
function logMessage(...args) {
|
|
24
21
|
if (process.env.IS_PLAYWRIGHT)
|
|
@@ -27,8 +24,7 @@ function logMessage(...args) {
|
|
|
27
24
|
}
|
|
28
25
|
/**
|
|
29
26
|
* Similar to "log" function but marks message in report as a step
|
|
30
|
-
* @param {string} message
|
|
31
|
-
* @returns {void}
|
|
27
|
+
* @param {string} message
|
|
32
28
|
*/
|
|
33
29
|
function addStep(message) {
|
|
34
30
|
if (process.env.IS_PLAYWRIGHT)
|
|
@@ -37,9 +33,8 @@ function addStep(message) {
|
|
|
37
33
|
}
|
|
38
34
|
/**
|
|
39
35
|
* Add key-value pair(s) to the test report
|
|
40
|
-
* @param {{[key: string]: string} | string} keyValue
|
|
41
|
-
* @param {string
|
|
42
|
-
* @returns {void}
|
|
36
|
+
* @param {{[key: string]: string} | string} keyValue object { key: value } (multiple props allowed) or key (string)
|
|
37
|
+
* @param {string?} value
|
|
43
38
|
*/
|
|
44
39
|
function setKeyValue(keyValue, value = null) {
|
|
45
40
|
if (process.env.IS_PLAYWRIGHT)
|
|
@@ -52,10 +47,13 @@ function setKeyValue(keyValue, value = null) {
|
|
|
52
47
|
/**
|
|
53
48
|
* Add a single label to the test report
|
|
54
49
|
* @param {string} key - label key (e.g. 'severity', 'feature', or just 'smoke' for labels without values)
|
|
55
|
-
* @param {string
|
|
56
|
-
* @returns {void}
|
|
50
|
+
* @param {string} [value] - optional label value (e.g. 'high', 'login')
|
|
57
51
|
*/
|
|
58
52
|
function setLabel(key, value = null) {
|
|
53
|
+
if (Array.isArray(value)) {
|
|
54
|
+
value.forEach(v => setLabel(key, v));
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
59
57
|
if (!key || typeof key !== 'string') {
|
|
60
58
|
console.warn('Label key must be a non-empty string');
|
|
61
59
|
return;
|
package/lib/reporter.d.ts
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
|
+
export type artifact = typeof import("./reporter-functions.js");
|
|
1
2
|
export const artifact: (data: string | {
|
|
2
3
|
path: string;
|
|
3
4
|
type: string;
|
|
4
5
|
name: string;
|
|
5
6
|
}, context?: any) => void;
|
|
7
|
+
export type log = typeof import("./reporter-functions.js");
|
|
6
8
|
export const log: (...args: any[]) => void;
|
|
9
|
+
export type logger = typeof import("./services/index.js");
|
|
7
10
|
export const logger: {
|
|
8
11
|
"__#13@#originalUserLogger": {
|
|
9
12
|
assert(condition?: boolean, ...data: any[]): void;
|
|
@@ -72,11 +75,14 @@ export const logger: {
|
|
|
72
75
|
}): void;
|
|
73
76
|
prettyObjects: boolean;
|
|
74
77
|
};
|
|
78
|
+
export type meta = typeof import("./reporter-functions.js");
|
|
75
79
|
export const meta: (keyValue: {
|
|
76
80
|
[key: string]: string;
|
|
77
81
|
} | string, value?: string | null) => void;
|
|
82
|
+
export type step = typeof import("./reporter-functions.js");
|
|
78
83
|
export const step: (message: string) => void;
|
|
79
|
-
export
|
|
84
|
+
export type label = typeof import("./reporter-functions.js");
|
|
85
|
+
export const label: (key: string, value?: string) => void;
|
|
80
86
|
declare namespace _default {
|
|
81
87
|
let testomatioLogger: {
|
|
82
88
|
"__#13@#originalUserLogger": {
|
|
@@ -224,12 +230,6 @@ declare namespace _default {
|
|
|
224
230
|
[key: string]: string;
|
|
225
231
|
} | string, value?: string | null) => void;
|
|
226
232
|
let step: (message: string) => void;
|
|
227
|
-
let label: (key: string, value?: string
|
|
233
|
+
let label: (key: string, value?: string) => void;
|
|
228
234
|
}
|
|
229
235
|
export default _default;
|
|
230
|
-
export type ArtifactFunction = typeof import("./reporter-functions.js").default.artifact;
|
|
231
|
-
export type LogFunction = typeof import("./reporter-functions.js").default.log;
|
|
232
|
-
export type LoggerService = typeof import("./services/index.js").services.logger;
|
|
233
|
-
export type MetaFunction = typeof import("./reporter-functions.js").default.keyValue;
|
|
234
|
-
export type StepFunction = typeof import("./reporter-functions.js").default.step;
|
|
235
|
-
export type LabelFunction = typeof import("./reporter-functions.js").default.label;
|
package/lib/reporter.js
CHANGED
|
@@ -15,12 +15,12 @@ exports.meta = reporter_functions_js_1.default.keyValue;
|
|
|
15
15
|
exports.step = reporter_functions_js_1.default.step;
|
|
16
16
|
exports.label = reporter_functions_js_1.default.label;
|
|
17
17
|
/**
|
|
18
|
-
* @typedef {
|
|
19
|
-
* @typedef {
|
|
20
|
-
* @typedef {
|
|
21
|
-
* @typedef {
|
|
22
|
-
* @typedef {
|
|
23
|
-
* @typedef {
|
|
18
|
+
* @typedef {import('./reporter-functions.js')} artifact
|
|
19
|
+
* @typedef {import('./reporter-functions.js')} log
|
|
20
|
+
* @typedef {import('./services/index.js')} logger
|
|
21
|
+
* @typedef {import('./reporter-functions.js')} meta
|
|
22
|
+
* @typedef {import('./reporter-functions.js')} step
|
|
23
|
+
* @typedef {import('./reporter-functions.js')} label
|
|
24
24
|
*/
|
|
25
25
|
module.exports = {
|
|
26
26
|
/**
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export const linkStorage: LinkStorage;
|
|
2
|
+
declare class LinkStorage {
|
|
3
|
+
static "__#13@#instance": any;
|
|
4
|
+
/**
|
|
5
|
+
*
|
|
6
|
+
* @returns {LinkStorage}
|
|
7
|
+
*/
|
|
8
|
+
static getInstance(): LinkStorage;
|
|
9
|
+
/**
|
|
10
|
+
* Stores links array and passes it to reporter
|
|
11
|
+
* @param {object[]} links - array of link objects
|
|
12
|
+
* @param {*} context - full test title
|
|
13
|
+
*/
|
|
14
|
+
put(links: object[], context?: any): void;
|
|
15
|
+
/**
|
|
16
|
+
* Returns links array for the test
|
|
17
|
+
* @param {*} context testId or test context from test runner
|
|
18
|
+
* @returns {object[]} links array, e.g. [{test: 'TEST-123'}, {jira: 'JIRA-456'}]
|
|
19
|
+
*/
|
|
20
|
+
get(context?: any): object[];
|
|
21
|
+
}
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.linkStorage = void 0;
|
|
7
|
+
const debug_1 = __importDefault(require("debug"));
|
|
8
|
+
const data_storage_js_1 = require("../data-storage.js");
|
|
9
|
+
const debug = (0, debug_1.default)('@testomatio/reporter:services-links');
|
|
10
|
+
class LinkStorage {
|
|
11
|
+
static #instance;
|
|
12
|
+
/**
|
|
13
|
+
*
|
|
14
|
+
* @returns {LinkStorage}
|
|
15
|
+
*/
|
|
16
|
+
static getInstance() {
|
|
17
|
+
if (!this.#instance) {
|
|
18
|
+
this.#instance = new LinkStorage();
|
|
19
|
+
}
|
|
20
|
+
return this.#instance;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Stores links array and passes it to reporter
|
|
24
|
+
* @param {object[]} links - array of link objects
|
|
25
|
+
* @param {*} context - full test title
|
|
26
|
+
*/
|
|
27
|
+
put(links, context = null) {
|
|
28
|
+
if (!links || !Array.isArray(links))
|
|
29
|
+
return;
|
|
30
|
+
data_storage_js_1.dataStorage.putData('links', links, context);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Returns links array for the test
|
|
34
|
+
* @param {*} context testId or test context from test runner
|
|
35
|
+
* @returns {object[]} links array, e.g. [{test: 'TEST-123'}, {jira: 'JIRA-456'}]
|
|
36
|
+
*/
|
|
37
|
+
get(context = null) {
|
|
38
|
+
const linksList = data_storage_js_1.dataStorage.getData('links', context);
|
|
39
|
+
if (!linksList || !linksList?.length)
|
|
40
|
+
return [];
|
|
41
|
+
const allLinks = [];
|
|
42
|
+
for (const links of linksList) {
|
|
43
|
+
if (Array.isArray(links)) {
|
|
44
|
+
allLinks.push(...links);
|
|
45
|
+
}
|
|
46
|
+
else if (typeof links === 'string') {
|
|
47
|
+
try {
|
|
48
|
+
const parsedLinks = JSON.parse(links);
|
|
49
|
+
if (Array.isArray(parsedLinks)) {
|
|
50
|
+
allLinks.push(...parsedLinks);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
catch (e) {
|
|
54
|
+
debug(`Error parsing links for test ${context}`, links);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
// Remove duplicates based on JSON string comparison
|
|
59
|
+
const uniqueLinks = [];
|
|
60
|
+
const seen = new Set();
|
|
61
|
+
for (const link of allLinks) {
|
|
62
|
+
const key = JSON.stringify(link);
|
|
63
|
+
if (!seen.has(key)) {
|
|
64
|
+
seen.add(key);
|
|
65
|
+
uniqueLinks.push(link);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return uniqueLinks;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
exports.linkStorage = LinkStorage.getInstance();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export function checkForEnvPassedAsArguments(): void;
|