@ubox-tools/deploy-xperience 1.1.21 → 1.1.22

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 +24 -42
  2. package/package.json +1 -1
package/deploy.js CHANGED
@@ -416,33 +416,22 @@ 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
- * @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) {
419
+ /** Inject text content into the active Monaco/CodeMirror/Ace editor. */
420
+ async function injectToEditor(page, content) {
424
421
  // Try Monaco API
425
- const monacoResult = await page.evaluate((text, fn) => {
426
- if (!window.monaco?.editor) return null;
422
+ const monacoOk = await page.evaluate(text => {
423
+ if (!window.monaco?.editor) return false;
427
424
  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'; }
435
- }
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`);
425
+ if (!models?.length) return false;
426
+ // Use the LAST model, not the first. When the Parameters tab is visited before
427
+ // the source editor, Monaco pre-loads a read-only preview model (model/1) first.
428
+ // The actual edit model (model/4) is created later and sits at the end of the
429
+ // list. For apps with no parameters (lazy-load), there is only one model, so
430
+ // last === first and behaviour is unchanged.
431
+ models[models.length - 1].setValue(text);
432
+ return true;
433
+ }, content);
434
+ if (monacoOk) return;
446
435
 
447
436
  // Try CodeMirror API
448
437
  const cmOk = await page.evaluate(text => {
@@ -452,23 +441,16 @@ async function injectToEditor(page, content, filename) {
452
441
  }, content);
453
442
  if (cmOk) return;
454
443
 
455
- // Keyboard injection: click the visible editor, Ctrl+A, Ctrl+V.
456
- // Targets whatever editor is currently focused (active tab) — model-agnostic.
444
+ // Fallback: clipboard paste into Ace / generic textarea
457
445
  writeClipboard(content);
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);
446
+ const ed = await page.$('.ace_editor, .cm-editor, .monaco-editor, textarea');
447
+ if (!ed) throw new Error('No code editor found on page');
448
+ const edRect = await page.evaluate(el => {
449
+ el.scrollIntoView({ block: 'nearest' });
450
+ const r = el.getBoundingClientRect();
451
+ return { x: Math.round(r.x + r.width / 2), y: Math.round(r.y + r.height / 2) };
452
+ }, ed);
453
+ await page.mouse.click(edRect.x, edRect.y);
472
454
  await sleep(200);
473
455
  await page.keyboard.down('Control');
474
456
  await page.keyboard.press('a');
@@ -705,7 +687,7 @@ async function injectSource(page, proxy) {
705
687
  console.log(` ${filename} → ${tabLabel}`);
706
688
  await clickByText(page, tabLabel);
707
689
  await sleep(1000);
708
- await injectToEditor(page, proxy[filename], filename);
690
+ await injectToEditor(page, proxy[filename]);
709
691
  await sleep(500);
710
692
  }
711
693
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ubox-tools/deploy-xperience",
3
- "version": "1.1.21",
3
+ "version": "1.1.22",
4
4
  "description": "Deploy a Ubox experience to studio.ubox.world",
5
5
  "bin": { "deploy-xperience": "./deploy.js" },
6
6
  "dependencies": { "puppeteer": "*" },