@cqa-lib/cqa-ui 1.1.482 → 1.1.483
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/esm2020/lib/execution-screen/api-step/api-step.component.mjs +78 -54
- package/fesm2015/cqa-lib-cqa-ui.mjs +78 -55
- package/fesm2015/cqa-lib-cqa-ui.mjs.map +1 -1
- package/fesm2020/cqa-lib-cqa-ui.mjs +78 -54
- package/fesm2020/cqa-lib-cqa-ui.mjs.map +1 -1
- package/lib/execution-screen/api-step/api-step.component.d.ts +9 -1
- package/package.json +1 -1
|
@@ -14189,19 +14189,56 @@ class ApiStepComponent extends BaseStepComponent {
|
|
|
14189
14189
|
}
|
|
14190
14190
|
}
|
|
14191
14191
|
/**
|
|
14192
|
-
*
|
|
14192
|
+
* Walks jsonData and builds a map from each line number (in the output of
|
|
14193
|
+
* JSON.stringify(jsonData, null, 2)) to the segment path that line represents.
|
|
14194
|
+
* Segments are strings for object keys and numbers for array indices.
|
|
14195
|
+
*/
|
|
14196
|
+
buildLinePathMap(obj) {
|
|
14197
|
+
const map = new Map();
|
|
14198
|
+
const state = { line: 0 };
|
|
14199
|
+
const walk = (value, path) => {
|
|
14200
|
+
if (Array.isArray(value)) {
|
|
14201
|
+
if (value.length === 0)
|
|
14202
|
+
return;
|
|
14203
|
+
for (let i = 0; i < value.length; i++) {
|
|
14204
|
+
state.line += 1; // newline before element
|
|
14205
|
+
const elementPath = [...path, i];
|
|
14206
|
+
map.set(state.line, elementPath);
|
|
14207
|
+
walk(value[i], elementPath);
|
|
14208
|
+
}
|
|
14209
|
+
state.line += 1; // newline before closing ]
|
|
14210
|
+
return;
|
|
14211
|
+
}
|
|
14212
|
+
if (value && typeof value === 'object') {
|
|
14213
|
+
const keys = Object.keys(value);
|
|
14214
|
+
if (keys.length === 0)
|
|
14215
|
+
return;
|
|
14216
|
+
for (const key of keys) {
|
|
14217
|
+
state.line += 1; // newline before "key":
|
|
14218
|
+
const keyPath = [...path, key];
|
|
14219
|
+
map.set(state.line, keyPath);
|
|
14220
|
+
walk(value[key], keyPath);
|
|
14221
|
+
}
|
|
14222
|
+
state.line += 1; // newline before closing }
|
|
14223
|
+
return;
|
|
14224
|
+
}
|
|
14225
|
+
// primitive — no additional lines
|
|
14226
|
+
};
|
|
14227
|
+
// Root line (line 0) is the opening { or [ or primitive.
|
|
14228
|
+
walk(obj, []);
|
|
14229
|
+
return map;
|
|
14230
|
+
}
|
|
14231
|
+
/**
|
|
14232
|
+
* Extracts JSON path from the clicked position in a formatted JSON string.
|
|
14233
|
+
* Returns an array of segments (string keys or numeric array indices), or null.
|
|
14193
14234
|
*/
|
|
14194
14235
|
getJsonPathFromClick(event, jsonData, prefix = '') {
|
|
14195
|
-
var _a, _b;
|
|
14196
14236
|
const target = event.target;
|
|
14197
|
-
if (!target ||
|
|
14237
|
+
if (!target || jsonData == null)
|
|
14198
14238
|
return null;
|
|
14199
14239
|
const preElement = target.closest('pre');
|
|
14200
14240
|
if (!preElement)
|
|
14201
14241
|
return null;
|
|
14202
|
-
// Get the formatted JSON text
|
|
14203
|
-
const formattedJson = this.formatJson(jsonData);
|
|
14204
|
-
const lines = formattedJson.split('\n');
|
|
14205
14242
|
// Create a range at the click position
|
|
14206
14243
|
let range = null;
|
|
14207
14244
|
if (document.caretRangeFromPoint) {
|
|
@@ -14224,58 +14261,44 @@ class ApiStepComponent extends BaseStepComponent {
|
|
|
14224
14261
|
const textBeforeClick = preRange.toString();
|
|
14225
14262
|
// Count newlines to find which line we're on
|
|
14226
14263
|
const lineIndex = (textBeforeClick.match(/\n/g) || []).length;
|
|
14227
|
-
|
|
14228
|
-
|
|
14229
|
-
//
|
|
14230
|
-
|
|
14231
|
-
if (!
|
|
14232
|
-
|
|
14233
|
-
|
|
14234
|
-
|
|
14235
|
-
|
|
14236
|
-
|
|
14237
|
-
|
|
14238
|
-
|
|
14239
|
-
|
|
14240
|
-
|
|
14241
|
-
const lineKeyMatch = line.match(/^(\s+)"([^"]+)":/);
|
|
14242
|
-
if (lineKeyMatch) {
|
|
14243
|
-
const lineIndent = lineKeyMatch[1].length / 2; // Divide by 2 for 2-space indentation
|
|
14244
|
-
const lineKey = lineKeyMatch[2];
|
|
14245
|
-
// If this line has less indentation, it's a parent
|
|
14246
|
-
if (lineIndent < currentIndent) {
|
|
14247
|
-
path.unshift(lineKey);
|
|
14248
|
-
currentIndent = lineIndent;
|
|
14249
|
-
// Stop if we've reached the root level
|
|
14250
|
-
if (lineIndent === 0)
|
|
14251
|
-
break;
|
|
14252
|
-
}
|
|
14253
|
-
}
|
|
14254
|
-
}
|
|
14255
|
-
// Add the clicked key
|
|
14256
|
-
path.push(clickedKey);
|
|
14257
|
-
// Build the full path string
|
|
14258
|
-
if (path.length === 0)
|
|
14264
|
+
const linePathMap = this.buildLinePathMap(jsonData);
|
|
14265
|
+
// Exact match first; otherwise fall back to the nearest preceding mapped line
|
|
14266
|
+
// (handles clicks on closing brackets or blank columns).
|
|
14267
|
+
let segments = linePathMap.get(lineIndex);
|
|
14268
|
+
if (!segments) {
|
|
14269
|
+
for (let i = lineIndex - 1; i >= 0; i--) {
|
|
14270
|
+
const candidate = linePathMap.get(i);
|
|
14271
|
+
if (candidate) {
|
|
14272
|
+
segments = candidate;
|
|
14273
|
+
break;
|
|
14274
|
+
}
|
|
14275
|
+
}
|
|
14276
|
+
}
|
|
14277
|
+
if (!segments || segments.length === 0)
|
|
14259
14278
|
return null;
|
|
14260
|
-
|
|
14261
|
-
return fullPath;
|
|
14279
|
+
return prefix ? [prefix, ...segments] : [...segments];
|
|
14262
14280
|
}
|
|
14263
|
-
|
|
14264
|
-
|
|
14265
|
-
|
|
14266
|
-
|
|
14267
|
-
|
|
14268
|
-
|
|
14269
|
-
|
|
14281
|
+
formatSegmentsPath(segments) {
|
|
14282
|
+
return segments.reduce((acc, seg) => {
|
|
14283
|
+
if (typeof seg === 'number')
|
|
14284
|
+
return `${acc}[${seg}]`;
|
|
14285
|
+
return acc ? `${acc}.${seg}` : String(seg);
|
|
14286
|
+
}, '');
|
|
14287
|
+
}
|
|
14288
|
+
normalizeJsonPath(segments, prefix) {
|
|
14289
|
+
if (!segments || segments.length === 0)
|
|
14290
|
+
return '';
|
|
14291
|
+
if (!prefix || segments.length < 2) {
|
|
14292
|
+
return this.formatSegmentsPath(segments);
|
|
14270
14293
|
}
|
|
14271
|
-
const [, ...rest] =
|
|
14294
|
+
const [, ...rest] = segments;
|
|
14272
14295
|
if (prefix === 'requestHeaders' || prefix === 'responseHeaders') {
|
|
14273
|
-
return rest.length ? `headers
|
|
14296
|
+
return rest.length ? `headers${this.formatSegmentsPath(rest).startsWith('[') ? '' : '.'}${this.formatSegmentsPath(rest)}` : 'headers';
|
|
14274
14297
|
}
|
|
14275
14298
|
if (prefix === 'requestBody' || prefix === 'responseBody') {
|
|
14276
|
-
return rest.length ? `body
|
|
14299
|
+
return rest.length ? `body${this.formatSegmentsPath(rest).startsWith('[') ? '' : '.'}${this.formatSegmentsPath(rest)}` : 'body';
|
|
14277
14300
|
}
|
|
14278
|
-
return
|
|
14301
|
+
return this.formatSegmentsPath(segments);
|
|
14279
14302
|
}
|
|
14280
14303
|
/**
|
|
14281
14304
|
* Copy JSON path on double-click
|
|
@@ -14283,12 +14306,12 @@ class ApiStepComponent extends BaseStepComponent {
|
|
|
14283
14306
|
copyJsonPath(event, jsonData, prefix = '') {
|
|
14284
14307
|
if (!jsonData)
|
|
14285
14308
|
return;
|
|
14286
|
-
const
|
|
14287
|
-
if (
|
|
14309
|
+
const segments = this.getJsonPathFromClick(event, jsonData, prefix);
|
|
14310
|
+
if (segments && segments.length > 0) {
|
|
14288
14311
|
const source = prefix;
|
|
14289
|
-
const normalizedPath = this.normalizeJsonPath(
|
|
14312
|
+
const normalizedPath = this.normalizeJsonPath(segments, prefix);
|
|
14290
14313
|
navigator.clipboard.writeText(normalizedPath).then(() => {
|
|
14291
|
-
console.log('Copied to clipboard:',
|
|
14314
|
+
console.log('Copied to clipboard:', normalizedPath);
|
|
14292
14315
|
// Call the handler on every double-click (even on success, for now showing error as per requirement)
|
|
14293
14316
|
if (this.onJsonPathCopiedHandler) {
|
|
14294
14317
|
console.log('Calling onJsonPathCopiedHandler on success with:', { path: normalizedPath, source });
|