@api-client/core 0.3.2 → 0.3.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/build/browser.d.ts +1 -0
- package/build/browser.js +1 -0
- package/build/browser.js.map +1 -1
- package/build/index.d.ts +1 -1
- package/build/index.js +1 -1
- package/build/index.js.map +1 -1
- package/build/src/models/ErrorResponse.d.ts +5 -4
- package/build/src/models/ErrorResponse.js +18 -5
- package/build/src/models/ErrorResponse.js.map +1 -1
- package/build/src/models/SerializableError.d.ts +30 -0
- package/build/src/models/SerializableError.js +63 -0
- package/build/src/models/SerializableError.js.map +1 -0
- package/build/src/runtime/http-engine/ArcEngine.js +8 -4
- package/build/src/runtime/http-engine/ArcEngine.js.map +1 -1
- package/build/src/runtime/http-engine/HttpEngine.d.ts +3 -3
- package/build/src/runtime/http-engine/HttpEngine.js +3 -3
- package/build/src/runtime/http-engine/HttpEngine.js.map +1 -1
- package/build/src/runtime/http-engine/NodeEngine.js +9 -4
- package/build/src/runtime/http-engine/NodeEngine.js.map +1 -1
- package/build/src/runtime/http-engine/NodeEngineDirect.js +8 -2
- package/build/src/runtime/http-engine/NodeEngineDirect.js.map +1 -1
- package/build/src/runtime/node/ProjectRunner.d.ts +2 -2
- package/build/src/runtime/node/ProjectRunner.js +9 -2
- package/build/src/runtime/node/ProjectRunner.js.map +1 -1
- package/build/src/runtime/store/StoreSdk.js +10 -15
- package/build/src/runtime/store/StoreSdk.js.map +1 -1
- package/package.json +1 -1
- package/src/data/DataReader.ts +11 -0
- package/src/data/DataUtils.ts +108 -0
- package/src/data/JmesparthReader.ts +26 -0
- package/src/data/Json2Xml.ts +190 -0
- package/src/data/JsonReader.ts +41 -0
- package/src/data/PayloadPointer.ts +48 -0
- package/src/data/RequestDataExtractor.ts +133 -0
- package/src/data/UrlEncodedReader.ts +20 -0
- package/src/data/XmlReader.ts +103 -0
- package/src/events/BaseEvents.ts +259 -0
- package/src/events/CustomEvent.ts +27 -0
- package/src/events/EventTypes.ts +19 -0
- package/src/events/Events.ts +19 -0
- package/src/events/authorization/AuthorizationEventTypes.ts +22 -0
- package/src/events/authorization/AuthorizationEvents.ts +61 -0
- package/src/events/cookies/CookieEventTypes.ts +13 -0
- package/src/events/cookies/CookieEvents.ts +157 -0
- package/src/events/encryption/EncryptionEventTypes.ts +4 -0
- package/src/events/encryption/EncryptionEvents.ts +51 -0
- package/src/events/environment/EnvironmentEventTypes.ts +3 -0
- package/src/events/environment/EnvironmentEvents.ts +24 -0
- package/src/events/models/ClientCertificateEvents.ts +87 -0
- package/src/events/models/ModelEventTypes.ts +47 -0
- package/src/events/models/ModelEvents.ts +7 -0
- package/src/events/models/ProjectEvents.ts +331 -0
- package/src/events/process/ProcessEventTypes.ts +5 -0
- package/src/events/process/ProcessEvents.ts +76 -0
- package/src/events/readme.md +22 -0
- package/src/events/reporting/ReportingEventTypes.ts +3 -0
- package/src/events/reporting/ReportingEvents.ts +28 -0
- package/src/events/telemetry/TelemetryEventTypes.ts +10 -0
- package/src/events/telemetry/TelemetryEvents.ts +156 -0
- package/src/lib/cookies/Cookie.ts +312 -0
- package/src/lib/cookies/Cookies.ts +326 -0
- package/src/lib/cookies/Utils.ts +168 -0
- package/src/lib/headers/Headers.ts +219 -0
- package/src/lib/logging/DefaultLogger.ts +19 -0
- package/src/lib/logging/DummyLogger.ts +21 -0
- package/src/lib/logging/Logger.ts +16 -0
- package/src/lib/transformers/PayloadSerializer.ts +332 -0
- package/src/lib/transformers/Utils.ts +18 -0
- package/src/lib/uuid.ts +40 -0
- package/src/mocking/LegacyInterfaces.ts +52 -0
- package/src/mocking/LegacyMock.ts +37 -0
- package/src/mocking/legacy/Authorization.ts +39 -0
- package/src/mocking/legacy/Certificates.ts +145 -0
- package/src/mocking/legacy/Cookies.ts +51 -0
- package/src/mocking/legacy/HostRules.ts +43 -0
- package/src/mocking/legacy/Http.ts +236 -0
- package/src/mocking/legacy/HttpResponse.ts +106 -0
- package/src/mocking/legacy/RestApi.ts +68 -0
- package/src/mocking/legacy/Urls.ts +44 -0
- package/src/mocking/legacy/Variables.ts +53 -0
- package/src/models/ArcResponse.ts +166 -0
- package/src/models/Authorization.ts +481 -0
- package/src/models/AuthorizationData.ts +60 -0
- package/src/models/Backend.ts +107 -0
- package/src/models/ClientCertificate.ts +68 -0
- package/src/models/Environment.ts +279 -0
- package/src/models/ErrorResponse.ts +113 -0
- package/src/models/HistoryIndex.ts +76 -0
- package/src/models/HistoryRequest.ts +28 -0
- package/src/models/HostRule.ts +163 -0
- package/src/models/HttpCookie.ts +285 -0
- package/src/models/HttpProject.ts +1294 -0
- package/src/models/HttpProjectListItem.ts +23 -0
- package/src/models/HttpRequest.ts +124 -0
- package/src/models/HttpResponse.ts +143 -0
- package/src/models/License.ts +113 -0
- package/src/models/ProjectDefinitionProperty.ts +40 -0
- package/src/models/ProjectFolder.ts +439 -0
- package/src/models/ProjectItem.ts +135 -0
- package/src/models/ProjectParent.ts +113 -0
- package/src/models/ProjectRequest.ts +277 -0
- package/src/models/ProjectSchema.ts +202 -0
- package/src/models/Property.ts +423 -0
- package/src/models/Provider.ts +98 -0
- package/src/models/README.md +20 -0
- package/src/models/Request.ts +452 -0
- package/src/models/RequestActions.ts +163 -0
- package/src/models/RequestAuthorization.ts +115 -0
- package/src/models/RequestConfig.ts +317 -0
- package/src/models/RequestLog.ts +159 -0
- package/src/models/RequestTime.ts +108 -0
- package/src/models/RequestUiMeta.ts +258 -0
- package/src/models/RequestsSize.ts +65 -0
- package/src/models/ResponseAuthorization.ts +104 -0
- package/src/models/ResponseRedirect.ts +158 -0
- package/src/models/RevisionInfo.ts +37 -0
- package/src/models/SentRequest.ts +125 -0
- package/src/models/SerializableError.ts +80 -0
- package/src/models/SerializablePayload.ts +68 -0
- package/src/models/Server.ts +153 -0
- package/src/models/Thing.ts +110 -0
- package/src/models/Url.ts +90 -0
- package/src/models/User.ts +120 -0
- package/src/models/WebApi.ts +234 -0
- package/src/models/WebApiIndex.ts +122 -0
- package/src/models/Workspace.ts +182 -0
- package/src/models/actions/Action.ts +213 -0
- package/src/models/actions/ActionView.ts +40 -0
- package/src/models/actions/Condition.ts +207 -0
- package/src/models/actions/ConditionView.ts +42 -0
- package/src/models/actions/Enums.ts +29 -0
- package/src/models/actions/RunnableAction.ts +144 -0
- package/src/models/actions/runnable/DeleteCookieAction.ts +113 -0
- package/src/models/actions/runnable/Runnable.ts +9 -0
- package/src/models/actions/runnable/SetCookieAction.ts +216 -0
- package/src/models/actions/runnable/SetVariableAction.ts +81 -0
- package/src/models/legacy/DataExport.ts +172 -0
- package/src/models/legacy/Normalizer.ts +110 -0
- package/src/models/legacy/actions/Actions.ts +269 -0
- package/src/models/legacy/authorization/Authorization.ts +572 -0
- package/src/models/legacy/models/ApiTypes.ts +202 -0
- package/src/models/legacy/models/ArcLegacyProject.ts +39 -0
- package/src/models/legacy/models/AuthData.ts +17 -0
- package/src/models/legacy/models/ClientCertificate.ts +95 -0
- package/src/models/legacy/models/Cookies.ts +52 -0
- package/src/models/legacy/models/HostRule.ts +35 -0
- package/src/models/legacy/models/RestApi.ts +49 -0
- package/src/models/legacy/models/UrlHistory.ts +37 -0
- package/src/models/legacy/models/Variable.ts +43 -0
- package/src/models/legacy/models/base.d.ts +95 -0
- package/src/models/legacy/request/ArcRequest.ts +405 -0
- package/src/models/legacy/request/ArcResponse.ts +177 -0
- package/src/models/legacy/request/HistoryData.ts +47 -0
- package/src/models/legacy/request/Legacy.ts +45 -0
- package/src/models/legacy/request/RequestBody.ts +87 -0
- package/src/models/transformers/ArcDexieTransformer.ts +323 -0
- package/src/models/transformers/ArcLegacyNormalizer.ts +85 -0
- package/src/models/transformers/ArcLegacyTransformer.ts +200 -0
- package/src/models/transformers/ArcPouchTransformer.ts +184 -0
- package/src/models/transformers/BaseTransformer.ts +116 -0
- package/src/models/transformers/ImportUtils.ts +141 -0
- package/src/models/transformers/LegacyDataExportToApiProject.ts +76 -0
- package/src/models/transformers/LegacyExportProcessor.ts +252 -0
- package/src/models/transformers/PostmanBackupTransformer.ts +306 -0
- package/src/models/transformers/PostmanDataTransformer.ts +50 -0
- package/src/models/transformers/PostmanTransformer.ts +106 -0
- package/src/models/transformers/PostmanV21Transformer.ts +311 -0
- package/src/models/transformers/PostmanV2Transformer.ts +308 -0
- package/src/models/transformers/har.ts +865 -0
- package/src/runtime/actions/ActionRunner.ts +83 -0
- package/src/runtime/actions/ConditionRunner.ts +194 -0
- package/src/runtime/actions/RunnableCondition.ts +57 -0
- package/src/runtime/actions/runnable/ActionRunnable.ts +19 -0
- package/src/runtime/actions/runnable/DeleteCookieRunnable.ts +39 -0
- package/src/runtime/actions/runnable/SetCookieRunnable.ts +92 -0
- package/src/runtime/actions/runnable/SetVariableRunnable.ts +53 -0
- package/src/runtime/http-engine/ArcEngine.ts +1068 -0
- package/src/runtime/http-engine/FormData.ts +85 -0
- package/src/runtime/http-engine/HttpEngine.ts +874 -0
- package/src/runtime/http-engine/HttpErrorCodes.ts +270 -0
- package/src/runtime/http-engine/NodeEngine.ts +792 -0
- package/src/runtime/http-engine/NodeEngineDirect.ts +482 -0
- package/src/runtime/http-engine/PayloadSupport.ts +84 -0
- package/src/runtime/http-engine/RequestUtils.ts +164 -0
- package/src/runtime/http-engine/ntlm/Des.ts +345 -0
- package/src/runtime/http-engine/ntlm/MD4.ts +135 -0
- package/src/runtime/http-engine/ntlm/NtlmAuth.ts +186 -0
- package/src/runtime/http-engine/ntlm/NtlmMessage.ts +57 -0
- package/src/runtime/modules/BasicAuthCache.ts +133 -0
- package/src/runtime/modules/ExecutionResponse.ts +4 -0
- package/src/runtime/modules/ModulesRegistry.ts +136 -0
- package/src/runtime/modules/RequestAuthorization.ts +110 -0
- package/src/runtime/modules/RequestCookies.ts +145 -0
- package/src/runtime/node/ProjectRunner.ts +281 -0
- package/src/runtime/node/RequestFactory.ts +422 -0
- package/src/runtime/node/VariablesStore.ts +25 -0
- package/src/runtime/store/StoreSdk.ts +838 -0
- package/src/runtime/variables/Cache.ts +53 -0
- package/src/runtime/variables/EvalFunctions.ts +132 -0
- package/src/runtime/variables/ProjectVariables.ts +6 -0
- package/src/runtime/variables/VariablesProcessor.ts +543 -0
- package/src/runtime/variables/VariablesTokenizer.ts +55 -0
- package/build/src/runtime/http-engine/Errors.d.ts +0 -10
- package/build/src/runtime/http-engine/Errors.js +0 -14
- package/build/src/runtime/http-engine/Errors.js.map +0 -1
|
@@ -0,0 +1,543 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
import { Jexl } from '@pawel-up/jexl';
|
|
3
|
+
import { Property } from '../../models/Property.js';
|
|
4
|
+
import { VariablesTokenizer } from './VariablesTokenizer.js';
|
|
5
|
+
import { EvalFunctions } from './EvalFunctions.js';
|
|
6
|
+
import { clear } from './Cache.js';
|
|
7
|
+
|
|
8
|
+
export interface EvaluateOptions {
|
|
9
|
+
/**
|
|
10
|
+
* The execution context to use instead of creating the context
|
|
11
|
+
*/
|
|
12
|
+
context?: Record<string, string>;
|
|
13
|
+
/**
|
|
14
|
+
* The list of properties to evaluate. If not set then it scans for all keys in the object.
|
|
15
|
+
* This is used when evaluating objects.
|
|
16
|
+
*/
|
|
17
|
+
names?: string[];
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function valueHasVariable(value: string): boolean {
|
|
21
|
+
let trimmed = value.trim();
|
|
22
|
+
if (trimmed.startsWith('{') && trimmed.endsWith('}')) {
|
|
23
|
+
// the input here can be a JSON string or a variable.
|
|
24
|
+
try {
|
|
25
|
+
// if we can parse the string then this is a JSON string
|
|
26
|
+
JSON.parse(trimmed);
|
|
27
|
+
// we trim the first `{` and the last `}` so the rest of this logic can check for existing variables.
|
|
28
|
+
trimmed = trimmed.substring(1, trimmed.length -1);
|
|
29
|
+
} catch (e) {
|
|
30
|
+
// otherwise this must be a variable.
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
const isJSLiteral = trimmed.includes('${');
|
|
35
|
+
const isAPILiteral = !isJSLiteral && trimmed.includes('{');
|
|
36
|
+
return isJSLiteral || isAPILiteral;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export const functionRegex = /(?:\$?{)?([.a-zA-Z0-9_-]+)\(([^)]*)?\)(?:})?/gm;
|
|
40
|
+
export const varValueRe = /^[a-zA-Z0-9_]+$/;
|
|
41
|
+
export const varExprRe = /\$?{[a-zA-Z0-9_]+}/;
|
|
42
|
+
export const varStrictExprRe = /^\$?{[a-zA-Z0-9_]+}$/;
|
|
43
|
+
|
|
44
|
+
export class VariablesProcessor {
|
|
45
|
+
jexl = new Jexl();
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* A helper function to map properties to the context object.
|
|
49
|
+
*
|
|
50
|
+
* The arguments are the lists of `Property`. It starts reading the variables from the right to left,
|
|
51
|
+
* meaning, variables on the left override variables already defined on the left.
|
|
52
|
+
*
|
|
53
|
+
* ```javascript
|
|
54
|
+
* const result = VariablesProcessor.createContextFromProperties([Property.String('test1', 'value1')], [Property.String('test1', 'value2')]);
|
|
55
|
+
* ```
|
|
56
|
+
* The result has only one variable `test1` with value `value1` because this value if left most in the arguments list.
|
|
57
|
+
*
|
|
58
|
+
* When a property with the same name is repeated in the same group then the last value wins.
|
|
59
|
+
*
|
|
60
|
+
* Note, variables without a name, not enabled, or which `value` is undefined are ignored.
|
|
61
|
+
*/
|
|
62
|
+
static createContextFromProperties(...input: Property[][]): Record<string, string> {
|
|
63
|
+
const result: Record<string, string> = {};
|
|
64
|
+
input.reverse().forEach((group) => {
|
|
65
|
+
group.forEach((item) => {
|
|
66
|
+
const { enabled, name, value } = item;
|
|
67
|
+
if (!enabled || !name || value === undefined) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
result[name] = value as string;
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
return result;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Processes the context itself. This way the context can also contain variables.
|
|
78
|
+
*
|
|
79
|
+
* @return Promise resolved to the context to be passed to Jexl.
|
|
80
|
+
*/
|
|
81
|
+
async buildContext(unprocessedContext: Record<string, string>): Promise<Record<string, string>> {
|
|
82
|
+
const result: Record<string, string> = {};
|
|
83
|
+
return this._processContextVariables(result, unprocessedContext);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Processes variables in the context recursively.
|
|
88
|
+
*
|
|
89
|
+
* @param result A result to where to put the values.
|
|
90
|
+
* @param variables The map of current variables
|
|
91
|
+
* @param runCount Current run count in the recursive function. It stops executing after second run.
|
|
92
|
+
*/
|
|
93
|
+
async _processContextVariables(result: Record<string, string>, variables: Record<string, string>, runCount: number = 0): Promise<Record<string, string>> {
|
|
94
|
+
let needsRerun = false;
|
|
95
|
+
const keys = Object.keys(variables);
|
|
96
|
+
const keysWithVariables: string[] = [];
|
|
97
|
+
|
|
98
|
+
// In the first run put all variables that does not require processing to the list of results
|
|
99
|
+
for (const key of keys) {
|
|
100
|
+
const value = variables[key];
|
|
101
|
+
if (!valueHasVariable(String(value))) {
|
|
102
|
+
result[key] = value;
|
|
103
|
+
} else {
|
|
104
|
+
keysWithVariables.push(key);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
if (!keysWithVariables.length) {
|
|
108
|
+
return result;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
for (const key of keysWithVariables) {
|
|
112
|
+
const value = variables[key];
|
|
113
|
+
const evaluated = await this.evaluateWithContext(result, value);
|
|
114
|
+
result[key] = evaluated;
|
|
115
|
+
if (!needsRerun && valueHasVariable(evaluated)) {
|
|
116
|
+
needsRerun = true;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
if (!needsRerun || runCount >= 2) {
|
|
120
|
+
return result;
|
|
121
|
+
}
|
|
122
|
+
runCount += 1;
|
|
123
|
+
return this._processContextVariables(result, variables, runCount);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Clears cached groups.
|
|
128
|
+
*/
|
|
129
|
+
clearCache(): void {
|
|
130
|
+
clear(this);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Evaluates a value against the passed variables.
|
|
135
|
+
*
|
|
136
|
+
* Use this method when the context is not evaluated against itself. You can manually
|
|
137
|
+
* build context with `buildContext()` and call `evaluateWithContext()` for additional
|
|
138
|
+
* performance improvement.
|
|
139
|
+
*
|
|
140
|
+
* @param value A value to evaluate
|
|
141
|
+
* @param unprocessedContext The context (or variables) to use when evaluating the value.
|
|
142
|
+
* @return Promise that resolves to the evaluated value.
|
|
143
|
+
*/
|
|
144
|
+
async evaluateVariable(value: string, unprocessedContext: Record<string, string>): Promise<string> {
|
|
145
|
+
const typeOf = typeof value;
|
|
146
|
+
// Non primitives + null
|
|
147
|
+
if (typeOf === 'object') {
|
|
148
|
+
return value;
|
|
149
|
+
}
|
|
150
|
+
if (typeOf !== 'string') {
|
|
151
|
+
value = String(value);
|
|
152
|
+
}
|
|
153
|
+
const ctx = await this.buildContext(unprocessedContext);
|
|
154
|
+
return this.evaluateWithContext(ctx, value);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Evaluates the object against the passed variables.
|
|
159
|
+
*
|
|
160
|
+
* Note, it only performs a shallow evaluation. Deep objects are not evaluated.
|
|
161
|
+
*
|
|
162
|
+
* Use this method when the context is not evaluated against itself. You can manually
|
|
163
|
+
* build context with `buildContext()` and call `evaluateVariablesWithContext()` for additional
|
|
164
|
+
* performance improvement.
|
|
165
|
+
*
|
|
166
|
+
* @param obj The object to evaluate.
|
|
167
|
+
* @param unprocessedContext The context (or variables) to use when evaluating the value.
|
|
168
|
+
* @return Copy of the passed object with the evaluated values.
|
|
169
|
+
*/
|
|
170
|
+
async evaluateVariables<T>(obj: T, unprocessedContext: Record<string, string>, names?: string[]): Promise<T> {
|
|
171
|
+
const ctx = await this.buildContext(unprocessedContext);
|
|
172
|
+
return this.evaluateVariablesWithContext(obj, ctx, names);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Evaluates the object against the passed variables.
|
|
177
|
+
*
|
|
178
|
+
* Note, it only performs a shallow evaluation. Deep objects are not evaluated.
|
|
179
|
+
*
|
|
180
|
+
* This method is to be used when the passed context is already evaluated against itself.
|
|
181
|
+
*
|
|
182
|
+
* @param obj The object to evaluate.
|
|
183
|
+
* @param context The evaluated context. use `buildContext()` to prepare the values.
|
|
184
|
+
* @param names The list of names of variables to evaluate. Note, this function changes this array.
|
|
185
|
+
* @returns Copy of the passed object with the evaluated values.
|
|
186
|
+
*/
|
|
187
|
+
async evaluateVariablesWithContext<T>(obj: T, context: Record<string, string>, names?: string[]): Promise<T> {
|
|
188
|
+
const result = { ...obj };
|
|
189
|
+
names = names || Object.keys(result);
|
|
190
|
+
const prop = names.shift();
|
|
191
|
+
if (!prop) {
|
|
192
|
+
return result;
|
|
193
|
+
}
|
|
194
|
+
const typed = result as any;
|
|
195
|
+
if (!typed[prop]) {
|
|
196
|
+
// just process next name.
|
|
197
|
+
return this.evaluateVariablesWithContext(result, context, names);
|
|
198
|
+
}
|
|
199
|
+
if (typeof typed[prop] === 'string') {
|
|
200
|
+
typed[prop] = await this.evaluateWithContext(context, typed[prop]);
|
|
201
|
+
}
|
|
202
|
+
return this.evaluateVariablesWithContext(result, context, names);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Evaluates a value with context passed to Jexl.
|
|
207
|
+
*
|
|
208
|
+
* @param context Jexl's context
|
|
209
|
+
* @param value Value to evaluate
|
|
210
|
+
*/
|
|
211
|
+
async evaluateWithContext(context: Record<string, string>, value: string): Promise<string> {
|
|
212
|
+
value = this._upgradeLegacy(value);
|
|
213
|
+
value = this._evalFunctions(value, context);
|
|
214
|
+
if (!value) {
|
|
215
|
+
return value;
|
|
216
|
+
}
|
|
217
|
+
const typedValue = String(value);
|
|
218
|
+
const hasVariable = varExprRe.test(typedValue);
|
|
219
|
+
if (!hasVariable) {
|
|
220
|
+
return value;
|
|
221
|
+
}
|
|
222
|
+
const isVariable = varStrictExprRe.test(typedValue);
|
|
223
|
+
if (isVariable) {
|
|
224
|
+
return this._parse(this._prepareValue(typedValue), context);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
const isJSLiteral = typedValue.includes('${');
|
|
228
|
+
const isAPILiteral = !isJSLiteral && typedValue.includes('{');
|
|
229
|
+
if (!isJSLiteral && !isAPILiteral) {
|
|
230
|
+
return value;
|
|
231
|
+
}
|
|
232
|
+
let result;
|
|
233
|
+
const parts = value.split('\n');
|
|
234
|
+
if (parts.length > 1) {
|
|
235
|
+
result = this._prepareMultilineValue(parts);
|
|
236
|
+
} else {
|
|
237
|
+
result = this._prepareValue(typedValue);
|
|
238
|
+
}
|
|
239
|
+
const { jexl } = this;
|
|
240
|
+
if (Array.isArray(result)) {
|
|
241
|
+
const items = [];
|
|
242
|
+
for (let i = 0, len = result.length; i < len; i++) {
|
|
243
|
+
const item = result[i];
|
|
244
|
+
if (['{', '}'].includes(item.trim())) {
|
|
245
|
+
items[items.length] = item;
|
|
246
|
+
} else {
|
|
247
|
+
try {
|
|
248
|
+
items[items.length] = await jexl.eval(item, context);
|
|
249
|
+
} catch (e) {
|
|
250
|
+
items[items.length] = item;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
return items.join('\n');
|
|
255
|
+
}
|
|
256
|
+
// We can have a situation where the input is something like "{"test":true}".
|
|
257
|
+
// In this case we need to make sure that this is plain JSON without variables.
|
|
258
|
+
const isJsonObject = typedValue.startsWith('{') && typedValue.endsWith('}');
|
|
259
|
+
const isJsonArray = typedValue.startsWith('[') && typedValue.endsWith(']');
|
|
260
|
+
const isJson = isJsonObject || isJsonArray;
|
|
261
|
+
const innerString = isJson ? typedValue.substring(1, typedValue.length - 1) : '';
|
|
262
|
+
// On the other hand we can have a string like "{operation}" which should also be
|
|
263
|
+
// evaluated
|
|
264
|
+
if (isJson && !varExprRe.test(innerString) && !varValueRe.test(innerString)) {
|
|
265
|
+
return value;
|
|
266
|
+
}
|
|
267
|
+
return this._parse(result, context);
|
|
268
|
+
// let returnValue = result;
|
|
269
|
+
// try {
|
|
270
|
+
// returnValue = await jexl.eval(result, context);
|
|
271
|
+
// } catch (e) {
|
|
272
|
+
// // ...
|
|
273
|
+
// }
|
|
274
|
+
// return returnValue;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
async _parse(value: string, context: Record<string, string>): Promise<string> {
|
|
278
|
+
const { jexl } = this;
|
|
279
|
+
let returnValue = value;
|
|
280
|
+
try {
|
|
281
|
+
returnValue = await jexl.eval(value, context);
|
|
282
|
+
} catch (e) {
|
|
283
|
+
// ...
|
|
284
|
+
}
|
|
285
|
+
return returnValue;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Upgrades old syntax of magic variables to new one.
|
|
290
|
+
* It replaces `${now}` and `${random}` to function calls: `now()` and
|
|
291
|
+
* `random()`. It also keeps grouping.
|
|
292
|
+
*
|
|
293
|
+
* @param value Currently evaluated value
|
|
294
|
+
* @return Parsed value without old syntax.
|
|
295
|
+
*/
|
|
296
|
+
_upgradeLegacy(value: string): string {
|
|
297
|
+
const reg = /\$?{(random|now):?([0-9]+)?}/gm;
|
|
298
|
+
const test = reg.test(value);
|
|
299
|
+
if (!test) {
|
|
300
|
+
return value;
|
|
301
|
+
}
|
|
302
|
+
reg.lastIndex = 0;
|
|
303
|
+
const loopTest = true;
|
|
304
|
+
while (loopTest) {
|
|
305
|
+
const matches = reg.exec(value);
|
|
306
|
+
if (!matches) {
|
|
307
|
+
break;
|
|
308
|
+
}
|
|
309
|
+
const variable = matches[0];
|
|
310
|
+
const word = matches[1];
|
|
311
|
+
const group = matches[2];
|
|
312
|
+
let replacement = `\${${word}(`;
|
|
313
|
+
if (group) {
|
|
314
|
+
replacement += group;
|
|
315
|
+
}
|
|
316
|
+
replacement += ')}';
|
|
317
|
+
value = value.replace(variable, replacement);
|
|
318
|
+
reg.lastIndex -= 2; // replacement word is shorter by 2 characters
|
|
319
|
+
}
|
|
320
|
+
return value;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* Evaluates functions.
|
|
325
|
+
*
|
|
326
|
+
* @param value A value to evaluate
|
|
327
|
+
* @returns Evaluated value with removed functions.
|
|
328
|
+
* @throws Error if a function is not supported.
|
|
329
|
+
*/
|
|
330
|
+
_evalFunctions(value: string, context: Record<string, string>): string {
|
|
331
|
+
if (!value) {
|
|
332
|
+
return '';
|
|
333
|
+
}
|
|
334
|
+
functionRegex.lastIndex = 0;
|
|
335
|
+
const cnd = true;
|
|
336
|
+
while (cnd) {
|
|
337
|
+
const matches = functionRegex.exec(value);
|
|
338
|
+
if (!matches) {
|
|
339
|
+
break;
|
|
340
|
+
}
|
|
341
|
+
const fnName = matches[1];
|
|
342
|
+
const argsStr = matches[2];
|
|
343
|
+
let args;
|
|
344
|
+
if (argsStr) {
|
|
345
|
+
args = argsStr.split(',').map(item => item.trim());
|
|
346
|
+
}
|
|
347
|
+
const _value = this._callFn(context, fnName, args);
|
|
348
|
+
value = value.replace(matches[0], String(_value));
|
|
349
|
+
functionRegex.lastIndex -= matches[0].length - String(_value).length;
|
|
350
|
+
}
|
|
351
|
+
return value;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
/**
|
|
355
|
+
* Calls one of the predefined functions and returns its value.
|
|
356
|
+
*
|
|
357
|
+
* @param fnName A function name to call.
|
|
358
|
+
* @param args Arguments find in the expression.
|
|
359
|
+
* @return Result of calling a function. Always a string.
|
|
360
|
+
*/
|
|
361
|
+
_callFn(context: Record<string, string>, fnName: string, args?: string[]): string | number {
|
|
362
|
+
const dotIndex = fnName.indexOf('.');
|
|
363
|
+
if (dotIndex !== -1) {
|
|
364
|
+
const namespace = fnName.substring(0, dotIndex);
|
|
365
|
+
const name = fnName.substring(dotIndex + 1);
|
|
366
|
+
if (['Math', 'String'].indexOf(namespace) !== -1) {
|
|
367
|
+
try {
|
|
368
|
+
return this._callNamespaceFunction(context, namespace, name, args);
|
|
369
|
+
} catch (e) {
|
|
370
|
+
throw new Error(`Unsupported function ${fnName}`);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
} else {
|
|
374
|
+
fnName = fnName[0].toUpperCase() + fnName.substring(1);
|
|
375
|
+
if (fnName in EvalFunctions) {
|
|
376
|
+
return EvalFunctions[fnName](this, args);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
throw new Error(`Unsupported function ${fnName}`);
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
/**
|
|
383
|
+
* Calls JavaScript native function.
|
|
384
|
+
* Currently only `Math`, 'JSON', and `String` namespaces are supported.
|
|
385
|
+
*
|
|
386
|
+
* @param namespace The namespace of the function to call
|
|
387
|
+
* @param fn Name of the function to call
|
|
388
|
+
* @param args A list of arguments to call
|
|
389
|
+
* @returns Processed value.
|
|
390
|
+
*/
|
|
391
|
+
_callNamespaceFunction(context: Record<string, string>, namespace: string, fn: string, args?: string[]): string | number {
|
|
392
|
+
if (context && args) {
|
|
393
|
+
args = args.map(arg => this._applyArgumentsContext(arg, context));
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
if (namespace === 'Math') {
|
|
397
|
+
const ns = globalThis[namespace] as any;
|
|
398
|
+
return ns[fn].apply(globalThis, args?.map(Number));
|
|
399
|
+
}
|
|
400
|
+
if (namespace === 'JSON') {
|
|
401
|
+
const ns = globalThis[namespace] as any;
|
|
402
|
+
return ns[fn].apply(globalThis, args);
|
|
403
|
+
}
|
|
404
|
+
if (namespace === 'String') {
|
|
405
|
+
if (!args || !args.length) {
|
|
406
|
+
throw new Error('String functions need an argument');
|
|
407
|
+
}
|
|
408
|
+
const str = args.shift();
|
|
409
|
+
const ns = (String.prototype as any)[fn];
|
|
410
|
+
return ns.apply(str, args);
|
|
411
|
+
}
|
|
412
|
+
return '';
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
/**
|
|
416
|
+
* Prepares variables to be evaluated where a value is a multiline value.
|
|
417
|
+
* @param lines Lines in the expression
|
|
418
|
+
* @returns Processed lines
|
|
419
|
+
*/
|
|
420
|
+
_prepareMultilineValue(lines: string[]): string[] {
|
|
421
|
+
return lines.map((line) => {
|
|
422
|
+
if (['{', '}'].includes(line.trim())) {
|
|
423
|
+
return line;
|
|
424
|
+
}
|
|
425
|
+
let _res = this._prepareValue(line);
|
|
426
|
+
if (_res === line) {
|
|
427
|
+
_res = _res.replace(/'/g, "\\'");
|
|
428
|
+
_res = _res.replace(/\\\\/, '\\\\\\');
|
|
429
|
+
_res = `'${_res}'`;
|
|
430
|
+
}
|
|
431
|
+
return _res;
|
|
432
|
+
});
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
_applyArgumentsContext(arg: any, context: Record<string, string>): any {
|
|
436
|
+
const typedValue = String(arg);
|
|
437
|
+
const hasJsLiteral = typedValue.startsWith('${');
|
|
438
|
+
const hasApiLiteral = typedValue.startsWith('{');
|
|
439
|
+
if (hasJsLiteral|| hasApiLiteral) {
|
|
440
|
+
const index = hasJsLiteral ? 2 : 1;
|
|
441
|
+
const varName = arg.substring(index, arg.length - 1);
|
|
442
|
+
if (this.isValidName(varName) && context[varName]) {
|
|
443
|
+
return context[varName];
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
return arg;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
/**
|
|
450
|
+
* Replaces strings with quoted string and variables notation into
|
|
451
|
+
* variables that Jexl understands.
|
|
452
|
+
*
|
|
453
|
+
* @param value Value to evaluate
|
|
454
|
+
* @return Proper syntax for Jexl
|
|
455
|
+
*/
|
|
456
|
+
_prepareValue(value: string): string {
|
|
457
|
+
if (!value) {
|
|
458
|
+
return value;
|
|
459
|
+
}
|
|
460
|
+
let typedValue = String(value);
|
|
461
|
+
let isJsonValue = typedValue[0] === '{' && typedValue[typedValue.length - 1] === '}';
|
|
462
|
+
if (isJsonValue) {
|
|
463
|
+
try {
|
|
464
|
+
// to handle `{x} something {y}`
|
|
465
|
+
JSON.parse(typedValue);
|
|
466
|
+
typedValue = typedValue.substring(1, typedValue.length - 1);
|
|
467
|
+
} catch (e) {
|
|
468
|
+
isJsonValue = false;
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
const isJSLiteral = typedValue.includes('${');
|
|
472
|
+
let isAPILiteral = !isJSLiteral && typedValue.includes('{');
|
|
473
|
+
if (!isJSLiteral && !isAPILiteral && isJsonValue) {
|
|
474
|
+
// this handles the case when the value contains a single variable in
|
|
475
|
+
// the URL variables syntax.
|
|
476
|
+
isAPILiteral = true;
|
|
477
|
+
isJsonValue = false;
|
|
478
|
+
typedValue = `{${typedValue}}`;
|
|
479
|
+
}
|
|
480
|
+
if (!isJSLiteral && !isAPILiteral) {
|
|
481
|
+
return value;
|
|
482
|
+
}
|
|
483
|
+
typedValue = typedValue.replace(/'/g, "\\'");
|
|
484
|
+
const tokenizer = new VariablesTokenizer(typedValue);
|
|
485
|
+
let parsed = '';
|
|
486
|
+
const loopTest = true;
|
|
487
|
+
const prefix = isJSLiteral ? '$' : '{';
|
|
488
|
+
while (loopTest) {
|
|
489
|
+
const _startIndex = tokenizer.index;
|
|
490
|
+
const left = tokenizer.nextUntil(prefix);
|
|
491
|
+
if (left === null) {
|
|
492
|
+
// no more variables
|
|
493
|
+
if (!parsed) {
|
|
494
|
+
return this._wrapJsonValue(typedValue, isJsonValue);
|
|
495
|
+
}
|
|
496
|
+
tokenizer.index = _startIndex;
|
|
497
|
+
parsed += `'${tokenizer.eof()}'`;
|
|
498
|
+
return this._wrapJsonValue(parsed, isJsonValue);
|
|
499
|
+
}
|
|
500
|
+
let variable = tokenizer.nextUntil('}');
|
|
501
|
+
if (variable === '') {
|
|
502
|
+
// let this pass.
|
|
503
|
+
continue;
|
|
504
|
+
}
|
|
505
|
+
if (!variable) {
|
|
506
|
+
// https://github.com/advanced-rest-client/arc-environment/issues/2
|
|
507
|
+
// This may not be error, even if so, don't throw it in here, just ignore the expression
|
|
508
|
+
return value;
|
|
509
|
+
}
|
|
510
|
+
if (!isAPILiteral) {
|
|
511
|
+
variable = variable.substring(1);
|
|
512
|
+
}
|
|
513
|
+
if (!this.isValidName(variable)) {
|
|
514
|
+
continue;
|
|
515
|
+
}
|
|
516
|
+
const replacement = ` + ${variable} + `;
|
|
517
|
+
let newValue = '';
|
|
518
|
+
newValue += `'${left}'`;
|
|
519
|
+
newValue += replacement;
|
|
520
|
+
parsed += newValue;
|
|
521
|
+
}
|
|
522
|
+
return this._wrapJsonValue(typedValue, isJsonValue);
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
/**
|
|
526
|
+
* Wraps a passed value with `'{'` and `'}'` to be properly processed by Jexl.
|
|
527
|
+
* @param value The value to wrap.
|
|
528
|
+
* @param isJson Whether the passed string originally was a JSON string.
|
|
529
|
+
* @return Valid for Jexl JSON string.
|
|
530
|
+
*/
|
|
531
|
+
_wrapJsonValue(value: string, isJson: boolean): string {
|
|
532
|
+
return isJson ? `'{' + ${value} + '}'` : value;
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
/**
|
|
536
|
+
* Checks whether passed value is a valid variable name.
|
|
537
|
+
* @param name Variable name
|
|
538
|
+
* @return true if the passed name can be used as variable value.
|
|
539
|
+
*/
|
|
540
|
+
isValidName(name: string): boolean {
|
|
541
|
+
return varValueRe.test(name);
|
|
542
|
+
}
|
|
543
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Processes string value tokens.
|
|
3
|
+
*/
|
|
4
|
+
export class VariablesTokenizer {
|
|
5
|
+
value: string;
|
|
6
|
+
index = 0;
|
|
7
|
+
/**
|
|
8
|
+
* @param value The value to process
|
|
9
|
+
*/
|
|
10
|
+
constructor(value: string) {
|
|
11
|
+
this.value = value;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @returns The next character
|
|
16
|
+
*/
|
|
17
|
+
next(): string {
|
|
18
|
+
const { index } = this;
|
|
19
|
+
const char = this.value[index];
|
|
20
|
+
this.index = index + 1;
|
|
21
|
+
return char;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Consumes characters until specified character is encountered.
|
|
26
|
+
* @param char The search stop character
|
|
27
|
+
* @returns The remaining value from the string or null.
|
|
28
|
+
*/
|
|
29
|
+
nextUntil(char: string): string | null {
|
|
30
|
+
let result = '';
|
|
31
|
+
const test = true;
|
|
32
|
+
while (test) {
|
|
33
|
+
const ch = this.next();
|
|
34
|
+
if (ch === undefined) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
if (ch === char) {
|
|
38
|
+
return result;
|
|
39
|
+
}
|
|
40
|
+
result += ch;
|
|
41
|
+
}
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Reads the string from current position until the end and sets the index to the end.
|
|
47
|
+
* @returns The string from current position until end.
|
|
48
|
+
*/
|
|
49
|
+
eof(): string {
|
|
50
|
+
const { index, value } = this;
|
|
51
|
+
const result = value.substr(index);
|
|
52
|
+
this.index = value.length;
|
|
53
|
+
return result;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Network errors occurred during transport with a message and error code.
|
|
3
|
-
*/
|
|
4
|
-
export declare class NetError extends Error {
|
|
5
|
-
code?: number | string;
|
|
6
|
-
/**
|
|
7
|
-
* @param code Optional error code.
|
|
8
|
-
*/
|
|
9
|
-
constructor(message: string, code?: number | string);
|
|
10
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Network errors occurred during transport with a message and error code.
|
|
3
|
-
*/
|
|
4
|
-
export class NetError extends Error {
|
|
5
|
-
code;
|
|
6
|
-
/**
|
|
7
|
-
* @param code Optional error code.
|
|
8
|
-
*/
|
|
9
|
-
constructor(message, code) {
|
|
10
|
-
super(message);
|
|
11
|
-
this.code = code;
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
//# sourceMappingURL=Errors.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Errors.js","sourceRoot":"","sources":["../../../../src/runtime/http-engine/Errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,OAAO,QAAS,SAAQ,KAAK;IACjC,IAAI,CAAmB;IACvB;;OAEG;IACH,YAAY,OAAe,EAAE,IAAsB;QACjD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF"}
|