@rogatio/cli 5.0.0 → 5.1.1
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 +21 -0
- package/dist/editor/index.js +479 -61
- package/dist/node/index.js +3744 -2951
- package/package.json +2 -2
package/dist/editor/index.js
CHANGED
|
@@ -214,6 +214,353 @@ var HTTP_METHODS = Object.freeze([
|
|
|
214
214
|
"TRACE"
|
|
215
215
|
]);
|
|
216
216
|
|
|
217
|
+
// packages/editor/src/ai-assist-panel.ts
|
|
218
|
+
function createAIAssistPanel(_container, _editor, onApply, onClose) {
|
|
219
|
+
let visible = false;
|
|
220
|
+
let streamingContent = "";
|
|
221
|
+
let streamingMessageIndex = -1;
|
|
222
|
+
const messages = [];
|
|
223
|
+
const panel = document.createElement("div");
|
|
224
|
+
panel.className = "ai-assist-panel";
|
|
225
|
+
panel.style.cssText = `
|
|
226
|
+
position: fixed;
|
|
227
|
+
top: 0;
|
|
228
|
+
right: 0;
|
|
229
|
+
bottom: 0;
|
|
230
|
+
width: 400px;
|
|
231
|
+
max-width: 100vw;
|
|
232
|
+
background: #1e1e24;
|
|
233
|
+
border-left: 1px solid #333;
|
|
234
|
+
display: flex;
|
|
235
|
+
flex-direction: column;
|
|
236
|
+
z-index: 1000;
|
|
237
|
+
transform: translateX(100%);
|
|
238
|
+
transition: transform 0.2s ease;
|
|
239
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
240
|
+
font-size: 13px;
|
|
241
|
+
color: #e0e0e0;
|
|
242
|
+
`;
|
|
243
|
+
const header = document.createElement("div");
|
|
244
|
+
header.style.cssText = `
|
|
245
|
+
padding: 12px 16px;
|
|
246
|
+
border-bottom: 1px solid #333;
|
|
247
|
+
display: flex;
|
|
248
|
+
align-items: center;
|
|
249
|
+
justify-content: space-between;
|
|
250
|
+
background: #15151a;
|
|
251
|
+
`;
|
|
252
|
+
header.innerHTML = `
|
|
253
|
+
<div style="display: flex; align-items: center; gap: 8px;">
|
|
254
|
+
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
255
|
+
<path d="M12 2a10 10 0 1 0 10 10A10 10 0 0 0 12 2zm0 18a8 8 0 1 1 8-8 8 8 0 0 1-8 8z"/>
|
|
256
|
+
<path d="M12 6v6l4 2"/>
|
|
257
|
+
</svg>
|
|
258
|
+
<span style="font-weight: 600;">AI Assist</span>
|
|
259
|
+
</div>
|
|
260
|
+
<button class="ai-close-btn" style="
|
|
261
|
+
background: none;
|
|
262
|
+
border: none;
|
|
263
|
+
color: #888;
|
|
264
|
+
cursor: pointer;
|
|
265
|
+
padding: 4px;
|
|
266
|
+
border-radius: 4px;
|
|
267
|
+
">
|
|
268
|
+
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
269
|
+
<line x1="18" y1="6" x2="6" y2="18"/>
|
|
270
|
+
<line x1="6" y1="6" x2="18" y2="18"/>
|
|
271
|
+
</svg>
|
|
272
|
+
</button>
|
|
273
|
+
`;
|
|
274
|
+
const messagesContainer = document.createElement("div");
|
|
275
|
+
messagesContainer.style.cssText = `
|
|
276
|
+
flex: 1;
|
|
277
|
+
overflow-y: auto;
|
|
278
|
+
padding: 16px;
|
|
279
|
+
display: flex;
|
|
280
|
+
flex-direction: column;
|
|
281
|
+
gap: 12px;
|
|
282
|
+
`;
|
|
283
|
+
const inputContainer = document.createElement("div");
|
|
284
|
+
inputContainer.style.cssText = `
|
|
285
|
+
padding: 12px 16px;
|
|
286
|
+
border-top: 1px solid #333;
|
|
287
|
+
background: #15151a;
|
|
288
|
+
`;
|
|
289
|
+
const inputWrapper = document.createElement("div");
|
|
290
|
+
inputWrapper.style.cssText = `
|
|
291
|
+
display: flex;
|
|
292
|
+
gap: 8px;
|
|
293
|
+
margin-bottom: 8px;
|
|
294
|
+
`;
|
|
295
|
+
const textarea = document.createElement("textarea");
|
|
296
|
+
textarea.placeholder = "Ask AI to generate rules, fix issues, or explain...";
|
|
297
|
+
textarea.style.cssText = `
|
|
298
|
+
flex: 1;
|
|
299
|
+
background: #2a2a34;
|
|
300
|
+
border: 1px solid #3a3a48;
|
|
301
|
+
border-radius: 8px;
|
|
302
|
+
padding: 10px 12px;
|
|
303
|
+
color: #e0e0e0;
|
|
304
|
+
font-family: inherit;
|
|
305
|
+
font-size: 13px;
|
|
306
|
+
resize: none;
|
|
307
|
+
min-height: 60px;
|
|
308
|
+
max-height: 150px;
|
|
309
|
+
outline: none;
|
|
310
|
+
`;
|
|
311
|
+
const sendButton = document.createElement("button");
|
|
312
|
+
sendButton.textContent = "Send";
|
|
313
|
+
sendButton.style.cssText = `
|
|
314
|
+
background: #3b82f6;
|
|
315
|
+
color: white;
|
|
316
|
+
border: none;
|
|
317
|
+
border-radius: 8px;
|
|
318
|
+
padding: 10px 20px;
|
|
319
|
+
font-weight: 600;
|
|
320
|
+
cursor: pointer;
|
|
321
|
+
align-self: flex-end;
|
|
322
|
+
transition: background 0.2s;
|
|
323
|
+
`;
|
|
324
|
+
const statusText = document.createElement("div");
|
|
325
|
+
statusText.style.cssText = `
|
|
326
|
+
font-size: 11px;
|
|
327
|
+
color: #666;
|
|
328
|
+
text-align: center;
|
|
329
|
+
`;
|
|
330
|
+
inputWrapper.appendChild(textarea);
|
|
331
|
+
inputWrapper.appendChild(sendButton);
|
|
332
|
+
inputContainer.appendChild(inputWrapper);
|
|
333
|
+
inputContainer.appendChild(statusText);
|
|
334
|
+
panel.appendChild(header);
|
|
335
|
+
panel.appendChild(messagesContainer);
|
|
336
|
+
panel.appendChild(inputContainer);
|
|
337
|
+
const closeBtn = header.querySelector(".ai-close-btn");
|
|
338
|
+
function show() {
|
|
339
|
+
if (!visible) {
|
|
340
|
+
visible = true;
|
|
341
|
+
document.body.appendChild(panel);
|
|
342
|
+
requestAnimationFrame(() => {
|
|
343
|
+
panel.style.transform = "translateX(0)";
|
|
344
|
+
});
|
|
345
|
+
textarea.focus();
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
function hide() {
|
|
349
|
+
if (visible) {
|
|
350
|
+
visible = false;
|
|
351
|
+
panel.style.transform = "translateX(100%)";
|
|
352
|
+
setTimeout(() => {
|
|
353
|
+
if (!visible && panel.parentNode) {
|
|
354
|
+
panel.parentNode.removeChild(panel);
|
|
355
|
+
}
|
|
356
|
+
}, 200);
|
|
357
|
+
onClose();
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
function isVisible() {
|
|
361
|
+
return visible;
|
|
362
|
+
}
|
|
363
|
+
function addMessage(message) {
|
|
364
|
+
const messageEl = document.createElement("div");
|
|
365
|
+
messageEl.style.cssText = `
|
|
366
|
+
display: flex;
|
|
367
|
+
flex-direction: column;
|
|
368
|
+
gap: 8px;
|
|
369
|
+
max-width: 85%;
|
|
370
|
+
${message.role === "user" ? "align-self: flex-end;" : "align-self: flex-start;"}
|
|
371
|
+
`;
|
|
372
|
+
const bubble = document.createElement("div");
|
|
373
|
+
bubble.style.cssText = `
|
|
374
|
+
padding: 10px 14px;
|
|
375
|
+
border-radius: 16px;
|
|
376
|
+
${message.role === "user" ? "background: #3b82f6; color: white; border-bottom-right-radius: 4px;" : "background: #2a2a34; color: #e0e0e0; border-bottom-left-radius: 4px;"}
|
|
377
|
+
white-space: pre-wrap;
|
|
378
|
+
word-wrap: break-word;
|
|
379
|
+
`;
|
|
380
|
+
bubble.textContent = message.content;
|
|
381
|
+
messageEl.appendChild(bubble);
|
|
382
|
+
if (message.proposal) {
|
|
383
|
+
const proposalEl = createProposalElement(message.proposal);
|
|
384
|
+
messageEl.appendChild(proposalEl);
|
|
385
|
+
}
|
|
386
|
+
messagesContainer.appendChild(messageEl);
|
|
387
|
+
messagesContainer.scrollTop = messagesContainer.scrollHeight;
|
|
388
|
+
}
|
|
389
|
+
function createProposalElement(proposal) {
|
|
390
|
+
const container = document.createElement("div");
|
|
391
|
+
container.style.cssText = `
|
|
392
|
+
margin-top: 8px;
|
|
393
|
+
padding: 12px;
|
|
394
|
+
background: #1a1a24;
|
|
395
|
+
border: 1px solid #333;
|
|
396
|
+
border-radius: 8px;
|
|
397
|
+
`;
|
|
398
|
+
const explanation = document.createElement("div");
|
|
399
|
+
explanation.style.cssText = `
|
|
400
|
+
font-size: 12px;
|
|
401
|
+
color: #aaa;
|
|
402
|
+
margin-bottom: 12px;
|
|
403
|
+
line-height: 1.5;
|
|
404
|
+
`;
|
|
405
|
+
explanation.textContent = proposal.explanation;
|
|
406
|
+
container.appendChild(explanation);
|
|
407
|
+
const rulesList = document.createElement("div");
|
|
408
|
+
rulesList.style.cssText = `
|
|
409
|
+
display: flex;
|
|
410
|
+
flex-direction: column;
|
|
411
|
+
gap: 8px;
|
|
412
|
+
`;
|
|
413
|
+
for (const rule of proposal.rules) {
|
|
414
|
+
const ruleEl = document.createElement("div");
|
|
415
|
+
ruleEl.style.cssText = `
|
|
416
|
+
padding: 10px;
|
|
417
|
+
background: #2a2a34;
|
|
418
|
+
border-radius: 6px;
|
|
419
|
+
border: 1px solid #3a3a48;
|
|
420
|
+
`;
|
|
421
|
+
const ruleHeader = document.createElement("div");
|
|
422
|
+
ruleHeader.style.cssText = `
|
|
423
|
+
display: flex;
|
|
424
|
+
align-items: center;
|
|
425
|
+
gap: 8px;
|
|
426
|
+
margin-bottom: 8px;
|
|
427
|
+
`;
|
|
428
|
+
const kindBadge = document.createElement("span");
|
|
429
|
+
kindBadge.textContent = rule.kind;
|
|
430
|
+
kindBadge.style.cssText = `
|
|
431
|
+
font-size: 10px;
|
|
432
|
+
font-weight: 600;
|
|
433
|
+
text-transform: uppercase;
|
|
434
|
+
padding: 2px 8px;
|
|
435
|
+
border-radius: 4px;
|
|
436
|
+
background: #3b82f6;
|
|
437
|
+
color: white;
|
|
438
|
+
`;
|
|
439
|
+
const ruleName = document.createElement("span");
|
|
440
|
+
ruleName.textContent = rule.name;
|
|
441
|
+
ruleName.style.cssText = `
|
|
442
|
+
font-weight: 500;
|
|
443
|
+
flex: 1;
|
|
444
|
+
`;
|
|
445
|
+
ruleHeader.appendChild(kindBadge);
|
|
446
|
+
ruleHeader.appendChild(ruleName);
|
|
447
|
+
const ruleDetails = document.createElement("div");
|
|
448
|
+
ruleDetails.style.cssText = `
|
|
449
|
+
font-size: 11px;
|
|
450
|
+
color: #888;
|
|
451
|
+
display: grid;
|
|
452
|
+
grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
|
|
453
|
+
gap: 4px 12px;
|
|
454
|
+
`;
|
|
455
|
+
const addDetail = (label, value) => {
|
|
456
|
+
const detail = document.createElement("div");
|
|
457
|
+
detail.innerHTML = `<span style="color:#666;">${label}:</span> ${value}`;
|
|
458
|
+
ruleDetails.appendChild(detail);
|
|
459
|
+
};
|
|
460
|
+
addDetail("Regex", rule.urlRegex);
|
|
461
|
+
if (rule.origins?.length) addDetail("Origins", rule.origins.join(", "));
|
|
462
|
+
if (rule.resourceTypes?.length)
|
|
463
|
+
addDetail("Types", rule.resourceTypes.join(", "));
|
|
464
|
+
if (rule.priority !== void 0)
|
|
465
|
+
addDetail("Priority", rule.priority.toString());
|
|
466
|
+
if (rule.method) addDetail("Method", rule.method);
|
|
467
|
+
const actionBtn = document.createElement("button");
|
|
468
|
+
actionBtn.textContent = "Apply Rule";
|
|
469
|
+
actionBtn.style.cssText = `
|
|
470
|
+
margin-top: 10px;
|
|
471
|
+
width: 100%;
|
|
472
|
+
background: #22c55e;
|
|
473
|
+
color: white;
|
|
474
|
+
border: none;
|
|
475
|
+
border-radius: 6px;
|
|
476
|
+
padding: 8px;
|
|
477
|
+
font-weight: 600;
|
|
478
|
+
cursor: pointer;
|
|
479
|
+
transition: background 0.2s;
|
|
480
|
+
`;
|
|
481
|
+
actionBtn.addEventListener("click", () => {
|
|
482
|
+
onApply(proposal);
|
|
483
|
+
});
|
|
484
|
+
ruleEl.appendChild(ruleHeader);
|
|
485
|
+
ruleEl.appendChild(ruleDetails);
|
|
486
|
+
ruleEl.appendChild(actionBtn);
|
|
487
|
+
rulesList.appendChild(ruleEl);
|
|
488
|
+
}
|
|
489
|
+
container.appendChild(rulesList);
|
|
490
|
+
return container;
|
|
491
|
+
}
|
|
492
|
+
function clearMessages() {
|
|
493
|
+
messages.length = 0;
|
|
494
|
+
streamingContent = "";
|
|
495
|
+
streamingMessageIndex = -1;
|
|
496
|
+
messagesContainer.innerHTML = "";
|
|
497
|
+
}
|
|
498
|
+
function updateStreamingContent(content) {
|
|
499
|
+
if (streamingMessageIndex >= 0 && streamingMessageIndex < messages.length) {
|
|
500
|
+
const message = messages[streamingMessageIndex];
|
|
501
|
+
message.content = streamingContent + content;
|
|
502
|
+
const bubbles = messagesContainer.querySelectorAll(
|
|
503
|
+
"div > div:first-child"
|
|
504
|
+
);
|
|
505
|
+
if (bubbles[streamingMessageIndex]) {
|
|
506
|
+
bubbles[streamingMessageIndex].textContent = message.content;
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
function startStreaming(role) {
|
|
511
|
+
streamingContent = "";
|
|
512
|
+
const message = { role, content: "", isStreaming: true };
|
|
513
|
+
messages.push(message);
|
|
514
|
+
streamingMessageIndex = messages.length - 1;
|
|
515
|
+
addMessage(message);
|
|
516
|
+
}
|
|
517
|
+
function finishStreaming(proposal) {
|
|
518
|
+
if (streamingMessageIndex >= 0 && streamingMessageIndex < messages.length) {
|
|
519
|
+
const message = messages[streamingMessageIndex];
|
|
520
|
+
message.isStreaming = false;
|
|
521
|
+
if (proposal) message.proposal = proposal;
|
|
522
|
+
const messageEls = messagesContainer.children;
|
|
523
|
+
if (messageEls[streamingMessageIndex]) {
|
|
524
|
+
const existingProposal = messageEls[streamingMessageIndex].querySelector("div > div:last-child");
|
|
525
|
+
if (proposal) {
|
|
526
|
+
if (existingProposal) existingProposal.remove();
|
|
527
|
+
const proposalEl = createProposalElement(proposal);
|
|
528
|
+
messageEls[streamingMessageIndex].appendChild(
|
|
529
|
+
proposalEl
|
|
530
|
+
);
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
streamingContent = "";
|
|
535
|
+
streamingMessageIndex = -1;
|
|
536
|
+
}
|
|
537
|
+
function handleSend() {
|
|
538
|
+
const prompt = textarea.value.trim();
|
|
539
|
+
if (!prompt) return;
|
|
540
|
+
textarea.value = "";
|
|
541
|
+
textarea.style.height = "auto";
|
|
542
|
+
}
|
|
543
|
+
closeBtn.addEventListener("click", hide);
|
|
544
|
+
sendButton.addEventListener("click", handleSend);
|
|
545
|
+
textarea.addEventListener("keydown", (e) => {
|
|
546
|
+
if (e.key === "Enter" && !e.shiftKey) {
|
|
547
|
+
e.preventDefault();
|
|
548
|
+
handleSend();
|
|
549
|
+
}
|
|
550
|
+
});
|
|
551
|
+
return {
|
|
552
|
+
show,
|
|
553
|
+
hide,
|
|
554
|
+
isVisible,
|
|
555
|
+
addMessage,
|
|
556
|
+
clearMessages,
|
|
557
|
+
// Expose streaming methods for the aiAssist handler to use
|
|
558
|
+
startStreaming,
|
|
559
|
+
updateStreamingContent,
|
|
560
|
+
finishStreaming
|
|
561
|
+
};
|
|
562
|
+
}
|
|
563
|
+
|
|
217
564
|
// packages/editor/src/rule-types/mock.ts
|
|
218
565
|
function isRecord(value) {
|
|
219
566
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -340,7 +687,7 @@ function createMockRuleType() {
|
|
|
340
687
|
return stable(diagnostics);
|
|
341
688
|
},
|
|
342
689
|
mount(context) {
|
|
343
|
-
const { document, container } = context;
|
|
690
|
+
const { document: document2, container } = context;
|
|
344
691
|
const getCurrent = () => asMockAction(context.getField("mock"));
|
|
345
692
|
const setAction = (next) => {
|
|
346
693
|
context.setField("mock", next);
|
|
@@ -349,9 +696,9 @@ function createMockRuleType() {
|
|
|
349
696
|
const current = getCurrent();
|
|
350
697
|
container.replaceChildren();
|
|
351
698
|
if (current === void 0) return;
|
|
352
|
-
const statusLabel =
|
|
699
|
+
const statusLabel = document2.createElement("label");
|
|
353
700
|
statusLabel.textContent = "Status";
|
|
354
|
-
const statusInput =
|
|
701
|
+
const statusInput = document2.createElement("input");
|
|
355
702
|
statusInput.type = "number";
|
|
356
703
|
statusInput.min = String(LIMITS.minMockStatus);
|
|
357
704
|
statusInput.max = String(LIMITS.maxMockStatus);
|
|
@@ -365,9 +712,9 @@ function createMockRuleType() {
|
|
|
365
712
|
});
|
|
366
713
|
context.registerControl("/mock/status", statusInput);
|
|
367
714
|
statusLabel.append(statusInput);
|
|
368
|
-
const delayLabel =
|
|
715
|
+
const delayLabel = document2.createElement("label");
|
|
369
716
|
delayLabel.textContent = "Delay (ms)";
|
|
370
|
-
const delayInput =
|
|
717
|
+
const delayInput = document2.createElement("input");
|
|
371
718
|
delayInput.type = "number";
|
|
372
719
|
delayInput.min = "0";
|
|
373
720
|
delayInput.max = String(LIMITS.maxMockDelayMs);
|
|
@@ -383,20 +730,20 @@ function createMockRuleType() {
|
|
|
383
730
|
});
|
|
384
731
|
context.registerControl("/mock/delayMs", delayInput);
|
|
385
732
|
delayLabel.append(delayInput);
|
|
386
|
-
const sourceLabel =
|
|
733
|
+
const sourceLabel = document2.createElement("label");
|
|
387
734
|
sourceLabel.textContent = "Body source";
|
|
388
|
-
const sourceSelect =
|
|
735
|
+
const sourceSelect = document2.createElement("select");
|
|
389
736
|
sourceSelect.dataset.editorField = "true";
|
|
390
|
-
const bodyOption =
|
|
737
|
+
const bodyOption = document2.createElement("option");
|
|
391
738
|
bodyOption.value = "body";
|
|
392
739
|
bodyOption.textContent = "Inline body";
|
|
393
|
-
const fileOption =
|
|
740
|
+
const fileOption = document2.createElement("option");
|
|
394
741
|
fileOption.value = "file";
|
|
395
742
|
fileOption.textContent = "File snapshot";
|
|
396
743
|
sourceSelect.append(bodyOption, fileOption);
|
|
397
744
|
sourceSelect.value = typeof current.file === "string" ? "file" : "body";
|
|
398
745
|
context.registerControl("/mock/body-source", sourceSelect);
|
|
399
|
-
const bodyArea =
|
|
746
|
+
const bodyArea = document2.createElement("textarea");
|
|
400
747
|
bodyArea.value = typeof current.body === "string" ? current.body : "";
|
|
401
748
|
bodyArea.dataset.editorField = "true";
|
|
402
749
|
bodyArea.addEventListener("input", () => {
|
|
@@ -405,9 +752,9 @@ function createMockRuleType() {
|
|
|
405
752
|
setAction({ ...c, body: bodyArea.value, file: void 0 });
|
|
406
753
|
});
|
|
407
754
|
context.registerControl("/mock/body", bodyArea);
|
|
408
|
-
const fileLabel =
|
|
755
|
+
const fileLabel = document2.createElement("label");
|
|
409
756
|
fileLabel.textContent = "File path";
|
|
410
|
-
const fileInput =
|
|
757
|
+
const fileInput = document2.createElement("input");
|
|
411
758
|
fileInput.type = "text";
|
|
412
759
|
fileInput.value = typeof current.file === "string" ? current.file : "";
|
|
413
760
|
fileInput.dataset.editorField = "true";
|
|
@@ -425,8 +772,8 @@ function createMockRuleType() {
|
|
|
425
772
|
};
|
|
426
773
|
sourceSelect.addEventListener("change", syncSource);
|
|
427
774
|
syncSource();
|
|
428
|
-
const headersFieldset =
|
|
429
|
-
const headersLegend =
|
|
775
|
+
const headersFieldset = document2.createElement("fieldset");
|
|
776
|
+
const headersLegend = document2.createElement("legend");
|
|
430
777
|
headersLegend.textContent = "Response headers";
|
|
431
778
|
headersFieldset.append(headersLegend);
|
|
432
779
|
const renderHeaders = () => {
|
|
@@ -437,11 +784,11 @@ function createMockRuleType() {
|
|
|
437
784
|
});
|
|
438
785
|
const headers = c.headers ?? [];
|
|
439
786
|
headers.forEach((header, index) => {
|
|
440
|
-
const row =
|
|
787
|
+
const row = document2.createElement("div");
|
|
441
788
|
row.dataset.mockHeaderRow = String(index);
|
|
442
|
-
const nameLabel =
|
|
789
|
+
const nameLabel = document2.createElement("label");
|
|
443
790
|
nameLabel.textContent = "Name";
|
|
444
|
-
const nameInput =
|
|
791
|
+
const nameInput = document2.createElement("input");
|
|
445
792
|
nameInput.type = "text";
|
|
446
793
|
nameInput.value = header.name;
|
|
447
794
|
nameInput.dataset.editorField = "true";
|
|
@@ -455,9 +802,9 @@ function createMockRuleType() {
|
|
|
455
802
|
});
|
|
456
803
|
context.registerControl(`/mock/headers/${index}/name`, nameInput);
|
|
457
804
|
nameLabel.append(nameInput);
|
|
458
|
-
const valueLabel =
|
|
805
|
+
const valueLabel = document2.createElement("label");
|
|
459
806
|
valueLabel.textContent = "Value";
|
|
460
|
-
const valueInput =
|
|
807
|
+
const valueInput = document2.createElement("input");
|
|
461
808
|
valueInput.type = "text";
|
|
462
809
|
valueInput.value = header.value;
|
|
463
810
|
valueInput.dataset.editorField = "true";
|
|
@@ -471,7 +818,7 @@ function createMockRuleType() {
|
|
|
471
818
|
});
|
|
472
819
|
context.registerControl(`/mock/headers/${index}/value`, valueInput);
|
|
473
820
|
valueLabel.append(valueInput);
|
|
474
|
-
const remove =
|
|
821
|
+
const remove = document2.createElement("button");
|
|
475
822
|
remove.type = "button";
|
|
476
823
|
remove.textContent = "Remove";
|
|
477
824
|
remove.dataset.editorField = "true";
|
|
@@ -484,7 +831,7 @@ function createMockRuleType() {
|
|
|
484
831
|
row.append(nameLabel, valueLabel, remove);
|
|
485
832
|
headersFieldset.append(row);
|
|
486
833
|
});
|
|
487
|
-
const add =
|
|
834
|
+
const add = document2.createElement("button");
|
|
488
835
|
add.type = "button";
|
|
489
836
|
add.textContent = "Add header";
|
|
490
837
|
add.dataset.editorField = "true";
|
|
@@ -612,7 +959,7 @@ var queryRuleType = {
|
|
|
612
959
|
return stable2(diagnostics);
|
|
613
960
|
},
|
|
614
961
|
mount(context) {
|
|
615
|
-
const { document, container } = context;
|
|
962
|
+
const { document: document2, container } = context;
|
|
616
963
|
const getCurrent = () => asQueryAction(context.getField("action"));
|
|
617
964
|
const setAction = (next) => {
|
|
618
965
|
context.setField("action", next);
|
|
@@ -622,11 +969,11 @@ var queryRuleType = {
|
|
|
622
969
|
container.replaceChildren();
|
|
623
970
|
if (current === void 0) return;
|
|
624
971
|
current.params.forEach((param, index) => {
|
|
625
|
-
const row =
|
|
972
|
+
const row = document2.createElement("div");
|
|
626
973
|
row.dataset.queryParamRow = String(index);
|
|
627
|
-
const nameLabel =
|
|
974
|
+
const nameLabel = document2.createElement("label");
|
|
628
975
|
nameLabel.textContent = "Name";
|
|
629
|
-
const nameInput =
|
|
976
|
+
const nameInput = document2.createElement("input");
|
|
630
977
|
nameInput.type = "text";
|
|
631
978
|
nameInput.value = param.name;
|
|
632
979
|
nameInput.dataset.editorField = "true";
|
|
@@ -640,9 +987,9 @@ var queryRuleType = {
|
|
|
640
987
|
});
|
|
641
988
|
context.registerControl(`/action/params/${index}/name`, nameInput);
|
|
642
989
|
nameLabel.append(nameInput);
|
|
643
|
-
const valueLabel =
|
|
990
|
+
const valueLabel = document2.createElement("label");
|
|
644
991
|
valueLabel.textContent = "Value";
|
|
645
|
-
const valueInput =
|
|
992
|
+
const valueInput = document2.createElement("input");
|
|
646
993
|
valueInput.type = "text";
|
|
647
994
|
valueInput.value = param.value;
|
|
648
995
|
valueInput.dataset.editorField = "true";
|
|
@@ -656,7 +1003,7 @@ var queryRuleType = {
|
|
|
656
1003
|
});
|
|
657
1004
|
context.registerControl(`/action/params/${index}/value`, valueInput);
|
|
658
1005
|
valueLabel.append(valueInput);
|
|
659
|
-
const remove =
|
|
1006
|
+
const remove = document2.createElement("button");
|
|
660
1007
|
remove.type = "button";
|
|
661
1008
|
remove.textContent = "Remove";
|
|
662
1009
|
remove.dataset.editorField = "true";
|
|
@@ -669,7 +1016,7 @@ var queryRuleType = {
|
|
|
669
1016
|
row.append(nameLabel, valueLabel, remove);
|
|
670
1017
|
container.append(row);
|
|
671
1018
|
});
|
|
672
|
-
const add =
|
|
1019
|
+
const add = document2.createElement("button");
|
|
673
1020
|
add.type = "button";
|
|
674
1021
|
add.textContent = "Add parameter";
|
|
675
1022
|
add.dataset.editorField = "true";
|
|
@@ -834,17 +1181,17 @@ function createRequestBodyRuleType() {
|
|
|
834
1181
|
return stable3(diagnostics);
|
|
835
1182
|
},
|
|
836
1183
|
mount(context) {
|
|
837
|
-
const { document, container } = context;
|
|
1184
|
+
const { document: document2, container } = context;
|
|
838
1185
|
const render = () => {
|
|
839
1186
|
const current = requestBodyOf(context.getField("requestBody"));
|
|
840
1187
|
container.replaceChildren();
|
|
841
1188
|
if (current === void 0) return;
|
|
842
|
-
const modeSelect =
|
|
1189
|
+
const modeSelect = document2.createElement("select");
|
|
843
1190
|
modeSelect.value = current.mode;
|
|
844
|
-
const replaceOption =
|
|
1191
|
+
const replaceOption = document2.createElement("option");
|
|
845
1192
|
replaceOption.value = "replace";
|
|
846
1193
|
replaceOption.textContent = "Replace body";
|
|
847
|
-
const regexOption =
|
|
1194
|
+
const regexOption = document2.createElement("option");
|
|
848
1195
|
regexOption.value = "regex";
|
|
849
1196
|
regexOption.textContent = "Regex replace";
|
|
850
1197
|
modeSelect.append(replaceOption, regexOption);
|
|
@@ -862,7 +1209,7 @@ function createRequestBodyRuleType() {
|
|
|
862
1209
|
context.registerControl("/requestBody/mode", modeSelect);
|
|
863
1210
|
container.append(modeSelect);
|
|
864
1211
|
if (current.mode === "replace") {
|
|
865
|
-
const bodyInput =
|
|
1212
|
+
const bodyInput = document2.createElement("textarea");
|
|
866
1213
|
bodyInput.value = current.body ?? "";
|
|
867
1214
|
bodyInput.placeholder = "Replacement body";
|
|
868
1215
|
bodyInput.addEventListener("input", () => {
|
|
@@ -872,7 +1219,7 @@ function createRequestBodyRuleType() {
|
|
|
872
1219
|
context.registerControl("/requestBody/body", bodyInput);
|
|
873
1220
|
container.append(bodyInput);
|
|
874
1221
|
} else {
|
|
875
|
-
const patternInput =
|
|
1222
|
+
const patternInput = document2.createElement("input");
|
|
876
1223
|
patternInput.type = "text";
|
|
877
1224
|
patternInput.value = current.pattern ?? "";
|
|
878
1225
|
patternInput.placeholder = "Regex pattern";
|
|
@@ -882,7 +1229,7 @@ function createRequestBodyRuleType() {
|
|
|
882
1229
|
});
|
|
883
1230
|
context.registerControl("/requestBody/pattern", patternInput);
|
|
884
1231
|
container.append(patternInput);
|
|
885
|
-
const replacementInput =
|
|
1232
|
+
const replacementInput = document2.createElement("input");
|
|
886
1233
|
replacementInput.type = "text";
|
|
887
1234
|
replacementInput.value = current.replacement ?? "";
|
|
888
1235
|
replacementInput.placeholder = "Replacement";
|
|
@@ -964,15 +1311,15 @@ function createResponseBodyRuleType() {
|
|
|
964
1311
|
return stable4(diagnostics);
|
|
965
1312
|
},
|
|
966
1313
|
mount(context) {
|
|
967
|
-
const { document, container } = context;
|
|
1314
|
+
const { document: document2, container } = context;
|
|
968
1315
|
const render = () => {
|
|
969
1316
|
const current = replacementsOf(context.getField("responseBody"));
|
|
970
1317
|
container.replaceChildren();
|
|
971
1318
|
if (current === void 0) return;
|
|
972
1319
|
current.forEach((entry, index) => {
|
|
973
|
-
const row =
|
|
1320
|
+
const row = document2.createElement("div");
|
|
974
1321
|
row.dataset.responseBodyReplacement = String(index);
|
|
975
|
-
const pattern =
|
|
1322
|
+
const pattern = document2.createElement("input");
|
|
976
1323
|
pattern.type = "text";
|
|
977
1324
|
pattern.value = entry.pattern;
|
|
978
1325
|
pattern.placeholder = "Pattern";
|
|
@@ -987,7 +1334,7 @@ function createResponseBodyRuleType() {
|
|
|
987
1334
|
`/responseBody/replacements/${index}/pattern`,
|
|
988
1335
|
pattern
|
|
989
1336
|
);
|
|
990
|
-
const replacement =
|
|
1337
|
+
const replacement = document2.createElement("input");
|
|
991
1338
|
replacement.type = "text";
|
|
992
1339
|
replacement.value = entry.replacement;
|
|
993
1340
|
replacement.placeholder = "Replacement";
|
|
@@ -1002,7 +1349,7 @@ function createResponseBodyRuleType() {
|
|
|
1002
1349
|
`/responseBody/replacements/${index}/replacement`,
|
|
1003
1350
|
replacement
|
|
1004
1351
|
);
|
|
1005
|
-
const remove =
|
|
1352
|
+
const remove = document2.createElement("button");
|
|
1006
1353
|
remove.type = "button";
|
|
1007
1354
|
remove.textContent = "Remove replacement";
|
|
1008
1355
|
remove.addEventListener("click", () => {
|
|
@@ -1013,7 +1360,7 @@ function createResponseBodyRuleType() {
|
|
|
1013
1360
|
row.append(pattern, replacement, remove);
|
|
1014
1361
|
container.append(row);
|
|
1015
1362
|
});
|
|
1016
|
-
const add =
|
|
1363
|
+
const add = document2.createElement("button");
|
|
1017
1364
|
add.type = "button";
|
|
1018
1365
|
add.textContent = "Add replacement";
|
|
1019
1366
|
add.addEventListener("click", () => {
|
|
@@ -1463,6 +1810,7 @@ var EditorControllerImpl = class {
|
|
|
1463
1810
|
testResult = void 0;
|
|
1464
1811
|
testRunning = false;
|
|
1465
1812
|
testRequestId = 0;
|
|
1813
|
+
aiAssistPanel = null;
|
|
1466
1814
|
constructor(options, initial, extensions) {
|
|
1467
1815
|
this.root = options.root;
|
|
1468
1816
|
this.document = options.root.ownerDocument;
|
|
@@ -1475,6 +1823,19 @@ var EditorControllerImpl = class {
|
|
|
1475
1823
|
if (initialDiagnostics.length > 0) {
|
|
1476
1824
|
throw new EditorInitializationError(initialDiagnostics);
|
|
1477
1825
|
}
|
|
1826
|
+
if (options.aiAssist) {
|
|
1827
|
+
this.aiAssistPanel = createAIAssistPanel(
|
|
1828
|
+
this.root,
|
|
1829
|
+
{
|
|
1830
|
+
getDraft: () => this.getDraft(),
|
|
1831
|
+
navigateToGroup: (groupId) => this.navigateToGroup(groupId)
|
|
1832
|
+
},
|
|
1833
|
+
(proposal) => this.applyAIProposal(proposal),
|
|
1834
|
+
() => {
|
|
1835
|
+
}
|
|
1836
|
+
// onClose
|
|
1837
|
+
);
|
|
1838
|
+
}
|
|
1478
1839
|
this.host = this.document.createElement("div");
|
|
1479
1840
|
this.host.className = "rogatio-editor";
|
|
1480
1841
|
this.host.dataset.rogatioEditor = "true";
|
|
@@ -1548,6 +1909,10 @@ var EditorControllerImpl = class {
|
|
|
1548
1909
|
destroy() {
|
|
1549
1910
|
if (this.destroyed) return;
|
|
1550
1911
|
this.destroyed = true;
|
|
1912
|
+
if (this.aiAssistPanel) {
|
|
1913
|
+
this.aiAssistPanel.hide();
|
|
1914
|
+
this.aiAssistPanel = null;
|
|
1915
|
+
}
|
|
1551
1916
|
this.cleanupExtensions();
|
|
1552
1917
|
this.host.removeEventListener("click", this.handleClick);
|
|
1553
1918
|
this.host.removeEventListener("input", this.handleInput);
|
|
@@ -1677,6 +2042,12 @@ var EditorControllerImpl = class {
|
|
|
1677
2042
|
}
|
|
1678
2043
|
};
|
|
1679
2044
|
dispatchCommand(command, element) {
|
|
2045
|
+
if (command === "ai-assist") {
|
|
2046
|
+
if (this.aiAssistPanel) {
|
|
2047
|
+
this.aiAssistPanel.show();
|
|
2048
|
+
}
|
|
2049
|
+
return;
|
|
2050
|
+
}
|
|
1680
2051
|
if (command === "validate") {
|
|
1681
2052
|
this.validate();
|
|
1682
2053
|
return;
|
|
@@ -2189,6 +2560,48 @@ var EditorControllerImpl = class {
|
|
|
2189
2560
|
this.focusRequest = failure.path;
|
|
2190
2561
|
this.render();
|
|
2191
2562
|
}
|
|
2563
|
+
applyAIProposal(proposal) {
|
|
2564
|
+
for (const ruleProposal of proposal.rules) {
|
|
2565
|
+
let group = this.groupById(ruleProposal.groupId);
|
|
2566
|
+
if (!group) {
|
|
2567
|
+
const groupId = ruleProposal.groupId;
|
|
2568
|
+
this.draft.groups.push({
|
|
2569
|
+
id: groupId,
|
|
2570
|
+
name: "AI Group",
|
|
2571
|
+
origins: [],
|
|
2572
|
+
rules: []
|
|
2573
|
+
});
|
|
2574
|
+
group = this.groupById(groupId);
|
|
2575
|
+
}
|
|
2576
|
+
if (!group) return;
|
|
2577
|
+
const ruleId = this.nextId("rule-ai");
|
|
2578
|
+
const rule = {
|
|
2579
|
+
id: ruleId,
|
|
2580
|
+
name: ruleProposal.name,
|
|
2581
|
+
urlRegex: ruleProposal.urlRegex,
|
|
2582
|
+
origins: ruleProposal.origins ? [...ruleProposal.origins] : [],
|
|
2583
|
+
resourceTypes: ruleProposal.resourceTypes ? [...ruleProposal.resourceTypes] : ["main_frame"],
|
|
2584
|
+
priority: ruleProposal.priority ?? 100
|
|
2585
|
+
};
|
|
2586
|
+
if (ruleProposal.method) {
|
|
2587
|
+
rule.method = ruleProposal.method;
|
|
2588
|
+
}
|
|
2589
|
+
const actionField = ruleProposal.kind === "redirect" || ruleProposal.kind === "mock" ? ruleProposal.kind : "action";
|
|
2590
|
+
rule[actionField] = ruleProposal.action;
|
|
2591
|
+
group.rules.push(rule);
|
|
2592
|
+
this.markChanged();
|
|
2593
|
+
const groupIdStr = String(group.id);
|
|
2594
|
+
this.focusRequest = pointer(
|
|
2595
|
+
"groups",
|
|
2596
|
+
this.groupIndex(groupIdStr),
|
|
2597
|
+
"rules",
|
|
2598
|
+
group.rules.length - 1,
|
|
2599
|
+
"name"
|
|
2600
|
+
);
|
|
2601
|
+
}
|
|
2602
|
+
this.statusMessage = `Applied ${proposal.rules.length} rule${proposal.rules.length === 1 ? "" : "s"} from AI.`;
|
|
2603
|
+
this.render();
|
|
2604
|
+
}
|
|
2192
2605
|
addGroupOrigin(groupId) {
|
|
2193
2606
|
const group = this.groupById(groupId);
|
|
2194
2607
|
if (!group || this.saving) return;
|
|
@@ -2617,6 +3030,11 @@ var EditorControllerImpl = class {
|
|
|
2617
3030
|
renderCommandBar() {
|
|
2618
3031
|
this.commandBar.replaceChildren();
|
|
2619
3032
|
this.commandBar.setAttribute("aria-busy", this.saving ? "true" : "false");
|
|
3033
|
+
if (this.aiAssistPanel) {
|
|
3034
|
+
this.commandBar.append(
|
|
3035
|
+
this.createCommandButton("AI Assist", "ai-assist", this.saving)
|
|
3036
|
+
);
|
|
3037
|
+
}
|
|
2620
3038
|
this.commandBar.append(
|
|
2621
3039
|
this.createCommandButton("Validate", "validate", this.saving),
|
|
2622
3040
|
this.createCommandButton("Save", "save", this.saving || !this.isDirty()),
|
|
@@ -3596,10 +4014,10 @@ var HEADER_OPERATIONS = [
|
|
|
3596
4014
|
"append",
|
|
3597
4015
|
"remove"
|
|
3598
4016
|
];
|
|
3599
|
-
function createSelect(
|
|
3600
|
-
const select =
|
|
4017
|
+
function createSelect(document2, options, value, onChange) {
|
|
4018
|
+
const select = document2.createElement("select");
|
|
3601
4019
|
for (const option of options) {
|
|
3602
|
-
const opt =
|
|
4020
|
+
const opt = document2.createElement("option");
|
|
3603
4021
|
opt.value = option;
|
|
3604
4022
|
opt.textContent = option;
|
|
3605
4023
|
if (option === value) opt.selected = true;
|
|
@@ -3608,8 +4026,8 @@ function createSelect(document, options, value, onChange) {
|
|
|
3608
4026
|
select.addEventListener("change", () => onChange(select.value));
|
|
3609
4027
|
return select;
|
|
3610
4028
|
}
|
|
3611
|
-
function createInput(
|
|
3612
|
-
const input =
|
|
4029
|
+
function createInput(document2, value, onChange, maxLength) {
|
|
4030
|
+
const input = document2.createElement("input");
|
|
3613
4031
|
input.type = "text";
|
|
3614
4032
|
input.value = value;
|
|
3615
4033
|
if (maxLength !== void 0) input.maxLength = maxLength;
|
|
@@ -3624,16 +4042,16 @@ function createHeaderRuleType() {
|
|
|
3624
4042
|
return rule.type === "header";
|
|
3625
4043
|
},
|
|
3626
4044
|
mount(context) {
|
|
3627
|
-
const
|
|
3628
|
-
const fieldset =
|
|
3629
|
-
const legend =
|
|
4045
|
+
const document2 = context.document;
|
|
4046
|
+
const fieldset = document2.createElement("fieldset");
|
|
4047
|
+
const legend = document2.createElement("legend");
|
|
3630
4048
|
legend.textContent = "Header rule";
|
|
3631
4049
|
fieldset.append(legend);
|
|
3632
|
-
const directionLabel =
|
|
4050
|
+
const directionLabel = document2.createElement("label");
|
|
3633
4051
|
directionLabel.textContent = "Direction";
|
|
3634
4052
|
const directionValue = context.getField("headerDirection") ?? "request";
|
|
3635
4053
|
const directionSelect = createSelect(
|
|
3636
|
-
|
|
4054
|
+
document2,
|
|
3637
4055
|
HEADER_DIRECTIONS,
|
|
3638
4056
|
directionValue,
|
|
3639
4057
|
(value) => {
|
|
@@ -3643,11 +4061,11 @@ function createHeaderRuleType() {
|
|
|
3643
4061
|
context.registerControl("/headerDirection", directionSelect);
|
|
3644
4062
|
directionLabel.append(directionSelect);
|
|
3645
4063
|
fieldset.append(directionLabel);
|
|
3646
|
-
const operationLabel =
|
|
4064
|
+
const operationLabel = document2.createElement("label");
|
|
3647
4065
|
operationLabel.textContent = "Operation";
|
|
3648
4066
|
const operationValue = context.getField("headerOperation") ?? "set";
|
|
3649
4067
|
const operationSelect = createSelect(
|
|
3650
|
-
|
|
4068
|
+
document2,
|
|
3651
4069
|
HEADER_OPERATIONS,
|
|
3652
4070
|
operationValue,
|
|
3653
4071
|
(value) => {
|
|
@@ -3657,11 +4075,11 @@ function createHeaderRuleType() {
|
|
|
3657
4075
|
context.registerControl("/headerOperation", operationSelect);
|
|
3658
4076
|
operationLabel.append(operationSelect);
|
|
3659
4077
|
fieldset.append(operationLabel);
|
|
3660
|
-
const nameLabel =
|
|
4078
|
+
const nameLabel = document2.createElement("label");
|
|
3661
4079
|
nameLabel.textContent = "Header name";
|
|
3662
4080
|
const nameValue = context.getField("headerName") ?? "";
|
|
3663
4081
|
const nameInput = createInput(
|
|
3664
|
-
|
|
4082
|
+
document2,
|
|
3665
4083
|
nameValue,
|
|
3666
4084
|
(value) => {
|
|
3667
4085
|
context.setField("headerName", value);
|
|
@@ -3671,11 +4089,11 @@ function createHeaderRuleType() {
|
|
|
3671
4089
|
context.registerControl("/headerName", nameInput);
|
|
3672
4090
|
nameLabel.append(nameInput);
|
|
3673
4091
|
fieldset.append(nameLabel);
|
|
3674
|
-
const valueLabel =
|
|
4092
|
+
const valueLabel = document2.createElement("label");
|
|
3675
4093
|
valueLabel.textContent = "Header value";
|
|
3676
4094
|
const valueValue = context.getField("headerValue") ?? "";
|
|
3677
4095
|
const valueInput = createInput(
|
|
3678
|
-
|
|
4096
|
+
document2,
|
|
3679
4097
|
valueValue,
|
|
3680
4098
|
(value) => {
|
|
3681
4099
|
context.setField("headerValue", value);
|
|
@@ -3773,10 +4191,10 @@ function createRedirectRuleType() {
|
|
|
3773
4191
|
return rule.type === "redirect";
|
|
3774
4192
|
},
|
|
3775
4193
|
mount(context) {
|
|
3776
|
-
const
|
|
3777
|
-
const label =
|
|
4194
|
+
const document2 = context.document;
|
|
4195
|
+
const label = document2.createElement("label");
|
|
3778
4196
|
label.textContent = "Redirect destination URL";
|
|
3779
|
-
const input =
|
|
4197
|
+
const input = document2.createElement("input");
|
|
3780
4198
|
input.type = "text";
|
|
3781
4199
|
input.maxLength = 2048;
|
|
3782
4200
|
const existing = context.getField("redirect.destination");
|