@wix/himalaya-cli 0.1350.0 → 0.1352.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 +643 -107
- package/dist/preview-assets.generated.bin +0 -0
- package/guides/himi-json-output.md +26 -1
- package/package.json +2 -2
package/dist/cli.mjs
CHANGED
|
@@ -22082,6 +22082,9 @@ function isBinaryCore(configTs, distributionJson) {
|
|
|
22082
22082
|
return false;
|
|
22083
22083
|
}
|
|
22084
22084
|
}
|
|
22085
|
+
function binaryCoreSatelliteTrait(product) {
|
|
22086
|
+
return product;
|
|
22087
|
+
}
|
|
22085
22088
|
function binaryCoreSatellitePath(product) {
|
|
22086
22089
|
return `Satellites/${product}`;
|
|
22087
22090
|
}
|
|
@@ -22106,7 +22109,7 @@ function binaryCoreVersion(distributionJson, configTs = "") {
|
|
|
22106
22109
|
}
|
|
22107
22110
|
return /distribution:\s*\{[^}]*\bcoreVersion:\s*["']([^"']+)["']/.exec(configTs)?.[1]?.trim() || void 0;
|
|
22108
22111
|
}
|
|
22109
|
-
var BINARY_CORE_USAGE_STRINGS, BINARY_CORE_PRE_SPLIT_USAGE_STRINGS, BINARY_CORE_SPM_PACKAGE, BINARY_CORE_MAVEN_GROUP, BINARY_CORE_IOS_SATELLITES, BINARY_CORE_ANDROID_PUBLISH_BUILDS, BINARY_CORE_MODULES_SINCE;
|
|
22112
|
+
var BINARY_CORE_USAGE_STRINGS, BINARY_CORE_PRE_SPLIT_USAGE_STRINGS, BINARY_CORE_SPM_PACKAGE, BINARY_CORE_MAVEN_GROUP, BINARY_CORE_IOS_SATELLITES, BINARY_CORE_IOS_PATH_ONLY_SATELLITES, BINARY_CORE_IOS_TRAIT_SATELLITES, BINARY_CORE_IOS_TRAIT_SELECTOR, BINARY_CORE_ANDROID_PUBLISH_BUILDS, BINARY_CORE_MODULES_SINCE;
|
|
22110
22113
|
var init_binary_core = __esm({
|
|
22111
22114
|
"../../core/sdk/capability-catalog/src/binary-core.ts"() {
|
|
22112
22115
|
init_modules();
|
|
@@ -22133,6 +22136,11 @@ var init_binary_core = __esm({
|
|
|
22133
22136
|
"HimalayaCoreGodot",
|
|
22134
22137
|
"HimalayaCoreSentry"
|
|
22135
22138
|
]);
|
|
22139
|
+
BINARY_CORE_IOS_PATH_ONLY_SATELLITES = Object.freeze(["HimalayaCoreGodot"]);
|
|
22140
|
+
BINARY_CORE_IOS_TRAIT_SATELLITES = Object.freeze(
|
|
22141
|
+
BINARY_CORE_IOS_SATELLITES.filter((p2) => !BINARY_CORE_IOS_PATH_ONLY_SATELLITES.includes(p2))
|
|
22142
|
+
);
|
|
22143
|
+
BINARY_CORE_IOS_TRAIT_SELECTOR = "HimalayaCoreTraits";
|
|
22136
22144
|
BINARY_CORE_ANDROID_PUBLISH_BUILDS = Object.freeze({
|
|
22137
22145
|
":core-runtime-godot": "apps/himi-game/android"
|
|
22138
22146
|
});
|
|
@@ -22965,10 +22973,13 @@ __export(gen_native_config_exports, {
|
|
|
22965
22973
|
androidTvLeanbackPlan: () => androidTvLeanbackPlan,
|
|
22966
22974
|
applyModuleFlags: () => applyModuleFlags,
|
|
22967
22975
|
applyToFile: () => applyToFile,
|
|
22976
|
+
applyTraitSelector: () => applyTraitSelector,
|
|
22968
22977
|
assertModuleFlagsMarkers: () => assertModuleFlagsMarkers,
|
|
22969
22978
|
assertSingleMarkerPair: () => assertSingleMarkerPair,
|
|
22970
22979
|
assertSingleModuleInstall: () => assertSingleModuleInstall,
|
|
22971
22980
|
automotiveAppDescPath: () => automotiveAppDescPath,
|
|
22981
|
+
binaryCorePackage: () => binaryCorePackage,
|
|
22982
|
+
binaryCorePackageFields: () => binaryCorePackageFields,
|
|
22972
22983
|
binaryCorePackagePath: () => binaryCorePackagePath,
|
|
22973
22984
|
buildSet: () => buildSet,
|
|
22974
22985
|
buildSetOfAppDir: () => buildSetOfAppDir,
|
|
@@ -23013,6 +23024,7 @@ __export(gen_native_config_exports, {
|
|
|
23013
23024
|
renderModulesSwiftInstall: () => renderModulesSwiftInstall,
|
|
23014
23025
|
renderOrientationXml: () => renderOrientationXml,
|
|
23015
23026
|
renderPlistYaml: () => renderPlistYaml,
|
|
23027
|
+
renderTraitSelector: () => renderTraitSelector,
|
|
23016
23028
|
resolveDistBake: () => resolveDistBake,
|
|
23017
23029
|
swiftFilesWithModuleMarkers: () => swiftFilesWithModuleMarkers,
|
|
23018
23030
|
tvInfoPlan: () => tvInfoPlan,
|
|
@@ -23188,38 +23200,85 @@ function renderModulesAndroidInclude(projects, indent) {
|
|
|
23188
23200
|
function renderModulesAndroidLink(projects, indent) {
|
|
23189
23201
|
return projects.map((p2) => `${indent}implementation(project("${p2}"))`);
|
|
23190
23202
|
}
|
|
23191
|
-
function renderModulesIosLinkBinary(products, indent) {
|
|
23203
|
+
function renderModulesIosLinkBinary(products, indent, form = "path") {
|
|
23192
23204
|
return products.flatMap(
|
|
23193
|
-
(p2) => BINARY_CORE_IOS_SATELLITES.includes(p2) ? [`${indent}- package: ${p2}`, `${indent} product: ${p2}`] : [`${indent}- package: ${BINARY_CORE_SPM_PACKAGE}`, `${indent} product: ${p2}`]
|
|
23205
|
+
(p2) => BINARY_CORE_IOS_SATELLITES.includes(p2) && form === "path" ? [`${indent}- package: ${p2}`, `${indent} product: ${p2}`] : [`${indent}- package: ${BINARY_CORE_SPM_PACKAGE}`, `${indent} product: ${p2}`]
|
|
23194
23206
|
);
|
|
23195
23207
|
}
|
|
23196
|
-
function renderModulesIosPackageBinary(products,
|
|
23208
|
+
function renderModulesIosPackageBinary(products, core, indent) {
|
|
23197
23209
|
const satellites = products.filter((p2) => BINARY_CORE_IOS_SATELLITES.includes(p2));
|
|
23198
23210
|
if (!satellites.length) return [];
|
|
23199
|
-
if (!
|
|
23211
|
+
if (!core) {
|
|
23200
23212
|
throw new Error(
|
|
23201
|
-
`a binary-core app that links ${satellites.join(", ")} needs its ${BINARY_CORE_SPM_PACKAGE} package declared
|
|
23213
|
+
`a binary-core app that links ${satellites.join(", ")} needs its ${BINARY_CORE_SPM_PACKAGE} package declared in ios/project.yml by \`path:\` or \`url:\` (#4129)`
|
|
23202
23214
|
);
|
|
23203
23215
|
}
|
|
23204
|
-
|
|
23216
|
+
if ("url" in core) {
|
|
23217
|
+
assertUrlFormSatellites(satellites);
|
|
23218
|
+
return [`${indent}${BINARY_CORE_IOS_TRAIT_SELECTOR}:`, `${indent} path: ${BINARY_CORE_IOS_TRAIT_SELECTOR}`];
|
|
23219
|
+
}
|
|
23220
|
+
return satellites.flatMap((p2) => [`${indent}${p2}:`, `${indent} path: ${yamlScalar(`${core.path.replace(/\/+$/, "")}/${binaryCoreSatellitePath(p2)}`)}`]);
|
|
23205
23221
|
}
|
|
23206
|
-
function
|
|
23222
|
+
function assertUrlFormSatellites(satellites) {
|
|
23223
|
+
const pathOnly = satellites.filter((p2) => BINARY_CORE_IOS_PATH_ONLY_SATELLITES.includes(p2));
|
|
23224
|
+
if (pathOnly.length) {
|
|
23225
|
+
throw new Error(
|
|
23226
|
+
`a binary-core app that links ${pathOnly.join(", ")} needs its ${BINARY_CORE_SPM_PACKAGE} package declared by \`path:\` in ios/project.yml: its third-party package needs a higher iOS floor than the published package's, and SwiftPM has no per-product platform, so the \`url:\` package cannot carry it (BINARY_CORE_IOS_PATH_ONLY_SATELLITES)`
|
|
23227
|
+
);
|
|
23228
|
+
}
|
|
23229
|
+
}
|
|
23230
|
+
function renderTraitSelector(products, core) {
|
|
23231
|
+
if (!core || !("url" in core)) return void 0;
|
|
23232
|
+
const satellites = products.filter((p2) => BINARY_CORE_IOS_SATELLITES.includes(p2));
|
|
23233
|
+
if (!satellites.length) return void 0;
|
|
23234
|
+
assertUrlFormSatellites(satellites);
|
|
23235
|
+
const traits = satellites.filter((p2) => BINARY_CORE_IOS_TRAIT_SATELLITES.includes(p2)).map(binaryCoreSatelliteTrait).sort();
|
|
23236
|
+
return `// swift-tools-version:6.1
|
|
23237
|
+
// GENERATED by tools/native-config from config.ts capabilities \u2014 do not edit.
|
|
23238
|
+
//
|
|
23239
|
+
// Enables the satellite modules this app links (${satellites.join(", ")}) in the published
|
|
23240
|
+
// ${BINARY_CORE_SPM_PACKAGE} package: each is a product there whose third-party packages are gated by a
|
|
23241
|
+
// package trait, off by default, and an Xcode project cannot set traits itself (#4129). No targets:
|
|
23242
|
+
// this package only depends on the same url with those traits.
|
|
23243
|
+
import PackageDescription
|
|
23244
|
+
|
|
23245
|
+
let package = Package(
|
|
23246
|
+
name: ${JSON.stringify(BINARY_CORE_IOS_TRAIT_SELECTOR)},
|
|
23247
|
+
dependencies: [
|
|
23248
|
+
.package(url: ${JSON.stringify(core.url)}, ${core.requirement}, traits: [${traits.map((t2) => JSON.stringify(t2)).join(", ")}]),
|
|
23249
|
+
]
|
|
23250
|
+
)
|
|
23251
|
+
`;
|
|
23252
|
+
}
|
|
23253
|
+
function binaryCorePackageFields(projectYml) {
|
|
23207
23254
|
const lines = projectYml.replace(/\r\n?/g, "\n").split("\n");
|
|
23208
23255
|
const head = lines.findIndex((l2) => new RegExp(`^[ \\t]*${BINARY_CORE_SPM_PACKAGE}:[ \\t]*(?:#.*)?$`).test(l2));
|
|
23209
|
-
|
|
23256
|
+
const fields = {};
|
|
23257
|
+
if (head < 0) return fields;
|
|
23210
23258
|
const indent = /^[ \t]*/.exec(lines[head])[0].length;
|
|
23211
23259
|
for (const line of lines.slice(head + 1)) {
|
|
23212
23260
|
if (!line.trim() || /^[ \t]*#/.test(line)) continue;
|
|
23213
23261
|
if (/^[ \t]*/.exec(line)[0].length <= indent) break;
|
|
23214
|
-
const m2 = /^[ \t]*
|
|
23262
|
+
const m2 = /^[ \t]*([A-Za-z]+):[ \t]*(.*)$/.exec(line);
|
|
23215
23263
|
if (!m2) continue;
|
|
23216
|
-
const v2 = m2[
|
|
23264
|
+
const v2 = m2[2];
|
|
23217
23265
|
const quoted2 = /^"((?:[^"\\]|\\.)*)"|^'((?:[^']|'')*)'/.exec(v2);
|
|
23218
|
-
|
|
23219
|
-
|
|
23220
|
-
return plain2 || void 0;
|
|
23266
|
+
const value = quoted2 ? quoted2[1] !== void 0 ? JSON.parse(`"${quoted2[1]}"`) : quoted2[2].replace(/''/g, "'") : v2.replace(/[ \t]+#.*$/, "").trim();
|
|
23267
|
+
if (value && !(m2[1] in fields)) fields[m2[1]] = value;
|
|
23221
23268
|
}
|
|
23222
|
-
return
|
|
23269
|
+
return fields;
|
|
23270
|
+
}
|
|
23271
|
+
function binaryCorePackagePath(projectYml) {
|
|
23272
|
+
return binaryCorePackageFields(projectYml).path;
|
|
23273
|
+
}
|
|
23274
|
+
function binaryCorePackage(projectYml) {
|
|
23275
|
+
const f2 = binaryCorePackageFields(projectYml);
|
|
23276
|
+
if (f2.path) return { path: f2.path };
|
|
23277
|
+
if (!f2.url) return void 0;
|
|
23278
|
+
const q2 = (v2) => JSON.stringify(v2);
|
|
23279
|
+
const requirement = f2.from ?? f2.majorVersion ? `from: ${q2(f2.from ?? f2.majorVersion)}` : f2.minorVersion ? `.upToNextMinor(from: ${q2(f2.minorVersion)})` : f2.exactVersion ?? f2.version ? `exact: ${q2(f2.exactVersion ?? f2.version)}` : f2.minVersion && f2.maxVersion ? `${q2(f2.minVersion)}..<${q2(f2.maxVersion)}` : f2.branch ? `branch: ${q2(f2.branch)}` : f2.revision ? `revision: ${q2(f2.revision)}` : void 0;
|
|
23280
|
+
if (!requirement) throw new Error(`ios/project.yml: the ${BINARY_CORE_SPM_PACKAGE} \`url:\` package has no version requirement native-config can read (from / exactVersion / minorVersion / minVersion+maxVersion / branch / revision)`);
|
|
23281
|
+
return { url: f2.url, requirement };
|
|
23223
23282
|
}
|
|
23224
23283
|
function renderModulesAndroidLinkBinary(projects, coreVersion, indent) {
|
|
23225
23284
|
return projects.map((p2) => {
|
|
@@ -23231,6 +23290,7 @@ function moduleLinkRenderers(modules, binary) {
|
|
|
23231
23290
|
if (!binary) {
|
|
23232
23291
|
return {
|
|
23233
23292
|
iosLinked: () => modules.spm,
|
|
23293
|
+
iosTraitSelector: () => void 0,
|
|
23234
23294
|
iosPackage: (i2) => renderModulesIosPackage(modules.spm, i2),
|
|
23235
23295
|
iosLink: (i2) => renderModulesIosLink(modules.spm, i2),
|
|
23236
23296
|
androidInclude: (i2) => renderModulesAndroidInclude(modules.gradle, i2),
|
|
@@ -23238,11 +23298,13 @@ function moduleLinkRenderers(modules, binary) {
|
|
|
23238
23298
|
};
|
|
23239
23299
|
}
|
|
23240
23300
|
const iosLinked = () => modules.spm.length && coreVersionHasModules(binary.coreVersion()) ? modules.spm : [];
|
|
23301
|
+
const form = () => binary.corePackage?.() && "url" in binary.corePackage() ? "url" : "path";
|
|
23241
23302
|
return {
|
|
23242
23303
|
iosLinked,
|
|
23243
|
-
iosPackage: (i2) =>
|
|
23304
|
+
iosPackage: (i2) => iosLinked().length ? renderModulesIosPackageBinary(modules.spm, binary.corePackage?.(), i2) : [],
|
|
23305
|
+
iosTraitSelector: () => iosLinked().length ? renderTraitSelector(modules.spm, binary.corePackage?.()) : void 0,
|
|
23244
23306
|
// Same version rule as Android: a pre-split core carries the capabilities and has no products.
|
|
23245
|
-
iosLink: (i2) =>
|
|
23307
|
+
iosLink: (i2) => iosLinked().length ? renderModulesIosLinkBinary(modules.spm, i2, form()) : [],
|
|
23246
23308
|
androidInclude: () => [],
|
|
23247
23309
|
// A core pinned below BINARY_CORE_MODULES_SINCE predates the split and carries the capabilities
|
|
23248
23310
|
// itself; no module AAR exists at that version, so it links none.
|
|
@@ -23470,6 +23532,9 @@ function removeWholeFile(path2, check) {
|
|
|
23470
23532
|
rmSync7(path2);
|
|
23471
23533
|
return { path: path2, outcome: "removed" };
|
|
23472
23534
|
}
|
|
23535
|
+
function applyTraitSelector(path2, content, check) {
|
|
23536
|
+
return content === void 0 ? removeWholeFile(path2, check) : applyWholeFile(path2, content, check);
|
|
23537
|
+
}
|
|
23473
23538
|
function iapBindingInfo(binding2) {
|
|
23474
23539
|
return { HimiIapPurchasesAppId: binding2.purchasesAppId, HimiIapSiteId: binding2.siteId, HimiIapBundleId: binding2.bundleId };
|
|
23475
23540
|
}
|
|
@@ -23535,7 +23600,7 @@ function genNativeConfig(app, opts = {}) {
|
|
|
23535
23600
|
if (!v2) throw new Error(`${app}: a binary-core app that links native modules (${modules.gradle.join(", ")}) needs distribution.json coreVersion`);
|
|
23536
23601
|
return v2;
|
|
23537
23602
|
},
|
|
23538
|
-
|
|
23603
|
+
corePackage: () => existsSync34(iosProjectYml(app)) ? binaryCorePackage(readFileSync33(iosProjectYml(app), "utf8")) : void 0
|
|
23539
23604
|
} : void 0
|
|
23540
23605
|
);
|
|
23541
23606
|
if (binaryCore) {
|
|
@@ -23614,6 +23679,9 @@ function genNativeConfig(app, opts = {}) {
|
|
|
23614
23679
|
applyToFile(iosProjectYml(app), "yaml", LABEL_MODULES_IOS_PACKAGE, moduleLinks.iosPackage, check),
|
|
23615
23680
|
applyToFile(iosProjectYml(app), "yaml", LABEL_MODULES_IOS_LINK, moduleLinks.iosLink, check),
|
|
23616
23681
|
applyModuleFlags(iosProjectYml(app), moduleLinks.iosLinked(), check),
|
|
23682
|
+
// Model B, `url:` form: the trait selector package that enables the linked satellites' traits
|
|
23683
|
+
// in the published package (#4129). Removed when the app links none, or is not in that form.
|
|
23684
|
+
applyTraitSelector(join34(dirname21(iosProjectYml(app)), BINARY_CORE_IOS_TRAIT_SELECTOR, "Package.swift"), moduleLinks.iosTraitSelector(), check),
|
|
23617
23685
|
// macOS (RFC 0046) reuses the iOS boot, so it links the same macOS-capable modules.
|
|
23618
23686
|
applyToFile(macosProjectYml(app), "yaml", LABEL_MODULES_IOS_PACKAGE, (i2) => renderModulesIosPackage(modules.macos, i2), check),
|
|
23619
23687
|
applyToFile(macosProjectYml(app), "yaml", LABEL_MODULES_IOS_LINK, (i2) => renderModulesIosLink(modules.macos, i2), check),
|
|
@@ -32757,8 +32825,15 @@ var init_app_identity = __esm({
|
|
|
32757
32825
|
});
|
|
32758
32826
|
|
|
32759
32827
|
// ../../core/ts/src/registry-app-normalize.ts
|
|
32828
|
+
function isPlayerRequirements(v2) {
|
|
32829
|
+
if (!v2 || typeof v2 !== "object") return false;
|
|
32830
|
+
const r2 = v2;
|
|
32831
|
+
return PLAYER_REQUIREMENT_KINDS.every((kind) => Array.isArray(r2[kind]) && r2[kind].every((id) => typeof id === "string"));
|
|
32832
|
+
}
|
|
32833
|
+
var PLAYER_REQUIREMENT_KINDS;
|
|
32760
32834
|
var init_registry_app_normalize = __esm({
|
|
32761
32835
|
"../../core/ts/src/registry-app-normalize.ts"() {
|
|
32836
|
+
PLAYER_REQUIREMENT_KINDS = ["capabilities", "nativeComponents", "authProviders"];
|
|
32762
32837
|
}
|
|
32763
32838
|
});
|
|
32764
32839
|
|
|
@@ -37349,7 +37424,7 @@ function newRicosRequestId() {
|
|
|
37349
37424
|
async function runRicosImageUpload(o2) {
|
|
37350
37425
|
const { session, uploadService: svc, requestId: requestId2, file: file2, deps } = o2;
|
|
37351
37426
|
const t2 = deps.timers ?? { setTimeout: (fn2, ms2) => setTimeout(fn2, ms2), clearTimeout: (h2) => clearTimeout(h2) };
|
|
37352
|
-
const
|
|
37427
|
+
const fail5 = (reason) => {
|
|
37353
37428
|
session.failMedia(requestId2);
|
|
37354
37429
|
return { ok: false, reason };
|
|
37355
37430
|
};
|
|
@@ -37375,32 +37450,32 @@ async function runRicosImageUpload(o2) {
|
|
|
37375
37450
|
});
|
|
37376
37451
|
deps.dispatch({ actionId: `tier5.${svc}.genUpload`, args: { requestId: requestId2, mimeType: file2.mimeType, fileName: file2.fileName, ...file2.sizeBytes !== void 0 ? { sizeBytes: file2.sizeBytes } : {} } });
|
|
37377
37452
|
});
|
|
37378
|
-
if (!entry) return
|
|
37379
|
-
if (entry.status !== "ready" || !entry.uploadUrl || !/^https:\/\//i.test(entry.uploadUrl)) return
|
|
37453
|
+
if (!entry) return fail5("timeout");
|
|
37454
|
+
if (entry.status !== "ready" || !entry.uploadUrl || !/^https:\/\//i.test(entry.uploadUrl)) return fail5("gen_upload");
|
|
37380
37455
|
let body;
|
|
37381
37456
|
try {
|
|
37382
37457
|
body = typeof file2.body === "function" ? await file2.body() : file2.body;
|
|
37383
37458
|
} catch {
|
|
37384
|
-
return
|
|
37459
|
+
return fail5("read");
|
|
37385
37460
|
}
|
|
37386
37461
|
const sep21 = entry.uploadUrl.includes("?") ? "&" : "?";
|
|
37387
37462
|
let res;
|
|
37388
37463
|
try {
|
|
37389
37464
|
res = await deps.fetch(`${entry.uploadUrl}${sep21}filename=${encodeURIComponent(file2.fileName)}`, { method: "PUT", headers: { "Content-Type": file2.mimeType }, body });
|
|
37390
37465
|
} catch {
|
|
37391
|
-
return
|
|
37466
|
+
return fail5("put");
|
|
37392
37467
|
}
|
|
37393
|
-
if (!res.ok) return
|
|
37468
|
+
if (!res.ok) return fail5("put");
|
|
37394
37469
|
let json6;
|
|
37395
37470
|
try {
|
|
37396
37471
|
json6 = await res.json();
|
|
37397
37472
|
} catch {
|
|
37398
|
-
return
|
|
37473
|
+
return fail5("bad_descriptor");
|
|
37399
37474
|
}
|
|
37400
37475
|
const root = json6 && typeof json6 === "object" ? json6 : {};
|
|
37401
37476
|
const d2 = root.file && typeof root.file === "object" ? root.file : root;
|
|
37402
37477
|
const id = typeof d2.id === "string" ? d2.id : "";
|
|
37403
|
-
if (!id) return
|
|
37478
|
+
if (!id) return fail5("bad_descriptor");
|
|
37404
37479
|
const ok2 = session.resolveMedia(requestId2, {
|
|
37405
37480
|
id,
|
|
37406
37481
|
url: typeof d2.url === "string" ? d2.url : "",
|
|
@@ -134449,7 +134524,7 @@ async function crawlScreen(opts) {
|
|
|
134449
134524
|
async function crawlScreenJourney(opts) {
|
|
134450
134525
|
return withSwallowedRejections(async () => {
|
|
134451
134526
|
const findings = [];
|
|
134452
|
-
const
|
|
134527
|
+
const fail5 = (message, step) => {
|
|
134453
134528
|
findings.push({
|
|
134454
134529
|
screen: opts.screenId,
|
|
134455
134530
|
trigger: step ? { tap: step.component ?? null, key: "journey", action: step.action } : "boot",
|
|
@@ -134460,7 +134535,7 @@ async function crawlScreenJourney(opts) {
|
|
|
134460
134535
|
});
|
|
134461
134536
|
};
|
|
134462
134537
|
if (!opts.bundleJs) {
|
|
134463
|
-
|
|
134538
|
+
fail5(`journey "${opts.journey.name}" targets a screen without a worker bundle`);
|
|
134464
134539
|
return { screen: opts.screenId, journey: opts.journey.name, stepsExercised: 0, findings };
|
|
134465
134540
|
}
|
|
134466
134541
|
const { call: wixCall } = layeredTransport({ rules: opts.rules, cmsSeed: opts.cmsSeed, canned: opts.canned });
|
|
@@ -134485,23 +134560,23 @@ async function crawlScreenJourney(opts) {
|
|
|
134485
134560
|
for (const step of opts.journey.steps) {
|
|
134486
134561
|
const declared = sites.find((site2) => site2.actionId === step.action && (step.component === void 0 || site2.componentId === step.component));
|
|
134487
134562
|
if (!declared) {
|
|
134488
|
-
|
|
134563
|
+
fail5(`journey "${opts.journey.name}" cannot find ${step.component ? `${step.component} \u2192 ` : ""}${step.action} in this screen`, step);
|
|
134489
134564
|
continue;
|
|
134490
134565
|
}
|
|
134491
134566
|
const state = snapshot(worker).state;
|
|
134492
134567
|
const site = effectiveSiteFor(declared, state);
|
|
134493
134568
|
if (!site) {
|
|
134494
|
-
|
|
134569
|
+
fail5(`journey "${opts.journey.name}" cannot dispatch ${step.action}: its list has no rendered row`, step);
|
|
134495
134570
|
continue;
|
|
134496
134571
|
}
|
|
134497
134572
|
const parsed = parseWorkerAction(site.actionId);
|
|
134498
134573
|
if (!parsed) {
|
|
134499
|
-
|
|
134574
|
+
fail5(`journey "${opts.journey.name}" step ${step.action} is not a worker action; cross-screen navigation belongs in the regular edge pass`, step);
|
|
134500
134575
|
continue;
|
|
134501
134576
|
}
|
|
134502
134577
|
const handle = worker.handles[parsed.service];
|
|
134503
134578
|
if (!handle || !handle.actionNames().includes(parsed.action)) {
|
|
134504
|
-
|
|
134579
|
+
fail5(`journey "${opts.journey.name}" names unavailable worker action ${step.action}`, step);
|
|
134505
134580
|
continue;
|
|
134506
134581
|
}
|
|
134507
134582
|
const mark = { wix: worker.calls.length, host: worker.hostCalls.length };
|
|
@@ -134510,18 +134585,18 @@ async function crawlScreenJourney(opts) {
|
|
|
134510
134585
|
for (let i2 = 0; i2 < 8; i2++) await yieldMacrotask();
|
|
134511
134586
|
stepsExercised += 1;
|
|
134512
134587
|
} catch (error) {
|
|
134513
|
-
|
|
134588
|
+
fail5(`journey "${opts.journey.name}" step ${step.action} threw: ${errText(error)}`, step);
|
|
134514
134589
|
}
|
|
134515
134590
|
const stepEffect = effectSince(worker, mark, site.actionId, site.componentId);
|
|
134516
134591
|
if (stepEffect) effects.push(stepEffect);
|
|
134517
134592
|
}
|
|
134518
134593
|
const settled = snapshot(worker);
|
|
134519
134594
|
if (worker.errors.length) {
|
|
134520
|
-
for (const error of worker.errors)
|
|
134595
|
+
for (const error of worker.errors) fail5(`journey "${opts.journey.name}" worker error: ${error.service}: ${error.message}`);
|
|
134521
134596
|
}
|
|
134522
134597
|
const values = collectObservations(opts.descriptor, settled.state).join("\n");
|
|
134523
134598
|
for (const expected of opts.journey.expectText) {
|
|
134524
|
-
if (!values.includes(expected))
|
|
134599
|
+
if (!values.includes(expected)) fail5(`journey "${opts.journey.name}" never rendered its expected visible result: ${JSON.stringify(expected)}`);
|
|
134525
134600
|
}
|
|
134526
134601
|
return { screen: opts.screenId, journey: opts.journey.name, stepsExercised, findings, ...effects.length ? { effects } : {} };
|
|
134527
134602
|
});
|
|
@@ -135985,12 +136060,14 @@ __export(build_exports2, {
|
|
|
135985
136060
|
bakeCatalogs: () => bakeCatalogs,
|
|
135986
136061
|
bakeNeedsLiveOrigin: () => bakeNeedsLiveOrigin,
|
|
135987
136062
|
bakeWidgets: () => bakeWidgets,
|
|
136063
|
+
buildFromLoaded: () => buildFromLoaded,
|
|
135988
136064
|
buildRelease: () => buildRelease,
|
|
135989
136065
|
buildReleaseFromContent: () => buildReleaseFromContent,
|
|
135990
136066
|
bundleNameFromUrl: () => bundleNameFromUrl,
|
|
135991
136067
|
collectComponentTypes: () => collectComponentTypes,
|
|
135992
136068
|
contentReleaseId: () => contentReleaseId,
|
|
135993
136069
|
countingWixCall: () => countingWixCall,
|
|
136070
|
+
declaresHostProvidedIdentity: () => declaresHostProvidedIdentity,
|
|
135994
136071
|
gitSha: () => gitSha,
|
|
135995
136072
|
isMonorepoCheckout: () => isMonorepoCheckout,
|
|
135996
136073
|
l10nLintOptions: () => l10nLintOptions,
|
|
@@ -137149,6 +137226,11 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
137149
137226
|
nativeComponents: [...requiredNativeComponents].sort(),
|
|
137150
137227
|
authProviders: [config.auth.providerId].filter(Boolean).sort()
|
|
137151
137228
|
},
|
|
137229
|
+
// #4091 — the app takes its Wix identity from a HOST (Spaces Lite) instead of signing in
|
|
137230
|
+
// itself (#4088 `hostProvided` on its auth provider). A host that lends its identity only
|
|
137231
|
+
// opens an app that accepts it. Written only when true, so every other app's release — and
|
|
137232
|
+
// its releaseId — is byte-identical to one built before the field existed.
|
|
137233
|
+
...declaresHostProvidedIdentity(config.auth) ? { hostProvidedIdentity: true } : {},
|
|
137152
137234
|
iconHash,
|
|
137153
137235
|
...brandFonts.length ? { brandFonts } : {},
|
|
137154
137236
|
handlers,
|
|
@@ -137275,6 +137357,10 @@ function listBuildableApps() {
|
|
|
137275
137357
|
const appsDir = join47(REPO_ROOT7, "apps");
|
|
137276
137358
|
return readdirSync25(appsDir, { withFileTypes: true }).filter((d2) => d2.isDirectory() && !d2.name.startsWith("_")).map((d2) => d2.name);
|
|
137277
137359
|
}
|
|
137360
|
+
function declaresHostProvidedIdentity(auth) {
|
|
137361
|
+
const config = auth?.config;
|
|
137362
|
+
return typeof config === "object" && config !== null && config.hostProvided === true;
|
|
137363
|
+
}
|
|
137278
137364
|
var BAKE_OFFLINE_BASE, KNOWN_ICON_NAMES, KNOWN_ICONS, REPO_ROOT7, TIER5_DIR, requireFromHere, SOURCEMAP_ON_DEMAND_PATH, BAKED_SERVER_BASE_URL;
|
|
137279
137365
|
var init_build3 = __esm({
|
|
137280
137366
|
"../release-build/build.ts"() {
|
|
@@ -152306,30 +152392,30 @@ function logicalCollection(spec, app) {
|
|
|
152306
152392
|
}
|
|
152307
152393
|
function assertFieldValue(type, key2, value) {
|
|
152308
152394
|
if (value === null) return;
|
|
152309
|
-
const
|
|
152395
|
+
const fail5 = () => {
|
|
152310
152396
|
throw new Error(`field "${key2}" must be ${type}`);
|
|
152311
152397
|
};
|
|
152312
152398
|
if (type === "NUMBER") {
|
|
152313
|
-
if (typeof value !== "number" || !Number.isFinite(value))
|
|
152399
|
+
if (typeof value !== "number" || !Number.isFinite(value)) fail5();
|
|
152314
152400
|
return;
|
|
152315
152401
|
}
|
|
152316
152402
|
if (type === "BOOLEAN") {
|
|
152317
|
-
if (typeof value !== "boolean")
|
|
152403
|
+
if (typeof value !== "boolean") fail5();
|
|
152318
152404
|
return;
|
|
152319
152405
|
}
|
|
152320
152406
|
if (type === "ARRAY_STRING") {
|
|
152321
|
-
if (!Array.isArray(value) || value.some((item) => typeof item !== "string"))
|
|
152407
|
+
if (!Array.isArray(value) || value.some((item) => typeof item !== "string")) fail5();
|
|
152322
152408
|
return;
|
|
152323
152409
|
}
|
|
152324
152410
|
if (type === "ADDRESS" || type === "RICH_CONTENT") {
|
|
152325
|
-
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
152411
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) fail5();
|
|
152326
152412
|
return;
|
|
152327
152413
|
}
|
|
152328
152414
|
if (type === "MEDIA_GALLERY") {
|
|
152329
|
-
if (!Array.isArray(value))
|
|
152415
|
+
if (!Array.isArray(value)) fail5();
|
|
152330
152416
|
return;
|
|
152331
152417
|
}
|
|
152332
|
-
if (typeof value !== "string")
|
|
152418
|
+
if (typeof value !== "string") fail5();
|
|
152333
152419
|
}
|
|
152334
152420
|
function createFunctionDataCapability(options) {
|
|
152335
152421
|
const declaredKv = new Map((options.data?.kv ?? []).map((spec) => [spec.name, spec]));
|
|
@@ -155750,6 +155836,9 @@ ${releaseId}`;
|
|
|
155750
155836
|
...m2.publishedAt ? { publishedAt: m2.publishedAt } : {},
|
|
155751
155837
|
...publicationKind ? { publicationKind } : {},
|
|
155752
155838
|
...m2.playerRequirements ? { playerRequirements: m2.playerRequirements } : {},
|
|
155839
|
+
// #4091 — whether the app accepts its host's identity; Spaces opens an owner-picked
|
|
155840
|
+
// member app only when it does. Absent = it signs in itself (or predates the field).
|
|
155841
|
+
...m2.hostProvidedIdentity === true ? { hostProvidedIdentity: true } : {},
|
|
155753
155842
|
// RFC 0051 §3.6 — the release's surface envelope, for tooling that has no
|
|
155754
155843
|
// source tree (hosted admin surface picker, gallery). Absent on releases
|
|
155755
155844
|
// built before the envelope rode the manifest.
|
|
@@ -155870,11 +155959,11 @@ ${releaseId}`;
|
|
|
155870
155959
|
if (pin) {
|
|
155871
155960
|
const m3 = app ? await pinnedManifest(app, pin) : null;
|
|
155872
155961
|
if (!m3) return json4(404, { error: "release_not_found", app, releaseId: pin });
|
|
155873
|
-
return json4(200, { releaseId: m3.releaseId, app: m3.app, pinned: true, ...m3.minBinaryVersion ? { minBinaryVersion: m3.minBinaryVersion } : {}, ...m3.playerRequirements ? { playerRequirements: m3.playerRequirements } : {}, ...m3.platforms ? { platforms: m3.platforms } : {} });
|
|
155962
|
+
return json4(200, { releaseId: m3.releaseId, app: m3.app, pinned: true, ...m3.minBinaryVersion ? { minBinaryVersion: m3.minBinaryVersion } : {}, ...m3.playerRequirements ? { playerRequirements: m3.playerRequirements } : {}, ...m3.hostProvidedIdentity === true ? { hostProvidedIdentity: true } : {}, ...m3.platforms ? { platforms: m3.platforms } : {} });
|
|
155874
155963
|
}
|
|
155875
155964
|
const m2 = app ? await manifest(app) : null;
|
|
155876
155965
|
if (!m2) return json4(404, { error: "no_release", app });
|
|
155877
|
-
return json4(200, { releaseId: m2.releaseId, app: m2.app, ...m2.minBinaryVersion ? { minBinaryVersion: m2.minBinaryVersion } : {}, ...m2.playerRequirements ? { playerRequirements: m2.playerRequirements } : {}, ...m2.platforms ? { platforms: m2.platforms } : {} });
|
|
155966
|
+
return json4(200, { releaseId: m2.releaseId, app: m2.app, ...m2.minBinaryVersion ? { minBinaryVersion: m2.minBinaryVersion } : {}, ...m2.playerRequirements ? { playerRequirements: m2.playerRequirements } : {}, ...m2.hostProvidedIdentity === true ? { hostProvidedIdentity: true } : {}, ...m2.platforms ? { platforms: m2.platforms } : {} });
|
|
155878
155967
|
}
|
|
155879
155968
|
const bundleMatch = /^\/v1\/bundles\/([a-f0-9]{64})\.bundle\.js$/.exec(path2);
|
|
155880
155969
|
if (bundleMatch) {
|
|
@@ -156629,25 +156718,25 @@ var init_preview_assets_generated = __esm({
|
|
|
156629
156718
|
"../../packages/serve/src/preview-assets.generated.ts"() {
|
|
156630
156719
|
init_preview_assets_format();
|
|
156631
156720
|
PREVIEW_ASSET_MANIFEST = [
|
|
156632
|
-
{ key: "assets/index
|
|
156633
|
-
{ key: "assets/pdf-
|
|
156634
|
-
{ key: "assets/pdf.worker.min-BQa_JDET.js", contentType: "application/javascript; charset=utf-8", offset:
|
|
156635
|
-
{ key: "assets/pdf.worker.min-BmVo14Nb.mjs", contentType: "application/javascript; charset=utf-8", offset:
|
|
156636
|
-
{ key: "assets/pdfDocument-
|
|
156637
|
-
{ key: "fonts/Roboto-LICENSE.txt", contentType: "application/octet-stream", offset:
|
|
156638
|
-
{ key: "fonts/Roboto-Variable.ttf", contentType: "font/ttf", offset:
|
|
156639
|
-
{ key: "fonts/WixMadeforDisplay-Bold.ttf", contentType: "font/ttf", offset:
|
|
156640
|
-
{ key: "fonts/WixMadeforDisplay-ExtraBold.ttf", contentType: "font/ttf", offset:
|
|
156641
|
-
{ key: "fonts/WixMadeforDisplay-Medium.ttf", contentType: "font/ttf", offset:
|
|
156642
|
-
{ key: "fonts/WixMadeforDisplay-Regular.ttf", contentType: "font/ttf", offset:
|
|
156643
|
-
{ key: "fonts/WixMadeforDisplay-SemiBold.ttf", contentType: "font/ttf", offset:
|
|
156644
|
-
{ key: "fonts/WixMadeforText-Bold.ttf", contentType: "font/ttf", offset:
|
|
156645
|
-
{ key: "fonts/WixMadeforText-ExtraBold.ttf", contentType: "font/ttf", offset:
|
|
156646
|
-
{ key: "fonts/WixMadeforText-Medium.ttf", contentType: "font/ttf", offset:
|
|
156647
|
-
{ key: "fonts/WixMadeforText-Regular.ttf", contentType: "font/ttf", offset:
|
|
156648
|
-
{ key: "fonts/WixMadeforText-SemiBold.ttf", contentType: "font/ttf", offset:
|
|
156649
|
-
{ key: "index.html", contentType: "text/html; charset=utf-8", offset:
|
|
156650
|
-
{ key: "t5-frame.html", contentType: "text/html; charset=utf-8", offset:
|
|
156721
|
+
{ key: "assets/index-BDNhcRLx.js", contentType: "application/javascript; charset=utf-8", offset: 8, length: 1271913, sha256: "b78f7b3400ea25a2066e24c6b771199b819a833b624499d221edbc5f1b01a18b" },
|
|
156722
|
+
{ key: "assets/pdf-mXRF2YFr.js", contentType: "application/javascript; charset=utf-8", offset: 1271921, length: 488199, sha256: "3ecd61c959307bee0f74d6d9a3c6ab94dbf7b7305d6d67e2f0167dbf3bc6034a" },
|
|
156723
|
+
{ key: "assets/pdf.worker.min-BQa_JDET.js", contentType: "application/javascript; charset=utf-8", offset: 1760120, length: 73, sha256: "41bcfda4f3c8c0a81c785ea87c69afc8e7d0ed8c333324aee94c273d881bb6aa" },
|
|
156724
|
+
{ key: "assets/pdf.worker.min-BmVo14Nb.mjs", contentType: "application/javascript; charset=utf-8", offset: 1760193, length: 1317034, sha256: "a33cfe728c584fdba4fcc1fd54bcdc2f9f2f13889ddbb5b2bd1d0f8cbe49b84e" },
|
|
156725
|
+
{ key: "assets/pdfDocument-BZIqh5sA.js", contentType: "application/javascript; charset=utf-8", offset: 3077227, length: 2858, sha256: "32abe2da16ae5c22ce831a4a75bdb6e6121dc99fdae72be8ec22038d6982dd81" },
|
|
156726
|
+
{ key: "fonts/Roboto-LICENSE.txt", contentType: "application/octet-stream", offset: 3080085, length: 4610, sha256: "994062dd7af4186a739de55dd9e151c63b6301f8e2cbafc608d35c2e87da0cd2" },
|
|
156727
|
+
{ key: "fonts/Roboto-Variable.ttf", contentType: "font/ttf", offset: 3084695, length: 488584, sha256: "d7598e12c5dbef095ff8272cfc55da0250bd07fbdecbac8a530b9b277872a134" },
|
|
156728
|
+
{ key: "fonts/WixMadeforDisplay-Bold.ttf", contentType: "font/ttf", offset: 3573279, length: 90924, sha256: "ec4c7d63772d980d6e147b2df6215fd2737e4b04cebe0cf7e11dc695fb63cdcf" },
|
|
156729
|
+
{ key: "fonts/WixMadeforDisplay-ExtraBold.ttf", contentType: "font/ttf", offset: 3664203, length: 90984, sha256: "bf4c16a2774edd38a921edf3099469866cd74c094fd596f3fa4e81f54a04dfaa" },
|
|
156730
|
+
{ key: "fonts/WixMadeforDisplay-Medium.ttf", contentType: "font/ttf", offset: 3755187, length: 90980, sha256: "368faca44fb9f7207e4af784e94750b1ee59c1098b8689e0f4a918926f244fb5" },
|
|
156731
|
+
{ key: "fonts/WixMadeforDisplay-Regular.ttf", contentType: "font/ttf", offset: 3846167, length: 90872, sha256: "97ed8f1a6772abe26e3d8af5cecfc4b02faa94497d585b0398b5053b739a70c1" },
|
|
156732
|
+
{ key: "fonts/WixMadeforDisplay-SemiBold.ttf", contentType: "font/ttf", offset: 3937039, length: 90980, sha256: "642feab8a48ddf6c7a89d7c2a7c0edfa0e6e773f671287e460e222703563191e" },
|
|
156733
|
+
{ key: "fonts/WixMadeforText-Bold.ttf", contentType: "font/ttf", offset: 4028019, length: 108636, sha256: "37c179b4fefb63ea9637322b84583a2df53aa226c150294eea1675c14b1b8e29" },
|
|
156734
|
+
{ key: "fonts/WixMadeforText-ExtraBold.ttf", contentType: "font/ttf", offset: 4136655, length: 109084, sha256: "62e2fe4718129f36ecdb0ae4de385bd6b81ecc876146447167c6c140fad699a9" },
|
|
156735
|
+
{ key: "fonts/WixMadeforText-Medium.ttf", contentType: "font/ttf", offset: 4245739, length: 109048, sha256: "4ecf270136af928612c76fe4ebade91d8156975e5ea4c0cf9225501dd1788e02" },
|
|
156736
|
+
{ key: "fonts/WixMadeforText-Regular.ttf", contentType: "font/ttf", offset: 4354787, length: 107700, sha256: "dee56f09fd3efc127c1ea95557edc74110c1460a46287da36e0af25efd341ef5" },
|
|
156737
|
+
{ key: "fonts/WixMadeforText-SemiBold.ttf", contentType: "font/ttf", offset: 4462487, length: 88108, sha256: "dced97a77624bc5f8b1ae65850360908297f4588e09feb6f22792d29dc7e765b" },
|
|
156738
|
+
{ key: "index.html", contentType: "text/html; charset=utf-8", offset: 4550595, length: 4947, sha256: "475486545202c2973900224ffffa48ffbd7313e49b559cbcf9be678b068bff82" },
|
|
156739
|
+
{ key: "t5-frame.html", contentType: "text/html; charset=utf-8", offset: 4555542, length: 17512, sha256: "c5c8612a8b3f5a1828d0c6593106036a180eea11da80232f5181548a50679137" }
|
|
156651
156740
|
];
|
|
156652
156741
|
}
|
|
156653
156742
|
});
|
|
@@ -160506,19 +160595,19 @@ async function runWixMobileRelease(pos, flags, io2, deps) {
|
|
|
160506
160595
|
const invokedAs = pos[0];
|
|
160507
160596
|
const app = invokedAs === "testflight" ? pos[1] : pos[2];
|
|
160508
160597
|
const print = (value) => io2.log(JSON.stringify(value, null, 2));
|
|
160509
|
-
const
|
|
160598
|
+
const fail5 = (error, extra = {}) => {
|
|
160510
160599
|
io2.error(JSON.stringify({ error, provider: "wix-mobile-release", ...extra }));
|
|
160511
160600
|
return 2;
|
|
160512
160601
|
};
|
|
160513
|
-
if (invokedAs !== "testflight" && !(invokedAs === "store" && pos[1] === "upload")) return
|
|
160514
|
-
if (app !== "himi-player") return
|
|
160515
|
-
if (str5(flags.artifact)) return
|
|
160516
|
-
if (on2(flags["no-wait"])) return
|
|
160602
|
+
if (invokedAs !== "testflight" && !(invokedAs === "store" && pos[1] === "upload")) return fail5("Wix Mobile Release only supports `himi testflight <app>` or `himi store upload <app>`");
|
|
160603
|
+
if (app !== "himi-player") return fail5("Wix Mobile Release is reserved for the Wix-owned Himi Player binary", { app });
|
|
160604
|
+
if (str5(flags.artifact)) return fail5("--artifact is not accepted for Himi Player; pass --release so deployed serve can validate the Job Service IPA and call MRE with its service identity");
|
|
160605
|
+
if (on2(flags["no-wait"])) return fail5("--no-wait is not supported for Himi Player TestFlight releases; wait for MRE processing to complete");
|
|
160517
160606
|
const release2 = str5(flags.release);
|
|
160518
160607
|
const version4 = str5(flags.version);
|
|
160519
|
-
if (!release2) return
|
|
160520
|
-
if (!version4 || !/^\d+(?:\.\d+){0,2}$/.test(version4)) return
|
|
160521
|
-
if (str5(flags.track) && str5(flags.track) !== "testflight" && str5(flags.track) !== "internal") return
|
|
160608
|
+
if (!release2) return fail5("--release is required for a Himi Player TestFlight release");
|
|
160609
|
+
if (!version4 || !/^\d+(?:\.\d+){0,2}$/.test(version4)) return fail5("--version needs the Player marketing version (for example 1.0.0)");
|
|
160610
|
+
if (str5(flags.track) && str5(flags.track) !== "testflight" && str5(flags.track) !== "internal") return fail5("Wix Mobile Release only supports TestFlight upload; public App Store release remains a separate human step");
|
|
160522
160611
|
const plan = {
|
|
160523
160612
|
ok: true,
|
|
160524
160613
|
dryRun: on2(flags["dry-run"]),
|
|
@@ -160533,9 +160622,9 @@ async function runWixMobileRelease(pos, flags, io2, deps) {
|
|
|
160533
160622
|
print(plan);
|
|
160534
160623
|
return 0;
|
|
160535
160624
|
}
|
|
160536
|
-
if (!deps.releasePlayerJob) return
|
|
160625
|
+
if (!deps.releasePlayerJob) return fail5("this Himi CLI cannot create a service-side Himi Player TestFlight job; target deployed serve");
|
|
160537
160626
|
if (!on2(flags.yes)) {
|
|
160538
|
-
if (io2.isTTY !== true) return
|
|
160627
|
+
if (io2.isTTY !== true) return fail5("refusing to dispatch a Wix TestFlight release without --yes in a non-interactive shell");
|
|
160539
160628
|
if (!await deps.confirm(` Dispatch Himi Player ${version4} to Wix TestFlight?`)) {
|
|
160540
160629
|
io2.log(" aborted \u2014 no release was dispatched.");
|
|
160541
160630
|
return 1;
|
|
@@ -160544,11 +160633,11 @@ async function runWixMobileRelease(pos, flags, io2, deps) {
|
|
|
160544
160633
|
try {
|
|
160545
160634
|
const released = await deps.releasePlayerJob(release2, version4);
|
|
160546
160635
|
const status = released.status.toUpperCase();
|
|
160547
|
-
if (mreStatusKind(status) !== "completed") return
|
|
160636
|
+
if (mreStatusKind(status) !== "completed") return fail5(`Himi Player TestFlight job ${status || "FAILED"}`, { jobId: released.jobId, ...released.requestId ? { requestId: released.requestId } : {}, ...released.error ? { error: released.error } : {} });
|
|
160548
160637
|
print({ ok: true, provider: "wix-mobile-release", app, jobId: released.jobId, ...released.requestId ? { requestId: released.requestId } : {}, status, ...released.url ? { url: released.url } : {} });
|
|
160549
160638
|
return 0;
|
|
160550
160639
|
} catch (error) {
|
|
160551
|
-
return
|
|
160640
|
+
return fail5(`could not complete the Himi Player TestFlight Job Service release: ${error.message}`);
|
|
160552
160641
|
}
|
|
160553
160642
|
}
|
|
160554
160643
|
var str5, on2;
|
|
@@ -160604,23 +160693,23 @@ async function runStore(pos, flags, io2, deps) {
|
|
|
160604
160693
|
const app = invokedAs === "testflight" ? pos[1] : pos[2];
|
|
160605
160694
|
const json6 = on3(flags.json);
|
|
160606
160695
|
const print = (o2) => io2.log(JSON.stringify(o2, null, 2));
|
|
160607
|
-
const
|
|
160696
|
+
const fail5 = (error, extra = {}) => {
|
|
160608
160697
|
io2.error(JSON.stringify({ error, ...extra }));
|
|
160609
160698
|
return 2;
|
|
160610
160699
|
};
|
|
160611
160700
|
if (!sub || !["preflight", "upload", "status"].includes(sub)) {
|
|
160612
|
-
return
|
|
160701
|
+
return fail5(`unknown store subcommand ${sub ? `"${sub}"` : ""}`.trim(), {
|
|
160613
160702
|
usage: "himi store preflight|upload|status <app> \xB7 himi testflight <app>"
|
|
160614
160703
|
});
|
|
160615
160704
|
}
|
|
160616
|
-
if (!app) return
|
|
160705
|
+
if (!app) return fail5(`store ${sub} needs an <app>`);
|
|
160617
160706
|
if (flags.provider !== void 0) {
|
|
160618
|
-
return
|
|
160707
|
+
return fail5(`unknown release provider "${String(flags.provider)}"`, {
|
|
160619
160708
|
known: ["wix-mobile-release"]
|
|
160620
160709
|
});
|
|
160621
160710
|
}
|
|
160622
160711
|
if (!deps.hasRepoCheckout()) {
|
|
160623
|
-
return
|
|
160712
|
+
return fail5(
|
|
160624
160713
|
"himi store needs a Himalaya monorepo checkout \u2014 it builds and signs apps/<app>'s native target, which does not exist off-repo. Content changes (screens, Tier-5 bundles, tokens, app-config) ship over the air with `himi push` and need no binary.",
|
|
160625
160714
|
{ app }
|
|
160626
160715
|
);
|
|
@@ -160629,14 +160718,14 @@ async function runStore(pos, flags, io2, deps) {
|
|
|
160629
160718
|
try {
|
|
160630
160719
|
cfg = deps.loadStoreConfig(app);
|
|
160631
160720
|
} catch (e2) {
|
|
160632
|
-
return
|
|
160721
|
+
return fail5(e2.message);
|
|
160633
160722
|
}
|
|
160634
160723
|
if (sub === "status") {
|
|
160635
160724
|
let creds2;
|
|
160636
160725
|
try {
|
|
160637
160726
|
creds2 = deps.resolveCredentials({ app, cfg, profileFlag: str6(flags.profile) });
|
|
160638
160727
|
} catch (e2) {
|
|
160639
|
-
return
|
|
160728
|
+
return fail5(e2.message);
|
|
160640
160729
|
}
|
|
160641
160730
|
try {
|
|
160642
160731
|
const s2 = await deps.ascStatus(app, credsToEnv(creds2));
|
|
@@ -160649,14 +160738,14 @@ async function runStore(pos, flags, io2, deps) {
|
|
|
160649
160738
|
}
|
|
160650
160739
|
return 0;
|
|
160651
160740
|
} catch (e2) {
|
|
160652
|
-
return
|
|
160741
|
+
return fail5(`could not read App Store Connect status: ${e2.message}`);
|
|
160653
160742
|
}
|
|
160654
160743
|
}
|
|
160655
160744
|
let findings;
|
|
160656
160745
|
try {
|
|
160657
160746
|
findings = await deps.preflightApp(app, { profileFlag: str6(flags.profile) });
|
|
160658
160747
|
} catch (e2) {
|
|
160659
|
-
return
|
|
160748
|
+
return fail5(e2.message);
|
|
160660
160749
|
}
|
|
160661
160750
|
const { errors, warnings } = partitionFindings(findings);
|
|
160662
160751
|
if (sub === "preflight") {
|
|
@@ -160673,12 +160762,12 @@ async function runStore(pos, flags, io2, deps) {
|
|
|
160673
160762
|
const configTrack = cfg.review?.defaultTrackIos;
|
|
160674
160763
|
const track = explicitTrack ?? (invokedAs === "testflight" ? "testflight" : configTrack ?? "testflight");
|
|
160675
160764
|
if (track === "appstore") {
|
|
160676
|
-
return
|
|
160765
|
+
return fail5(
|
|
160677
160766
|
"himi store does not submit for public App Store review \u2014 that stays a human step. Use TestFlight here, then /submit-ios-app when you mean to go public." + (explicitTrack ? "" : ` (inherited from review.defaultTrackIos; pass --track testflight to upload.)`)
|
|
160678
160767
|
);
|
|
160679
160768
|
}
|
|
160680
160769
|
if (!TRACKS.has(track)) {
|
|
160681
|
-
return
|
|
160770
|
+
return fail5(`unknown --track "${track}"`, { known: [...TRACKS] });
|
|
160682
160771
|
}
|
|
160683
160772
|
const bundleId = cfg.ios?.bundleId ?? "(unset)";
|
|
160684
160773
|
let creds;
|
|
@@ -160687,10 +160776,10 @@ async function runStore(pos, flags, io2, deps) {
|
|
|
160687
160776
|
creds = deps.resolveCredentials({ app, cfg, profileFlag: str6(flags.profile) });
|
|
160688
160777
|
version4 = deps.readVersion(app);
|
|
160689
160778
|
} catch (e2) {
|
|
160690
|
-
return
|
|
160779
|
+
return fail5(e2.message);
|
|
160691
160780
|
}
|
|
160692
160781
|
if (!Number.isInteger(version4.build)) {
|
|
160693
|
-
return
|
|
160782
|
+
return fail5(
|
|
160694
160783
|
`${app} has a non-integer CFBundleVersion (${JSON.stringify(version4.build)}) \u2014 this command bumps and matches build numbers arithmetically. Use an integer CFBundleVersion.`,
|
|
160695
160784
|
{ app, marketing: version4.marketing }
|
|
160696
160785
|
);
|
|
@@ -160705,7 +160794,7 @@ async function runStore(pos, flags, io2, deps) {
|
|
|
160705
160794
|
for (const f2 of findings) io2.log(` ${f2.level === "error" ? "\u2717" : "!"} ${f2.message}`);
|
|
160706
160795
|
}
|
|
160707
160796
|
if (errors.length) {
|
|
160708
|
-
return
|
|
160797
|
+
return fail5(`${app} is not ready to upload \u2014 ${errors.length} blocking preflight issue(s).`, {
|
|
160709
160798
|
findings: errors,
|
|
160710
160799
|
hint: "himi store preflight " + app
|
|
160711
160800
|
});
|
|
@@ -160736,7 +160825,7 @@ async function runStore(pos, flags, io2, deps) {
|
|
|
160736
160825
|
}
|
|
160737
160826
|
if (!on3(flags.yes)) {
|
|
160738
160827
|
if (io2.isTTY !== true) {
|
|
160739
|
-
return
|
|
160828
|
+
return fail5(
|
|
160740
160829
|
"refusing to upload without confirmation in a non-interactive shell. Pass --yes if you really mean to publish this build, or --dry-run to see the plan.",
|
|
160741
160830
|
{ app, track, team: creds.team }
|
|
160742
160831
|
);
|
|
@@ -160751,7 +160840,7 @@ async function runStore(pos, flags, io2, deps) {
|
|
|
160751
160840
|
try {
|
|
160752
160841
|
uploaded = reuseExisting ? version4 : deps.bumpBuild(app);
|
|
160753
160842
|
} catch (e2) {
|
|
160754
|
-
return
|
|
160843
|
+
return fail5(`could not bump the build number: ${e2.message}`);
|
|
160755
160844
|
}
|
|
160756
160845
|
const rollback = () => {
|
|
160757
160846
|
if (reuseExisting) return;
|
|
@@ -160767,11 +160856,11 @@ async function runStore(pos, flags, io2, deps) {
|
|
|
160767
160856
|
r2 = await deps.exec(step, env);
|
|
160768
160857
|
} catch (e2) {
|
|
160769
160858
|
rollback();
|
|
160770
|
-
return
|
|
160859
|
+
return fail5(`${step} failed: ${e2.message}`, { app, step, build: uploaded.build, buildNumberRestored: !reuseExisting });
|
|
160771
160860
|
}
|
|
160772
160861
|
if (r2.code !== 0) {
|
|
160773
160862
|
if (step !== "upload") rollback();
|
|
160774
|
-
return
|
|
160863
|
+
return fail5(`${step} failed (exit ${r2.code})`, {
|
|
160775
160864
|
app,
|
|
160776
160865
|
step,
|
|
160777
160866
|
build: uploaded.build,
|
|
@@ -160795,7 +160884,7 @@ async function runStore(pos, flags, io2, deps) {
|
|
|
160795
160884
|
try {
|
|
160796
160885
|
s2 = await deps.ascStatus(app, env);
|
|
160797
160886
|
} catch (e2) {
|
|
160798
|
-
return
|
|
160887
|
+
return fail5(`uploaded build ${uploaded.build}, but could not read processing status: ${e2.message}`, {
|
|
160799
160888
|
app,
|
|
160800
160889
|
build: uploaded.build,
|
|
160801
160890
|
uploaded: true
|
|
@@ -160811,7 +160900,7 @@ async function runStore(pos, flags, io2, deps) {
|
|
|
160811
160900
|
return 0;
|
|
160812
160901
|
}
|
|
160813
160902
|
if (mine && (mine.processingState === "FAILED" || mine.processingState === "INVALID")) {
|
|
160814
|
-
return
|
|
160903
|
+
return fail5(`build ${uploaded.build} is ${mine.processingState} in App Store Connect`, {
|
|
160815
160904
|
app,
|
|
160816
160905
|
build: uploaded.build,
|
|
160817
160906
|
processingState: mine.processingState,
|
|
@@ -160819,7 +160908,7 @@ async function runStore(pos, flags, io2, deps) {
|
|
|
160819
160908
|
});
|
|
160820
160909
|
}
|
|
160821
160910
|
if (waited >= deadline) {
|
|
160822
|
-
return
|
|
160911
|
+
return fail5(
|
|
160823
160912
|
`build ${uploaded.build} never appeared in App Store Connect after ${Math.round(deadline / 6e4)} minutes. A binary rejected during processing leaves no record and the reason is emailed, not exposed by the API \u2014 check the Apple ID inbox for team ${creds.team}.`,
|
|
160824
160913
|
{ app, build: uploaded.build, uploaded: true, processed: false }
|
|
160825
160914
|
);
|
|
@@ -165391,7 +165480,7 @@ async function ownerPass(appId2, ports, sample) {
|
|
|
165391
165480
|
const gaps = [];
|
|
165392
165481
|
const r2 = { identity: {}, entities: [], functions: [], agents: [], connectors: [], secrets: [], routes: [], sourceFiles: [], gaps };
|
|
165393
165482
|
const client2 = api(ports, appId2);
|
|
165394
|
-
const
|
|
165483
|
+
const fail5 = (chapter, e2) => {
|
|
165395
165484
|
gaps.push({ chapter, reason: e2.message });
|
|
165396
165485
|
};
|
|
165397
165486
|
try {
|
|
@@ -165407,7 +165496,7 @@ async function ownerPass(appId2, ports, sample) {
|
|
|
165407
165496
|
source: "rest"
|
|
165408
165497
|
};
|
|
165409
165498
|
} catch (e2) {
|
|
165410
|
-
|
|
165499
|
+
fail5("auth", e2);
|
|
165411
165500
|
}
|
|
165412
165501
|
let files = /* @__PURE__ */ new Map();
|
|
165413
165502
|
if (!ports.downloadSource) {
|
|
@@ -165424,7 +165513,7 @@ async function ownerPass(appId2, ports, sample) {
|
|
|
165424
165513
|
files = new Map(kept.map((e2) => [e2.path, e2.bytes.toString("utf8")]));
|
|
165425
165514
|
r2.source = { root: "source", files: kept.length, denied: skipped.map((p2) => p2.split("\\").join("/")), secretFlagged: flagged };
|
|
165426
165515
|
} catch (e2) {
|
|
165427
|
-
|
|
165516
|
+
fail5("source", e2);
|
|
165428
165517
|
} finally {
|
|
165429
165518
|
dl2?.cleanup();
|
|
165430
165519
|
}
|
|
@@ -165458,13 +165547,13 @@ async function ownerPass(appId2, ports, sample) {
|
|
|
165458
165547
|
if (typeof f2.name !== "string" || r2.functions.some((x2) => x2.name === f2.name)) continue;
|
|
165459
165548
|
r2.functions.push({ name: f2.name, kind: "unknown", invoke: `base44.functions.invoke(${JSON.stringify(f2.name)}, payload)`, ...typeof f2.entry === "string" ? { sourcePath: f2.entry } : {}, source: "rest" });
|
|
165460
165549
|
}
|
|
165461
|
-
} else if (!r2.functions.length)
|
|
165550
|
+
} else if (!r2.functions.length) fail5("functions", fnList.reason);
|
|
165462
165551
|
if (agentList.status === "fulfilled") {
|
|
165463
165552
|
for (const cfg of agentList.value.items ?? []) {
|
|
165464
165553
|
const a2 = agentFromConfig(cfg, "rest");
|
|
165465
165554
|
if (a2 && !r2.agents.some((x2) => x2.name === a2.name)) r2.agents.push(a2);
|
|
165466
165555
|
}
|
|
165467
|
-
} else if (!r2.agents.length)
|
|
165556
|
+
} else if (!r2.agents.length) fail5("agents", agentList.reason);
|
|
165468
165557
|
if (connList.status === "fulfilled") {
|
|
165469
165558
|
for (const c2 of connList.value.integrations ?? []) {
|
|
165470
165559
|
const type = typeof c2.integration_type === "string" ? c2.integration_type : void 0;
|
|
@@ -165477,9 +165566,9 @@ async function ownerPass(appId2, ports, sample) {
|
|
|
165477
165566
|
if (!existing.scopes.length) existing.scopes = scopes;
|
|
165478
165567
|
} else r2.connectors.push({ type, scopes, ...status ? { status } : {}, source: "rest" });
|
|
165479
165568
|
}
|
|
165480
|
-
} else if (!r2.connectors.length)
|
|
165569
|
+
} else if (!r2.connectors.length) fail5("connectors", connList.reason);
|
|
165481
165570
|
if (secretMap.status === "fulfilled") r2.secrets = Object.keys(secretMap.value ?? {}).sort();
|
|
165482
|
-
else
|
|
165571
|
+
else fail5("secrets", secretMap.reason);
|
|
165483
165572
|
if (sample > 0 && samples.status === "fulfilled") {
|
|
165484
165573
|
const refused2 = [];
|
|
165485
165574
|
samples.value.forEach((settled, i2) => {
|
|
@@ -169638,6 +169727,436 @@ var init_cli = __esm({
|
|
|
169638
169727
|
}
|
|
169639
169728
|
});
|
|
169640
169729
|
|
|
169730
|
+
// ../../apps/himi-spaces-lite/spaces-host-manifest.ts
|
|
169731
|
+
var SPACES_HOST_MANIFEST;
|
|
169732
|
+
var init_spaces_host_manifest = __esm({
|
|
169733
|
+
"../../apps/himi-spaces-lite/spaces-host-manifest.ts"() {
|
|
169734
|
+
SPACES_HOST_MANIFEST = {
|
|
169735
|
+
"version": "1.3.0",
|
|
169736
|
+
"capabilities": [
|
|
169737
|
+
"animation",
|
|
169738
|
+
"app_info",
|
|
169739
|
+
"base44",
|
|
169740
|
+
"browser_auth",
|
|
169741
|
+
"calendar",
|
|
169742
|
+
"clipboard",
|
|
169743
|
+
"file_picker",
|
|
169744
|
+
"files",
|
|
169745
|
+
"godot",
|
|
169746
|
+
"haptics",
|
|
169747
|
+
"himi_apps",
|
|
169748
|
+
"iap",
|
|
169749
|
+
"keyboard",
|
|
169750
|
+
"live_activity",
|
|
169751
|
+
"local_database",
|
|
169752
|
+
"media_playback",
|
|
169753
|
+
"motion",
|
|
169754
|
+
"on_device_ai",
|
|
169755
|
+
"open_url",
|
|
169756
|
+
"pdf",
|
|
169757
|
+
"presigned_upload",
|
|
169758
|
+
"push",
|
|
169759
|
+
"release_control",
|
|
169760
|
+
"secure_storage",
|
|
169761
|
+
"share",
|
|
169762
|
+
"speaker_diarization",
|
|
169763
|
+
"stream",
|
|
169764
|
+
"theme",
|
|
169765
|
+
"ui",
|
|
169766
|
+
"wix_api",
|
|
169767
|
+
"wix_cashier",
|
|
169768
|
+
"wix_platform"
|
|
169769
|
+
],
|
|
169770
|
+
"unlinked": {
|
|
169771
|
+
"ios": [
|
|
169772
|
+
"animation",
|
|
169773
|
+
"base44",
|
|
169774
|
+
"browser_auth",
|
|
169775
|
+
"file_picker",
|
|
169776
|
+
"files",
|
|
169777
|
+
"godot",
|
|
169778
|
+
"himi_apps",
|
|
169779
|
+
"keyboard",
|
|
169780
|
+
"on_device_ai",
|
|
169781
|
+
"pdf",
|
|
169782
|
+
"presigned_upload",
|
|
169783
|
+
"speaker_diarization",
|
|
169784
|
+
"ui",
|
|
169785
|
+
"wix-native",
|
|
169786
|
+
"wix_cashier"
|
|
169787
|
+
],
|
|
169788
|
+
"macos": [
|
|
169789
|
+
"animation",
|
|
169790
|
+
"base44",
|
|
169791
|
+
"browser_auth",
|
|
169792
|
+
"calendar",
|
|
169793
|
+
"file_picker",
|
|
169794
|
+
"files",
|
|
169795
|
+
"godot",
|
|
169796
|
+
"himi_apps",
|
|
169797
|
+
"iap",
|
|
169798
|
+
"keyboard",
|
|
169799
|
+
"live_activity",
|
|
169800
|
+
"motion",
|
|
169801
|
+
"on_device_ai",
|
|
169802
|
+
"pdf",
|
|
169803
|
+
"presigned_upload",
|
|
169804
|
+
"push",
|
|
169805
|
+
"speaker_diarization",
|
|
169806
|
+
"ui",
|
|
169807
|
+
"wix-native",
|
|
169808
|
+
"wix_cashier"
|
|
169809
|
+
],
|
|
169810
|
+
"android": [
|
|
169811
|
+
"animation",
|
|
169812
|
+
"base44",
|
|
169813
|
+
"browser_auth",
|
|
169814
|
+
"file_picker",
|
|
169815
|
+
"files",
|
|
169816
|
+
"godot",
|
|
169817
|
+
"himi_apps",
|
|
169818
|
+
"keyboard",
|
|
169819
|
+
"on_device_ai",
|
|
169820
|
+
"pdf",
|
|
169821
|
+
"presigned_upload",
|
|
169822
|
+
"speaker_diarization",
|
|
169823
|
+
"ui",
|
|
169824
|
+
"wix-native",
|
|
169825
|
+
"wix_cashier"
|
|
169826
|
+
],
|
|
169827
|
+
"web": []
|
|
169828
|
+
},
|
|
169829
|
+
"nativeComponents": [
|
|
169830
|
+
"himi_spaces_lite.HimiSpacesLiteCard"
|
|
169831
|
+
],
|
|
169832
|
+
"authProviders": [
|
|
169833
|
+
"wix-consumer",
|
|
169834
|
+
"wix-native"
|
|
169835
|
+
],
|
|
169836
|
+
"nativeActions": [
|
|
169837
|
+
"himi_spaces_lite.greet"
|
|
169838
|
+
]
|
|
169839
|
+
};
|
|
169840
|
+
}
|
|
169841
|
+
});
|
|
169842
|
+
|
|
169843
|
+
// ../../core/ts/src/host-compatibility.ts
|
|
169844
|
+
function compareVersion(a2, b2) {
|
|
169845
|
+
const parts = (v2) => v2.split("-")[0].split(".").map((p2) => /^\d+$/.test(p2) ? Number(p2) : 0);
|
|
169846
|
+
const av = parts(a2);
|
|
169847
|
+
const bv = parts(b2);
|
|
169848
|
+
for (let i2 = 0; i2 < Math.max(av.length, bv.length); i2 += 1) {
|
|
169849
|
+
if ((av[i2] ?? 0) !== (bv[i2] ?? 0)) return (av[i2] ?? 0) - (bv[i2] ?? 0);
|
|
169850
|
+
}
|
|
169851
|
+
return 0;
|
|
169852
|
+
}
|
|
169853
|
+
function claimsFor(host, shell) {
|
|
169854
|
+
const gaps = shell && host.unlinked[shell] ? host.unlinked[shell] : [...host.unlinked.ios ?? [], ...host.unlinked.android ?? []];
|
|
169855
|
+
const served = (ids) => ids.filter((id) => !gaps.includes(id));
|
|
169856
|
+
return { capabilities: served(host.capabilities), nativeComponents: served(host.nativeComponents), authProviders: served(host.authProviders) };
|
|
169857
|
+
}
|
|
169858
|
+
function missingClaims(requirements, offered) {
|
|
169859
|
+
const out2 = {};
|
|
169860
|
+
for (const kind of HOST_CLAIM_KINDS) {
|
|
169861
|
+
const has = new Set(offered[kind]);
|
|
169862
|
+
out2[kind] = [...new Set(requirements[kind].filter((id) => !has.has(id)))];
|
|
169863
|
+
}
|
|
169864
|
+
return out2;
|
|
169865
|
+
}
|
|
169866
|
+
function missingReasons(missing, hostName = "the host") {
|
|
169867
|
+
const reasons = [];
|
|
169868
|
+
if (missing.capabilities.length) reasons.push(`Missing capabilities: ${missing.capabilities.join(", ")}`);
|
|
169869
|
+
if (missing.nativeComponents.length) reasons.push(`Native components not compiled into ${hostName}: ${missing.nativeComponents.join(", ")}`);
|
|
169870
|
+
if (missing.authProviders.length) reasons.push(`Unsupported auth providers: ${missing.authProviders.join(", ")}`);
|
|
169871
|
+
return reasons;
|
|
169872
|
+
}
|
|
169873
|
+
function checkHostCompatibility(requirements, host, options = {}) {
|
|
169874
|
+
const hostName = options.hostName ?? "the host";
|
|
169875
|
+
const reasons = missingReasons(missingClaims(requirements, claimsFor(host, options.shell)), hostName);
|
|
169876
|
+
const running = options.installedVersion || host.version;
|
|
169877
|
+
if (requirements.minBinaryVersion && compareVersion(running, requirements.minBinaryVersion) < 0) {
|
|
169878
|
+
reasons.push(`Requires ${hostName} ${requirements.minBinaryVersion} or newer (installed ${running})`);
|
|
169879
|
+
}
|
|
169880
|
+
if (options.requiresHostIdentity && !requirements.hostProvidedIdentity) {
|
|
169881
|
+
reasons.push(`Does not accept ${hostName}'s sign-in: the app must take its identity from the host (hostProvided)`);
|
|
169882
|
+
}
|
|
169883
|
+
return reasons.length ? { ok: false, reason: reasons.join("; "), reasons } : { ok: true };
|
|
169884
|
+
}
|
|
169885
|
+
var HOST_CLAIM_KINDS;
|
|
169886
|
+
var init_host_compatibility = __esm({
|
|
169887
|
+
"../../core/ts/src/host-compatibility.ts"() {
|
|
169888
|
+
init_registry_app_normalize();
|
|
169889
|
+
HOST_CLAIM_KINDS = PLAYER_REQUIREMENT_KINDS;
|
|
169890
|
+
}
|
|
169891
|
+
});
|
|
169892
|
+
|
|
169893
|
+
// ../../core/dev-server/tier5-bundles-src/_shared/branded-lite-hosted.ts
|
|
169894
|
+
var VERTICAL_ROOT_SCREENS, VERTICALS;
|
|
169895
|
+
var init_branded_lite_hosted = __esm({
|
|
169896
|
+
"../../core/dev-server/tier5-bundles-src/_shared/branded-lite-hosted.ts"() {
|
|
169897
|
+
VERTICAL_ROOT_SCREENS = {
|
|
169898
|
+
store: ["himi_shop"],
|
|
169899
|
+
bookings: ["himi_services"],
|
|
169900
|
+
restaurants: ["himi_menu", "himi_reserve"],
|
|
169901
|
+
programs: ["himi_programs"],
|
|
169902
|
+
plans: ["himi_plans"],
|
|
169903
|
+
feed: ["himi_feed"],
|
|
169904
|
+
members: ["himi_members"],
|
|
169905
|
+
forum: ["himi_forum"],
|
|
169906
|
+
coupons: ["himi_coupons"],
|
|
169907
|
+
notifications: ["himi_notifications"],
|
|
169908
|
+
loyalty: ["himi_loyalty"],
|
|
169909
|
+
reviews: ["himi_reviews"],
|
|
169910
|
+
portfolio: ["himi_portfolio"],
|
|
169911
|
+
reservations: ["himi_reservations"],
|
|
169912
|
+
invoices: ["himi_invoices"],
|
|
169913
|
+
badges: ["himi_badges"],
|
|
169914
|
+
notifsettings: ["himi_notif_settings"],
|
|
169915
|
+
events: ["himi_events"],
|
|
169916
|
+
blog: ["himi_blog"],
|
|
169917
|
+
groups: ["himi_groups"],
|
|
169918
|
+
cms: ["himi_cms"],
|
|
169919
|
+
donations: ["himi_donations"],
|
|
169920
|
+
giftCards: ["himi_gift_cards"],
|
|
169921
|
+
videos: ["himi_videos"],
|
|
169922
|
+
podcasts: ["himi_podcasts"],
|
|
169923
|
+
forms: ["himi_forms"],
|
|
169924
|
+
galleries: ["himi_galleries"],
|
|
169925
|
+
inbox: ["himi_inbox"],
|
|
169926
|
+
faq: ["himi_faq"]
|
|
169927
|
+
};
|
|
169928
|
+
VERTICALS = new Set(Object.keys(VERTICAL_ROOT_SCREENS));
|
|
169929
|
+
}
|
|
169930
|
+
});
|
|
169931
|
+
|
|
169932
|
+
// ../../apps/himi-branded-lite/hosted-mode.ts
|
|
169933
|
+
var init_hosted_mode = __esm({
|
|
169934
|
+
"../../apps/himi-branded-lite/hosted-mode.ts"() {
|
|
169935
|
+
init_branded_lite_hosted();
|
|
169936
|
+
}
|
|
169937
|
+
});
|
|
169938
|
+
|
|
169939
|
+
// ../../apps/himi-branded-lite/site-provisioning.ts
|
|
169940
|
+
var init_site_provisioning = __esm({
|
|
169941
|
+
"../../apps/himi-branded-lite/site-provisioning.ts"() {
|
|
169942
|
+
}
|
|
169943
|
+
});
|
|
169944
|
+
|
|
169945
|
+
// ../../apps/himi-spaces-lite/site-open.ts
|
|
169946
|
+
var HOSTED_MEMBER_APP;
|
|
169947
|
+
var init_site_open = __esm({
|
|
169948
|
+
"../../apps/himi-spaces-lite/site-open.ts"() {
|
|
169949
|
+
init_hosted_mode();
|
|
169950
|
+
init_site_provisioning();
|
|
169951
|
+
HOSTED_MEMBER_APP = "himi-branded-lite";
|
|
169952
|
+
}
|
|
169953
|
+
});
|
|
169954
|
+
|
|
169955
|
+
// ../../apps/himi-spaces-lite/site-app.ts
|
|
169956
|
+
function siteAppPickFrom(value) {
|
|
169957
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return void 0;
|
|
169958
|
+
const appId2 = value.appId;
|
|
169959
|
+
if (appId2 === null) return null;
|
|
169960
|
+
if (typeof appId2 !== "string") return void 0;
|
|
169961
|
+
const id = appId2.trim();
|
|
169962
|
+
return APP_ID3.test(id) ? id : void 0;
|
|
169963
|
+
}
|
|
169964
|
+
function siteAppRequirementsFrom(appId2, entry) {
|
|
169965
|
+
if (typeof entry !== "object" || entry === null || Array.isArray(entry)) return { ok: false, reason: `No release of ${appId2} to judge` };
|
|
169966
|
+
const e2 = entry;
|
|
169967
|
+
const names = e2.id !== void 0 ? e2.id : e2.app;
|
|
169968
|
+
if (names !== appId2) return { ok: false, reason: `No release of ${appId2} to judge` };
|
|
169969
|
+
if (!isPlayerRequirements(e2.playerRequirements)) {
|
|
169970
|
+
return { ok: false, reason: e2.playerRequirements === void 0 ? `${appId2}'s release does not declare what it requires (republish it)` : `${appId2}'s release declares malformed requirements` };
|
|
169971
|
+
}
|
|
169972
|
+
const minBinaryVersion = typeof e2.minBinaryVersion === "string" && e2.minBinaryVersion ? e2.minBinaryVersion : void 0;
|
|
169973
|
+
return {
|
|
169974
|
+
ok: true,
|
|
169975
|
+
requirements: {
|
|
169976
|
+
capabilities: [...e2.playerRequirements.capabilities],
|
|
169977
|
+
nativeComponents: [...e2.playerRequirements.nativeComponents],
|
|
169978
|
+
authProviders: [...e2.playerRequirements.authProviders],
|
|
169979
|
+
...minBinaryVersion ? { minBinaryVersion } : {},
|
|
169980
|
+
// Only an explicit `true` counts: an app that signs in by itself would ask a member to sign
|
|
169981
|
+
// in again inside Spaces, with an identity Spaces does not lend (#4088).
|
|
169982
|
+
...e2.hostProvidedIdentity === true ? { hostProvidedIdentity: true } : {}
|
|
169983
|
+
}
|
|
169984
|
+
};
|
|
169985
|
+
}
|
|
169986
|
+
function messageOf2(err) {
|
|
169987
|
+
const message = err?.message;
|
|
169988
|
+
return typeof message === "string" && message ? message : String(err);
|
|
169989
|
+
}
|
|
169990
|
+
function decideSiteApp(input) {
|
|
169991
|
+
const fallback = (pickedAppId, reason) => ({ appId: DEFAULT_SITE_APP, source: "fallback", pickedAppId, reason });
|
|
169992
|
+
if (input.pick === void 0) return { appId: DEFAULT_SITE_APP, source: "default" };
|
|
169993
|
+
if (!input.pick.ok) return fallback(null, `Could not read the site's member app: ${messageOf2(input.pick.error)}`);
|
|
169994
|
+
const picked = siteAppPickFrom(input.pick.value);
|
|
169995
|
+
if (picked === void 0) return fallback(null, "The site's member app setting is unreadable");
|
|
169996
|
+
if (picked === null || picked === DEFAULT_SITE_APP) return { appId: DEFAULT_SITE_APP, source: "default" };
|
|
169997
|
+
if (input.release === void 0) return fallback(picked, `No release of ${picked} to judge`);
|
|
169998
|
+
if (!input.release.ok) return fallback(picked, `Could not read ${picked}'s release: ${messageOf2(input.release.error)}`);
|
|
169999
|
+
const req = siteAppRequirementsFrom(picked, input.release.value);
|
|
170000
|
+
if (!req.ok) return fallback(picked, req.reason);
|
|
170001
|
+
const verdict = checkHostCompatibility(req.requirements, input.host, {
|
|
170002
|
+
hostName: "Spaces",
|
|
170003
|
+
requiresHostIdentity: true,
|
|
170004
|
+
...input.shell ? { shell: input.shell } : {},
|
|
170005
|
+
...input.installedVersion ? { installedVersion: input.installedVersion } : {}
|
|
170006
|
+
});
|
|
170007
|
+
if (!verdict.ok) return fallback(picked, verdict.reason);
|
|
170008
|
+
if (!(input.hostable ?? NATIVELY_HOSTABLE_APPS).includes(picked)) {
|
|
170009
|
+
return fallback(picked, `This Spaces build cannot host a custom member app yet (${picked} is compatible)`);
|
|
170010
|
+
}
|
|
170011
|
+
return { appId: picked, source: "picked" };
|
|
170012
|
+
}
|
|
170013
|
+
var DEFAULT_SITE_APP, NATIVELY_HOSTABLE_APPS, APP_ID3;
|
|
170014
|
+
var init_site_app = __esm({
|
|
170015
|
+
"../../apps/himi-spaces-lite/site-app.ts"() {
|
|
170016
|
+
init_host_compatibility();
|
|
170017
|
+
init_registry_app_normalize();
|
|
170018
|
+
init_site_open();
|
|
170019
|
+
DEFAULT_SITE_APP = HOSTED_MEMBER_APP;
|
|
170020
|
+
NATIVELY_HOSTABLE_APPS = [DEFAULT_SITE_APP];
|
|
170021
|
+
APP_ID3 = /^[a-z0-9][a-z0-9._-]{0,127}$/i;
|
|
170022
|
+
}
|
|
170023
|
+
});
|
|
170024
|
+
|
|
170025
|
+
// src/site-member-app.ts
|
|
170026
|
+
var site_member_app_exports = {};
|
|
170027
|
+
__export(site_member_app_exports, {
|
|
170028
|
+
SITE_MEMBER_APP_CODES: () => SITE_MEMBER_APP_CODES,
|
|
170029
|
+
SITE_MEMBER_APP_USAGE: () => SITE_MEMBER_APP_USAGE,
|
|
170030
|
+
SPACES_DEFAULT_APP: () => SPACES_DEFAULT_APP,
|
|
170031
|
+
memberAppVerdict: () => memberAppVerdict,
|
|
170032
|
+
runSiteMemberApp: () => runSiteMemberApp
|
|
170033
|
+
});
|
|
170034
|
+
function codeFor(status, serverError) {
|
|
170035
|
+
if (serverError === "forbidden_site" || serverError === "forbidden_app" || serverError === "app_bound_to_other_site") return serverError;
|
|
170036
|
+
if (status === 401) return "unauthorized";
|
|
170037
|
+
return "request_failed";
|
|
170038
|
+
}
|
|
170039
|
+
function memberAppVerdict(appId2, release2, shell) {
|
|
170040
|
+
if (!appId2 || appId2 === SPACES_DEFAULT_APP) return { opens: SPACES_DEFAULT_APP, compatible: null };
|
|
170041
|
+
const input = {
|
|
170042
|
+
pick: { ok: true, value: { appId: appId2 } },
|
|
170043
|
+
...release2 !== void 0 ? { release: { ok: true, value: release2 } } : {},
|
|
170044
|
+
host: SPACES_HOST_MANIFEST,
|
|
170045
|
+
...shell ? { shell } : {}
|
|
170046
|
+
};
|
|
170047
|
+
const fits = decideSiteApp({ ...input, hostable: [SPACES_DEFAULT_APP, appId2] });
|
|
170048
|
+
const opens = decideSiteApp(input);
|
|
170049
|
+
return {
|
|
170050
|
+
opens: opens.appId,
|
|
170051
|
+
compatible: fits.source === "picked",
|
|
170052
|
+
...opens.source === "fallback" ? { reason: opens.reason } : {}
|
|
170053
|
+
};
|
|
170054
|
+
}
|
|
170055
|
+
async function runSiteMemberApp(input, deps = {}) {
|
|
170056
|
+
const op = input.op;
|
|
170057
|
+
if (op !== "set" && op !== "clear" && op !== "show") {
|
|
170058
|
+
return fail4("invalid_usage", op ? `unknown site member-app op "${op}"` : "site member-app needs an op: set | clear | show", { usage: SITE_MEMBER_APP_USAGE });
|
|
170059
|
+
}
|
|
170060
|
+
const site = input.site;
|
|
170061
|
+
if (!site || !SITE_RE2.test(site)) return fail4("invalid_usage", "a metaSiteId (UUID) is required", { usage: SITE_MEMBER_APP_USAGE });
|
|
170062
|
+
if (op === "set" && !input.app) return fail4("invalid_usage", "set needs --app <id>", { usage: SITE_MEMBER_APP_USAGE });
|
|
170063
|
+
if (op === "set" && !isValidAppId(input.app)) return fail4("invalid_usage", `--app "${input.app}" is not a valid app id`, { usage: SITE_MEMBER_APP_USAGE });
|
|
170064
|
+
if (input.shell !== void 0 && input.shell !== "ios" && input.shell !== "android") {
|
|
170065
|
+
return fail4("invalid_usage", `--platform must be ios or android (got "${input.shell}")`, { usage: SITE_MEMBER_APP_USAGE });
|
|
170066
|
+
}
|
|
170067
|
+
let target;
|
|
170068
|
+
try {
|
|
170069
|
+
target = (deps.resolve ?? resolveTarget)({ target: input.target, defaultTarget: input.defaultTarget, controlUrl: input.controlUrl, controlToken: input.controlToken });
|
|
170070
|
+
} catch (err) {
|
|
170071
|
+
return fail4("invalid_usage", err.message);
|
|
170072
|
+
}
|
|
170073
|
+
const insecure = credentialHostRefusal(target.control);
|
|
170074
|
+
if (insecure) return fail4("insecure_target", insecure);
|
|
170075
|
+
if (!target.controlToken) return fail4("control_token_required", "no control token \u2014 run `himi login` (or pass --control-token)");
|
|
170076
|
+
let wixToken;
|
|
170077
|
+
try {
|
|
170078
|
+
wixToken = await (deps.wixToken ?? accountToken)();
|
|
170079
|
+
} catch {
|
|
170080
|
+
return fail4("wix_token_unavailable", "could not mint the account's Wix token (`wix token`) \u2014 the publishing service needs it to verify you own the site");
|
|
170081
|
+
}
|
|
170082
|
+
const fetchImpl = deps.fetchImpl ?? fetch;
|
|
170083
|
+
const control = target.control.replace(/\/+$/, "");
|
|
170084
|
+
const url = `${control}/v1/admin/site/member-app${op === "set" ? "" : `?site=${encodeURIComponent(site)}`}`;
|
|
170085
|
+
let status;
|
|
170086
|
+
let body;
|
|
170087
|
+
try {
|
|
170088
|
+
const response = await fetchImpl(url, {
|
|
170089
|
+
method: op === "set" ? "PUT" : op === "clear" ? "DELETE" : "GET",
|
|
170090
|
+
redirect: "error",
|
|
170091
|
+
signal: AbortSignal.timeout(3e4),
|
|
170092
|
+
headers: {
|
|
170093
|
+
"content-type": "application/json",
|
|
170094
|
+
"x-control-token": target.controlToken,
|
|
170095
|
+
Authorization: wixToken,
|
|
170096
|
+
...target.previewRoute ? { "x-wix-route-serve": target.previewRoute } : {}
|
|
170097
|
+
},
|
|
170098
|
+
...op === "set" ? { body: JSON.stringify({ site, app: input.app }) } : {}
|
|
170099
|
+
});
|
|
170100
|
+
status = response.status;
|
|
170101
|
+
body = await response.json().catch(() => ({}));
|
|
170102
|
+
} catch {
|
|
170103
|
+
return fail4("control_unreachable", `could not reach the publishing service at ${control}`);
|
|
170104
|
+
}
|
|
170105
|
+
if (status < 200 || status >= 300) {
|
|
170106
|
+
return fail4(
|
|
170107
|
+
codeFor(status, body.error),
|
|
170108
|
+
typeof body.error === "string" ? body.error : `HTTP ${status}`,
|
|
170109
|
+
{ status, ...typeof body.error === "string" ? { serverError: body.error } : {} }
|
|
170110
|
+
);
|
|
170111
|
+
}
|
|
170112
|
+
if (op !== "show") return { ok: true, ...body };
|
|
170113
|
+
const pick2 = body.memberAppInSpaces;
|
|
170114
|
+
const appId2 = typeof pick2?.appId === "string" ? pick2.appId : null;
|
|
170115
|
+
let release2;
|
|
170116
|
+
if (appId2 && appId2 !== SPACES_DEFAULT_APP && !body.invalid) {
|
|
170117
|
+
try {
|
|
170118
|
+
const response = await fetchImpl(`${target.serve.replace(/\/+$/, "")}/v1/release/current?app=${encodeURIComponent(appId2)}`, {
|
|
170119
|
+
redirect: "error",
|
|
170120
|
+
signal: AbortSignal.timeout(3e4),
|
|
170121
|
+
// The same deployment the pick was read from (a preview route), never production's release.
|
|
170122
|
+
...target.previewRoute ? { headers: { "x-wix-route-serve": target.previewRoute } } : {}
|
|
170123
|
+
});
|
|
170124
|
+
release2 = response.ok ? await response.json() : void 0;
|
|
170125
|
+
} catch {
|
|
170126
|
+
release2 = void 0;
|
|
170127
|
+
}
|
|
170128
|
+
}
|
|
170129
|
+
const verdict = body.invalid ? { opens: SPACES_DEFAULT_APP, compatible: false, reason: `The pick is no longer valid (${String(body.invalid)}): the site resolves to Branded Lite` } : memberAppVerdict(appId2, release2, input.shell);
|
|
170130
|
+
return { ok: true, ...body, ...verdict, host: { name: "Spaces", version: SPACES_HOST_MANIFEST.version, ...input.shell ? { shell: input.shell } : {} } };
|
|
170131
|
+
}
|
|
170132
|
+
var SPACES_DEFAULT_APP, SITE_MEMBER_APP_USAGE, SITE_MEMBER_APP_CODES, SITE_RE2, fail4;
|
|
170133
|
+
var init_site_member_app = __esm({
|
|
170134
|
+
"src/site-member-app.ts"() {
|
|
170135
|
+
init_config();
|
|
170136
|
+
init_credential_hosts();
|
|
170137
|
+
init_contract();
|
|
170138
|
+
init_spaces_host_manifest();
|
|
170139
|
+
init_site_app();
|
|
170140
|
+
init_wix_owner();
|
|
170141
|
+
SPACES_DEFAULT_APP = DEFAULT_SITE_APP;
|
|
170142
|
+
SITE_MEMBER_APP_USAGE = "himi site member-app set <site> --app <id> | clear <site> | show <site> [--platform ios|android] [--target <name>] [--control-url <url>] [--control-token <t>] (<site> may be given as --site <msid>)";
|
|
170143
|
+
SITE_MEMBER_APP_CODES = [
|
|
170144
|
+
"invalid_usage",
|
|
170145
|
+
"insecure_target",
|
|
170146
|
+
"control_token_required",
|
|
170147
|
+
"wix_token_unavailable",
|
|
170148
|
+
"forbidden_site",
|
|
170149
|
+
"forbidden_app",
|
|
170150
|
+
"app_bound_to_other_site",
|
|
170151
|
+
"unauthorized",
|
|
170152
|
+
"control_unreachable",
|
|
170153
|
+
"request_failed"
|
|
170154
|
+
];
|
|
170155
|
+
SITE_RE2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
|
|
170156
|
+
fail4 = (code, error, extra = {}) => ({ ok: false, code, error, ...extra });
|
|
170157
|
+
}
|
|
170158
|
+
});
|
|
170159
|
+
|
|
169641
170160
|
// src/site-analyze/visitor-auth.ts
|
|
169642
170161
|
async function mintVisitorToken(fetchImpl, clientId) {
|
|
169643
170162
|
const res = await fetchImpl(`${WIX_API3}/oauth2/token`, {
|
|
@@ -176397,7 +176916,7 @@ var COMMANDS2 = [
|
|
|
176397
176916
|
{ name: "connector", summary: "personal access tokens for the hosted MCP connector (Wix Native App Builder), for an AI tool that cannot sign in with OAuth (e.g. Base44's builder): `token create` opens a Wix sign-in page and prints a long-lived token once, to paste into the tool as `Authorization: Bearer <token>`; `token list` / `token revoke <id>` manage them with the `himi login --browser` token. The token can only build and publish DRAFTS.", required: "token create [--name <n>] [--days <1-90>] [--no-open] | token list | token revoke <id> [--target <t>]" },
|
|
176398
176917
|
{ name: "notify", summary: "Hosted --all-members requires --yes for a live send; --dry-run checks ownership/readiness and counts approved recipients without sending. `setup` optionally configures Branded/Ping from local customer key files; `status --refresh` reads live backend readiness. Setup may be deferred while building. These use serve-control and require owner plus Wix account authentication. `send`, `tokens`, `doctor`: send a REAL push notification to registered devices (RFC 0036 WS5) \u2014 APNs .p8 over HTTP/2 for iOS, FCM v1 for Android. `send` targets one device (--token / --device <registry id>) or fans out to the whole app (--all), reporting a per-device result; a token the provider says is uninstalled (APNs 410 Unregistered / FCM UNREGISTERED) is auto-disabled, while a merely wrong one (BadDeviceToken \u2014 usually a sandbox/production mismatch) is recorded and left enabled. `tokens` lists the registry. `doctor` reports which credentials resolve and which sender each platform picks. Talks to the admin-server via --admin-url/HIMALAYA_ADMIN_URL, authenticated with --admin-session/HIMALAYA_ADMIN_SESSION. `send --provider ping` is the hosted alternative: the serve plane sends to one site member (--member-email) or all approved members (--all-members) through Ping as Himalaya, with owner login instead of provider keys, and reports acceptance, never delivery. NOT `himi push`, which publishes a release.", required: "setup|status [--content <dir>] [--target <t>] [--refresh] [--yes] [--no-push-setup] | send --provider ping [--content <dir>] [--app <a>] [--site <msid>] (--member-email <email> | --all-members (--dry-run | --yes)) --title <s> [--body <s>] --link <url> [--request-id <uuid>] [--dry-run] [--json] | send|tokens|doctor [--app <a>] [--token <t> | --device <id> | --all] [--title <s>] [--body <s>] [--link <url>] [--platform ios|android] [--badge <n>] [--channel <id>] [--silent] [--dry-run] [--json]" },
|
|
176399
176918
|
{ name: "signing", summary: "READ-ONLY App Store Connect inventory for customer BYO TestFlight readiness. `inspect` lists whether the bundle id, distribution certificate, IOS_APP_STORE profile, and ASC app record exist for --bundle-id / --team-id using a local ASC .p8 (flags or ASC_KEY_* env). Never uploads or mutates Apple resources. Optional --cert-file/--profile-file classify on-disk material.", required: "inspect --bundle-id <id> --team-id <id> --asc-key-file <path> --asc-key-id <id> --asc-issuer-id <id> [--cert-file <p12> --cert-password <pw> --profile-file <mobileprovision>] [--json]" },
|
|
176400
|
-
{ name: "site", summary: "PROVISION a Wix project, then analyze or extend it. `create` is the one door that makes a site instead of adopting one: POST /funnel/projects/v1/create (a WIX site, a HEADLESS backend, a BRANDED_APP, or a VIBE site), and for headless it also mints the OAuth app whose id IS the `WIX_CLIENT_ID` \u2014 with --redirect-uri already registered, because an unregistered redirect makes native signInDirect fail at redirect-session. `--verticals` REQUIRES `--template` and reports only what Wix confirmed: measured, installing onto a project created from the BLANK template returns 200 while the vertical's API answers 428 forever, because there is no site for it to attach to (the install asks for CREATE_SITE). A real template ships its verticals installed and populated, and installing further ones onto it then works. It MUTATES your Wix account and needs --yes; without it you get the payload and nothing is sent. `list` is the read-only site inventory (with each site's premium flag, which is what explains an installed-but-428 vertical). Auth is the account-scoped `wix token` (no --site), falling back to WIX_API_KEY + WIX_ACCOUNT_ID. `client` is the same OAuth step for a site that ALREADY exists \u2014 the one himi adopts rather than makes \u2014 so a clientId no longer means a manual trip to the dashboard: `client ensure` reconciles rather than mints, because a site can already carry a client with NO registered redirect and shipping that one fails signInDirect at runtime; it reuses a client that carries --redirect-uri, PATCHes one that matches --name but lacks it (unioning, so another app's redirect survives), and creates only when there is nothing to reuse (--new forces a fresh one). --name IS the idempotency key. `client` auth is SITE-scoped (`wix token --site <msid>`) because minting is owner-of-that-site, and --yes gates every mutation: a site that already has a usable client resolves WITHOUT it, but --write-provisioning needs --yes even then because it rewrites a manifest on disk (the dry run's planned.provisioning names the file). That query endpoint IGNORES paging (measured: query.paging, cursorPaging and a top-level paging all return the full set at offset 0), so when pagingMetadata reports more clients than came back, `ensure` REFUSES EVERY outcome \u2014 create, patch AND reuse. Reuse is refused too because pickClient breaks ties on the OLDEST createdDate, so an omitted older same-named MOBILE client with the same redirect would win a later complete read and the resolved clientId would MOVE between runs \u2014 and it gets written into provisioning.json; convergence is what makes a stray duplicate untidy rather than harmful. --name cannot narrow the query (no filter is sent; the name is applied to the rows after they arrive), so the recovery is the dashboard; --new skips the query entirely. A `patched` result is verified against what Wix STORED \u2014 the redirect list is read off the PATCH response, and re-read via GET when the response omits it, because falling back to the list himi just sent would make the guard pass vacuously on exactly the silent no-op it exists to catch. `client list` is the read-only inventory of a site's clients: act on its `shippable` column rather than `hasRedirect`, because shippable ALSO requires a MOBILE applicationType and `ensure` refuses a WEB client \u2014 a WEB one carrying your redirect looks right and is not a candidate \u2014 and it sets truncated:true rather than presenting a partial inventory as the whole one. `analyze --read-only` returns API-only generation context as JSON (identity, access probes, CMS permissions and selected redacted Velo source); it needs no browser and never uploads or applies anything. A URL is optional there: `--url` lets it read the published page's Velo code-app ids (credential-free, pinned transport) so the backend source is found on sites where the owner code-app probe 404s. `analyze` reads a site into a business-book folder (REST + Playwright, GET-only); `--url` alone is the visitor-only pass over the published pages, and `--client-id` adds the vertical probes and the app binding `--apply` requires; `site function` list/get/put/publish/invokes that site's Velo HTTP functions and is not `himi functions` (serve-plane jobs). `--apply` bakes into a brandable shell (a site shell needs no `--client-id`: it is visitor-only and binds no client); `--shell` takes the same names `himi dist --shell` does and defaults to branded-lite, and a shell that ships no prepare:customer is refused by name rather than half-built. `--shell brandy` (the site shell, RFC 0062) also derives the site's page map from its published pages and header menu \u2014 Home first, up to four tabs for the pages a visitor returns to, the rest in the drawer \u2014 into the overlay's `site` block, so it can be edited before `--apply`; only a site shell ever receives that block. It never overwrites any shell's committed apps/<shell>/provisioning.json.", required: "create <name> [--type wix|headless|branded-app|vibe] [--template <guid>] [--verticals stores,bookings,\u2026] [--folder <guid>] [--redirect-uri <uri>] [--no-oauth-app] [--write-provisioning [path]] [--site-url <url>] [--json] --yes | list | client ensure|list --site <msid> [--name <name>] [--redirect-uri <uri>] [--new] [--write-provisioning [path]] [--site-url <url>] [--json] --yes | analyze --read-only [--site <msid>] [--client-id <id>] [--url <https>] [--json] | analyze --url <https> [--client-id <id>] [--site <msid>] [--out <dir>] [--redirect-uri <uri>] [--apply] [--shell " + SHELL_ENUM + "] | function list|get|put|publish|invoke [--site <msid>] [--url <https>] [--method GET|POST|PUT|DELETE] [--source <file>] [--body <json>] [--publish] [--invoke]" },
|
|
176919
|
+
{ name: "site", summary: "PROVISION a Wix project, then analyze or extend it. `create` is the one door that makes a site instead of adopting one: POST /funnel/projects/v1/create (a WIX site, a HEADLESS backend, a BRANDED_APP, or a VIBE site), and for headless it also mints the OAuth app whose id IS the `WIX_CLIENT_ID` \u2014 with --redirect-uri already registered, because an unregistered redirect makes native signInDirect fail at redirect-session. `--verticals` REQUIRES `--template` and reports only what Wix confirmed: measured, installing onto a project created from the BLANK template returns 200 while the vertical's API answers 428 forever, because there is no site for it to attach to (the install asks for CREATE_SITE). A real template ships its verticals installed and populated, and installing further ones onto it then works. It MUTATES your Wix account and needs --yes; without it you get the payload and nothing is sent. `list` is the read-only site inventory (with each site's premium flag, which is what explains an installed-but-428 vertical). Auth is the account-scoped `wix token` (no --site), falling back to WIX_API_KEY + WIX_ACCOUNT_ID. `client` is the same OAuth step for a site that ALREADY exists \u2014 the one himi adopts rather than makes \u2014 so a clientId no longer means a manual trip to the dashboard: `client ensure` reconciles rather than mints, because a site can already carry a client with NO registered redirect and shipping that one fails signInDirect at runtime; it reuses a client that carries --redirect-uri, PATCHes one that matches --name but lacks it (unioning, so another app's redirect survives), and creates only when there is nothing to reuse (--new forces a fresh one). --name IS the idempotency key. `client` auth is SITE-scoped (`wix token --site <msid>`) because minting is owner-of-that-site, and --yes gates every mutation: a site that already has a usable client resolves WITHOUT it, but --write-provisioning needs --yes even then because it rewrites a manifest on disk (the dry run's planned.provisioning names the file). That query endpoint IGNORES paging (measured: query.paging, cursorPaging and a top-level paging all return the full set at offset 0), so when pagingMetadata reports more clients than came back, `ensure` REFUSES EVERY outcome \u2014 create, patch AND reuse. Reuse is refused too because pickClient breaks ties on the OLDEST createdDate, so an omitted older same-named MOBILE client with the same redirect would win a later complete read and the resolved clientId would MOVE between runs \u2014 and it gets written into provisioning.json; convergence is what makes a stray duplicate untidy rather than harmful. --name cannot narrow the query (no filter is sent; the name is applied to the rows after they arrive), so the recovery is the dashboard; --new skips the query entirely. A `patched` result is verified against what Wix STORED \u2014 the redirect list is read off the PATCH response, and re-read via GET when the response omits it, because falling back to the list himi just sent would make the guard pass vacuously on exactly the silent no-op it exists to catch. `client list` is the read-only inventory of a site's clients: act on its `shippable` column rather than `hasRedirect`, because shippable ALSO requires a MOBILE applicationType and `ensure` refuses a WEB client \u2014 a WEB one carrying your redirect looks right and is not a candidate \u2014 and it sets truncated:true rather than presenting a partial inventory as the whole one. `analyze --read-only` returns API-only generation context as JSON (identity, access probes, CMS permissions and selected redacted Velo source); it needs no browser and never uploads or applies anything. A URL is optional there: `--url` lets it read the published page's Velo code-app ids (credential-free, pinned transport) so the backend source is found on sites where the owner code-app probe 404s. `analyze` reads a site into a business-book folder (REST + Playwright, GET-only); `--url` alone is the visitor-only pass over the published pages, and `--client-id` adds the vertical probes and the app binding `--apply` requires; `site function` list/get/put/publish/invokes that site's Velo HTTP functions and is not `himi functions` (serve-plane jobs). `--apply` bakes into a brandable shell (a site shell needs no `--client-id`: it is visitor-only and binds no client); `--shell` takes the same names `himi dist --shell` does and defaults to branded-lite, and a shell that ships no prepare:customer is refused by name rather than half-built. `--shell brandy` (the site shell, RFC 0062) also derives the site's page map from its published pages and header menu \u2014 Home first, up to four tabs for the pages a visitor returns to, the rest in the drawer \u2014 into the overlay's `site` block, so it can be edited before `--apply`; only a site shell ever receives that block. It never overwrites any shell's committed apps/<shell>/provisioning.json. `member-app set|clear|show <msid>` is the site's member app in Spaces (#4091): the himi app the site's members open in Spaces Lite instead of Branded Lite. `set --app <id>` takes the site's own app or one your account owns (an owned app not yet tied to the site is linked first; another account's app is refused, 403); `clear` returns the site to Branded Lite; `show` prints the pick plus the COMPUTED verdict \u2014 the picked release's requirements judged against the Spaces host manifest (checkHostCompatibility, `--platform` to judge one phone platform) \u2014 and `reason` when it falls back to Branded Lite. Auth is your `himi login` control token plus the account `wix token`, which the plane uses to verify you own the site.", required: "create <name> [--type wix|headless|branded-app|vibe] [--template <guid>] [--verticals stores,bookings,\u2026] [--folder <guid>] [--redirect-uri <uri>] [--no-oauth-app] [--write-provisioning [path]] [--site-url <url>] [--json] --yes | list | client ensure|list --site <msid> [--name <name>] [--redirect-uri <uri>] [--new] [--write-provisioning [path]] [--site-url <url>] [--json] --yes | analyze --read-only [--site <msid>] [--client-id <id>] [--url <https>] [--json] | analyze --url <https> [--client-id <id>] [--site <msid>] [--out <dir>] [--redirect-uri <uri>] [--apply] [--shell " + SHELL_ENUM + "] | function list|get|put|publish|invoke [--site <msid>] [--url <https>] [--method GET|POST|PUT|DELETE] [--source <file>] [--body <json>] [--publish] [--invoke] | member-app set|clear|show <msid> [--app <id>] [--platform ios|android]" },
|
|
176401
176920
|
{ name: "base44", summary: "read a BASE44 app into an app book (book.json + BOOK.md) for the agent building a Himi app from it \u2014 the Base44 counterpart of `site analyze`, READ-ONLY. `analyze --url <published app>` is the VISITOR pass: the app id, name, favicon and colours from the published SPA, its router paths, and screenshots + look tokens from the Playwright crawl. `analyze --app-id <id>` adds the OWNER pass and needs a session: the project source under <out>/source/ (the read half of `base44 eject` \u2014 GET api/apps/<id>/eject \u2014 through the same deny-list and secret scan `himi push` uses, widened by the book's token shapes; `eject` itself is never run because it CREATES a copy of the app), every entity's JSON schema, required fields and RLS rules with up to --sample redacted rows (default 5, 0 = off), backend functions, agents, connectors (names and scopes only, never tokens), secret NAMES (never values), auth visibility + providers, and the route \u2192 component \u2192 entities map from the source router. Every chapter it could not read is listed in `gaps` rather than failing the run. `login` runs Base44's device sign-in and stores the session in ~/.himi/base44/session.json (never the repo; --from-base44-cli imports `npx base44 login`'s session instead); BASE44_ACCESS_TOKEN in the environment wins, for CI. `whoami` prints who is signed in (never the token); `logout` removes the stored session. `auth-check --url <tenant> --ios-app-id <PREFIX.bundle.id>` and/or `--android-package <package> --android-sha256 <fingerprint>` checks public native-login associations and prints missing entries; it never reads an owner token. --json prints the book itself. himi docs base44-app-context", required: "analyze (--url <https://\u2026> | --app-id <id>) [--out .himi/base44-book] [--sample <n>] [--json] | login [--from-base44-cli] | whoami | logout | auth-check --url <https://tenant> [--ios-app-id <PREFIX.bundle.id>] [--android-package <package> --android-sha256 <fingerprint>]" },
|
|
176402
176921
|
{ name: "doctor", summary: 'off-VPN preflight in one shot: probe the PUBLIC data plane (www.wixapis.com \u2014 reachable off-VPN), the INTERNAL serve/control plane for the selected target (VPN-gated), and report auth state (dpx session on disk + stored control token). --dpx additionally runs a live, EADDRINUSE-safe `dpx whoami`. Machine-readable with --json (an unreachable internal plane carries a stable code:"needs_vpn" so an agent branches on the code, not the prose); human-readable otherwise. Never loads the authoring runtime \u2014 works off-repo.', required: "[--target <t>] [--dpx] [--json] [--data-url <url>] [--timeout <ms>]" },
|
|
176403
176922
|
{ name: "upgrade", summary: "install the newest published CLI (`npm i -g @wix/himalaya-cli@latest`) and report what moved. This is the explicit door: himi also updates itself when the running build is more than a week old \u2014 unattended it just does it and re-runs your command, at a terminal it asks first \u2014 and `HIMI_NO_UPDATE_CHECK=1` turns that off, leaving this command as the way to catch up. Reports `unchanged` rather than claiming success when npm exits 0 without moving the version, which is what a registry mirror serving its own pinned copy looks like.", required: "[--json]" },
|
|
@@ -177110,13 +177629,13 @@ function previewTelemetryUrl(serveBase, app, release2) {
|
|
|
177110
177629
|
function diagnoseBody(body) {
|
|
177111
177630
|
const findings = body.findings;
|
|
177112
177631
|
if (!Array.isArray(findings)) return body;
|
|
177113
|
-
const
|
|
177632
|
+
const messageOf3 = (entry) => {
|
|
177114
177633
|
const message = entry && typeof entry === "object" ? entry.message : void 0;
|
|
177115
177634
|
return typeof message === "string" ? message : void 0;
|
|
177116
177635
|
};
|
|
177117
|
-
const shown2 = new Set(findings.map(
|
|
177636
|
+
const shown2 = new Set(findings.map(messageOf3).filter((message) => message !== void 0));
|
|
177118
177637
|
const folded = (value) => Array.isArray(value) && value.length > 0 && value.every((entry) => {
|
|
177119
|
-
const message =
|
|
177638
|
+
const message = messageOf3(entry);
|
|
177120
177639
|
return message !== void 0 && shown2.has(message);
|
|
177121
177640
|
});
|
|
177122
177641
|
const out2 = {};
|
|
@@ -184270,6 +184789,23 @@ Code: ${userCode}`);
|
|
|
184270
184789
|
}
|
|
184271
184790
|
case "site": {
|
|
184272
184791
|
const sub = pos[1];
|
|
184792
|
+
if (sub === "member-app") {
|
|
184793
|
+
const { runSiteMemberApp: runSiteMemberApp2 } = await Promise.resolve().then(() => (init_site_member_app(), site_member_app_exports));
|
|
184794
|
+
const r2 = await runSiteMemberApp2({
|
|
184795
|
+
op: pos[2],
|
|
184796
|
+
site: pos[3] ?? str9(flags.site),
|
|
184797
|
+
app: str9(flags.app),
|
|
184798
|
+
shell: str9(flags.platform),
|
|
184799
|
+
target: str9(flags.target),
|
|
184800
|
+
// Off-repo, `himi login` stores its token under `wix`; resolve where it did.
|
|
184801
|
+
defaultTarget: contextualDefaultTarget,
|
|
184802
|
+
controlUrl: str9(flags["control-url"]),
|
|
184803
|
+
controlToken: str9(flags["control-token"])
|
|
184804
|
+
});
|
|
184805
|
+
if (r2.ok) print(r2);
|
|
184806
|
+
else io2.error(JSON.stringify(r2));
|
|
184807
|
+
return r2.ok ? 0 : r2.code === "invalid_usage" ? 2 : 1;
|
|
184808
|
+
}
|
|
184273
184809
|
if (sub === "function") {
|
|
184274
184810
|
const { runSiteFunctionCli: runSiteFunctionCli2, SITE_FUNCTION_USAGE: SITE_FUNCTION_USAGE2 } = await Promise.resolve().then(() => (init_cli2(), cli_exports2));
|
|
184275
184811
|
try {
|