@ubox-tools/deploy-xperience 1.0.0 → 1.1.0
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 +6 -0
- package/deploy.js +38 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -27,6 +27,8 @@ npx @ubox-tools/deploy-xperience [app1 app2 ...] [options]
|
|
|
27
27
|
| `--project-name <name>` | Override the project name (default: parent directory name) |
|
|
28
28
|
| `--noassets` | Skip uploading assets (images, fonts, files) |
|
|
29
29
|
| `--noplayer` | Skip Phase 3 — deploy apps only, do not create/update Uboxes |
|
|
30
|
+
| `--ubox-id <id>` | Use a pre-existing Ubox by ID — skips search/create (single-app deployments) |
|
|
31
|
+
| `--ubox-id <app>:<id>` | Scoped form for multi-app deployments (repeatable) |
|
|
30
32
|
| `--show` | Show the browser window (default: headless) |
|
|
31
33
|
| `--help` | Print usage and exit |
|
|
32
34
|
|
|
@@ -47,6 +49,8 @@ npx @ubox-tools/deploy-xperience mobile # Deploy only the mobile
|
|
|
47
49
|
npx @ubox-tools/deploy-xperience main --noassets # Deploy main app, skip asset uploads
|
|
48
50
|
npx @ubox-tools/deploy-xperience --noplayer # Deploy apps only, skip Uboxes
|
|
49
51
|
npx @ubox-tools/deploy-xperience --project-name "MyProject"
|
|
52
|
+
npx @ubox-tools/deploy-xperience mobile --ubox-id 42 # Use existing Ubox #42 for mobile
|
|
53
|
+
npx @ubox-tools/deploy-xperience --ubox-id mobile:42 --ubox-id main:99
|
|
50
54
|
```
|
|
51
55
|
|
|
52
56
|
## Deployment Phases
|
|
@@ -76,6 +80,8 @@ Runs once per app:
|
|
|
76
80
|
|
|
77
81
|
If the Ubox already exists, installation and parameter changes are skipped; the mobile virtual link is still retrieved so the main Ubox can use it.
|
|
78
82
|
|
|
83
|
+
When `--ubox-id` is provided, the search/create step is skipped entirely and the script navigates directly to `https://studio.ubox.world/#/ubox/<id>`. The same "already exists" logic then applies.
|
|
84
|
+
|
|
79
85
|
## Proxy / Source Transformation
|
|
80
86
|
|
|
81
87
|
Before injecting source files, `generateProxy()` applies three transforms to each file:
|
package/deploy.js
CHANGED
|
@@ -52,6 +52,8 @@ Options:
|
|
|
52
52
|
--project-name <name> Override project name (default: directory name)
|
|
53
53
|
--noassets Skip uploading assets (resources)
|
|
54
54
|
--noplayer Skip Ubox creation (Phase 3) — only deploy applications
|
|
55
|
+
--ubox-id <id> Use a pre-existing Ubox by ID (skips search/create)
|
|
56
|
+
--ubox-id <app>:<id> Scoped form when deploying multiple apps
|
|
55
57
|
--show Show the browser window (default: headless)
|
|
56
58
|
--help Show this help
|
|
57
59
|
|
|
@@ -61,6 +63,8 @@ Examples:
|
|
|
61
63
|
npx @ubox-tools/deploy-xperience main # Deploy only main
|
|
62
64
|
npx @ubox-tools/deploy-xperience --noassets # Deploy without re-uploading assets
|
|
63
65
|
npx @ubox-tools/deploy-xperience --noplayer # Deploy apps only, skip Uboxes
|
|
66
|
+
npx @ubox-tools/deploy-xperience --ubox-id 42 # Use existing Ubox #42 (single-app)
|
|
67
|
+
npx @ubox-tools/deploy-xperience --ubox-id mobile:42 --ubox-id main:99
|
|
64
68
|
UBOX_EMAIL=me@x.com npx @ubox-tools/deploy-xperience
|
|
65
69
|
`.trim());
|
|
66
70
|
process.exit(0);
|
|
@@ -73,6 +77,8 @@ Examples:
|
|
|
73
77
|
let noPlayer = false;
|
|
74
78
|
let show = false;
|
|
75
79
|
const appArgs = [];
|
|
80
|
+
const uboxIds = {};
|
|
81
|
+
let bareUboxId = null;
|
|
76
82
|
|
|
77
83
|
for (let i = 0; i < args.length; i++) {
|
|
78
84
|
if (args[i] === '--email') { email = args[++i]; }
|
|
@@ -81,6 +87,15 @@ Examples:
|
|
|
81
87
|
else if (args[i] === '--noassets') { noAssets = true; }
|
|
82
88
|
else if (args[i] === '--noplayer') { noPlayer = true; }
|
|
83
89
|
else if (args[i] === '--show') { show = true; }
|
|
90
|
+
else if (args[i] === '--ubox-id') {
|
|
91
|
+
const val = args[++i];
|
|
92
|
+
if (val.includes(':')) {
|
|
93
|
+
const colon = val.indexOf(':');
|
|
94
|
+
uboxIds[val.slice(0, colon)] = val.slice(colon + 1);
|
|
95
|
+
} else {
|
|
96
|
+
bareUboxId = val;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
84
99
|
else if (!args[i].startsWith('--')) { appArgs.push(args[i]); }
|
|
85
100
|
}
|
|
86
101
|
|
|
@@ -101,7 +116,15 @@ Examples:
|
|
|
101
116
|
...selected.filter(a => !DEPLOY_ORDER.includes(a)),
|
|
102
117
|
];
|
|
103
118
|
|
|
104
|
-
|
|
119
|
+
if (bareUboxId !== null) {
|
|
120
|
+
if (ordered.length !== 1) {
|
|
121
|
+
console.error('Error: bare --ubox-id <id> requires exactly one app to be selected.\nUse --ubox-id <app>:<id> form when deploying multiple apps (e.g. --ubox-id mobile:42 --ubox-id main:99).');
|
|
122
|
+
process.exit(1);
|
|
123
|
+
}
|
|
124
|
+
uboxIds[ordered[0]] = bareUboxId;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return { apps: ordered, email, password, projectName, noAssets, noPlayer, show, uboxIds };
|
|
105
128
|
}
|
|
106
129
|
|
|
107
130
|
// ─── Credentials ──────────────────────────────────────────────────────────────
|
|
@@ -943,11 +966,20 @@ async function setMobileLink(page, appFullName, mobileVirtualLink) {
|
|
|
943
966
|
console.log(` [ubox] mobileLink = ${mobileVirtualLink}`);
|
|
944
967
|
}
|
|
945
968
|
|
|
946
|
-
async function deployUbox(page, appName, projectName, appParams, mobileVirtualLink) {
|
|
969
|
+
async function deployUbox(page, appName, projectName, appParams, mobileVirtualLink, targetUboxId = null) {
|
|
947
970
|
const fullName = `${projectName} ${appName}`;
|
|
948
971
|
console.log(`\n[Phase 3] Ubox: ${fullName}`);
|
|
949
972
|
|
|
950
|
-
|
|
973
|
+
let uboxUrl, created;
|
|
974
|
+
if (targetUboxId) {
|
|
975
|
+
uboxUrl = `${BASE_URL}/#/ubox/${targetUboxId}`;
|
|
976
|
+
console.log(` [ubox] Using pre-existing Ubox ID ${targetUboxId} — navigating directly...`);
|
|
977
|
+
await page.goto(uboxUrl, { waitUntil: 'networkidle2' });
|
|
978
|
+
await sleep(2000);
|
|
979
|
+
created = false;
|
|
980
|
+
} else {
|
|
981
|
+
({ url: uboxUrl, created } = await findOrCreateUbox(page, fullName));
|
|
982
|
+
}
|
|
951
983
|
|
|
952
984
|
let virtualLink = null;
|
|
953
985
|
|
|
@@ -990,7 +1022,7 @@ async function deployUbox(page, appName, projectName, appParams, mobileVirtualLi
|
|
|
990
1022
|
// ─── Main ─────────────────────────────────────────────────────────────────────
|
|
991
1023
|
|
|
992
1024
|
async function main() {
|
|
993
|
-
const { apps, email: emailArg, password: passwordArg, projectName: projectNameArg, noAssets, noPlayer, show } = parseArgs();
|
|
1025
|
+
const { apps, email: emailArg, password: passwordArg, projectName: projectNameArg, noAssets, noPlayer, show, uboxIds } = parseArgs();
|
|
994
1026
|
|
|
995
1027
|
if (apps.length === 0) {
|
|
996
1028
|
console.error('No apps found in apps/ directory. Nothing to deploy.');
|
|
@@ -1039,7 +1071,8 @@ async function main() {
|
|
|
1039
1071
|
let mobileVirtualLink = null;
|
|
1040
1072
|
for (const appName of apps) {
|
|
1041
1073
|
const { uboxId, virtualLink } = await deployUbox(
|
|
1042
|
-
page, appName, projectName, appParamsMap[appName], mobileVirtualLink
|
|
1074
|
+
page, appName, projectName, appParamsMap[appName], mobileVirtualLink,
|
|
1075
|
+
uboxIds[appName] ?? null
|
|
1043
1076
|
);
|
|
1044
1077
|
state[appName].uboxId = uboxId;
|
|
1045
1078
|
if (appName === 'mobile' && virtualLink) {
|
package/package.json
CHANGED