@ubox-tools/deploy-xperience 1.1.1 → 1.1.3

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 (3) hide show
  1. package/README.md +4 -0
  2. package/deploy.js +40 -12
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -26,6 +26,8 @@ npx @ubox-tools/deploy-xperience [app1 app2 ...] [options]
26
26
  | `--password <pass>` | Ubox Studio password (or `UBOX_PASSWORD` env var) |
27
27
  | `--project-name <name>` | Override the project name (default: parent directory name) |
28
28
  | `--noassets` | Skip uploading assets (images, fonts, files) |
29
+ | `--nosource` | Skip source injection entirely |
30
+ | `--nosource <files>` | Skip specific files (comma-separated, e.g. `ubox.js,logic.js`) |
29
31
  | `--noplayer` | Skip Phase 3 — deploy apps only, do not create/update Uboxes |
30
32
  | `--ubox-id <id>` | Use a pre-existing Ubox by ID — skips search/create (single-app deployments) |
31
33
  | `--ubox-id <app>:<id>` | Scoped form for multi-app deployments (repeatable) |
@@ -47,6 +49,8 @@ npx @ubox-tools/deploy-xperience # Deploy all apps (headl
47
49
  npx @ubox-tools/deploy-xperience --show # Deploy all apps, show browser
48
50
  npx @ubox-tools/deploy-xperience mobile # Deploy only the mobile app
49
51
  npx @ubox-tools/deploy-xperience main --noassets # Deploy main app, skip asset uploads
52
+ npx @ubox-tools/deploy-xperience --nosource # Deploy without re-injecting source
53
+ npx @ubox-tools/deploy-xperience --nosource ubox.js # Skip only ubox.js injection
50
54
  npx @ubox-tools/deploy-xperience --noplayer # Deploy apps only, skip Uboxes
51
55
  npx @ubox-tools/deploy-xperience --project-name "MyProject"
52
56
  npx @ubox-tools/deploy-xperience mobile --ubox-id 42 # Use existing Ubox #42 for mobile
package/deploy.js CHANGED
@@ -52,6 +52,8 @@ Options:
52
52
  --password <pass> Ubox studio password (or set UBOX_PASSWORD env var)
53
53
  --project-name <name> Override project name (default: directory name)
54
54
  --noassets Skip uploading assets (resources)
55
+ --nosource Skip source injection entirely
56
+ --nosource <files> Skip specific files (comma-separated, e.g. ubox.js,logic.js)
55
57
  --noplayer Skip Ubox creation (Phase 3) — only deploy applications
56
58
  --ubox-id <id> Use a pre-existing Ubox by ID (skips search/create)
57
59
  --ubox-id <app>:<id> Scoped form when deploying multiple apps
@@ -75,6 +77,7 @@ Examples:
75
77
  let password = process.env.UBOX_PASSWORD;
76
78
  let projectName = null;
77
79
  let noAssets = false;
80
+ let noSource = false;
78
81
  let noPlayer = false;
79
82
  let show = false;
80
83
  const appArgs = [];
@@ -86,6 +89,11 @@ Examples:
86
89
  else if (args[i] === '--password') { password = args[++i]; }
87
90
  else if (args[i] === '--project-name') { projectName = args[++i]; }
88
91
  else if (args[i] === '--noassets') { noAssets = true; }
92
+ else if (args[i] === '--nosource') {
93
+ const next = args[i + 1];
94
+ if (next && !next.startsWith('--')) { noSource = args[++i]; }
95
+ else { noSource = true; }
96
+ }
89
97
  else if (args[i] === '--noplayer') { noPlayer = true; }
90
98
  else if (args[i] === '--show') { show = true; }
91
99
  else if (args[i] === '--ubox-id') {
@@ -125,7 +133,7 @@ Examples:
125
133
  uboxIds[ordered[0]] = bareUboxId;
126
134
  }
127
135
 
128
- return { apps: ordered, email, password, projectName, noAssets, noPlayer, show, uboxIds };
136
+ return { apps: ordered, email, password, projectName, noAssets, noSource, noPlayer, show, uboxIds };
129
137
  }
130
138
 
131
139
  // ─── Credentials ──────────────────────────────────────────────────────────────
@@ -652,7 +660,7 @@ async function injectSource(page, proxy) {
652
660
  await sleep(3000);
653
661
  }
654
662
 
