@wix/himalaya-cli 0.1366.0 → 0.1368.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/dist/cli.mjs +48 -11
- package/guides/himi-json-output.md +15 -4
- package/package.json +2 -2
package/dist/cli.mjs
CHANGED
|
@@ -7706,6 +7706,7 @@ function resolveTranslation(value, catalog3, sourceCatalog) {
|
|
|
7706
7706
|
var BINDING_SIGILS, BINDING_SIGIL_RE, TRANSLATION_PREFIX, TRANSLATION_KEY_RE;
|
|
7707
7707
|
var init_bindings = __esm({
|
|
7708
7708
|
"../../core/ts/src/bindings.ts"() {
|
|
7709
|
+
"use strict";
|
|
7709
7710
|
BINDING_SIGILS = ["service", "flag", "item", "t"];
|
|
7710
7711
|
BINDING_SIGIL_RE = new RegExp(
|
|
7711
7712
|
`^\\$(?:${BINDING_SIGILS.filter((s2) => s2 !== "t").join("|")})\\b|^\\$t:`
|
|
@@ -35370,6 +35371,16 @@ function loadSupervisorRegistry() {
|
|
|
35370
35371
|
function isPlayerHost(appName2) {
|
|
35371
35372
|
return appName2 === PLAYER_APP_ID || process.env.HIMALAYA_DEV_MULTI_APP === "1";
|
|
35372
35373
|
}
|
|
35374
|
+
function tenantsOf(hostApp) {
|
|
35375
|
+
if (!Object.prototype.hasOwnProperty.call(HOSTED_TENANTS, hostApp)) return [];
|
|
35376
|
+
const fixed = HOSTED_TENANTS[hostApp];
|
|
35377
|
+
const extra = (process.env.HIMALAYA_DEV_HOSTED_TENANTS ?? "").split(",").map((a2) => a2.trim()).filter((a2) => /^[a-z0-9][a-z0-9._-]{0,127}$/i.test(a2) && a2 !== hostApp && a2 !== PLAYER_APP_ID);
|
|
35378
|
+
return extra.length ? [...fixed, ...extra.filter((a2) => !fixed.includes(a2))] : fixed;
|
|
35379
|
+
}
|
|
35380
|
+
function optedInTenant(tenant) {
|
|
35381
|
+
if (Object.values(HOSTED_TENANTS).some((t2) => t2.includes(tenant))) return false;
|
|
35382
|
+
return (process.env.HIMALAYA_DEV_HOSTED_TENANTS ?? "").split(",").some((a2) => a2.trim() === tenant);
|
|
35383
|
+
}
|
|
35373
35384
|
function isTenantHost(appName2) {
|
|
35374
35385
|
return !!appName2 && Object.prototype.hasOwnProperty.call(HOSTED_TENANTS, appName2);
|
|
35375
35386
|
}
|
|
@@ -35385,7 +35396,7 @@ function resolveTenantBase(tenant, registry2 = loadSupervisorRegistry) {
|
|
|
35385
35396
|
if (running?.status === "running" && running.port) port = running.port;
|
|
35386
35397
|
} catch {
|
|
35387
35398
|
}
|
|
35388
|
-
port ??= ledgerDevServerPort(tenant);
|
|
35399
|
+
if (!optedInTenant(tenant)) port ??= ledgerDevServerPort(tenant);
|
|
35389
35400
|
if (port) return `http://127.0.0.1:${port}`;
|
|
35390
35401
|
}
|
|
35391
35402
|
return resolveServeBase();
|
|
@@ -35410,7 +35421,7 @@ function tenantPrefixed(url, hostApp, method = "GET") {
|
|
|
35410
35421
|
return null;
|
|
35411
35422
|
}
|
|
35412
35423
|
if (!normalized.startsWith("/v1/") || normalized !== path2 || isTenantAdminPath(normalized)) return null;
|
|
35413
|
-
return
|
|
35424
|
+
return tenantsOf(hostApp).includes(tenant) ? { tenant, url: tenantUrl } : null;
|
|
35414
35425
|
}
|
|
35415
35426
|
function forwardedBaseUrl(req) {
|
|
35416
35427
|
if (!LOOPBACK_PEERS.has(req.socket?.remoteAddress ?? "")) return null;
|
|
@@ -35492,7 +35503,9 @@ function tenantHostPlaneRead(url, headers2, hostApp, method = "GET") {
|
|
|
35492
35503
|
if (path2 === "/v1/release/current") {
|
|
35493
35504
|
const app = new URLSearchParams(query).get("app")?.trim();
|
|
35494
35505
|
if (!app || app === hostApp || HOSTED_TENANTS[hostApp].includes(app)) return null;
|
|
35495
|
-
|
|
35506
|
+
const hdr = headers2["x-himalaya-app"];
|
|
35507
|
+
const headerApp = (Array.isArray(hdr) ? hdr[0] : hdr)?.trim();
|
|
35508
|
+
if (headerApp && tenantsOf(hostApp).includes(headerApp)) return null;
|
|
35496
35509
|
return resolveServeBase() || null;
|
|
35497
35510
|
}
|
|
35498
35511
|
return null;
|
|
@@ -35512,7 +35525,7 @@ function targetTenant(url, headers2, hostApp) {
|
|
|
35512
35525
|
}
|
|
35513
35526
|
if (!app) return null;
|
|
35514
35527
|
if (app === hostApp || app === PLAYER_APP_ID) return null;
|
|
35515
|
-
if (hostApp && isTenantHost(hostApp) && !
|
|
35528
|
+
if (hostApp && isTenantHost(hostApp) && !tenantsOf(hostApp).includes(app)) return null;
|
|
35516
35529
|
return app;
|
|
35517
35530
|
}
|
|
35518
35531
|
function shouldServeFromPlane(url, headers2, hostApp) {
|
|
@@ -132562,6 +132575,8 @@ function createDevServer(opts = {}) {
|
|
|
132562
132575
|
await maybeReseedNetMocks(state);
|
|
132563
132576
|
if (url.startsWith("/__dev/")) return await handleDev(req, res, state);
|
|
132564
132577
|
if (isTenantHost(state.appName)) {
|
|
132578
|
+
const planeRead = tenantHostPlaneRead(url, req.headers, state.appName, req.method);
|
|
132579
|
+
if (planeRead) return await proxyToServe(planeRead, req, res);
|
|
132565
132580
|
const prefixed = tenantPrefixed(url, state.appName, req.method);
|
|
132566
132581
|
const tenant = prefixed?.tenant ?? (shouldServeFromPlane(url, req.headers, state.appName) && !isTenantAdminPath(url) ? targetTenant(url, req.headers, state.appName) : null);
|
|
132567
132582
|
if (tenant) {
|
|
@@ -132579,8 +132594,6 @@ function createDevServer(opts = {}) {
|
|
|
132579
132594
|
forwardAs: clientHost ? { host: clientHost, prefix: `${TENANT_PREFIX}${encodeURIComponent(tenant)}` } : void 0
|
|
132580
132595
|
});
|
|
132581
132596
|
}
|
|
132582
|
-
const planeRead = tenantHostPlaneRead(url, req.headers, state.appName, req.method);
|
|
132583
|
-
if (planeRead) return await proxyToServe(planeRead, req, res);
|
|
132584
132597
|
}
|
|
132585
132598
|
if (url.split("?")[0] === "/v1/app-icon" && req.method === "GET") {
|
|
132586
132599
|
const iconApp = new URLSearchParams(url.split("?")[1] ?? "").get("app") ?? "";
|
|
@@ -170121,19 +170134,42 @@ function decideSiteApp(input) {
|
|
|
170121
170134
|
...input.installedVersion ? { installedVersion: input.installedVersion } : {}
|
|
170122
170135
|
});
|
|
170123
170136
|
if (!verdict.ok) return fallback(picked, verdict.reason);
|
|
170124
|
-
|
|
170137
|
+
const ungranted = req.requirements.capabilities.filter((c2) => !HOSTED_APP_CAPABILITIES.includes(c2));
|
|
170138
|
+
if ((input.hostable ?? NATIVELY_HOSTABLE_APPS) === "any" && ungranted.length) {
|
|
170139
|
+
return fallback(picked, `This Spaces build does not grant a member app ${ungranted.join(", ")} yet (${picked} declares it)`);
|
|
170140
|
+
}
|
|
170141
|
+
const hostable = input.hostable ?? NATIVELY_HOSTABLE_APPS;
|
|
170142
|
+
if (hostable !== "any" && !hostable.includes(picked)) {
|
|
170125
170143
|
return fallback(picked, `This Spaces build cannot host a custom member app yet (${picked} is compatible)`);
|
|
170126
170144
|
}
|
|
170127
170145
|
return { appId: picked, source: "picked" };
|
|
170128
170146
|
}
|
|
170129
|
-
var DEFAULT_SITE_APP, NATIVELY_HOSTABLE_APPS, APP_ID3;
|
|
170147
|
+
var DEFAULT_SITE_APP, NATIVELY_HOSTABLE_APPS, HOSTED_APP_CAPABILITIES, APP_ID3;
|
|
170130
170148
|
var init_site_app = __esm({
|
|
170131
170149
|
"../../apps/himi-spaces-lite/site-app.ts"() {
|
|
170132
170150
|
init_host_compatibility();
|
|
170133
170151
|
init_registry_app_normalize();
|
|
170134
170152
|
init_site_open();
|
|
170135
170153
|
DEFAULT_SITE_APP = HOSTED_MEMBER_APP;
|
|
170136
|
-
NATIVELY_HOSTABLE_APPS =
|
|
170154
|
+
NATIVELY_HOSTABLE_APPS = "any";
|
|
170155
|
+
HOSTED_APP_CAPABILITIES = [
|
|
170156
|
+
"animation",
|
|
170157
|
+
"app_info",
|
|
170158
|
+
"clipboard",
|
|
170159
|
+
"file_picker",
|
|
170160
|
+
"haptics",
|
|
170161
|
+
"keyboard",
|
|
170162
|
+
"media_playback",
|
|
170163
|
+
"motion",
|
|
170164
|
+
"on_device_ai",
|
|
170165
|
+
"open_url",
|
|
170166
|
+
"pdf",
|
|
170167
|
+
"share",
|
|
170168
|
+
"stream",
|
|
170169
|
+
"theme",
|
|
170170
|
+
"ui",
|
|
170171
|
+
"wix_api"
|
|
170172
|
+
];
|
|
170137
170173
|
APP_ID3 = /^[a-z0-9][a-z0-9._-]{0,127}$/i;
|
|
170138
170174
|
}
|
|
170139
170175
|
});
|
|
@@ -174440,7 +174476,7 @@ var ServeCliClient = class {
|
|
|
174440
174476
|
const headers2 = { ...this.ctrlHeaders(), ...gzip ? { "content-encoding": "gzip" } : {} };
|
|
174441
174477
|
const res = await this.request("control", "POST", "/v1/admin/release", { rawBody: bytes2, headers: headers2 });
|
|
174442
174478
|
if (gzip && res.status === 400 && res.json?.error === "bad_json") {
|
|
174443
|
-
const json6 = { error: "compressed_publish_unsupported", hint: "this body is over the plain publish cap, and
|
|
174479
|
+
const json6 = { code: "compressed_publish_unsupported", error: "compressed_publish_unsupported", hint: "this body is over the plain publish cap, and the plane did not accept it compressed: either the plane predates gzip publish bodies (it needs a serve deploy), or this is a self-serve credential, which keeps the plain 8 MB cap" };
|
|
174444
174480
|
return { ...res, json: json6, text: JSON.stringify(json6) };
|
|
174445
174481
|
}
|
|
174446
174482
|
return res;
|
|
@@ -179820,7 +179856,8 @@ ${doNow.map((l2) => ` ${l2}`).join("\n")}`);
|
|
|
179820
179856
|
}
|
|
179821
179857
|
if (!r2.ok) {
|
|
179822
179858
|
const hint = releaseIdExistsHint(r2.status, r2.json);
|
|
179823
|
-
|
|
179859
|
+
const code = r2.json?.code === "compressed_publish_unsupported" ? "compressed_publish_unsupported" : void 0;
|
|
179860
|
+
print({ ok: false, ...code ? { code } : {}, status: r2.status, body: r2.json ?? r2.text, ...hint ? { hint } : {} });
|
|
179824
179861
|
return 1;
|
|
179825
179862
|
}
|
|
179826
179863
|
if (sendPayload.sourceGz && r2.json?.template !== true) {
|
|
@@ -106,6 +106,15 @@ failure codes. A forced push still follows the existing override rules.
|
|
|
106
106
|
| `config_not_applied` | `--content` was given, but the binding is not in its `config.ts` (no config file, a dynamic or symlinked config, an edit `himi validate` rolled back, or no validator); the `config` report or `note` says what to add by hand. |
|
|
107
107
|
| `connect_failed` | An otherwise unclassified error stopped connect (for example an unreadable manifest, or a failed `--out` write). The original message is preserved. |
|
|
108
108
|
|
|
109
|
+
## `himi template publish` codes
|
|
110
|
+
|
|
111
|
+
`template publish` is still mostly legacy. It carries one code so far, on the path that sends the
|
|
112
|
+
whole body gzip-encoded because it is over the plain 8 MB cap:
|
|
113
|
+
|
|
114
|
+
| Code | Meaning |
|
|
115
|
+
|---|---|
|
|
116
|
+
| `compressed_publish_unsupported` | The publish body went out gzipped and the publishing service did not accept it compressed, so it read the bytes as malformed JSON. Either the service does not accept compressed bodies yet, or the credential is a self-serve one, which keeps the 8 MB uncompressed limit. Nothing was written. |
|
|
117
|
+
|
|
109
118
|
## `himi site member-app` codes
|
|
110
119
|
|
|
111
120
|
`himi site member-app set|clear|show <site>` prints one envelope. A refusal from the publishing service
|
|
@@ -126,10 +135,12 @@ keeps the service's own `error` in `serverError` and its HTTP `status`; the CLI
|
|
|
126
135
|
|
|
127
136
|
`show` succeeds with `opens` (what members get: the picked app or `himi-branded-lite`), `compatible`
|
|
128
137
|
(whether the picked release fits the Spaces host manifest, judged with `checkHostCompatibility`), and —
|
|
129
|
-
whenever members get Branded Lite instead of the pick — `reason`. `opens` is Spaces' own decision
|
|
130
|
-
compatible pick
|
|
131
|
-
|
|
132
|
-
`
|
|
138
|
+
whenever members get Branded Lite instead of the pick — `reason`. `opens` is Spaces' own decision: a
|
|
139
|
+
compatible pick reports `compatible: true` with `opens` naming that app — except one that needs a
|
|
140
|
+
capability the hosted-app sandbox does not grant (on-device stores such as `local_database`,
|
|
141
|
+
`secure_storage` and `files`, or push, purchases, release control and the like), which reports
|
|
142
|
+
`compatible: true` with `opens: "himi-branded-lite"` and that reason. Read `opens`, not `compatible`, for
|
|
143
|
+
what members get. An incompatible pick is not a failure: it is `ok: true` with `compatible: false`.
|
|
133
144
|
|
|
134
145
|
## Follow-ups
|
|
135
146
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wix/himalaya-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1368.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "himi — the Himalaya authoring CLI. Build a Tier-5 content package on your own machine, push it to the production serve as a draft, preview it on web + Himi Player, and read worker logs back — the remote dev loop. Wraps @himalaya/serve-cli for transport.",
|
|
6
6
|
"keywords": [
|
|
@@ -71,5 +71,5 @@
|
|
|
71
71
|
"artifactId": "himalaya-cli"
|
|
72
72
|
}
|
|
73
73
|
},
|
|
74
|
-
"falconPackageHash": "
|
|
74
|
+
"falconPackageHash": "b0dba7f9b4c5184e704a739e1f459e4930cc9b446af7d0866d9038ae"
|
|
75
75
|
}
|