@loadmill/executer 0.1.52 → 0.1.53
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/package.json +3 -3
- package/src/asserter.ts +0 -137
- package/src/errors.ts +0 -10
- package/src/extraction-combiner.ts +0 -110
- package/src/failures.ts +0 -79
- package/src/message-creators.ts +0 -44
- package/src/mill-info.ts +0 -81
- package/src/mill-version.ts +0 -7
- package/src/post-script/ast-walker/index.ts +0 -160
- package/src/post-script/ast-walker/type-guard.ts +0 -73
- package/src/post-script/ast-walker/types.ts +0 -35
- package/src/post-script/console-log.ts +0 -24
- package/src/post-script/parser/acorn-js-parser.ts +0 -8
- package/src/post-script/parser/js-parser.ts +0 -22
- package/src/post-script/parser/parser.ts +0 -5
- package/src/post-script/post-script-executor.ts +0 -93
- package/src/post-script/virtual-machine/virtual-machine.ts +0 -15
- package/src/post-script/virtual-machine/vm2-virtual-machine.ts +0 -45
- package/src/report-types.ts +0 -127
- package/src/request-sequence-result.ts +0 -63
- package/src/request-stats.ts +0 -20
- package/src/res-keeper.ts +0 -53
- package/src/sampler.ts +0 -133
- package/src/sequence.ts +0 -1115
- package/src/single-runner.ts +0 -68
- package/src/test-run-event-emitter.ts +0 -25
- package/src/utils.ts +0 -8
- package/src/work.ts +0 -17
- package/src/ws.ts +0 -286
- package/test/post-script-console-log.spec.ts +0 -73
- package/test/post-script-executor.spec.ts +0 -685
- package/tsconfig.json +0 -9
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@loadmill/executer",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.53",
|
|
4
4
|
"description": "Loadmill executer library",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"ts-watch": "rimraf dist && tsc -w -p tsconfig.json",
|
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
},
|
|
15
15
|
"license": "Apache-2.0",
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@loadmill/core": "0.3.
|
|
18
|
-
"@loadmill/universal": "0.3.
|
|
17
|
+
"@loadmill/core": "0.3.52",
|
|
18
|
+
"@loadmill/universal": "0.3.47",
|
|
19
19
|
"@types/estree": "^0.0.50",
|
|
20
20
|
"acorn": "^8.4.1",
|
|
21
21
|
"agentkeepalive": "^4.1.3",
|
package/src/asserter.ts
DELETED
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
import { Parameters } from '@loadmill/core/dist/parameters';
|
|
2
|
-
import { Assertion } from '@loadmill/core/dist/request';
|
|
3
|
-
import { parameterUtils, valueUtils } from '@loadmill/core/dist/parameters';
|
|
4
|
-
import log from '@loadmill/universal/dist/log';
|
|
5
|
-
|
|
6
|
-
export class Asserter {
|
|
7
|
-
constructor(private parameters: Parameters) {}
|
|
8
|
-
|
|
9
|
-
assert({
|
|
10
|
-
check,
|
|
11
|
-
equals,
|
|
12
|
-
notEquals,
|
|
13
|
-
contains,
|
|
14
|
-
notContains,
|
|
15
|
-
matches,
|
|
16
|
-
falsy,
|
|
17
|
-
greater,
|
|
18
|
-
lesser,
|
|
19
|
-
JSONSchema
|
|
20
|
-
}: Assertion): boolean {
|
|
21
|
-
const actual =
|
|
22
|
-
parameterUtils.resolveParameter(check, this.parameters) || '';
|
|
23
|
-
|
|
24
|
-
if (
|
|
25
|
-
contains == null &&
|
|
26
|
-
notContains == null &&
|
|
27
|
-
equals == null &&
|
|
28
|
-
notEquals == null &&
|
|
29
|
-
matches == null &&
|
|
30
|
-
greater == null &&
|
|
31
|
-
lesser == null &&
|
|
32
|
-
JSONSchema == null
|
|
33
|
-
) {
|
|
34
|
-
// only if no other assertions exist, the target expression is to check
|
|
35
|
-
// for "truthfulness" or "falslyness"(in case falsy flag is on).
|
|
36
|
-
|
|
37
|
-
// Note that failed/null extractions evaluate to an empty string while
|
|
38
|
-
// other nonexistent parameters are left untouched in the resolved expression
|
|
39
|
-
|
|
40
|
-
let result;
|
|
41
|
-
if (falsy) {
|
|
42
|
-
result = valueUtils.isFalsyParameterValue(actual);
|
|
43
|
-
log.debug('Assert False:', { actual, result });
|
|
44
|
-
} else {
|
|
45
|
-
result = valueUtils.isTruthyParameterValue(actual);
|
|
46
|
-
log.debug('Assert True:', { actual, result });
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
return result;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// short circuiting with approximate increasing complexity:
|
|
53
|
-
return (
|
|
54
|
-
this.check(actual, checkContains, contains) ||
|
|
55
|
-
this.check(actual, checkNotContains, notContains) ||
|
|
56
|
-
this.check(actual, checkEquals, equals) ||
|
|
57
|
-
this.check(actual, checkNotEquals, notEquals) ||
|
|
58
|
-
this.check(actual, checkMatches, matches) ||
|
|
59
|
-
this.check(actual, checkGreater, greater) ||
|
|
60
|
-
this.check(actual, checkLesser, lesser) ||
|
|
61
|
-
this.check(actual, checkJSONSchema, JSONSchema)
|
|
62
|
-
);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
private resolve(parametrized: string) {
|
|
66
|
-
return parameterUtils.resolveExpression(parametrized, this.parameters);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
private check(actual: string, checker: Checker, expected?: string) {
|
|
70
|
-
if (expected != null) {
|
|
71
|
-
const resolved = this.resolve(expected);
|
|
72
|
-
return checker(actual, resolved);
|
|
73
|
-
}
|
|
74
|
-
return false;
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
type Checker = (actual: string, expected: string) => boolean;
|
|
79
|
-
|
|
80
|
-
function checkMatches(actual: string, expected: string) {
|
|
81
|
-
const regExp = new RegExp(expected);
|
|
82
|
-
const result = regExp.test(actual);
|
|
83
|
-
log.debug('Assert regex:', { actual, expected, regExp, result });
|
|
84
|
-
return result;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
function checkEquals(actual: string, expected: string) {
|
|
88
|
-
let result;
|
|
89
|
-
if (expected === 'null' && actual === '' ) {
|
|
90
|
-
result = true;
|
|
91
|
-
}
|
|
92
|
-
else {
|
|
93
|
-
result = actual == expected;
|
|
94
|
-
}
|
|
95
|
-
log.debug('Assert equals:', { actual, expected, result });
|
|
96
|
-
return result;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
function checkNotEquals(actual: string, expected: string) {
|
|
100
|
-
const result = actual !== expected;
|
|
101
|
-
log.debug('Assert not equal:', { actual, expected, result });
|
|
102
|
-
return result;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
function checkContains(actual: string, expected: string) {
|
|
106
|
-
const result = actual.includes(expected);
|
|
107
|
-
log.debug('Assert contains:', { actual, expected, result });
|
|
108
|
-
return result;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
function checkNotContains(actual: string, expected: string) {
|
|
112
|
-
const result = !actual.includes(expected);
|
|
113
|
-
log.debug('Assert not contains:', { actual, expected, result });
|
|
114
|
-
return result;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
function checkGreater(actual: string, expected: string) {
|
|
118
|
-
const numericActual = parseFloat(actual);
|
|
119
|
-
const numericExpected = parseFloat(expected);
|
|
120
|
-
const result = numericActual > numericExpected;
|
|
121
|
-
log.debug('Assert greater:', { actual, expected, result });
|
|
122
|
-
return result;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
function checkLesser(actual: string, expected: string) {
|
|
126
|
-
const numericActual = parseFloat(actual);
|
|
127
|
-
const numericExpected = parseFloat(expected);
|
|
128
|
-
const result = numericActual < numericExpected;
|
|
129
|
-
log.debug('Assert lesser:', { actual, expected, result });
|
|
130
|
-
return result;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
function checkJSONSchema(actual: string, expected: string) {
|
|
134
|
-
const result = parameterUtils.applyJSONSchema(actual, expected);
|
|
135
|
-
log.debug('Assert JSONSchema:', { actual, expected, result });
|
|
136
|
-
return result;
|
|
137
|
-
}
|
package/src/errors.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { Histogram } from './failures';
|
|
2
|
-
|
|
3
|
-
export class RequestFailuresError extends Error {
|
|
4
|
-
constructor(message: string, public histogram: Histogram = { [message]: 1 }) {
|
|
5
|
-
super(message);
|
|
6
|
-
|
|
7
|
-
// Workaround suggested in: https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work
|
|
8
|
-
Object.setPrototypeOf(this, RequestFailuresError.prototype);
|
|
9
|
-
}
|
|
10
|
-
}
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
RegexExtractor,
|
|
3
|
-
Extractor,
|
|
4
|
-
HeaderExtractor,
|
|
5
|
-
CheerioExtractor,
|
|
6
|
-
JsonPathExtractor,
|
|
7
|
-
ExpressionExtractor,
|
|
8
|
-
ParametrizedExtractor,
|
|
9
|
-
WsExtractor,
|
|
10
|
-
} from '@loadmill/core/dist/parameters/extractors';
|
|
11
|
-
import { Parameters } from '@loadmill/core/dist/parameters';
|
|
12
|
-
import { Extraction } from '@loadmill/core/dist/request';
|
|
13
|
-
import log from '@loadmill/universal/dist/log';
|
|
14
|
-
import ednParser from 'jsedn';
|
|
15
|
-
import { WSExtractionData } from '@loadmill/core/dist/parameters/extractors/ws-extractor';
|
|
16
|
-
|
|
17
|
-
export class ExtractionCombiner {
|
|
18
|
-
headerExtractor: HeaderExtractor;
|
|
19
|
-
cheerioExtractor: CheerioExtractor;
|
|
20
|
-
jsonPathExtractor: JsonPathExtractor;
|
|
21
|
-
ednPathExtractor: JsonPathExtractor;
|
|
22
|
-
expressionExtractor: ExpressionExtractor;
|
|
23
|
-
|
|
24
|
-
constructor(private contextParameters: Parameters, private res: any, private wsExtractionData: WSExtractionData) {
|
|
25
|
-
this.headerExtractor = new HeaderExtractor(res, this.contextParameters);
|
|
26
|
-
this.expressionExtractor = new ExpressionExtractor(this.contextParameters);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
async combine(extraction: Extraction) {
|
|
30
|
-
let query: string | string[], extractor!: ParametrizedExtractor;
|
|
31
|
-
|
|
32
|
-
if (typeof extraction === 'string') {
|
|
33
|
-
query = extraction;
|
|
34
|
-
extractor = this.expressionExtractor;
|
|
35
|
-
} else {
|
|
36
|
-
const { header, jQuery, jsonPath, edn, regex, ws } = extraction;
|
|
37
|
-
|
|
38
|
-
if (header != null) {
|
|
39
|
-
query = header;
|
|
40
|
-
extractor = this.headerExtractor;
|
|
41
|
-
} else if (jQuery != null) {
|
|
42
|
-
if (!this.cheerioExtractor) {
|
|
43
|
-
this.cheerioExtractor = new CheerioExtractor(
|
|
44
|
-
this.res.text,
|
|
45
|
-
this.contextParameters
|
|
46
|
-
);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
query =
|
|
50
|
-
typeof jQuery === 'string'
|
|
51
|
-
? jQuery
|
|
52
|
-
: [jQuery.query, '0', jQuery.attr || ''];
|
|
53
|
-
|
|
54
|
-
extractor = this.cheerioExtractor;
|
|
55
|
-
} else if (jsonPath != null) {
|
|
56
|
-
if (!this.jsonPathExtractor) {
|
|
57
|
-
this.jsonPathExtractor = new JsonPathExtractor(
|
|
58
|
-
this.res.text,
|
|
59
|
-
this.contextParameters
|
|
60
|
-
);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
query = jsonPath;
|
|
64
|
-
extractor = this.jsonPathExtractor;
|
|
65
|
-
} else if (edn != null) {
|
|
66
|
-
if (!this.ednPathExtractor) {
|
|
67
|
-
let converted: string = '';
|
|
68
|
-
try {
|
|
69
|
-
converted = JSON.stringify(
|
|
70
|
-
ednParser.toJS(ednParser.parse(this.res.text))
|
|
71
|
-
);
|
|
72
|
-
} catch (e) {
|
|
73
|
-
log.error(e); // just log. The error will shown later because we send '' to JsonPathExtractor
|
|
74
|
-
}
|
|
75
|
-
this.ednPathExtractor = new JsonPathExtractor(
|
|
76
|
-
converted,
|
|
77
|
-
this.contextParameters
|
|
78
|
-
);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
query = edn;
|
|
82
|
-
extractor = this.ednPathExtractor;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
if (regex != null) {
|
|
86
|
-
extractor = new RegexExtractor(
|
|
87
|
-
extractor ? wrap(extractor, query!) : () => this.res.text,
|
|
88
|
-
this.contextParameters
|
|
89
|
-
);
|
|
90
|
-
|
|
91
|
-
query = regex;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
if (ws != null) {
|
|
95
|
-
extractor = new WsExtractor(
|
|
96
|
-
this.wsExtractionData,
|
|
97
|
-
this.contextParameters
|
|
98
|
-
);
|
|
99
|
-
|
|
100
|
-
query = ws;
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
return () => extractor.extract(query);
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
function wrap(extractor: Extractor, query) {
|
|
109
|
-
return () => extractor.extract(query);
|
|
110
|
-
}
|
package/src/failures.ts
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
export function OneFailure(histogram: Histogram): RequestFailures {
|
|
2
|
-
return {
|
|
3
|
-
histogram,
|
|
4
|
-
numFailures: 1,
|
|
5
|
-
};
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export function mergeFailures(to: Failures, from: Failures) {
|
|
9
|
-
Object.keys(from).forEach(index => {
|
|
10
|
-
const fromReqFailures = from[index];
|
|
11
|
-
const toReqFailures = to[index!];
|
|
12
|
-
|
|
13
|
-
if (toReqFailures == null) {
|
|
14
|
-
to[index!] = {
|
|
15
|
-
numFailures: fromReqFailures.numFailures,
|
|
16
|
-
histogram: { ...fromReqFailures.histogram },
|
|
17
|
-
};
|
|
18
|
-
} else {
|
|
19
|
-
mergeRequestFailures(toReqFailures, fromReqFailures);
|
|
20
|
-
}
|
|
21
|
-
});
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export function mergeRequestFailures(
|
|
25
|
-
to: RequestFailures,
|
|
26
|
-
from: RequestFailures
|
|
27
|
-
) {
|
|
28
|
-
to.numFailures += from.numFailures;
|
|
29
|
-
mergeHistograms(to.histogram, from.histogram);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export function mergeHistograms(to: Histogram, from: Histogram) {
|
|
33
|
-
Object.keys(from).forEach(reason => {
|
|
34
|
-
const fromCount = from[reason];
|
|
35
|
-
const toCount = to[reason];
|
|
36
|
-
|
|
37
|
-
if (toCount != null) {
|
|
38
|
-
to[reason] = toCount + fromCount;
|
|
39
|
-
} else {
|
|
40
|
-
to[reason] = fromCount;
|
|
41
|
-
}
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export function getFailureKeys(failures?: Failures) {
|
|
46
|
-
const safeFailures = failures || {};
|
|
47
|
-
|
|
48
|
-
return Object.keys(safeFailures).map(reqIndex =>
|
|
49
|
-
Object.keys(safeFailures[reqIndex].histogram).map(reason =>
|
|
50
|
-
getFailureKey(reqIndex, reason)
|
|
51
|
-
)
|
|
52
|
-
).reduce((a, b) => a.concat(b), []);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export function getFailureKey(reqIndex: string | number, reason: string) {
|
|
56
|
-
return `${reqIndex},${reason}`;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export interface Failures {
|
|
60
|
-
[index: number]: RequestFailures;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
export interface RequestFailures {
|
|
64
|
-
/**
|
|
65
|
-
* Counts the number of times the request has failed.
|
|
66
|
-
*/
|
|
67
|
-
numFailures: number;
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* Maps each failure reason (an error message or assertion name) to the
|
|
71
|
-
* [positive] number of times the request has failed because of it.
|
|
72
|
-
*
|
|
73
|
-
* Note that these may sum up to more than `numFailures`!
|
|
74
|
-
* This happens when multiple assertions fail for the same request.
|
|
75
|
-
*/
|
|
76
|
-
histogram: Histogram;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
export type Histogram = { [reason: string]: number };
|
package/src/message-creators.ts
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { Work } from './work';
|
|
2
|
-
import { FromMillStatsReport } from './report-types';
|
|
3
|
-
import { RequestSequenceResult } from './request-sequence-result';
|
|
4
|
-
|
|
5
|
-
export const messageCreators = {
|
|
6
|
-
work(work) {
|
|
7
|
-
return JSON.stringify(new WorkLordMessage(work));
|
|
8
|
-
},
|
|
9
|
-
|
|
10
|
-
askRes(failureKeys) {
|
|
11
|
-
return JSON.stringify(new AskResLordMessage(failureKeys));
|
|
12
|
-
},
|
|
13
|
-
|
|
14
|
-
report(report) {
|
|
15
|
-
return JSON.stringify(new ReportMillMessage(report));
|
|
16
|
-
},
|
|
17
|
-
|
|
18
|
-
fullRes(results) {
|
|
19
|
-
return JSON.stringify(new FullResMillMessage(results));
|
|
20
|
-
},
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
export class WorkLordMessage {
|
|
24
|
-
readonly type = 'work';
|
|
25
|
-
constructor(public work: Work) {}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export class AskResLordMessage {
|
|
29
|
-
readonly type = 'askRes';
|
|
30
|
-
constructor(public failureKeys: string[]) {}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export class ReportMillMessage {
|
|
34
|
-
readonly type = 'report';
|
|
35
|
-
constructor(public report: FromMillStatsReport) {}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export class FullResMillMessage {
|
|
39
|
-
readonly type = 'fullRes';
|
|
40
|
-
constructor(public results: RequestSequenceResult[]) {}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export type LordMessage = WorkLordMessage | AskResLordMessage;
|
|
44
|
-
export type MillMessage = ReportMillMessage | FullResMillMessage;
|
package/src/mill-info.ts
DELETED
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
export interface MillInfo {
|
|
2
|
-
/**
|
|
3
|
-
* The mill socket IP address (or addresses in case IP is forwarded).
|
|
4
|
-
*/
|
|
5
|
-
IPs: string[];
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* True if and only if this mill is a spy.
|
|
9
|
-
*/
|
|
10
|
-
spy: boolean;
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* True if and only if this mill is a simulator.
|
|
14
|
-
*/
|
|
15
|
-
sim: boolean;
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* True if and only if this mill restricted to using SSL.
|
|
19
|
-
*/
|
|
20
|
-
onlySsl: boolean;
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* True if and only if this mill has cookie support.
|
|
24
|
-
*/
|
|
25
|
-
cookieAble: boolean;
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* True if and only if this mill runs through a proxy.
|
|
29
|
-
*/
|
|
30
|
-
proxyAble: boolean;
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Number of loads capable of running (Angie)
|
|
34
|
-
*/
|
|
35
|
-
loadsCapacity: number;
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* The location resolved from the first mill IP or an empty string.
|
|
39
|
-
*/
|
|
40
|
-
location: string;
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* The country code provided by Cloudflare or empty string.
|
|
44
|
-
*/
|
|
45
|
-
countryCode: string;
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* The mill user-agent string or an empty string.
|
|
49
|
-
*/
|
|
50
|
-
userAgent: string;
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* The mill browser and version (parsed from user-agent string).
|
|
54
|
-
*/
|
|
55
|
-
browserVersion: string;
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* The full affiliate id.
|
|
59
|
-
*/
|
|
60
|
-
affiliateId: string;
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* The owner of the agent.
|
|
64
|
-
*/
|
|
65
|
-
userId?: string;
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* The agent's owner's team.
|
|
69
|
-
*/
|
|
70
|
-
teamId?: string;
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Agent pool(if the user supplied)
|
|
74
|
-
*/
|
|
75
|
-
pool?: string;
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* If the agent can't handle API tests
|
|
79
|
-
*/
|
|
80
|
-
noApi: boolean;
|
|
81
|
-
}
|
package/src/mill-version.ts
DELETED
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
AssignmentExpression,
|
|
3
|
-
AssignmentProperty,
|
|
4
|
-
ExpressionStatement,
|
|
5
|
-
Identifier,
|
|
6
|
-
ObjectPattern,
|
|
7
|
-
Pattern,
|
|
8
|
-
RestElement,
|
|
9
|
-
SequenceExpression,
|
|
10
|
-
VariableDeclaration,
|
|
11
|
-
} from 'estree';
|
|
12
|
-
import { ESTree } from '../parser/js-parser';
|
|
13
|
-
import { AcornJSParser } from '../parser/acorn-js-parser';
|
|
14
|
-
import { ArrayPattern, FunctionDeclaration } from './types';
|
|
15
|
-
import {
|
|
16
|
-
isArray,
|
|
17
|
-
isAssignmentExpression,
|
|
18
|
-
isExpressionStatement,
|
|
19
|
-
isFunctionDeclaration,
|
|
20
|
-
isIdentifier,
|
|
21
|
-
isObject,
|
|
22
|
-
isRestElement,
|
|
23
|
-
isSequenceExpression,
|
|
24
|
-
isVariableDeclaration,
|
|
25
|
-
} from './type-guard';
|
|
26
|
-
|
|
27
|
-
export class ASTWalker {
|
|
28
|
-
private ast: ESTree;
|
|
29
|
-
private untouchables: string[];
|
|
30
|
-
private detected: Set<string>;
|
|
31
|
-
|
|
32
|
-
constructor(script: string) {
|
|
33
|
-
this.ast = new AcornJSParser().parse(script);
|
|
34
|
-
this.untouchables = [];
|
|
35
|
-
this.detected = new Set();
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
public detectDeclarations = (untouchables: string[]): string[] => {
|
|
39
|
-
this.untouchables = untouchables;
|
|
40
|
-
|
|
41
|
-
for (const node of this.ast.body) {
|
|
42
|
-
if (isFunctionDeclaration(node)) {
|
|
43
|
-
this.addDeclaredFunction(node as FunctionDeclaration);
|
|
44
|
-
}
|
|
45
|
-
else if (isVariableDeclaration(node)) {
|
|
46
|
-
this.addDeclaredVariables(node as VariableDeclaration);
|
|
47
|
-
}
|
|
48
|
-
else if (isExpressionStatement(node)) {
|
|
49
|
-
this.addImplicitDeclarations(node as ExpressionStatement);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
return Array.from(this.detected);
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
private addDeclaredFunction = (node: FunctionDeclaration) => {
|
|
56
|
-
this.addIdentifier(node.id);
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
private getIdentifierName = (id: Identifier) => id.name;
|
|
60
|
-
|
|
61
|
-
private addNestedDeclaredProps = ({ properties }: ObjectPattern) => {
|
|
62
|
-
for (const prop of properties) {
|
|
63
|
-
if (isRestElement(prop)) {
|
|
64
|
-
this.addRestElement(prop as RestElement);
|
|
65
|
-
}
|
|
66
|
-
else {
|
|
67
|
-
this.addAssignmentProperty(prop as AssignmentProperty);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
private addAssignmentProperty = ({ value }: AssignmentProperty) => {
|
|
73
|
-
if (isIdentifier(value)) {
|
|
74
|
-
this.addIdentifier(value as Identifier);
|
|
75
|
-
}
|
|
76
|
-
else if (isObject(value)) {
|
|
77
|
-
this.addNestedDeclaredProps(value as ObjectPattern);
|
|
78
|
-
}
|
|
79
|
-
else if (isArray(value)) {
|
|
80
|
-
this.addDestructuredArrayElements(value as ArrayPattern);
|
|
81
|
-
}
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
private addRestElement = ({ argument }: RestElement) => {
|
|
85
|
-
if (isIdentifier(argument)) {
|
|
86
|
-
this.addIdentifier(argument as Identifier);
|
|
87
|
-
}
|
|
88
|
-
else if (isObject(argument)) {
|
|
89
|
-
this.addNestedDeclaredProps(argument as ObjectPattern);
|
|
90
|
-
}
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
private addDestructuredArrayElements = ({ elements }: ArrayPattern) => {
|
|
94
|
-
for (const element of elements) {
|
|
95
|
-
if (isIdentifier(element)) {
|
|
96
|
-
this.addIdentifier(element as Identifier);
|
|
97
|
-
}
|
|
98
|
-
else if (isRestElement(element)) {
|
|
99
|
-
this.addRestElement(element as RestElement);
|
|
100
|
-
}
|
|
101
|
-
else if (isObject(element)) {
|
|
102
|
-
this.addNestedDeclaredProps(element as ObjectPattern);
|
|
103
|
-
}
|
|
104
|
-
else if (isArray(element)) {
|
|
105
|
-
this.addDestructuredArrayElements(element as ArrayPattern);
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
private addDeclaredVariables = (node: VariableDeclaration) => {
|
|
111
|
-
for (const declaration of node.declarations) {
|
|
112
|
-
const pattern: Pattern = declaration.id;
|
|
113
|
-
if (isIdentifier(pattern)) {
|
|
114
|
-
this.addIdentifier(pattern as Identifier);
|
|
115
|
-
}
|
|
116
|
-
else if (isObject(pattern)) {
|
|
117
|
-
this.addNestedDeclaredProps(pattern as ObjectPattern);
|
|
118
|
-
}
|
|
119
|
-
else if (isArray(pattern)) {
|
|
120
|
-
this.addDestructuredArrayElements(pattern as ArrayPattern);
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
};
|
|
124
|
-
|
|
125
|
-
private addImplicitDeclarations = ({ expression }: ExpressionStatement) => {
|
|
126
|
-
if (isAssignmentExpression(expression)) {
|
|
127
|
-
this.addSingleImplicitVar(expression as AssignmentExpression);
|
|
128
|
-
}
|
|
129
|
-
else if (isSequenceExpression(expression)) {
|
|
130
|
-
this.addMultipleImplicitVar(expression as SequenceExpression);
|
|
131
|
-
}
|
|
132
|
-
};
|
|
133
|
-
|
|
134
|
-
private addSingleImplicitVar = (expression: AssignmentExpression) => {
|
|
135
|
-
if (isIdentifier(expression.left)) {
|
|
136
|
-
const assignedName = this.getIdentifierName(expression.left as Identifier);
|
|
137
|
-
if (!this.untouchables.includes(assignedName)) {
|
|
138
|
-
this.addIdentifier(expression.left as Identifier);
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
else if (isObject(expression.left)) {
|
|
142
|
-
this.addNestedDeclaredProps(expression.left as ObjectPattern);
|
|
143
|
-
}
|
|
144
|
-
else if (isArray(expression.left)) {
|
|
145
|
-
this.addDestructuredArrayElements(expression.left as ArrayPattern);
|
|
146
|
-
}
|
|
147
|
-
};
|
|
148
|
-
|
|
149
|
-
private addMultipleImplicitVar = ({ expressions }: SequenceExpression) => {
|
|
150
|
-
for (const expression of expressions) {
|
|
151
|
-
if (isAssignmentExpression(expression)) {
|
|
152
|
-
this.addSingleImplicitVar(expression as AssignmentExpression);
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
};
|
|
156
|
-
|
|
157
|
-
private addIdentifier(id: Identifier) {
|
|
158
|
-
this.detected.add(this.getIdentifierName(id));
|
|
159
|
-
}
|
|
160
|
-
}
|