655
- async function deployApp(page, appName, projectName, { noAssets = false } = {}) {
663
+ async function deployApp(page, appName, projectName, { noAssets = false, noSource = false } = {}) {
656
664
  const fullName = `${projectName} ${appName}`;
657
665
  const { proxy, assets, params } = generateProxy(appName);
658
666
 
@@ -666,7 +674,14 @@ async function deployApp(page, appName, projectName, { noAssets = false } = {})
666
674
  await uploadResources(page, assets);
667
675
  }
668
676
  await configureParameters(page, params);
669
- await injectSource(page, proxy);
677
+ if (noSource === true) {
678
+ console.log(' [source] Skipped (--nosource)');
679
+ } else {
680
+ const filteredProxy = typeof noSource === 'string'
681
+ ? Object.fromEntries(Object.entries(proxy).filter(([f]) => !noSource.split(',').includes(f)))
682
+ : proxy;
683
+ await injectSource(page, filteredProxy);
684
+ }
670
685
 
671
686
  // Extract app ID from current URL
672
687
  const appId = page.url().match(/#\/application(?:-source)?\/(\d+)/)?.[1] || '?';
@@ -967,25 +982,37 @@ async function setMobileLink(page, appFullName, mobileVirtualLink) {
967
982
  console.log(` [ubox] mobileLink = ${mobileVirtualLink}`);
968
983
  }
969
984
 
985
+ async function isAppInstalled(page, appFullName) {
986
+ return page.evaluate(name => {
987
+ for (const card of document.querySelectorAll('.card-body.ubox-app-installed')) {
988
+ const title = card.querySelector('p.card-text');
989
+ if (title && title.textContent.trim() === name) return true;
990
+ }
991
+ return false;
992
+ }, appFullName);
993
+ }
994
+
970
995
  async function deployUbox(page, appName, projectName, appParams, mobileVirtualLink, targetUboxId = null) {
971
996
  const fullName = `${projectName} ${appName}`;
972
997
  console.log(`\n[Phase 3] Ubox: ${fullName}`);
973
998
 
974
- let uboxUrl, created;
999
+ let uboxUrl;
975
1000
  if (targetUboxId) {
976
1001
  uboxUrl = `${BASE_URL}/#/ubox/${targetUboxId}`;
977
1002
  console.log(` [ubox] Using pre-existing Ubox ID ${targetUboxId} — navigating directly...`);
978
1003
  await page.goto(uboxUrl, { waitUntil: 'networkidle2' });
979
1004
  await sleep(2000);
980
- created = false;
981
1005
  } else {
982
- ({ url: uboxUrl, created } = await findOrCreateUbox(page, fullName));
1006
+ ({ url: uboxUrl } = await findOrCreateUbox(page, fullName));
983
1007
  }
984
1008
 
985
1009
  let virtualLink = null;
986
1010
 
987
- if (created) {
988
- // Fresh ubox — need to make public, install app, get virtual link, set params
1011
+ const installed = await isAppInstalled(page, fullName);
1012
+
1013
+ if (!installed) {
1014
+ // App not installed — make public, install, get virtual link, set params
1015
+ console.log(` [ubox] "${fullName}" not installed — proceeding with install...`);
989
1016
  await checkMakePublic(page);
990
1017
  await installApp(page, fullName);
991
1018
 
@@ -1003,8 +1030,7 @@ async function deployUbox(page, appName, projectName, appParams, mobileVirtualLi
1003
1030
  await setMobileLink(page, fullName, mobileVirtualLink);
1004
1031
  }
1005
1032
  } else {
1006
- // Existing uboxskip install, params, and virtual link retrieval
1007
- console.log(' [ubox] Already exists — skipping install, params, and virtual link');
1033
+ console.log(` [ubox] "${fullName}" already installed skipping install`);
1008
1034
 
1009
1035
  // Still retrieve the virtual link for mobile so main can use it
1010
1036
  if (appName === 'mobile') {
@@ -1023,7 +1049,7 @@ async function deployUbox(page, appName, projectName, appParams, mobileVirtualLi
1023
1049
  // ─── Main ─────────────────────────────────────────────────────────────────────
1024
1050
 
1025
1051
  async function main() {
1026
- const { apps, email: emailArg, password: passwordArg, projectName: projectNameArg, noAssets, noPlayer, show, uboxIds } = parseArgs();
1052
+ const { apps, email: emailArg, password: passwordArg, projectName: projectNameArg, noAssets, noSource, noPlayer, show, uboxIds } = parseArgs();
1027
1053
 
1028
1054
  if (apps.length === 0) {
1029
1055
  console.error('No apps found in apps/ directory. Nothing to deploy.');
@@ -1035,6 +1061,8 @@ async function main() {
1035
1061
  console.log(`Project : ${projectName}`);
1036
1062
  console.log(`Apps : ${apps.join(', ')}`);
1037
1063
  if (noAssets) console.log('Flags : --noassets (skip resource uploads)');
1064
+ if (noSource === true) console.log('Flags : --nosource (skip all source injection)');
1065
+ else if (noSource) console.log(`Flags : --nosource ${noSource} (skip specific files)`);
1038
1066
  if (noPlayer) console.log('Flags : --noplayer (skip Ubox creation)');
1039
1067
  console.log('');
1040
1068
 
@@ -1062,7 +1090,7 @@ async function main() {
1062
1090
  state[appName] = {};
1063
1091
  const { params } = generateProxy(appName);
1064
1092
  appParamsMap[appName] = params;
1065
- state[appName].appId = await deployApp(page, appName, projectName, { noAssets });
1093
+ state[appName].appId = await deployApp(page, appName, projectName, { noAssets, noSource });
1066
1094
  }
1067
1095
 
1068
1096
  // Phase 3 — Deploy Uboxes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ubox-tools/deploy-xperience",
3
- "version": "1.1.1",
3
+ "version": "1.1.3",
4
4
  "description": "Deploy a Ubox experience to studio.ubox.world",
5
5
  "bin": { "deploy-xperience": "./deploy.js" },
6
6
  "dependencies": { "puppeteer": "*" },