@apiquest/fracture 1.0.2 → 1.0.5
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/README.md +207 -0
- package/bin/cli.js +2 -2
- package/dist/CollectionRunner.d.ts +2 -0
- package/dist/CollectionRunner.d.ts.map +1 -1
- package/dist/CollectionRunner.js +23 -5
- package/dist/CollectionRunner.js.map +1 -1
- package/dist/LibraryLoader.d.ts +49 -0
- package/dist/LibraryLoader.d.ts.map +1 -0
- package/dist/LibraryLoader.js +198 -0
- package/dist/LibraryLoader.js.map +1 -0
- package/dist/PluginLoader.d.ts.map +1 -1
- package/dist/PluginLoader.js +9 -6
- package/dist/PluginLoader.js.map +1 -1
- package/dist/PluginResolver.d.ts +1 -1
- package/dist/PluginResolver.d.ts.map +1 -1
- package/dist/PluginResolver.js +1 -1
- package/dist/PluginResolver.js.map +1 -1
- package/dist/ScriptEngine.d.ts +2 -1
- package/dist/ScriptEngine.d.ts.map +1 -1
- package/dist/ScriptEngine.js +19 -12
- package/dist/ScriptEngine.js.map +1 -1
- package/dist/cli/index.js +35 -3
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/plugin-commands.d.ts.map +1 -1
- package/dist/cli/plugin-commands.js +48 -81
- package/dist/cli/plugin-commands.js.map +1 -1
- package/dist/cli/plugin-installer.d.ts +48 -0
- package/dist/cli/plugin-installer.d.ts.map +1 -0
- package/dist/cli/plugin-installer.js +136 -0
- package/dist/cli/plugin-installer.js.map +1 -0
- package/dist/cli/plugin-registry.d.ts +17 -0
- package/dist/cli/plugin-registry.d.ts.map +1 -0
- package/dist/cli/plugin-registry.js +77 -0
- package/dist/cli/plugin-registry.js.map +1 -0
- package/package.json +55 -50
- package/tsconfig.json +20 -20
- package/tsconfig.test.json +5 -5
- package/vitest.config.ts +22 -22
- package/dist/ExecutionTree.d.ts +0 -77
- package/dist/ExecutionTree.d.ts.map +0 -1
- package/dist/ExecutionTree.js +0 -265
- package/dist/ExecutionTree.js.map +0 -1
- package/dist/fracture/src/CollectionAnalyzer.d.ts +0 -17
- package/dist/fracture/src/CollectionAnalyzer.d.ts.map +0 -1
- package/dist/fracture/src/CollectionAnalyzer.js +0 -70
- package/dist/fracture/src/CollectionAnalyzer.js.map +0 -1
- package/dist/fracture/src/CollectionRunner.d.ts +0 -39
- package/dist/fracture/src/CollectionRunner.d.ts.map +0 -1
- package/dist/fracture/src/CollectionRunner.js +0 -802
- package/dist/fracture/src/CollectionRunner.js.map +0 -1
- package/dist/fracture/src/CollectionRunner.types.d.ts +0 -8
- package/dist/fracture/src/CollectionRunner.types.d.ts.map +0 -1
- package/dist/fracture/src/CollectionRunner.types.js +0 -2
- package/dist/fracture/src/CollectionRunner.types.js.map +0 -1
- package/dist/fracture/src/CollectionValidator.d.ts +0 -14
- package/dist/fracture/src/CollectionValidator.d.ts.map +0 -1
- package/dist/fracture/src/CollectionValidator.js +0 -145
- package/dist/fracture/src/CollectionValidator.js.map +0 -1
- package/dist/fracture/src/ConsoleReporter.d.ts +0 -24
- package/dist/fracture/src/ConsoleReporter.d.ts.map +0 -1
- package/dist/fracture/src/ConsoleReporter.js +0 -123
- package/dist/fracture/src/ConsoleReporter.js.map +0 -1
- package/dist/fracture/src/CookieJar.d.ts +0 -70
- package/dist/fracture/src/CookieJar.d.ts.map +0 -1
- package/dist/fracture/src/CookieJar.js +0 -233
- package/dist/fracture/src/CookieJar.js.map +0 -1
- package/dist/fracture/src/ExecutionTree.d.ts +0 -77
- package/dist/fracture/src/ExecutionTree.d.ts.map +0 -1
- package/dist/fracture/src/ExecutionTree.js +0 -258
- package/dist/fracture/src/ExecutionTree.js.map +0 -1
- package/dist/fracture/src/Logger.d.ts +0 -25
- package/dist/fracture/src/Logger.d.ts.map +0 -1
- package/dist/fracture/src/Logger.js +0 -78
- package/dist/fracture/src/Logger.js.map +0 -1
- package/dist/fracture/src/PluginLoader.d.ts +0 -23
- package/dist/fracture/src/PluginLoader.d.ts.map +0 -1
- package/dist/fracture/src/PluginLoader.js +0 -102
- package/dist/fracture/src/PluginLoader.js.map +0 -1
- package/dist/fracture/src/PluginManager.d.ts +0 -64
- package/dist/fracture/src/PluginManager.d.ts.map +0 -1
- package/dist/fracture/src/PluginManager.js +0 -162
- package/dist/fracture/src/PluginManager.js.map +0 -1
- package/dist/fracture/src/PluginResolver.d.ts +0 -35
- package/dist/fracture/src/PluginResolver.d.ts.map +0 -1
- package/dist/fracture/src/PluginResolver.js +0 -128
- package/dist/fracture/src/PluginResolver.js.map +0 -1
- package/dist/fracture/src/QuestAPI.d.ts +0 -9
- package/dist/fracture/src/QuestAPI.d.ts.map +0 -1
- package/dist/fracture/src/QuestAPI.js +0 -679
- package/dist/fracture/src/QuestAPI.js.map +0 -1
- package/dist/fracture/src/QuestAPI.types.d.ts +0 -35
- package/dist/fracture/src/QuestAPI.types.d.ts.map +0 -1
- package/dist/fracture/src/QuestAPI.types.js +0 -3
- package/dist/fracture/src/QuestAPI.types.js.map +0 -1
- package/dist/fracture/src/QuestTestAPI.d.ts +0 -12
- package/dist/fracture/src/QuestTestAPI.d.ts.map +0 -1
- package/dist/fracture/src/QuestTestAPI.js +0 -133
- package/dist/fracture/src/QuestTestAPI.js.map +0 -1
- package/dist/fracture/src/ScriptEngine.d.ts +0 -21
- package/dist/fracture/src/ScriptEngine.d.ts.map +0 -1
- package/dist/fracture/src/ScriptEngine.js +0 -183
- package/dist/fracture/src/ScriptEngine.js.map +0 -1
- package/dist/fracture/src/ScriptValidator.d.ts +0 -68
- package/dist/fracture/src/ScriptValidator.d.ts.map +0 -1
- package/dist/fracture/src/ScriptValidator.js +0 -351
- package/dist/fracture/src/ScriptValidator.js.map +0 -1
- package/dist/fracture/src/TestCounter.d.ts +0 -18
- package/dist/fracture/src/TestCounter.d.ts.map +0 -1
- package/dist/fracture/src/TestCounter.js +0 -82
- package/dist/fracture/src/TestCounter.js.map +0 -1
- package/dist/fracture/src/VariableResolver.d.ts +0 -20
- package/dist/fracture/src/VariableResolver.d.ts.map +0 -1
- package/dist/fracture/src/VariableResolver.js +0 -100
- package/dist/fracture/src/VariableResolver.js.map +0 -1
- package/dist/fracture/src/cli/index.d.ts +0 -3
- package/dist/fracture/src/cli/index.d.ts.map +0 -1
- package/dist/fracture/src/cli/index.js +0 -347
- package/dist/fracture/src/cli/index.js.map +0 -1
- package/dist/fracture/src/cli/plugin-commands.d.ts +0 -6
- package/dist/fracture/src/cli/plugin-commands.d.ts.map +0 -1
- package/dist/fracture/src/cli/plugin-commands.js +0 -263
- package/dist/fracture/src/cli/plugin-commands.js.map +0 -1
- package/dist/fracture/src/cli/plugin-discovery.d.ts +0 -11
- package/dist/fracture/src/cli/plugin-discovery.d.ts.map +0 -1
- package/dist/fracture/src/cli/plugin-discovery.js +0 -64
- package/dist/fracture/src/cli/plugin-discovery.js.map +0 -1
- package/dist/fracture/src/index.d.ts +0 -13
- package/dist/fracture/src/index.d.ts.map +0 -1
- package/dist/fracture/src/index.js +0 -17
- package/dist/fracture/src/index.js.map +0 -1
- package/dist/fracture/src/utils.d.ts +0 -28
- package/dist/fracture/src/utils.d.ts.map +0 -1
- package/dist/fracture/src/utils.js +0 -48
- package/dist/fracture/src/utils.js.map +0 -1
- package/dist/plugin-auth/src/apikey-auth.d.ts +0 -3
- package/dist/plugin-auth/src/apikey-auth.d.ts.map +0 -1
- package/dist/plugin-auth/src/apikey-auth.js +0 -73
- package/dist/plugin-auth/src/apikey-auth.js.map +0 -1
- package/dist/plugin-auth/src/basic-auth.d.ts +0 -3
- package/dist/plugin-auth/src/basic-auth.d.ts.map +0 -1
- package/dist/plugin-auth/src/basic-auth.js +0 -61
- package/dist/plugin-auth/src/basic-auth.js.map +0 -1
- package/dist/plugin-auth/src/bearer-auth.d.ts +0 -3
- package/dist/plugin-auth/src/bearer-auth.d.ts.map +0 -1
- package/dist/plugin-auth/src/bearer-auth.js +0 -49
- package/dist/plugin-auth/src/bearer-auth.js.map +0 -1
- package/dist/plugin-auth/src/helpers.d.ts +0 -3
- package/dist/plugin-auth/src/helpers.d.ts.map +0 -1
- package/dist/plugin-auth/src/helpers.js +0 -8
- package/dist/plugin-auth/src/helpers.js.map +0 -1
- package/dist/plugin-auth/src/index.d.ts +0 -10
- package/dist/plugin-auth/src/index.d.ts.map +0 -1
- package/dist/plugin-auth/src/index.js +0 -25
- package/dist/plugin-auth/src/index.js.map +0 -1
- package/dist/plugin-auth/src/oauth2-auth.d.ts +0 -35
- package/dist/plugin-auth/src/oauth2-auth.d.ts.map +0 -1
- package/dist/plugin-auth/src/oauth2-auth.js +0 -266
- package/dist/plugin-auth/src/oauth2-auth.js.map +0 -1
- package/dist/plugin-http/src/index.d.ts +0 -4
- package/dist/plugin-http/src/index.d.ts.map +0 -1
- package/dist/plugin-http/src/index.js +0 -266
- package/dist/plugin-http/src/index.js.map +0 -1
- package/dist/plugin-vault-file/src/index.d.ts +0 -67
- package/dist/plugin-vault-file/src/index.d.ts.map +0 -1
- package/dist/plugin-vault-file/src/index.js +0 -171
- package/dist/plugin-vault-file/src/index.js.map +0 -1
- package/dist/types.d.ts +0 -374
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -13
- package/dist/types.js.map +0 -1
- package/src/CollectionAnalyzer.ts +0 -102
- package/src/CollectionRunner.ts +0 -1423
- package/src/CollectionRunner.types.ts +0 -9
- package/src/CollectionValidator.ts +0 -289
- package/src/ConsoleReporter.ts +0 -143
- package/src/CookieJar.ts +0 -258
- package/src/DagScheduler.ts +0 -439
- package/src/Logger.ts +0 -85
- package/src/PluginLoader.ts +0 -126
- package/src/PluginManager.ts +0 -208
- package/src/PluginResolver.ts +0 -154
- package/src/QuestAPI.ts +0 -764
- package/src/QuestAPI.types.ts +0 -33
- package/src/QuestTestAPI.ts +0 -164
- package/src/RequestFilter.ts +0 -224
- package/src/ScriptEngine.ts +0 -219
- package/src/ScriptValidator.ts +0 -428
- package/src/TaskGraph.ts +0 -598
- package/src/TestCounter.ts +0 -109
- package/src/VariableResolver.ts +0 -114
- package/src/cli/index.ts +0 -480
- package/src/cli/plugin-commands.ts +0 -341
- package/src/cli/plugin-discovery.ts +0 -44
- package/src/index.ts +0 -24
- package/src/utils.ts +0 -52
|
@@ -1,351 +0,0 @@
|
|
|
1
|
-
import * as acorn from 'acorn';
|
|
2
|
-
import * as walk from 'acorn-walk';
|
|
3
|
-
import { ScriptType } from '@apiquest/types';
|
|
4
|
-
/**
|
|
5
|
-
* ScriptValidator provides AST-based validation and analysis of collection scripts
|
|
6
|
-
* - Validates quest.test() placement (disallowed in pre-scripts, certain plugin events)
|
|
7
|
-
* - Validates quest.expectMessages() placement (only in preRequestScript)
|
|
8
|
-
* - Detects conditional test declarations (breaks determinism)
|
|
9
|
-
* - Counts expected tests for progress reporting
|
|
10
|
-
*/
|
|
11
|
-
export class ScriptValidator {
|
|
12
|
-
/**
|
|
13
|
-
* Validate that quest.test() calls are only in allowed script types
|
|
14
|
-
* @param script - JavaScript code to validate
|
|
15
|
-
* @param scriptType - Type of script (collection-pre, request-post, etc.)
|
|
16
|
-
* @param path - Request path for error reporting
|
|
17
|
-
* @returns Array of validation errors (empty if valid)
|
|
18
|
-
*/
|
|
19
|
-
static validateTestLocation(script, scriptType, path) {
|
|
20
|
-
const errors = [];
|
|
21
|
-
// Disallow quest.test() in these script types
|
|
22
|
-
const disallowedTypes = [
|
|
23
|
-
ScriptType.CollectionPre,
|
|
24
|
-
ScriptType.CollectionPost,
|
|
25
|
-
ScriptType.FolderPre,
|
|
26
|
-
ScriptType.FolderPost,
|
|
27
|
-
ScriptType.PreRequest,
|
|
28
|
-
];
|
|
29
|
-
if (!disallowedTypes.includes(scriptType)) {
|
|
30
|
-
return []; // Allowed in PostRequest and some PluginEvent scripts
|
|
31
|
-
}
|
|
32
|
-
// Parse and check for quest.test() calls
|
|
33
|
-
try {
|
|
34
|
-
const ast = acorn.parse(script, { ecmaVersion: 2022, sourceType: 'module', locations: true });
|
|
35
|
-
walk.simple(ast, {
|
|
36
|
-
CallExpression(node) {
|
|
37
|
-
if (node.callee.type === 'MemberExpression' &&
|
|
38
|
-
(node.callee).object.type === 'Identifier' &&
|
|
39
|
-
((node.callee).object).name === 'quest' &&
|
|
40
|
-
(node.callee).property.type === 'Identifier' &&
|
|
41
|
-
((node.callee).property).name === 'test') {
|
|
42
|
-
errors.push({
|
|
43
|
-
message: `quest.test() is not allowed in ${scriptType} scripts`,
|
|
44
|
-
location: path,
|
|
45
|
-
source: 'script',
|
|
46
|
-
scriptType,
|
|
47
|
-
details: {
|
|
48
|
-
line: node.loc?.start.line,
|
|
49
|
-
column: node.loc?.start.column,
|
|
50
|
-
suggestion: 'Move tests to postRequestScript or use quest.skip() inside tests',
|
|
51
|
-
},
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
},
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
catch (error) {
|
|
58
|
-
const err = error;
|
|
59
|
-
errors.push({
|
|
60
|
-
message: `Syntax error in script: ${err.message ?? String(error)}`,
|
|
61
|
-
location: path,
|
|
62
|
-
source: 'script',
|
|
63
|
-
scriptType,
|
|
64
|
-
details: {
|
|
65
|
-
line: err.loc?.line,
|
|
66
|
-
column: err.loc?.column,
|
|
67
|
-
},
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
|
-
return errors;
|
|
71
|
-
}
|
|
72
|
-
/**
|
|
73
|
-
* Validate that quest.test() is NOT inside conditional statements (breaks determinism)
|
|
74
|
-
* @param script - JavaScript code to validate
|
|
75
|
-
* @param scriptType - Type of script
|
|
76
|
-
* @param path - Request path for error reporting
|
|
77
|
-
* @returns Array of validation errors (empty if valid)
|
|
78
|
-
*/
|
|
79
|
-
static validateNoConditionalTests(script, scriptType, path) {
|
|
80
|
-
const errors = [];
|
|
81
|
-
try {
|
|
82
|
-
const ast = acorn.parse(script, { ecmaVersion: 2022, sourceType: 'module', locations: true });
|
|
83
|
-
walk.ancestor(ast, {
|
|
84
|
-
CallExpression(node, ancestors) {
|
|
85
|
-
if (node.callee.type === 'MemberExpression' &&
|
|
86
|
-
(node.callee).object.type === 'Identifier' &&
|
|
87
|
-
((node.callee).object).name === 'quest' &&
|
|
88
|
-
(node.callee).property.type === 'Identifier' &&
|
|
89
|
-
((node.callee).property).name === 'test') {
|
|
90
|
-
const insideConditional = ancestors.some((ancestor) => ancestor.type === 'IfStatement' ||
|
|
91
|
-
ancestor.type === 'ConditionalExpression' ||
|
|
92
|
-
ancestor.type === 'LogicalExpression' ||
|
|
93
|
-
ancestor.type === 'TryStatement');
|
|
94
|
-
if (insideConditional) {
|
|
95
|
-
errors.push({
|
|
96
|
-
message: 'quest.test() cannot be declared conditionally (breaks deterministic test counting)',
|
|
97
|
-
location: path,
|
|
98
|
-
source: 'script',
|
|
99
|
-
scriptType,
|
|
100
|
-
details: {
|
|
101
|
-
line: node.loc?.start.line,
|
|
102
|
-
column: node.loc?.start.column,
|
|
103
|
-
suggestion: 'Use quest.skip() inside the test, or use request.condition field for request-level control',
|
|
104
|
-
},
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
},
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
catch (error) {
|
|
112
|
-
// Syntax errors already caught by validateTestLocation
|
|
113
|
-
}
|
|
114
|
-
return errors;
|
|
115
|
-
}
|
|
116
|
-
/**
|
|
117
|
-
* Validate quest.expectMessages() is only called in preRequestScript
|
|
118
|
-
* and validates protocol supports plugin events with canHaveTests
|
|
119
|
-
* @param script - JavaScript code to validate
|
|
120
|
-
* @param scriptType - Type of script
|
|
121
|
-
* @param path - Request path for error reporting
|
|
122
|
-
* @param protocolPlugin - Protocol plugin to check for event support (optional)
|
|
123
|
-
* @param eventName - Specific event name if this is a plugin event script (optional)
|
|
124
|
-
* @returns Array of validation errors (empty if valid)
|
|
125
|
-
*/
|
|
126
|
-
static validateExpectMessages(script, scriptType, path, protocolPlugin, eventName) {
|
|
127
|
-
const errors = [];
|
|
128
|
-
try {
|
|
129
|
-
const ast = acorn.parse(script, { ecmaVersion: 2022, sourceType: 'module', locations: true });
|
|
130
|
-
walk.simple(ast, {
|
|
131
|
-
CallExpression(node) {
|
|
132
|
-
if (node.callee.type === 'MemberExpression' &&
|
|
133
|
-
(node.callee).object.type === 'Identifier' &&
|
|
134
|
-
((node.callee).object).name === 'quest' &&
|
|
135
|
-
(node.callee).property.type === 'Identifier' &&
|
|
136
|
-
((node.callee).property).name === 'expectMessages') {
|
|
137
|
-
if (scriptType !== ScriptType.PreRequest) {
|
|
138
|
-
errors.push({
|
|
139
|
-
message: 'quest.expectMessages() can only be called in preRequestScript',
|
|
140
|
-
location: path,
|
|
141
|
-
source: 'script',
|
|
142
|
-
scriptType,
|
|
143
|
-
details: {
|
|
144
|
-
line: node.loc?.start.line,
|
|
145
|
-
column: node.loc?.start.column,
|
|
146
|
-
},
|
|
147
|
-
});
|
|
148
|
-
return;
|
|
149
|
-
}
|
|
150
|
-
if (node.arguments.length > 0) {
|
|
151
|
-
const arg = node.arguments[0];
|
|
152
|
-
if (arg.type === 'Literal' && typeof (arg).value === 'number') {
|
|
153
|
-
const numValue = (arg).value;
|
|
154
|
-
if (!Number.isInteger(numValue) || numValue <= 0) {
|
|
155
|
-
errors.push({
|
|
156
|
-
message: 'quest.expectMessages() requires a positive integer count',
|
|
157
|
-
location: path,
|
|
158
|
-
source: 'script',
|
|
159
|
-
scriptType,
|
|
160
|
-
details: {
|
|
161
|
-
line: node.loc?.start.line,
|
|
162
|
-
column: node.loc?.start.column,
|
|
163
|
-
suggestion: 'Use a positive integer like quest.expectMessages(10)',
|
|
164
|
-
},
|
|
165
|
-
});
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
else if (arg.type === 'UnaryExpression' && (arg).operator === '-') {
|
|
169
|
-
errors.push({
|
|
170
|
-
message: 'quest.expectMessages() requires a positive integer count',
|
|
171
|
-
location: path,
|
|
172
|
-
source: 'script',
|
|
173
|
-
scriptType,
|
|
174
|
-
details: {
|
|
175
|
-
line: node.loc?.start.line,
|
|
176
|
-
column: node.loc?.start.column,
|
|
177
|
-
suggestion: 'Use a positive integer like quest.expectMessages(10)',
|
|
178
|
-
},
|
|
179
|
-
});
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
if (protocolPlugin !== undefined) {
|
|
183
|
-
if (eventName !== undefined) {
|
|
184
|
-
const eventDef = protocolPlugin.events?.find((event) => event.name === eventName);
|
|
185
|
-
if (eventDef !== undefined && eventDef.canHaveTests !== true) {
|
|
186
|
-
errors.push({
|
|
187
|
-
message: `quest.expectMessages() is not supported for event '${eventName}' (canHaveTests is false)`,
|
|
188
|
-
location: path,
|
|
189
|
-
source: 'script',
|
|
190
|
-
scriptType,
|
|
191
|
-
details: {
|
|
192
|
-
line: node.loc?.start.line,
|
|
193
|
-
column: node.loc?.start.column,
|
|
194
|
-
suggestion: 'quest.expectMessages() can only be used with events that support tests',
|
|
195
|
-
},
|
|
196
|
-
});
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
else {
|
|
200
|
-
const hasTestableEvents = protocolPlugin.events?.some((event) => event.canHaveTests === true) ?? false;
|
|
201
|
-
if (hasTestableEvents === false) {
|
|
202
|
-
errors.push({
|
|
203
|
-
message: `quest.expectMessages() is not supported for protocol '${protocolPlugin.protocols[0]}' (no plugin events with canHaveTests)`,
|
|
204
|
-
location: path,
|
|
205
|
-
source: 'script',
|
|
206
|
-
scriptType,
|
|
207
|
-
details: {
|
|
208
|
-
line: node.loc?.start.line,
|
|
209
|
-
column: node.loc?.start.column,
|
|
210
|
-
suggestion: 'quest.expectMessages() is only for streaming protocols (websocket, sse, grpc)',
|
|
211
|
-
},
|
|
212
|
-
});
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
},
|
|
218
|
-
});
|
|
219
|
-
}
|
|
220
|
-
catch (error) {
|
|
221
|
-
// Syntax errors already caught by validateTestLocation
|
|
222
|
-
}
|
|
223
|
-
return errors;
|
|
224
|
-
}
|
|
225
|
-
/**
|
|
226
|
-
* Validate plugin event script can have tests (based on PluginEventDefinition)
|
|
227
|
-
* @param script - JavaScript code to validate
|
|
228
|
-
* @param eventDefinition - Plugin event definition with canHaveTests flag
|
|
229
|
-
* @param path - Request path for error reporting
|
|
230
|
-
* @returns Array of validation errors (empty if valid)
|
|
231
|
-
*/
|
|
232
|
-
static validatePluginEventScript(script, eventDefinition, path) {
|
|
233
|
-
const errors = [];
|
|
234
|
-
if (eventDefinition.canHaveTests) {
|
|
235
|
-
return []; // Tests are allowed
|
|
236
|
-
}
|
|
237
|
-
// Check for quest.test() calls when not allowed
|
|
238
|
-
try {
|
|
239
|
-
const ast = acorn.parse(script, { ecmaVersion: 2022, sourceType: 'module', locations: true });
|
|
240
|
-
walk.simple(ast, {
|
|
241
|
-
CallExpression(node) {
|
|
242
|
-
if (node.callee.type === 'MemberExpression' &&
|
|
243
|
-
(node.callee).object.type === 'Identifier' &&
|
|
244
|
-
((node.callee).object).name === 'quest' &&
|
|
245
|
-
(node.callee).property.type === 'Identifier' &&
|
|
246
|
-
((node.callee).property).name === 'test') {
|
|
247
|
-
errors.push({
|
|
248
|
-
message: `quest.test() is not allowed in plugin event '${eventDefinition.name}' (canHaveTests: false)`,
|
|
249
|
-
location: path,
|
|
250
|
-
source: 'script',
|
|
251
|
-
scriptType: ScriptType.PluginEvent,
|
|
252
|
-
details: {
|
|
253
|
-
line: node.loc?.start.line,
|
|
254
|
-
column: node.loc?.start.column,
|
|
255
|
-
suggestion: `Only use quest.test() in plugin events that allow tests (check plugin.events[].canHaveTests)`,
|
|
256
|
-
},
|
|
257
|
-
});
|
|
258
|
-
}
|
|
259
|
-
},
|
|
260
|
-
});
|
|
261
|
-
}
|
|
262
|
-
catch (error) {
|
|
263
|
-
// Syntax errors already caught by validateTestLocation
|
|
264
|
-
}
|
|
265
|
-
return errors;
|
|
266
|
-
}
|
|
267
|
-
/**
|
|
268
|
-
* Count total quest.test() calls in a script (for deterministic test counting)
|
|
269
|
-
* @param script - JavaScript code to analyze
|
|
270
|
-
* @returns Number of quest.test() calls found
|
|
271
|
-
*/
|
|
272
|
-
static countTests(script) {
|
|
273
|
-
let count = 0;
|
|
274
|
-
try {
|
|
275
|
-
const ast = acorn.parse(script, { ecmaVersion: 2022, sourceType: 'module' });
|
|
276
|
-
walk.simple(ast, {
|
|
277
|
-
CallExpression(node) {
|
|
278
|
-
if (node.callee.type === 'MemberExpression' &&
|
|
279
|
-
(node.callee).object.type === 'Identifier' &&
|
|
280
|
-
((node.callee).object).name === 'quest' &&
|
|
281
|
-
(node.callee).property.type === 'Identifier' &&
|
|
282
|
-
((node.callee).property).name === 'test') {
|
|
283
|
-
count++;
|
|
284
|
-
}
|
|
285
|
-
},
|
|
286
|
-
});
|
|
287
|
-
}
|
|
288
|
-
catch (error) {
|
|
289
|
-
// If script has syntax errors, return 0 (will be caught by validation)
|
|
290
|
-
return 0;
|
|
291
|
-
}
|
|
292
|
-
return count;
|
|
293
|
-
}
|
|
294
|
-
/**
|
|
295
|
-
* Extract expected message count from quest.expectMessages() call in preRequestScript
|
|
296
|
-
* @param script - JavaScript code to analyze (must be preRequestScript)
|
|
297
|
-
* @returns Expected message count, or null if not specified
|
|
298
|
-
*/
|
|
299
|
-
static extractExpectedMessages(script) {
|
|
300
|
-
let expectedCount = null;
|
|
301
|
-
try {
|
|
302
|
-
const ast = acorn.parse(script, { ecmaVersion: 2022, sourceType: 'module' });
|
|
303
|
-
walk.simple(ast, {
|
|
304
|
-
CallExpression(node) {
|
|
305
|
-
if (node.callee.type === 'MemberExpression' &&
|
|
306
|
-
(node.callee).object.type === 'Identifier' &&
|
|
307
|
-
((node.callee).object).name === 'quest' &&
|
|
308
|
-
(node.callee).property.type === 'Identifier' &&
|
|
309
|
-
((node.callee).property).name === 'expectMessages') {
|
|
310
|
-
if (node.arguments.length > 0) {
|
|
311
|
-
const firstArg = node.arguments[0];
|
|
312
|
-
if (firstArg.type === 'Literal' && typeof (firstArg).value === 'number') {
|
|
313
|
-
expectedCount = (firstArg).value;
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
},
|
|
318
|
-
});
|
|
319
|
-
}
|
|
320
|
-
catch (error) {
|
|
321
|
-
// If script has syntax errors, return null
|
|
322
|
-
return null;
|
|
323
|
-
}
|
|
324
|
-
return expectedCount;
|
|
325
|
-
}
|
|
326
|
-
/**
|
|
327
|
-
* Validate all aspects of a script (comprehensive validation)
|
|
328
|
-
* @param script - JavaScript code to validate
|
|
329
|
-
* @param scriptType - Type of script
|
|
330
|
-
* @param path - Request path for error reporting
|
|
331
|
-
* @param eventDefinition - Optional plugin event definition (for PluginEvent scripts)
|
|
332
|
-
* @param protocolPlugin - Optional protocol plugin for protocol-specific validation
|
|
333
|
-
* @returns Array of validation errors (empty if valid)
|
|
334
|
-
*/
|
|
335
|
-
static validateScript(script, scriptType, path, eventDefinition, protocolPlugin, strictMode = true) {
|
|
336
|
-
const errors = [];
|
|
337
|
-
// 1. Validate test location
|
|
338
|
-
errors.push(...this.validateTestLocation(script, scriptType, path));
|
|
339
|
-
if (strictMode === true && (scriptType === ScriptType.PostRequest || eventDefinition?.canHaveTests === true)) {
|
|
340
|
-
errors.push(...this.validateNoConditionalTests(script, scriptType, path));
|
|
341
|
-
}
|
|
342
|
-
// 3. Validate quest.expectMessages() placement
|
|
343
|
-
errors.push(...this.validateExpectMessages(script, scriptType, path, protocolPlugin, eventDefinition?.name // Pass event name if this is a plugin event script
|
|
344
|
-
));
|
|
345
|
-
if (scriptType === ScriptType.PluginEvent && eventDefinition !== undefined) {
|
|
346
|
-
errors.push(...this.validatePluginEventScript(script, eventDefinition, path));
|
|
347
|
-
}
|
|
348
|
-
return errors;
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
//# sourceMappingURL=ScriptValidator.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ScriptValidator.js","sourceRoot":"","sources":["../../../src/ScriptValidator.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import type { Collection } from '@apiquest/types';
|
|
2
|
-
import type { PluginManager } from './PluginManager.js';
|
|
3
|
-
/**
|
|
4
|
-
* Counts total expected tests in a collection for deterministic test reporting
|
|
5
|
-
*/
|
|
6
|
-
export declare class TestCounter {
|
|
7
|
-
private pluginManager;
|
|
8
|
-
constructor(pluginManager: PluginManager);
|
|
9
|
-
/**
|
|
10
|
-
* Count total expected tests in collection
|
|
11
|
-
* - Counts quest.test() calls in all scripts
|
|
12
|
-
* - Multiplies by iteration count
|
|
13
|
-
* - Returns -1 if collection has dynamic plugin events (can't determine count)
|
|
14
|
-
* @returns Total expected test count, or -1 if dynamic
|
|
15
|
-
*/
|
|
16
|
-
countTests(collection: Collection): number;
|
|
17
|
-
}
|
|
18
|
-
//# sourceMappingURL=TestCounter.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"TestCounter.d.ts","sourceRoot":"","sources":["../../../src/TestCounter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAmC,MAAM,iBAAiB,CAAC;AAEnF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD;;GAEG;AACH,qBAAa,WAAW;IACV,OAAO,CAAC,aAAa;gBAAb,aAAa,EAAE,aAAa;IAEhD;;;;;;OAMG;IACH,UAAU,CAAC,UAAU,EAAE,UAAU,GAAG,MAAM;CA4E3C"}
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import { ScriptValidator } from './ScriptValidator.js';
|
|
2
|
-
/**
|
|
3
|
-
* Counts total expected tests in a collection for deterministic test reporting
|
|
4
|
-
*/
|
|
5
|
-
export class TestCounter {
|
|
6
|
-
pluginManager;
|
|
7
|
-
constructor(pluginManager) {
|
|
8
|
-
this.pluginManager = pluginManager;
|
|
9
|
-
}
|
|
10
|
-
/**
|
|
11
|
-
* Count total expected tests in collection
|
|
12
|
-
* - Counts quest.test() calls in all scripts
|
|
13
|
-
* - Multiplies by iteration count
|
|
14
|
-
* - Returns -1 if collection has dynamic plugin events (can't determine count)
|
|
15
|
-
* @returns Total expected test count, or -1 if dynamic
|
|
16
|
-
*/
|
|
17
|
-
countTests(collection) {
|
|
18
|
-
let totalTests = 0;
|
|
19
|
-
let hasDynamicTests = false;
|
|
20
|
-
// Note: collectionPre/Post and folderPre/Post scripts CANNOT have tests (validation catches this)
|
|
21
|
-
// Only preRequestScript and postRequestScript can have tests
|
|
22
|
-
// Helper to walk tree and count tests for each REQUEST with inherited scripts
|
|
23
|
-
const countRequestTests = (item, inheritedPreRequest, inheritedPostRequest) => {
|
|
24
|
-
if (item.type === 'folder') {
|
|
25
|
-
const folder = item;
|
|
26
|
-
// Build inherited script chain (scripts STACK, not override)
|
|
27
|
-
const newInheritedPre = (folder.preRequestScript !== null && folder.preRequestScript !== undefined && folder.preRequestScript.length > 0)
|
|
28
|
-
? [...inheritedPreRequest, folder.preRequestScript]
|
|
29
|
-
: inheritedPreRequest;
|
|
30
|
-
const newInheritedPost = (folder.postRequestScript !== null && folder.postRequestScript !== undefined && folder.postRequestScript.length > 0)
|
|
31
|
-
? [...inheritedPostRequest, folder.postRequestScript]
|
|
32
|
-
: inheritedPostRequest;
|
|
33
|
-
// Recursively process folder contents
|
|
34
|
-
for (const child of folder.items) {
|
|
35
|
-
countRequestTests(child, newInheritedPre, newInheritedPost);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
else {
|
|
39
|
-
// Request - count ALL scripts in execution chain for THIS request
|
|
40
|
-
const request = item;
|
|
41
|
-
// Inherited postRequestScripts (collection and all ancestor folders) - they STACK
|
|
42
|
-
for (const script of inheritedPostRequest) {
|
|
43
|
-
totalTests += ScriptValidator.countTests(script);
|
|
44
|
-
}
|
|
45
|
-
// Request-level postRequestScript (this is where tests are!)
|
|
46
|
-
if (request.postRequestScript !== null && request.postRequestScript !== undefined && request.postRequestScript.length > 0) {
|
|
47
|
-
totalTests += ScriptValidator.countTests(request.postRequestScript);
|
|
48
|
-
}
|
|
49
|
-
// Plugin event scripts
|
|
50
|
-
if (request.data.scripts !== null && request.data.scripts !== undefined && Array.isArray(request.data.scripts)) {
|
|
51
|
-
const protocolPlugin = this.pluginManager.getPlugin(collection.protocol);
|
|
52
|
-
if (protocolPlugin?.events !== null && protocolPlugin?.events !== undefined) {
|
|
53
|
-
for (const script of request.data.scripts) {
|
|
54
|
-
const eventDef = protocolPlugin.events.find(e => e.name === script.event);
|
|
55
|
-
if (eventDef?.canHaveTests === true) {
|
|
56
|
-
const expectedMessages = ScriptValidator.extractExpectedMessages((request.preRequestScript !== null && request.preRequestScript !== undefined && request.preRequestScript.length > 0) ? request.preRequestScript : '');
|
|
57
|
-
if (expectedMessages !== null) {
|
|
58
|
-
const testsPerEvent = ScriptValidator.countTests(script.script);
|
|
59
|
-
totalTests += testsPerEvent * expectedMessages;
|
|
60
|
-
}
|
|
61
|
-
else {
|
|
62
|
-
hasDynamicTests = true;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
};
|
|
70
|
-
// Process all items with collection-level inherited scripts
|
|
71
|
-
const collectionPre = (collection.preRequestScript !== null && collection.preRequestScript !== undefined && collection.preRequestScript.length > 0) ? [collection.preRequestScript] : [];
|
|
72
|
-
const collectionPost = (collection.postRequestScript !== null && collection.postRequestScript !== undefined && collection.postRequestScript.length > 0) ? [collection.postRequestScript] : [];
|
|
73
|
-
for (const item of collection.items) {
|
|
74
|
-
countRequestTests(item, collectionPre, collectionPost);
|
|
75
|
-
}
|
|
76
|
-
// Multiply by iteration count
|
|
77
|
-
const iterationCount = (collection.testData?.length !== null && collection.testData?.length !== undefined && collection.testData.length > 0) ? collection.testData.length : 1;
|
|
78
|
-
totalTests *= iterationCount;
|
|
79
|
-
return hasDynamicTests ? -1 : totalTests;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
//# sourceMappingURL=TestCounter.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"TestCounter.js","sourceRoot":"","sources":["../../../src/TestCounter.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import type { ExecutionContext, ILogger } from '@apiquest/types';
|
|
2
|
-
export declare class VariableResolver {
|
|
3
|
-
private logger;
|
|
4
|
-
constructor(logger?: ILogger);
|
|
5
|
-
/**
|
|
6
|
-
* Resolve {{variables}} in a template string
|
|
7
|
-
* Priority: iteration data > local > collection > environment > global
|
|
8
|
-
*/
|
|
9
|
-
resolve(template: string, context: ExecutionContext): string;
|
|
10
|
-
/**
|
|
11
|
-
* Resolve all values in an object (recursively)
|
|
12
|
-
*/
|
|
13
|
-
resolveAll(obj: unknown, context: ExecutionContext): unknown;
|
|
14
|
-
/**
|
|
15
|
-
* Get variable value with cascading priority
|
|
16
|
-
* Priority: iteration data > scope stack (innermost to outermost) > collection > environment > global
|
|
17
|
-
*/
|
|
18
|
-
private getVariable;
|
|
19
|
-
}
|
|
20
|
-
//# sourceMappingURL=VariableResolver.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"VariableResolver.d.ts","sourceRoot":"","sources":["../../../src/VariableResolver.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAiB,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAKhF,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,CAAC,EAAE,OAAO;IAI5B;;;OAGG;IACH,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,GAAG,MAAM;IAyB5D;;OAEG;IACH,UAAU,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO;IAwB5D;;;OAGG;IACH,OAAO,CAAC,WAAW;CAyCpB"}
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
// Variable Resolution Engine
|
|
2
|
-
// Resolves {{variable}} syntax with cascading priority
|
|
3
|
-
import { LogLevel } from '@apiquest/types';
|
|
4
|
-
import { extractValue, isNullOrEmpty } from './utils.js';
|
|
5
|
-
import { Logger } from './Logger.js';
|
|
6
|
-
export class VariableResolver {
|
|
7
|
-
logger;
|
|
8
|
-
constructor(logger) {
|
|
9
|
-
this.logger = logger instanceof Logger ? logger : new Logger('VariableResolver', LogLevel.INFO);
|
|
10
|
-
}
|
|
11
|
-
/**
|
|
12
|
-
* Resolve {{variables}} in a template string
|
|
13
|
-
* Priority: iteration data > local > collection > environment > global
|
|
14
|
-
*/
|
|
15
|
-
resolve(template, context) {
|
|
16
|
-
if (isNullOrEmpty(template) || typeof template !== 'string') {
|
|
17
|
-
return template;
|
|
18
|
-
}
|
|
19
|
-
// Find all {{variable}} patterns
|
|
20
|
-
const variableCount = (template.match(/\{\{([^}]+)\}\}/g) ?? []).length;
|
|
21
|
-
if (variableCount > 0) {
|
|
22
|
-
this.logger.trace(`Resolving ${variableCount} variable(s) in template`);
|
|
23
|
-
}
|
|
24
|
-
return template.replace(/\{\{([^}]+)\}\}/g, (match, varName) => {
|
|
25
|
-
const trimmedName = varName.trim();
|
|
26
|
-
const value = this.getVariable(trimmedName, context);
|
|
27
|
-
if (value !== null && value !== undefined) {
|
|
28
|
-
this.logger.trace(`Resolved {{${trimmedName}}} -> ${typeof value === 'string' && value.length > 50 ? value.substring(0, 50) + '...' : value}`);
|
|
29
|
-
return String(value);
|
|
30
|
-
}
|
|
31
|
-
else {
|
|
32
|
-
this.logger.trace(`Variable {{${trimmedName}}} not found, keeping placeholder`);
|
|
33
|
-
return match;
|
|
34
|
-
}
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* Resolve all values in an object (recursively)
|
|
39
|
-
*/
|
|
40
|
-
resolveAll(obj, context) {
|
|
41
|
-
if (obj === null || obj === undefined) {
|
|
42
|
-
return obj;
|
|
43
|
-
}
|
|
44
|
-
if (typeof obj === 'string') {
|
|
45
|
-
return this.resolve(obj, context);
|
|
46
|
-
}
|
|
47
|
-
if (Array.isArray(obj)) {
|
|
48
|
-
return obj.map(item => this.resolveAll(item, context));
|
|
49
|
-
}
|
|
50
|
-
if (typeof obj === 'object') {
|
|
51
|
-
const resolved = {};
|
|
52
|
-
for (const [key, value] of Object.entries(obj)) {
|
|
53
|
-
resolved[key] = this.resolveAll(value, context);
|
|
54
|
-
}
|
|
55
|
-
return resolved;
|
|
56
|
-
}
|
|
57
|
-
return obj;
|
|
58
|
-
}
|
|
59
|
-
/**
|
|
60
|
-
* Get variable value with cascading priority
|
|
61
|
-
* Priority: iteration data > scope stack (innermost to outermost) > collection > environment > global
|
|
62
|
-
*/
|
|
63
|
-
getVariable(name, context) {
|
|
64
|
-
// 1. Iteration data (highest priority)
|
|
65
|
-
if (context.currentIterationData !== null && context.currentIterationData !== undefined && name in context.currentIterationData) {
|
|
66
|
-
this.logger.trace(`Variable '${name}' found in iteration data`);
|
|
67
|
-
return context.currentIterationData[name];
|
|
68
|
-
}
|
|
69
|
-
// 2. Scope stack (hierarchical scope variables - search from innermost to outermost)
|
|
70
|
-
// This represents quest.scope.variables which flows through the script inheritance chain
|
|
71
|
-
if (context.scopeStack !== null && context.scopeStack !== undefined && context.scopeStack.length > 0) {
|
|
72
|
-
// Search from top of stack (most specific) to bottom (least specific)
|
|
73
|
-
for (let i = context.scopeStack.length - 1; i >= 0; i--) {
|
|
74
|
-
const frame = context.scopeStack[i];
|
|
75
|
-
if (name in frame.vars) {
|
|
76
|
-
this.logger.trace(`Variable '${name}' found in scope stack (frame ${context.scopeStack.length - 1 - i})`);
|
|
77
|
-
return frame.vars[name];
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
// 3. Collection variables
|
|
82
|
-
if (name in context.collectionVariables) {
|
|
83
|
-
this.logger.trace(`Variable '${name}' found in collection variables`);
|
|
84
|
-
return extractValue(context.collectionVariables[name]);
|
|
85
|
-
}
|
|
86
|
-
// 4. Environment variables
|
|
87
|
-
if (context.environment !== null && context.environment !== undefined && name in context.environment.variables) {
|
|
88
|
-
this.logger.trace(`Variable '${name}' found in environment variables`);
|
|
89
|
-
return extractValue(context.environment.variables[name]);
|
|
90
|
-
}
|
|
91
|
-
// 5. Global variables (lowest priority)
|
|
92
|
-
if (name in context.globalVariables) {
|
|
93
|
-
this.logger.trace(`Variable '${name}' found in global variables`);
|
|
94
|
-
return extractValue(context.globalVariables[name]);
|
|
95
|
-
}
|
|
96
|
-
this.logger.trace(`Variable '${name}' not found in any scope`);
|
|
97
|
-
return null;
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
//# sourceMappingURL=VariableResolver.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"VariableResolver.js","sourceRoot":"","sources":["../../../src/VariableResolver.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/cli/index.ts"],"names":[],"mappings":""}
|