@ubox-tools/deploy-xperience 1.1.20 → 1.1.21

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.
Files changed (2) hide show
  1. package/deploy.js +43 -20
  2. package/package.json +1 -1
package/deploy.js CHANGED
@@ -416,17 +416,33 @@ async function uploadFile(page, absPath) {
416
416
  await client.detach();
417
417
  }
418
418
 
419
- /** Inject text content into the active Monaco/CodeMirror/Ace editor. */
420
- async function injectToEditor(page, content) {
421
- // Try Monaco API first (no clipboard needed)
422
- const monacoOk = await page.evaluate(text => {
423
- if (window.monaco?.editor) {
424
- const models = window.monaco.editor.getModels();
425
- if (models?.length > 0) { models[0].setValue(text); return true; }
419
+ /** Inject text content into the active Monaco/CodeMirror/Ace editor.
420
+ * @param {string} filename Source filename (e.g. "index.html") — used to pick
421
+ * the right Monaco model by URI when multiple models are
422
+ * pre-loaded (e.g. after visiting the Parameters tab). */
423
+ async function injectToEditor(page, content, filename) {
424
+ // Try Monaco API
425
+ const monacoResult = await page.evaluate((text, fn) => {
426
+ if (!window.monaco?.editor) return null;
427
+ const models = window.monaco.editor.getModels();
428
+ if (!models?.length) return null;
429
+
430
+ // Best: match model by filename in its URI — avoids the models[0] trap when
431
+ // multiple models are pre-loaded (happens after visiting the Parameters tab).
432
+ if (fn) {
433
+ const m = models.find(m => m.uri?.toString().includes(fn));
434
+ if (m) { m.setValue(text); return 'uri'; }
426
435
  }
427
- return false;
428
- }, content);
429
- if (monacoOk) return;
436
+
437
+ // Safe fallback: single model is always the active one (lazy-load case).
438
+ if (models.length === 1) { models[0].setValue(text); return 'single'; }
439
+
440
+ // Multiple models, no URI match — fall through to keyboard injection.
441
+ return `multi:${models.length}:${models.map(m => m.uri?.toString()).join('|')}`;
442
+ }, content, filename ?? null);
443
+
444
+ if (monacoResult === 'uri' || monacoResult === 'single') return;
445
+ if (monacoResult) console.log(` [editor] Monaco ${monacoResult} → keyboard fallback`);
430
446
 
431
447
  // Try CodeMirror API
432
448
  const cmOk = await page.evaluate(text => {
@@ -436,16 +452,23 @@ async function injectToEditor(page, content) {
436
452
  }, content);
437
453
  if (cmOk) return;
438
454
 
439
- // Fallback: clipboard paste into Ace / generic textarea
455
+ // Keyboard injection: click the visible editor, Ctrl+A, Ctrl+V.
456
+ // Targets whatever editor is currently focused (active tab) — model-agnostic.
440
457
  writeClipboard(content);
441
- const ed = await page.$('.ace_editor, .cm-editor, .monaco-editor, textarea');
442
- if (!ed) throw new Error('No code editor found on page');
443
- const edRect = await page.evaluate(el => {
444
- el.scrollIntoView({ block: 'nearest' });
445
- const r = el.getBoundingClientRect();
446
- return { x: Math.round(r.x + r.width / 2), y: Math.round(r.y + r.height / 2) };
447
- }, ed);
448
- await page.mouse.click(edRect.x, edRect.y);
458
+ const edPos = await page.evaluate(() => {
459
+ for (const sel of ['.monaco-editor', '.ace_editor', '.cm-editor', 'textarea']) {
460
+ const el = Array.from(document.querySelectorAll(sel))
461
+ .find(e => { const r = e.getBoundingClientRect(); return r.width > 10 && r.height > 10; });
462
+ if (el) {
463
+ el.scrollIntoView({ block: 'nearest' });
464
+ const r = el.getBoundingClientRect();
465
+ return { x: Math.round(r.x + r.width / 2), y: Math.round(r.y + r.height / 2) };
466
+ }
467
+ }
468
+ return null;
469
+ });
470
+ if (!edPos) throw new Error('No code editor found on page');
471
+ await page.mouse.click(edPos.x, edPos.y);
449
472
  await sleep(200);
450
473
  await page.keyboard.down('Control');
451
474
  await page.keyboard.press('a');
@@ -682,7 +705,7 @@ async function injectSource(page, proxy) {
682
705
  console.log(` ${filename} → ${tabLabel}`);
683
706
  await clickByText(page, tabLabel);
684
707
  await sleep(1000);
685
- await injectToEditor(page, proxy[filename]);
708
+ await injectToEditor(page, proxy[filename], filename);
686
709
  await sleep(500);
687
710
  }
688
711
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ubox-tools/deploy-xperience",
3
- "version": "1.1.20",
3
+ "version": "1.1.21",
4
4
  "description": "Deploy a Ubox experience to studio.ubox.world",
5
5
  "bin": { "deploy-xperience": "./deploy.js" },
6
6
  "dependencies": { "puppeteer": "*" },