@wix/himalaya-cli 0.1002.0 → 0.1003.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 +1135 -736
- package/guides/himi-test.md +1 -0
- package/guides/wix-business-context.md +27 -0
- package/package.json +2 -2
package/dist/cli.mjs
CHANGED
|
@@ -74,36 +74,36 @@ __export(config_exports, {
|
|
|
74
74
|
import { homedir } from "node:os";
|
|
75
75
|
import { join, dirname } from "node:path";
|
|
76
76
|
import { readFileSync, writeFileSync, mkdirSync, chmodSync } from "node:fs";
|
|
77
|
-
function loadTargetsFile(
|
|
77
|
+
function loadTargetsFile(path2 = defaultTargetsPath()) {
|
|
78
78
|
try {
|
|
79
|
-
return JSON.parse(readFileSync(
|
|
79
|
+
return JSON.parse(readFileSync(path2, "utf8"));
|
|
80
80
|
} catch {
|
|
81
81
|
return {};
|
|
82
82
|
}
|
|
83
83
|
}
|
|
84
|
-
function saveControlToken(target, token,
|
|
85
|
-
const file = loadTargetsFile(
|
|
84
|
+
function saveControlToken(target, token, path2 = defaultTargetsPath()) {
|
|
85
|
+
const file = loadTargetsFile(path2);
|
|
86
86
|
file.targets = file.targets ?? {};
|
|
87
87
|
file.targets[target] = { ...file.targets[target], controlToken: token };
|
|
88
|
-
writeTargetsFilePrivate(
|
|
89
|
-
return
|
|
88
|
+
writeTargetsFilePrivate(path2, file);
|
|
89
|
+
return path2;
|
|
90
90
|
}
|
|
91
|
-
function writeTargetsFilePrivate(
|
|
92
|
-
mkdirSync(dirname(
|
|
93
|
-
writeFileSync(
|
|
91
|
+
function writeTargetsFilePrivate(path2, file) {
|
|
92
|
+
mkdirSync(dirname(path2), { recursive: true, mode: 448 });
|
|
93
|
+
writeFileSync(path2, JSON.stringify(file, null, 2) + "\n", { mode: 384 });
|
|
94
94
|
try {
|
|
95
|
-
chmodSync(dirname(
|
|
96
|
-
chmodSync(
|
|
95
|
+
chmodSync(dirname(path2), 448);
|
|
96
|
+
chmodSync(path2, 384);
|
|
97
97
|
} catch {
|
|
98
98
|
}
|
|
99
99
|
}
|
|
100
|
-
function clearControlToken(target,
|
|
101
|
-
const file = loadTargetsFile(
|
|
100
|
+
function clearControlToken(target, path2 = defaultTargetsPath()) {
|
|
101
|
+
const file = loadTargetsFile(path2);
|
|
102
102
|
if (file.targets?.[target]?.controlToken) {
|
|
103
103
|
delete file.targets[target].controlToken;
|
|
104
|
-
writeFileSync(
|
|
104
|
+
writeFileSync(path2, JSON.stringify(file, null, 2) + "\n");
|
|
105
105
|
}
|
|
106
|
-
return
|
|
106
|
+
return path2;
|
|
107
107
|
}
|
|
108
108
|
function resolveTargetName(opts = {}) {
|
|
109
109
|
const env = opts.env ?? process.env;
|
|
@@ -2306,6 +2306,17 @@ var init_cms_schema = __esm({
|
|
|
2306
2306
|
});
|
|
2307
2307
|
|
|
2308
2308
|
// src/wix-owner.ts
|
|
2309
|
+
var wix_owner_exports = {};
|
|
2310
|
+
__export(wix_owner_exports, {
|
|
2311
|
+
WixApiError: () => WixApiError,
|
|
2312
|
+
accountToken: () => accountToken,
|
|
2313
|
+
mapLimit: () => mapLimit,
|
|
2314
|
+
ownerTransport: () => ownerTransport,
|
|
2315
|
+
redactForError: () => redactForError,
|
|
2316
|
+
resolveSiteId: () => resolveSiteId,
|
|
2317
|
+
siteToken: () => siteToken,
|
|
2318
|
+
withRetry: () => withRetry
|
|
2319
|
+
});
|
|
2309
2320
|
import { spawn } from "node:child_process";
|
|
2310
2321
|
function resolveSiteId(flag) {
|
|
2311
2322
|
const id = flag?.trim() || process.env.WIX_SITE_ID?.trim();
|
|
@@ -2384,7 +2395,7 @@ function mintHelp(label2, detail) {
|
|
|
2384
2395
|
return `could not run \`${label2}\` (${detail}). Install the Wix CLI and log in (\`npm i -g @wix/cli && wix login\`), or set WIX_TEST_TOKEN.`;
|
|
2385
2396
|
}
|
|
2386
2397
|
function ownerTransport(msid, fetchImpl = fetch, timeoutMs = DEFAULT_TIMEOUT_MS2) {
|
|
2387
|
-
return async (method,
|
|
2398
|
+
return async (method, path2, body) => {
|
|
2388
2399
|
const headers2 = {
|
|
2389
2400
|
Authorization: await siteToken(msid),
|
|
2390
2401
|
"wix-site-id": msid,
|
|
@@ -2394,7 +2405,7 @@ function ownerTransport(msid, fetchImpl = fetch, timeoutMs = DEFAULT_TIMEOUT_MS2
|
|
|
2394
2405
|
const started = Date.now();
|
|
2395
2406
|
let res;
|
|
2396
2407
|
try {
|
|
2397
|
-
res = await fetchImpl(`${API_BASE}${
|
|
2408
|
+
res = await fetchImpl(`${API_BASE}${path2}`, {
|
|
2398
2409
|
method,
|
|
2399
2410
|
headers: headers2,
|
|
2400
2411
|
body: body === void 0 ? void 0 : JSON.stringify(body),
|
|
@@ -2404,10 +2415,10 @@ function ownerTransport(msid, fetchImpl = fetch, timeoutMs = DEFAULT_TIMEOUT_MS2
|
|
|
2404
2415
|
const err = e;
|
|
2405
2416
|
if (err?.name === "TimeoutError" || /aborted due to timeout/i.test(err?.message ?? "")) {
|
|
2406
2417
|
throw new Error(
|
|
2407
|
-
`${method} ${
|
|
2418
|
+
`${method} ${path2} timed out after ${Date.now() - started}ms (limit ${timeoutMs}ms). Wix REST over a VPN'd link is slow and a large site's collection list can be ~1MB. Raise the ceiling with HIMI_WIX_TIMEOUT_MS=<ms>, or check the VPN.`
|
|
2408
2419
|
);
|
|
2409
2420
|
}
|
|
2410
|
-
throw new Error(`${method} ${
|
|
2421
|
+
throw new Error(`${method} ${path2} failed: ${err?.message ?? String(e)}`);
|
|
2411
2422
|
}
|
|
2412
2423
|
const text4 = await res.text();
|
|
2413
2424
|
let parsed = text4;
|
|
@@ -2415,7 +2426,7 @@ function ownerTransport(msid, fetchImpl = fetch, timeoutMs = DEFAULT_TIMEOUT_MS2
|
|
|
2415
2426
|
parsed = text4 ? JSON.parse(text4) : null;
|
|
2416
2427
|
} catch {
|
|
2417
2428
|
}
|
|
2418
|
-
if (!res.ok) throw new WixApiError(res.status, method,
|
|
2429
|
+
if (!res.ok) throw new WixApiError(res.status, method, path2, parsed);
|
|
2419
2430
|
return parsed;
|
|
2420
2431
|
};
|
|
2421
2432
|
}
|
|
@@ -2457,12 +2468,12 @@ var init_wix_owner = __esm({
|
|
|
2457
2468
|
TOKEN_MINT_TIMEOUT_MS = 3e4;
|
|
2458
2469
|
ACCOUNT_TOKEN_KEY = "account:*";
|
|
2459
2470
|
WixApiError = class extends Error {
|
|
2460
|
-
constructor(status, method,
|
|
2471
|
+
constructor(status, method, path2, body) {
|
|
2461
2472
|
const detail = typeof body === "string" ? body.slice(0, 300) : JSON.stringify(body)?.slice(0, 300);
|
|
2462
|
-
super(`${method} ${
|
|
2473
|
+
super(`${method} ${path2} -> ${status}: ${detail}`);
|
|
2463
2474
|
this.status = status;
|
|
2464
2475
|
this.method = method;
|
|
2465
|
-
this.path =
|
|
2476
|
+
this.path = path2;
|
|
2466
2477
|
this.body = body;
|
|
2467
2478
|
this.name = "WixApiError";
|
|
2468
2479
|
}
|
|
@@ -2542,8 +2553,8 @@ function homeRefreshActionId(name) {
|
|
|
2542
2553
|
function committedProvisioningPath(name) {
|
|
2543
2554
|
return `${shellAppDir(name)}/provisioning.json`;
|
|
2544
2555
|
}
|
|
2545
|
-
function committedShellFor(
|
|
2546
|
-
const normalized =
|
|
2556
|
+
function committedShellFor(path2) {
|
|
2557
|
+
const normalized = path2.replace(/\\/g, "/");
|
|
2547
2558
|
return SHELL_NAMES2.find((name) => {
|
|
2548
2559
|
const relative9 = committedProvisioningPath(name);
|
|
2549
2560
|
return normalized === relative9 || normalized.endsWith(`/${relative9}`);
|
|
@@ -3197,9 +3208,9 @@ function umbrellaRewritePlugin({ external = false } = {}) {
|
|
|
3197
3208
|
name: "himalaya-umbrella-rewrite",
|
|
3198
3209
|
setup(b) {
|
|
3199
3210
|
b.onResolve({ filter: /^@himalaya\// }, async (args) => {
|
|
3200
|
-
const
|
|
3201
|
-
if (external) return { path, external: true };
|
|
3202
|
-
return b.resolve(
|
|
3211
|
+
const path2 = args.path.replace(/^@himalaya\//, "@wix/himalaya/");
|
|
3212
|
+
if (external) return { path: path2, external: true };
|
|
3213
|
+
return b.resolve(path2, { resolveDir: args.resolveDir, kind: args.kind });
|
|
3203
3214
|
});
|
|
3204
3215
|
}
|
|
3205
3216
|
};
|
|
@@ -3232,8 +3243,8 @@ function tsExtResolvePlugin() {
|
|
|
3232
3243
|
setup(b) {
|
|
3233
3244
|
b.onResolve({ filter: /\.js$/ }, (args) => {
|
|
3234
3245
|
if (args.kind === "entry-point" || !args.path.startsWith(".")) return void 0;
|
|
3235
|
-
const
|
|
3236
|
-
return existsSync8(
|
|
3246
|
+
const ts2 = resolve8(args.resolveDir, args.path.replace(/\.js$/, ".ts"));
|
|
3247
|
+
return existsSync8(ts2) ? { path: ts2 } : void 0;
|
|
3237
3248
|
});
|
|
3238
3249
|
}
|
|
3239
3250
|
};
|
|
@@ -3949,7 +3960,7 @@ function bundleFor(file) {
|
|
|
3949
3960
|
const match = /^tier5-src\/([^/]+)\//.exec(file);
|
|
3950
3961
|
return match?.[1] ?? "_shared";
|
|
3951
3962
|
}
|
|
3952
|
-
function toIssue(
|
|
3963
|
+
function toIssue(ts2, contentDir2, diagnostic) {
|
|
3953
3964
|
const file = diagnostic.file ? relativeFile(contentDir2, diagnostic.file.fileName) : void 0;
|
|
3954
3965
|
const position = diagnostic.file && diagnostic.start !== void 0 ? diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start) : void 0;
|
|
3955
3966
|
return {
|
|
@@ -3957,13 +3968,13 @@ function toIssue(ts, contentDir2, diagnostic) {
|
|
|
3957
3968
|
...file ? { file } : {},
|
|
3958
3969
|
...position ? { line: position.line + 1, column: position.character + 1 } : {},
|
|
3959
3970
|
code: `TS${diagnostic.code}`,
|
|
3960
|
-
message:
|
|
3971
|
+
message: ts2.flattenDiagnosticMessageText(diagnostic.messageText, "\n")
|
|
3961
3972
|
};
|
|
3962
3973
|
}
|
|
3963
|
-
function confinedHost(
|
|
3974
|
+
function confinedHost(ts2, contentDir2, options) {
|
|
3964
3975
|
if (!buildConfinementRequired()) return void 0;
|
|
3965
|
-
const host =
|
|
3966
|
-
const libDir = resolve10(
|
|
3976
|
+
const host = ts2.createCompilerHost(options);
|
|
3977
|
+
const libDir = resolve10(ts2.getDefaultLibFilePath(options), "..");
|
|
3967
3978
|
const allows = confinementMatcher(contentDir2, [libDir]);
|
|
3968
3979
|
const getSourceFile = host.getSourceFile.bind(host);
|
|
3969
3980
|
const readFile3 = host.readFile.bind(host);
|
|
@@ -3991,7 +4002,7 @@ function confinedHost(ts, contentDir2, options) {
|
|
|
3991
4002
|
}
|
|
3992
4003
|
async function typecheckContentWorkers(contentDir2, options) {
|
|
3993
4004
|
if (!existsSync9(resolve10(contentDir2, "tier5-src"))) return [];
|
|
3994
|
-
const
|
|
4005
|
+
const ts2 = await compiler2();
|
|
3995
4006
|
const config = {
|
|
3996
4007
|
compilerOptions: {
|
|
3997
4008
|
...CONTENT_WORKER_COMPILER_OPTIONS,
|
|
@@ -4000,18 +4011,18 @@ async function typecheckContentWorkers(contentDir2, options) {
|
|
|
4000
4011
|
// The deployed authoring runtime stages TypeScript 6, which requires an explicit
|
|
4001
4012
|
// acknowledgement for this compatibility `baseUrl`; the repository's TypeScript 5 lane
|
|
4002
4013
|
// rejects that 6.0 value, so keep it specific to the compiler that needs it.
|
|
4003
|
-
...Number.parseInt(
|
|
4014
|
+
...Number.parseInt(ts2.versionMajorMinor, 10) >= 6 ? { ignoreDeprecations: "6.0" } : {}
|
|
4004
4015
|
},
|
|
4005
4016
|
include: ["tier5-src/*/index.ts", "tier5-src/_shared/**/*.ts"]
|
|
4006
4017
|
};
|
|
4007
|
-
const parsed =
|
|
4018
|
+
const parsed = ts2.parseJsonConfigFileContent(config, ts2.sys, contentDir2);
|
|
4008
4019
|
if (parsed.fileNames.length === 0) return [];
|
|
4009
|
-
const program =
|
|
4020
|
+
const program = ts2.createProgram({
|
|
4010
4021
|
rootNames: parsed.fileNames,
|
|
4011
4022
|
options: parsed.options,
|
|
4012
|
-
host: confinedHost(
|
|
4023
|
+
host: confinedHost(ts2, contentDir2, parsed.options)
|
|
4013
4024
|
});
|
|
4014
|
-
return [...parsed.errors, ...
|
|
4025
|
+
return [...parsed.errors, ...ts2.getPreEmitDiagnostics(program)].filter((diagnostic) => diagnostic.category === ts2.DiagnosticCategory.Error && belongsToContentWorkers(contentDir2, diagnostic)).map((diagnostic) => toIssue(ts2, contentDir2, diagnostic));
|
|
4015
4026
|
}
|
|
4016
4027
|
var compilerPromise;
|
|
4017
4028
|
var init_tier5_typecheck = __esm({
|
|
@@ -5267,47 +5278,46 @@ function buildTokenRegistry(tokens) {
|
|
|
5267
5278
|
materials: new Set(Object.keys(tokens.materials ?? {}))
|
|
5268
5279
|
};
|
|
5269
5280
|
}
|
|
5270
|
-
function findTokenViolations(payload, registry,
|
|
5281
|
+
function findTokenViolations(payload, registry, path2 = "$") {
|
|
5271
5282
|
const out = [];
|
|
5272
|
-
walk(payload, registry,
|
|
5283
|
+
walk(payload, registry, path2, out);
|
|
5273
5284
|
return out;
|
|
5274
5285
|
}
|
|
5275
|
-
function walk(node, registry,
|
|
5286
|
+
function walk(node, registry, path2, out) {
|
|
5276
5287
|
if (node === null || typeof node !== "object") return;
|
|
5277
5288
|
if (Array.isArray(node)) {
|
|
5278
|
-
node.forEach((item, i) => walk(item, registry, `${
|
|
5289
|
+
node.forEach((item, i) => walk(item, registry, `${path2}[${i}]`, out));
|
|
5279
5290
|
return;
|
|
5280
5291
|
}
|
|
5281
5292
|
const obj2 = node;
|
|
5282
5293
|
const bg = obj2.background;
|
|
5283
5294
|
if (bg && typeof bg.token === "string" && !registry.colors.has(bg.token)) {
|
|
5284
|
-
out.push({ path: `${
|
|
5295
|
+
out.push({ path: `${path2}.background.token`, kind: "color", name: bg.token });
|
|
5285
5296
|
}
|
|
5286
5297
|
if (obj2.type === "Text") {
|
|
5287
5298
|
const props = obj2.props;
|
|
5288
5299
|
if (props && typeof props.style === "string" && !registry.typography.has(props.style)) {
|
|
5289
5300
|
out.push({
|
|
5290
|
-
path: `${
|
|
5301
|
+
path: `${path2}.props.style`,
|
|
5291
5302
|
kind: "typography",
|
|
5292
5303
|
name: props.style
|
|
5293
5304
|
});
|
|
5294
5305
|
}
|
|
5295
5306
|
if (props && typeof props.color === "string" && !registry.colors.has(props.color)) {
|
|
5296
5307
|
out.push({
|
|
5297
|
-
path: `${
|
|
5308
|
+
path: `${path2}.props.color`,
|
|
5298
5309
|
kind: "color",
|
|
5299
5310
|
name: props.color
|
|
5300
5311
|
});
|
|
5301
5312
|
}
|
|
5302
5313
|
}
|
|
5303
5314
|
for (const [key2, value] of Object.entries(obj2)) {
|
|
5304
|
-
walk(value, registry, `${
|
|
5315
|
+
walk(value, registry, `${path2}.${key2}`, out);
|
|
5305
5316
|
}
|
|
5306
5317
|
}
|
|
5307
5318
|
var SYSTEM_FONT_FAMILY;
|
|
5308
5319
|
var init_tokens = __esm({
|
|
5309
5320
|
"../../core/ts/src/tokens.ts"() {
|
|
5310
|
-
"use strict";
|
|
5311
5321
|
SYSTEM_FONT_FAMILY = "$system";
|
|
5312
5322
|
}
|
|
5313
5323
|
});
|
|
@@ -5346,11 +5356,11 @@ var init_bindings = __esm({
|
|
|
5346
5356
|
// ../../core/ts/src/validator.ts
|
|
5347
5357
|
import Ajv from "ajv";
|
|
5348
5358
|
import addFormats from "ajv-formats";
|
|
5349
|
-
function findUnknownComponents(node, allowed2,
|
|
5359
|
+
function findUnknownComponents(node, allowed2, path2 = "$", out = []) {
|
|
5350
5360
|
if (node === null || typeof node !== "object") return out;
|
|
5351
5361
|
if (Array.isArray(node)) {
|
|
5352
5362
|
node.forEach(
|
|
5353
|
-
(item, i) => findUnknownComponents(item, allowed2, `${
|
|
5363
|
+
(item, i) => findUnknownComponents(item, allowed2, `${path2}[${i}]`, out)
|
|
5354
5364
|
);
|
|
5355
5365
|
return out;
|
|
5356
5366
|
}
|
|
@@ -5359,11 +5369,11 @@ function findUnknownComponents(node, allowed2, path = "$", out = []) {
|
|
|
5359
5369
|
if (body && typeof body.package === "string" && typeof body.type === "string") {
|
|
5360
5370
|
const key2 = `${body.package}.${body.type}`;
|
|
5361
5371
|
if (!allowed2.has(key2)) {
|
|
5362
|
-
out.push({ path, package: body.package, type: body.type });
|
|
5372
|
+
out.push({ path: path2, package: body.package, type: body.type });
|
|
5363
5373
|
}
|
|
5364
5374
|
}
|
|
5365
5375
|
for (const [key2, value] of Object.entries(obj2)) {
|
|
5366
|
-
findUnknownComponents(value, allowed2, `${
|
|
5376
|
+
findUnknownComponents(value, allowed2, `${path2}.${key2}`, out);
|
|
5367
5377
|
}
|
|
5368
5378
|
return out;
|
|
5369
5379
|
}
|
|
@@ -5375,9 +5385,9 @@ function compileWidgetSchema() {
|
|
|
5375
5385
|
}
|
|
5376
5386
|
return widgetValidateFn;
|
|
5377
5387
|
}
|
|
5378
|
-
function validateWidgetActionRef(action,
|
|
5388
|
+
function validateWidgetActionRef(action, path2, intents) {
|
|
5379
5389
|
if (typeof action !== "object" || action === null || Array.isArray(action)) {
|
|
5380
|
-
intents.push({ path, reason: "must be an object { actionId, params? }" });
|
|
5390
|
+
intents.push({ path: path2, reason: "must be an object { actionId, params? }" });
|
|
5381
5391
|
return;
|
|
5382
5392
|
}
|
|
5383
5393
|
const actionId = action.actionId;
|
|
@@ -5386,48 +5396,48 @@ function validateWidgetActionRef(action, path, intents) {
|
|
|
5386
5396
|
const unsupportedFields = Object.keys(action).filter((key2) => !WIDGET_ACTION_FIELDS.has(key2));
|
|
5387
5397
|
if (unsupportedFields.length > 0) {
|
|
5388
5398
|
intents.push({
|
|
5389
|
-
path,
|
|
5399
|
+
path: path2,
|
|
5390
5400
|
reason: `unsupported field(s) on a widget action: ${unsupportedFields.sort().join(", ")} \u2014 a frozen widget action carries only \`actionId\` and literal \`params\``
|
|
5391
5401
|
});
|
|
5392
5402
|
}
|
|
5393
5403
|
const knownAction = typeof actionId === "string" && Object.prototype.hasOwnProperty.call(WIDGET_INTENT_RULES, actionId);
|
|
5394
5404
|
if (typeof actionId !== "string" || actionId.length === 0) {
|
|
5395
|
-
intents.push({ path, reason: "`actionId` must be a non-empty string" });
|
|
5405
|
+
intents.push({ path: path2, reason: "`actionId` must be a non-empty string" });
|
|
5396
5406
|
} else if (!knownAction) {
|
|
5397
|
-
intents.push({ path, reason: `unsupported widget actionId "${actionId}"` });
|
|
5407
|
+
intents.push({ path: path2, reason: `unsupported widget actionId "${actionId}"` });
|
|
5398
5408
|
}
|
|
5399
5409
|
if (params !== void 0 && (typeof params !== "object" || params === null || Array.isArray(params) || !Object.values(params).every((value) => typeof value === "string"))) {
|
|
5400
|
-
intents.push({ path, reason: "`params` must be a { string: string } map of literals" });
|
|
5410
|
+
intents.push({ path: path2, reason: "`params` must be a { string: string } map of literals" });
|
|
5401
5411
|
} else if (knownAction) {
|
|
5402
5412
|
const rule = WIDGET_INTENT_RULES[actionId];
|
|
5403
5413
|
const literalParams = params ?? {};
|
|
5404
5414
|
if (Object.keys(literalParams).length > 8 || utf8ByteLength(JSON.stringify(literalParams)) > 1024 || Object.entries(literalParams).some(([key2, value]) => utf8ByteLength(key2) > 64 || utf8ByteLength(value) > 512)) {
|
|
5405
|
-
intents.push({ path, reason: "parameters exceed the widget action size limit" });
|
|
5415
|
+
intents.push({ path: path2, reason: "parameters exceed the widget action size limit" });
|
|
5406
5416
|
}
|
|
5407
5417
|
const allowed2 = /* @__PURE__ */ new Set([...rule.required, ...rule.optional ?? []]);
|
|
5408
5418
|
const unknown = Object.keys(literalParams).filter((key2) => !allowed2.has(key2));
|
|
5409
5419
|
const missing = rule.required.filter((key2) => !literalParams[key2]);
|
|
5410
5420
|
if (unknown.length > 0) {
|
|
5411
|
-
intents.push({ path, reason: `unsupported parameter(s): ${unknown.join(", ")}` });
|
|
5421
|
+
intents.push({ path: path2, reason: `unsupported parameter(s): ${unknown.join(", ")}` });
|
|
5412
5422
|
}
|
|
5413
5423
|
if (missing.length > 0) {
|
|
5414
|
-
intents.push({ path, reason: `missing required parameter(s): ${missing.join(", ")}` });
|
|
5424
|
+
intents.push({ path: path2, reason: `missing required parameter(s): ${missing.join(", ")}` });
|
|
5415
5425
|
}
|
|
5416
5426
|
for (const [key2, values] of Object.entries(rule.values ?? {})) {
|
|
5417
5427
|
const value = literalParams[key2];
|
|
5418
5428
|
if (value !== void 0 && !values.includes(value)) {
|
|
5419
|
-
intents.push({ path, reason: `invalid ${key2} "${value}"` });
|
|
5429
|
+
intents.push({ path: path2, reason: `invalid ${key2} "${value}"` });
|
|
5420
5430
|
}
|
|
5421
5431
|
}
|
|
5422
5432
|
}
|
|
5423
5433
|
}
|
|
5424
|
-
function scanWidgetPayload(node, family,
|
|
5434
|
+
function scanWidgetPayload(node, family, path2, bindings, disallowed, timeRefs, intents, actionSites2) {
|
|
5425
5435
|
if (typeof node === "string") {
|
|
5426
|
-
if (WIDGET_BINDING.test(node)) bindings.push({ path, value: node });
|
|
5436
|
+
if (WIDGET_BINDING.test(node)) bindings.push({ path: path2, value: node });
|
|
5427
5437
|
return;
|
|
5428
5438
|
}
|
|
5429
5439
|
if (Array.isArray(node)) {
|
|
5430
|
-
node.forEach((item, i) => scanWidgetPayload(item, family, `${
|
|
5440
|
+
node.forEach((item, i) => scanWidgetPayload(item, family, `${path2}[${i}]`, bindings, disallowed, timeRefs, intents, actionSites2));
|
|
5431
5441
|
return;
|
|
5432
5442
|
}
|
|
5433
5443
|
if (node === null || typeof node !== "object") return;
|
|
@@ -5436,46 +5446,46 @@ function scanWidgetPayload(node, family, path, bindings, disallowed, timeRefs, i
|
|
|
5436
5446
|
if (body && typeof body.package === "string" && typeof body.type === "string") {
|
|
5437
5447
|
const key2 = `${body.package}.${body.type}`;
|
|
5438
5448
|
if (family && !isComponentAllowedForFamily(key2, family)) {
|
|
5439
|
-
disallowed.push({ path, package: body.package, type: body.type, family });
|
|
5449
|
+
disallowed.push({ path: path2, package: body.package, type: body.type, family });
|
|
5440
5450
|
}
|
|
5441
5451
|
if (key2 === "himalaya.Button") {
|
|
5442
5452
|
const props = body.props;
|
|
5443
5453
|
if (!props || typeof props !== "object" || Array.isArray(props)) {
|
|
5444
|
-
intents.push({ path: `${
|
|
5454
|
+
intents.push({ path: `${path2}.body.props`, reason: "widget Button props must be an object" });
|
|
5445
5455
|
} else if (family === "ios_home" || family === "android_home") {
|
|
5446
5456
|
const button = props;
|
|
5447
5457
|
if (button.intent !== void 0) {
|
|
5448
|
-
intents.push({ path: `${
|
|
5458
|
+
intents.push({ path: `${path2}.body.props.intent`, reason: "widget Button commands use the required `action` field" });
|
|
5449
5459
|
}
|
|
5450
|
-
validateWidgetActionRef(button.action, `${
|
|
5460
|
+
validateWidgetActionRef(button.action, `${path2}.body.props.action`, intents);
|
|
5451
5461
|
const componentId = obj2.id;
|
|
5452
5462
|
if (typeof componentId !== "string" || !WIDGET_ACTION_IDENTIFIER.test(componentId)) {
|
|
5453
5463
|
intents.push({
|
|
5454
|
-
path: `${
|
|
5464
|
+
path: `${path2}.id`,
|
|
5455
5465
|
reason: "a widget Button carrying an action needs an id matching ^[A-Za-z0-9_.:-]{1,128}$, or the runtimes attach no handler to it"
|
|
5456
5466
|
});
|
|
5457
5467
|
}
|
|
5458
|
-
actionSites2.push(`${
|
|
5468
|
+
actionSites2.push(`${path2}.body.props.action`);
|
|
5459
5469
|
}
|
|
5460
5470
|
}
|
|
5461
5471
|
}
|
|
5462
5472
|
if (obj2.timeRef !== void 0 && obj2.timeRef !== null) {
|
|
5463
5473
|
const tr = obj2.timeRef;
|
|
5464
5474
|
if (typeof tr !== "object" || Array.isArray(tr)) {
|
|
5465
|
-
timeRefs.push({ path: `${
|
|
5475
|
+
timeRefs.push({ path: `${path2}.timeRef`, reason: "must be an object { at, style? }" });
|
|
5466
5476
|
} else {
|
|
5467
5477
|
const at = tr.at;
|
|
5468
5478
|
const style = tr.style;
|
|
5469
5479
|
if (typeof at !== "number" || !Number.isFinite(at)) {
|
|
5470
|
-
timeRefs.push({ path: `${
|
|
5480
|
+
timeRefs.push({ path: `${path2}.timeRef`, reason: "`at` must be a finite epoch-seconds number" });
|
|
5471
5481
|
}
|
|
5472
5482
|
if (style !== void 0 && (typeof style !== "string" || !VALID_TIMEREF_STYLES.has(style))) {
|
|
5473
|
-
timeRefs.push({ path: `${
|
|
5483
|
+
timeRefs.push({ path: `${path2}.timeRef`, reason: `invalid style "${String(style)}" (expected ${[...VALID_TIMEREF_STYLES].join("|")})` });
|
|
5474
5484
|
}
|
|
5475
5485
|
}
|
|
5476
5486
|
}
|
|
5477
5487
|
for (const [k, v] of Object.entries(obj2)) {
|
|
5478
|
-
scanWidgetPayload(v, family, `${
|
|
5488
|
+
scanWidgetPayload(v, family, `${path2}.${k}`, bindings, disallowed, timeRefs, intents, actionSites2);
|
|
5479
5489
|
}
|
|
5480
5490
|
}
|
|
5481
5491
|
function validateWidget(snapshot2) {
|
|
@@ -6392,9 +6402,9 @@ function collectDescriptorStrings(descriptor) {
|
|
|
6392
6402
|
seen.add(key2);
|
|
6393
6403
|
out.push(f);
|
|
6394
6404
|
};
|
|
6395
|
-
const visit = (node,
|
|
6405
|
+
const visit = (node, path2) => {
|
|
6396
6406
|
if (Array.isArray(node)) {
|
|
6397
|
-
node.forEach((n, i) => visit(n, `${
|
|
6407
|
+
node.forEach((n, i) => visit(n, `${path2}[${i}]`));
|
|
6398
6408
|
return;
|
|
6399
6409
|
}
|
|
6400
6410
|
if (!node || typeof node !== "object") return;
|
|
@@ -6407,7 +6417,7 @@ function collectDescriptorStrings(descriptor) {
|
|
|
6407
6417
|
for (const [prop, v] of Object.entries(props)) {
|
|
6408
6418
|
if (typeof v !== "string" || BINDING_SIGIL.test(v)) continue;
|
|
6409
6419
|
if (!isUserVisibleCopy(v)) continue;
|
|
6410
|
-
const at = `${
|
|
6420
|
+
const at = `${path2}.body.props.${prop}`;
|
|
6411
6421
|
if (mapped.includes(prop) || SECONDARY_FIELDS.has(prop)) {
|
|
6412
6422
|
push({ value: v, bucket: "reachable", type, prop, path: at });
|
|
6413
6423
|
} else if (UNREACHED_VISIBLE_FIELDS.has(prop)) {
|
|
@@ -6421,19 +6431,19 @@ function collectDescriptorStrings(descriptor) {
|
|
|
6421
6431
|
bucket: "reachable",
|
|
6422
6432
|
type,
|
|
6423
6433
|
prop: "template.template",
|
|
6424
|
-
path: `${
|
|
6434
|
+
path: `${path2}.body.props.template.template`
|
|
6425
6435
|
});
|
|
6426
6436
|
}
|
|
6427
6437
|
}
|
|
6428
6438
|
for (const [k, v] of Object.entries(obj2)) {
|
|
6429
6439
|
if (k === "body") continue;
|
|
6430
6440
|
if (typeof v === "string" && SECONDARY_FIELDS.has(k) && !BINDING_SIGIL.test(v) && isUserVisibleCopy(v)) {
|
|
6431
|
-
push({ value: v, bucket: "reachable", type, prop: k, path: `${
|
|
6441
|
+
push({ value: v, bucket: "reachable", type, prop: k, path: `${path2}.${k}` });
|
|
6432
6442
|
}
|
|
6433
6443
|
}
|
|
6434
6444
|
for (const [k, v] of Object.entries(obj2)) {
|
|
6435
|
-
if (
|
|
6436
|
-
if (v && typeof v === "object") visit(v,
|
|
6445
|
+
if (path2 === "" && k === "input" && v !== null && typeof v === "object") continue;
|
|
6446
|
+
if (v && typeof v === "object") visit(v, path2 ? `${path2}.${k}` : k);
|
|
6437
6447
|
}
|
|
6438
6448
|
};
|
|
6439
6449
|
visit(descriptor, "");
|
|
@@ -6907,10 +6917,10 @@ async function bootBundleWorker(bundleJs, opts) {
|
|
|
6907
6917
|
// `headers` is forwarded, not swallowed: it is how one call addresses a business other
|
|
6908
6918
|
// than the ambient one (`site.forSite(msid)` → `wix-site-id`), and a wrapper that drops
|
|
6909
6919
|
// it answers for the wrong business while every caller renders the result as correct.
|
|
6910
|
-
call: (method,
|
|
6911
|
-
const label2 = `${String(method)} ${String(
|
|
6920
|
+
call: (method, path2, body, headers2) => {
|
|
6921
|
+
const label2 = `${String(method)} ${String(path2)}`;
|
|
6912
6922
|
calls.push(label2);
|
|
6913
|
-
return Promise.resolve(opts.wixCall(method,
|
|
6923
|
+
return Promise.resolve(opts.wixCall(method, path2, body, headers2)).then((value) => {
|
|
6914
6924
|
const bytes2 = responseBytes(value);
|
|
6915
6925
|
if (bytes2 > MAX_FRAME_MESSAGE_BYTES) {
|
|
6916
6926
|
oversizeWixResponses.push({ call: label2, bytes: bytes2 });
|
|
@@ -7148,11 +7158,11 @@ async function bootBundleWorker(bundleJs, opts) {
|
|
|
7148
7158
|
}
|
|
7149
7159
|
message = typeof asJson === "string" ? asJson : String(raw);
|
|
7150
7160
|
} else message = String(raw);
|
|
7151
|
-
const
|
|
7152
|
-
if (prev.status === "loading")
|
|
7153
|
-
if (prev.loading === true)
|
|
7154
|
-
if (typeof prev.error === "string")
|
|
7155
|
-
def.state =
|
|
7161
|
+
const failed2 = { ...prev, _error: message };
|
|
7162
|
+
if (prev.status === "loading") failed2.status = "error";
|
|
7163
|
+
if (prev.loading === true) failed2.loading = false;
|
|
7164
|
+
if (typeof prev.error === "string") failed2.error = message;
|
|
7165
|
+
def.state = failed2;
|
|
7156
7166
|
};
|
|
7157
7167
|
const runAction = async (def, label2, fn, args) => {
|
|
7158
7168
|
let timer;
|
|
@@ -7349,9 +7359,9 @@ function validateDescriptorAction(action, context) {
|
|
|
7349
7359
|
function validateDescriptorActions(actions, context) {
|
|
7350
7360
|
return actions.map((action) => validateDescriptorAction(action, context)).filter((issue2) => issue2 !== null);
|
|
7351
7361
|
}
|
|
7352
|
-
function pathValue(state,
|
|
7362
|
+
function pathValue(state, path2) {
|
|
7353
7363
|
let cur = state;
|
|
7354
|
-
for (const part of
|
|
7364
|
+
for (const part of path2.replace(/\[(\d+)\]/g, ".$1").split(".")) {
|
|
7355
7365
|
if (cur == null || typeof cur !== "object") return void 0;
|
|
7356
7366
|
if (Array.isArray(cur)) {
|
|
7357
7367
|
const idx = Number(part);
|
|
@@ -7364,9 +7374,9 @@ function pathValue(state, path) {
|
|
|
7364
7374
|
}
|
|
7365
7375
|
return cur;
|
|
7366
7376
|
}
|
|
7367
|
-
function pathResolves(state,
|
|
7377
|
+
function pathResolves(state, path2) {
|
|
7368
7378
|
let cur = state;
|
|
7369
|
-
for (const part of
|
|
7379
|
+
for (const part of path2.replace(/\[(\d+)\]/g, ".$1").split(".")) {
|
|
7370
7380
|
if (cur == null || typeof cur !== "object") return false;
|
|
7371
7381
|
if (Array.isArray(cur)) {
|
|
7372
7382
|
const idx = Number(part);
|
|
@@ -7383,9 +7393,9 @@ function pathResolves(state, path) {
|
|
|
7383
7393
|
}
|
|
7384
7394
|
return true;
|
|
7385
7395
|
}
|
|
7386
|
-
function serviceFieldDeclared(state,
|
|
7396
|
+
function serviceFieldDeclared(state, path2) {
|
|
7387
7397
|
if (state == null || typeof state !== "object" || Array.isArray(state)) return false;
|
|
7388
|
-
const first =
|
|
7398
|
+
const first = path2.replace(/\[(\d+)\]/g, ".$1").split(".")[0];
|
|
7389
7399
|
return first in state;
|
|
7390
7400
|
}
|
|
7391
7401
|
function ellipsis(value, max) {
|
|
@@ -7398,70 +7408,70 @@ function isOpaqueAuthorJson(key2, value, atRoot) {
|
|
|
7398
7408
|
if (value === null || typeof value !== "object") return false;
|
|
7399
7409
|
return key2 === "args" || atRoot && key2 === "input";
|
|
7400
7410
|
}
|
|
7401
|
-
function pathCrossesOpaqueAuthorJson(
|
|
7402
|
-
if (typeof
|
|
7403
|
-
return /^\$\.input(?:[.[]|$)/.test(
|
|
7411
|
+
function pathCrossesOpaqueAuthorJson(path2) {
|
|
7412
|
+
if (typeof path2 !== "string") return false;
|
|
7413
|
+
return /^\$\.input(?:[.[]|$)/.test(path2) || /\.args(?:[.[]|$)/.test(path2);
|
|
7404
7414
|
}
|
|
7405
7415
|
function nativeRequiredFindings(descriptor) {
|
|
7406
7416
|
const out = [];
|
|
7407
7417
|
const shapeOf = (ref) => ref.startsWith("list:") ? "an array" : ref.startsWith("map:") ? "an object keyed by name" : "an object";
|
|
7408
7418
|
const kindOf = (value) => Array.isArray(value) ? "an array" : value === null ? "null" : typeof value === "object" ? "an object" : `a ${typeof value} (${JSON.stringify(value)})`;
|
|
7409
|
-
const reportKind = (ref, value,
|
|
7419
|
+
const reportKind = (ref, value, path2, from) => {
|
|
7410
7420
|
const cls = bareNestedClass(ref);
|
|
7411
7421
|
const got = kindOf(value);
|
|
7412
7422
|
const expected = ref.startsWith("list:") ? "Expected JsonArray" : `Expected JsonObject for type with serial name 'io.himalaya.core.${cls}'`;
|
|
7413
7423
|
out.push({
|
|
7414
|
-
path,
|
|
7424
|
+
path: path2,
|
|
7415
7425
|
message: `${cls} is what the native decoder expects here \u2014 ${shapeOf(ref)} \u2014 but the descriptor has ${got}. Native decode rejects it ("${expected}") and drops the WHOLE screen from the seed, while web renders it fine (reached from ${from})`
|
|
7416
7426
|
});
|
|
7417
7427
|
};
|
|
7418
|
-
const checkNested = (value, cls,
|
|
7428
|
+
const checkNested = (value, cls, path2, from) => {
|
|
7419
7429
|
if (cls.startsWith("map:")) {
|
|
7420
7430
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
7421
|
-
reportKind(cls, value,
|
|
7431
|
+
reportKind(cls, value, path2, from);
|
|
7422
7432
|
return;
|
|
7423
7433
|
}
|
|
7424
7434
|
const of = cls.slice("map:".length);
|
|
7425
7435
|
for (const [key2, v] of Object.entries(value)) {
|
|
7426
|
-
checkNested(v, of, `${
|
|
7436
|
+
checkNested(v, of, `${path2}.${key2}`, from);
|
|
7427
7437
|
}
|
|
7428
7438
|
return;
|
|
7429
7439
|
}
|
|
7430
7440
|
if (cls.startsWith("list:")) {
|
|
7431
7441
|
if (!Array.isArray(value)) {
|
|
7432
|
-
reportKind(cls, value,
|
|
7442
|
+
reportKind(cls, value, path2, from);
|
|
7433
7443
|
return;
|
|
7434
7444
|
}
|
|
7435
7445
|
const of = cls.slice("list:".length);
|
|
7436
|
-
value.forEach((v, i) => checkNested(v, of, `${
|
|
7446
|
+
value.forEach((v, i) => checkNested(v, of, `${path2}[${i}]`, from));
|
|
7437
7447
|
return;
|
|
7438
7448
|
}
|
|
7439
7449
|
const rule = own(NATIVE_NESTED_CLASSES, cls);
|
|
7440
7450
|
if (!rule) return;
|
|
7441
7451
|
if (Array.isArray(value) || !value || typeof value !== "object") {
|
|
7442
|
-
reportKind(cls, value,
|
|
7452
|
+
reportKind(cls, value, path2, from);
|
|
7443
7453
|
return;
|
|
7444
7454
|
}
|
|
7445
7455
|
const bag = value;
|
|
7446
7456
|
for (const name of rule.required) {
|
|
7447
7457
|
if (own(bag, name) !== void 0 && bag[name] !== null) continue;
|
|
7448
7458
|
out.push({
|
|
7449
|
-
path: `${
|
|
7459
|
+
path: `${path2}.${name}`,
|
|
7450
7460
|
message: `${cls}.${name} is REQUIRED by the native decoder but is missing \u2014 native decode rejects it ("Field '${name}' is required for type with serial name 'io.himalaya.core.${cls}', but it was missing") and drops the WHOLE screen from the seed, while web renders it fine (reached from ${from})`
|
|
7451
7461
|
});
|
|
7452
7462
|
}
|
|
7453
7463
|
for (const [name, sub] of Object.entries(rule.nested)) {
|
|
7454
7464
|
const inner = own(bag, name);
|
|
7455
|
-
if (inner !== void 0 && inner !== null) checkNested(inner, sub, `${
|
|
7465
|
+
if (inner !== void 0 && inner !== null) checkNested(inner, sub, `${path2}.${name}`, from);
|
|
7456
7466
|
}
|
|
7457
|
-
if (cls === "Action") checkActionParams(own(bag, "params"), `${
|
|
7467
|
+
if (cls === "Action") checkActionParams(own(bag, "params"), `${path2}.params`, from);
|
|
7458
7468
|
};
|
|
7459
|
-
const checkActionParams = (params,
|
|
7469
|
+
const checkActionParams = (params, path2, from) => {
|
|
7460
7470
|
if (params === void 0 || params === null) return;
|
|
7461
7471
|
const cost = "Native decode rejects it and drops the WHOLE screen from the seed, while web renders it fine";
|
|
7462
7472
|
if (typeof params !== "object" || Array.isArray(params)) {
|
|
7463
7473
|
out.push({
|
|
7464
|
-
path,
|
|
7474
|
+
path: path2,
|
|
7465
7475
|
message: `Action.params must be an object of strings, but the descriptor has ${kindOf(params)} ("Expected JsonObject"). ${cost} (reached from ${from})`
|
|
7466
7476
|
});
|
|
7467
7477
|
return;
|
|
@@ -7469,7 +7479,7 @@ function nativeRequiredFindings(descriptor) {
|
|
|
7469
7479
|
for (const [key2, value] of Object.entries(params)) {
|
|
7470
7480
|
if (typeof value === "string" || value === void 0) continue;
|
|
7471
7481
|
out.push({
|
|
7472
|
-
path: `${
|
|
7482
|
+
path: `${path2}.${key2}`,
|
|
7473
7483
|
message: `Action.params values must be strings, but params.${key2} is ${kindOf(value)} ("Expected JsonPrimitive at ${key2}" on Android, typeMismatch on iOS). ${cost}. Flatten it into string keys of params, or move structured data to Action.args (reached from ${from})`
|
|
7474
7484
|
});
|
|
7475
7485
|
}
|
|
@@ -7552,13 +7562,13 @@ function componentPropFindings(descriptor) {
|
|
|
7552
7562
|
const bag = props;
|
|
7553
7563
|
const base = at ? `${at}.body.props` : "body.props";
|
|
7554
7564
|
for (const name of Object.keys(bag)) {
|
|
7555
|
-
const
|
|
7565
|
+
const path2 = `${base}.${name}`;
|
|
7556
7566
|
const kind = own(declared, name);
|
|
7557
7567
|
if (kind === void 0) {
|
|
7558
7568
|
if (LEGACY_UNSCORED_KEYS.has(`${type}.${name}`)) continue;
|
|
7559
7569
|
const hint = MODIFIER_KEYS.has(name) ? ` \u2014 \`${name}\` is a MODIFIER, not a prop: move it out of \`props\` and into the node's \`modifiers\` bag (\`{ id, body, modifiers: { ${name}: \u2026 } }\`)` : "";
|
|
7560
7570
|
out.push({
|
|
7561
|
-
path,
|
|
7571
|
+
path: path2,
|
|
7562
7572
|
kind: "hygiene",
|
|
7563
7573
|
message: `${type} has no prop \`${name}\` \u2014 the native decoders are built with \`ignoreUnknownKeys = true\`, so this key is SILENTLY DROPPED on iOS and Android and the value never reaches the screen (web, whose props are \`any\`, may still show it). Declared props: ${Object.keys(declared).sort().join(", ") || "(none)"}${hint}`
|
|
7564
7574
|
});
|
|
@@ -7572,7 +7582,7 @@ function componentPropFindings(descriptor) {
|
|
|
7572
7582
|
const twin = own(declared, `${name}Path`) !== void 0 ? `${name}Path` : void 0;
|
|
7573
7583
|
const inArray = IN_ARRAY_BINDING_PROPS.has(`${type}.${name}`) && value.startsWith(SERVICE_SIGIL);
|
|
7574
7584
|
out.push({
|
|
7575
|
-
path,
|
|
7585
|
+
path: path2,
|
|
7576
7586
|
kind: "decode",
|
|
7577
7587
|
...inArray ? { authoringOnly: true } : {},
|
|
7578
7588
|
// TWO different defects share this branch, and they need DIFFERENT prose.
|
|
@@ -7588,7 +7598,7 @@ function componentPropFindings(descriptor) {
|
|
|
7588
7598
|
// copy-pasteable line that silently truncated a long path, so following the advice
|
|
7589
7599
|
// bound to missing state; it stays truncated only in the diagnostic prose, where it
|
|
7590
7600
|
// is describing rather than prescribing.
|
|
7591
|
-
message: inArray ? `${type}.${name} is declared ${kind}, and a bare \`${ellipsis(value, 32)}\` does not satisfy it: the authoring contract types this prop as an array (see core/ts/src/schema.ts and the generated component.schema.json), so a typed author cannot write the scalar even though the native decoders would accept it. Put the sentinel INSIDE the array \u2014 \`${name}: ["${value}"]\` \u2014 which is the form the renderers read and the authoring schema accepts. At ${jsonPointer(
|
|
7601
|
+
message: inArray ? `${type}.${name} is declared ${kind}, and a bare \`${ellipsis(value, 32)}\` does not satisfy it: the authoring contract types this prop as an array (see core/ts/src/schema.ts and the generated component.schema.json), so a typed author cannot write the scalar even though the native decoders would accept it. Put the sentinel INSIDE the array \u2014 \`${name}: ["${value}"]\` \u2014 which is the form the renderers read and the authoring schema accepts. At ${jsonPointer(path2)}` : `${type}.${name} is declared ${kind}, and a binding does NOT satisfy it \u2014 a \`${ellipsis(value, 32)}\` sentinel is a plain STRING on the wire and is resolved AFTER native decode, so kotlinx sees a string where it wants a ${kind}, REJECTS the document and drops the WHOLE screen from the seed (web renders it fine). ` + (twin ? `Bind \`${twin}\` instead \u2014 it is declared string exactly so a sentinel survives decode.` : `Bind this prop's \`\u2026Path\` twin if it has one; a typed slot cannot carry a sentinel.`) + ` At ${jsonPointer(path2)}`
|
|
7592
7602
|
});
|
|
7593
7603
|
continue;
|
|
7594
7604
|
}
|
|
@@ -7597,17 +7607,17 @@ function componentPropFindings(descriptor) {
|
|
|
7597
7607
|
if (actual === kind) {
|
|
7598
7608
|
if (kind === "number" && typeof value === "number" && !Number.isInteger(value) && own(INTEGER_PROPS, type)?.includes(name)) {
|
|
7599
7609
|
out.push({
|
|
7600
|
-
path,
|
|
7610
|
+
path: path2,
|
|
7601
7611
|
kind: "decode",
|
|
7602
|
-
message: `${type}.${name} is declared an INTEGER by the native decoders but this descriptor carries ${value} \u2014 a fraction is not representable in an \`Int\` field, so decode REJECTS the document and drops the WHOLE screen from the seed, while web renders it fine. Round it. At ${jsonPointer(
|
|
7612
|
+
message: `${type}.${name} is declared an INTEGER by the native decoders but this descriptor carries ${value} \u2014 a fraction is not representable in an \`Int\` field, so decode REJECTS the document and drops the WHOLE screen from the seed, while web renders it fine. Round it. At ${jsonPointer(path2)}`
|
|
7603
7613
|
});
|
|
7604
7614
|
}
|
|
7605
7615
|
continue;
|
|
7606
7616
|
}
|
|
7607
7617
|
out.push({
|
|
7608
|
-
path,
|
|
7618
|
+
path: path2,
|
|
7609
7619
|
kind: "decode",
|
|
7610
|
-
message: `${type}.${name} is declared ${kind} but this descriptor carries a ${actual} (${JSON.stringify(value)?.slice(0, 40)}) \u2014 native decode REJECTS the document ("Unexpected JSON token ... expected ${kind}") and drops the WHOLE screen from the seed, while web renders it fine. At ${jsonPointer(
|
|
7620
|
+
message: `${type}.${name} is declared ${kind} but this descriptor carries a ${actual} (${JSON.stringify(value)?.slice(0, 40)}) \u2014 native decode REJECTS the document ("Unexpected JSON token ... expected ${kind}") and drops the WHOLE screen from the seed, while web renders it fine. At ${jsonPointer(path2)}`
|
|
7611
7621
|
});
|
|
7612
7622
|
}
|
|
7613
7623
|
}
|
|
@@ -7870,15 +7880,15 @@ function workerSubtreeAllowed(screenId, allowlist) {
|
|
|
7870
7880
|
}
|
|
7871
7881
|
return false;
|
|
7872
7882
|
}
|
|
7873
|
-
function collectWixMediaReferences(value,
|
|
7883
|
+
function collectWixMediaReferences(value, path2, found, mediaContext = false, bareIdContext = false, componentType = "", atRoot = false) {
|
|
7874
7884
|
const unresolvedMedia = mediaContext && unresolvedWixMediaReference(value, bareIdContext);
|
|
7875
7885
|
if (unresolvedMedia) {
|
|
7876
|
-
found.push({ path, value: unresolvedMedia });
|
|
7886
|
+
found.push({ path: path2, value: unresolvedMedia });
|
|
7877
7887
|
return;
|
|
7878
7888
|
}
|
|
7879
7889
|
if (Array.isArray(value)) {
|
|
7880
7890
|
value.forEach((item, index) => {
|
|
7881
|
-
collectWixMediaReferences(item, `${
|
|
7891
|
+
collectWixMediaReferences(item, `${path2}[${index}]`, found, mediaContext, bareIdContext);
|
|
7882
7892
|
});
|
|
7883
7893
|
return;
|
|
7884
7894
|
}
|
|
@@ -7890,7 +7900,7 @@ function collectWixMediaReferences(value, path, found, mediaContext = false, bar
|
|
|
7890
7900
|
const childComponentType = key2 === "props" && typeof record2.type === "string" ? record2.type : "";
|
|
7891
7901
|
collectWixMediaReferences(
|
|
7892
7902
|
child,
|
|
7893
|
-
|
|
7903
|
+
path2 ? `${path2}.${key2}` : key2,
|
|
7894
7904
|
found,
|
|
7895
7905
|
mediaContext || isComponentMediaValueProperty(componentType, key2),
|
|
7896
7906
|
bareIdContext || isMediaLocationProperty(key2),
|
|
@@ -7936,16 +7946,16 @@ function validateScreenDescriptor(screenId, descriptor, opts = {}) {
|
|
|
7936
7946
|
};
|
|
7937
7947
|
for (const e of v.schemaErrors) {
|
|
7938
7948
|
const err = e;
|
|
7939
|
-
const
|
|
7940
|
-
if (
|
|
7949
|
+
const path2 = err.instancePath;
|
|
7950
|
+
if (path2 === "/logicBundle/integrity" && lbIntegrity === "") continue;
|
|
7941
7951
|
const issue2 = {
|
|
7942
7952
|
severity: hygiene,
|
|
7943
7953
|
pass: "schema",
|
|
7944
|
-
path,
|
|
7954
|
+
path: path2,
|
|
7945
7955
|
message: err.message ?? "schema violation"
|
|
7946
7956
|
};
|
|
7947
7957
|
issues.push(issue2);
|
|
7948
|
-
for (const at of dottedCandidates(
|
|
7958
|
+
for (const at of dottedCandidates(path2 ?? "")) {
|
|
7949
7959
|
if (err.keyword === "required" && err.params?.missingProperty) {
|
|
7950
7960
|
indexIssue(at ? `${at}.${err.params.missingProperty}` : err.params.missingProperty, issue2);
|
|
7951
7961
|
}
|
|
@@ -8355,11 +8365,11 @@ function validateScreenDescriptor(screenId, descriptor, opts = {}) {
|
|
|
8355
8365
|
{
|
|
8356
8366
|
const NAMED_ICON_PROPS = /* @__PURE__ */ new Set(["icon", "selectedIcon", "leadingIcon", "trailingIcon", "badgeIcon"]);
|
|
8357
8367
|
const shape = (v2) => Array.isArray(v2) ? "an array" : typeof v2;
|
|
8358
|
-
const flagNonString = (k, v2,
|
|
8368
|
+
const flagNonString = (k, v2, path2) => {
|
|
8359
8369
|
issues.push({
|
|
8360
8370
|
severity: "error",
|
|
8361
8371
|
pass: "icons",
|
|
8362
|
-
path,
|
|
8372
|
+
path: path2,
|
|
8363
8373
|
message: `icon prop "${k}" is ${shape(v2)} (${JSON.stringify(v2)}) \u2014 IconRef is an icon-name STRING (or a "$service:"/"$item." binding), never an object. The native decoders reject the descriptor and drop the whole screen; web degrades to the unknown-icon marker. Pass the name directly, e.g. ${k}: "cart".`
|
|
8364
8374
|
});
|
|
8365
8375
|
};
|
|
@@ -8390,12 +8400,12 @@ function validateScreenDescriptor(screenId, descriptor, opts = {}) {
|
|
|
8390
8400
|
const normIcon = (n) => n.toLowerCase().replace(/[_.\s-]/g, "");
|
|
8391
8401
|
const ICON_NAME_PROPS = /* @__PURE__ */ new Set(["icon", "selectedIcon", "leadingIcon", "trailingIcon", "badgeIcon"]);
|
|
8392
8402
|
const judgeable = (v2) => typeof v2 === "string" && v2.length > 0 && !v2.startsWith("$") && !v2.includes("/") && !v2.includes(":") && !/\.(png|jpe?g|svg|webp|gif)$/i.test(v2);
|
|
8393
|
-
const flagIcon = (name,
|
|
8403
|
+
const flagIcon = (name, path2) => {
|
|
8394
8404
|
if (allowedIcons.has(name) || allowedIcons.has(normIcon(name))) return;
|
|
8395
8405
|
issues.push({
|
|
8396
8406
|
severity: hygiene,
|
|
8397
8407
|
pass: "icons",
|
|
8398
|
-
path,
|
|
8408
|
+
path: path2,
|
|
8399
8409
|
message: `unknown icon "${name}" \u2014 renders the _unknown marker on device. Run \`himi icons\` for the valid names, or add a row to core/schema/icon-sources.json + \`yarn icons:gen\`. Already an ERROR under --strict; becomes an error by default one release after the catalog ships (docs/icons.md \xA72.6).`
|
|
8400
8410
|
});
|
|
8401
8411
|
};
|
|
@@ -10675,14 +10685,14 @@ function tokenColorProblems(colors) {
|
|
|
10675
10685
|
const problems = [];
|
|
10676
10686
|
for (const [name, value] of Object.entries(colors ?? {})) {
|
|
10677
10687
|
const leaves = typeof value === "object" && value !== null && !Array.isArray(value) ? Object.entries(value).map(([variant, raw]) => [`${name}.${variant}`, raw]) : [[name, value]];
|
|
10678
|
-
for (const [
|
|
10688
|
+
for (const [path2, raw] of leaves) {
|
|
10679
10689
|
if (typeof raw !== "string") {
|
|
10680
|
-
problems.push({ path, value: JSON.stringify(raw) ?? String(raw) });
|
|
10690
|
+
problems.push({ path: path2, value: JSON.stringify(raw) ?? String(raw) });
|
|
10681
10691
|
continue;
|
|
10682
10692
|
}
|
|
10683
10693
|
if (isCanonicalHex(raw)) continue;
|
|
10684
10694
|
const suggestion = canonicalHex(raw);
|
|
10685
|
-
problems.push(suggestion ? { path, value: raw, suggestion } : { path, value: raw });
|
|
10695
|
+
problems.push(suggestion ? { path: path2, value: raw, suggestion } : { path: path2, value: raw });
|
|
10686
10696
|
}
|
|
10687
10697
|
}
|
|
10688
10698
|
return problems;
|
|
@@ -11345,10 +11355,10 @@ function resolveAppDirIcon(appDir2) {
|
|
|
11345
11355
|
return findContentIconPath(appDir2) ?? findAppIconPath(appDir2);
|
|
11346
11356
|
}
|
|
11347
11357
|
function readIconFromDir(appDir2) {
|
|
11348
|
-
const
|
|
11349
|
-
if (!
|
|
11358
|
+
const path2 = resolveAppDirIcon(appDir2);
|
|
11359
|
+
if (!path2) return null;
|
|
11350
11360
|
try {
|
|
11351
|
-
return readFileSync15(
|
|
11361
|
+
return readFileSync15(path2);
|
|
11352
11362
|
} catch {
|
|
11353
11363
|
return null;
|
|
11354
11364
|
}
|
|
@@ -11698,11 +11708,11 @@ function playState(dir) {
|
|
|
11698
11708
|
}
|
|
11699
11709
|
async function iconStatus(dir) {
|
|
11700
11710
|
const declared = declaredIconName(dir);
|
|
11701
|
-
const
|
|
11711
|
+
const path2 = resolveAppDirIcon(dir);
|
|
11702
11712
|
const play = playState(dir);
|
|
11703
11713
|
const base = {
|
|
11704
11714
|
declared,
|
|
11705
|
-
path,
|
|
11715
|
+
path: path2,
|
|
11706
11716
|
play,
|
|
11707
11717
|
bytes: null,
|
|
11708
11718
|
sha256: null,
|
|
@@ -11714,21 +11724,21 @@ async function iconStatus(dir) {
|
|
|
11714
11724
|
verdict: "missing",
|
|
11715
11725
|
policyChecklist: POLICY_CHECKLIST
|
|
11716
11726
|
};
|
|
11717
|
-
if (!
|
|
11727
|
+
if (!path2 || !existsSync15(path2)) return base;
|
|
11718
11728
|
let png;
|
|
11719
11729
|
try {
|
|
11720
|
-
if (!statSync4(
|
|
11730
|
+
if (!statSync4(path2).isFile()) {
|
|
11721
11731
|
return {
|
|
11722
11732
|
...base,
|
|
11723
|
-
byteIssues: [`at ${
|
|
11733
|
+
byteIssues: [`at ${path2} is a directory, not a PNG file`],
|
|
11724
11734
|
verdict: "blocked"
|
|
11725
11735
|
};
|
|
11726
11736
|
}
|
|
11727
|
-
png = readFileSync16(
|
|
11737
|
+
png = readFileSync16(path2);
|
|
11728
11738
|
} catch (err) {
|
|
11729
11739
|
return {
|
|
11730
11740
|
...base,
|
|
11731
|
-
byteIssues: [`at ${
|
|
11741
|
+
byteIssues: [`at ${path2} could not be read (${err.message.split("\n")[0]})`],
|
|
11732
11742
|
verdict: "blocked"
|
|
11733
11743
|
};
|
|
11734
11744
|
}
|
|
@@ -11766,7 +11776,7 @@ async function iconStatus(dir) {
|
|
|
11766
11776
|
...status,
|
|
11767
11777
|
pixelFindings: [{
|
|
11768
11778
|
level: "error",
|
|
11769
|
-
message: `App icon at ${
|
|
11779
|
+
message: `App icon at ${path2} could not be decoded as an image (${err.message.split("\n")[0]}) \u2014 it is not a usable PNG. Replace it with \`himi icon set <file.png>\`.`
|
|
11770
11780
|
}],
|
|
11771
11781
|
pixelsChecked: false,
|
|
11772
11782
|
verdict: "blocked"
|
|
@@ -11951,15 +11961,15 @@ function loadCatalog() {
|
|
|
11951
11961
|
cached = JSON.parse(readFileSync17(override, "utf8"));
|
|
11952
11962
|
return cached;
|
|
11953
11963
|
}
|
|
11954
|
-
const
|
|
11955
|
-
if (!
|
|
11964
|
+
const path2 = CATALOG_CANDIDATES.find((p) => existsSync17(p));
|
|
11965
|
+
if (!path2) {
|
|
11956
11966
|
throw new Error(
|
|
11957
11967
|
`font catalog not found. Looked in:
|
|
11958
11968
|
${CATALOG_CANDIDATES.join("\n ")}
|
|
11959
11969
|
In the repo, run \`npm run fonts:catalog\`. In a published @wix/himalaya-cli this is a packaging bug \u2014 the catalog should ship under the package's stdlib/fonts/.`
|
|
11960
11970
|
);
|
|
11961
11971
|
}
|
|
11962
|
-
cached = JSON.parse(readFileSync17(
|
|
11972
|
+
cached = JSON.parse(readFileSync17(path2, "utf8"));
|
|
11963
11973
|
return cached;
|
|
11964
11974
|
}
|
|
11965
11975
|
function renderableFamilies(catalog = loadCatalog()) {
|
|
@@ -12242,9 +12252,9 @@ async function offRepoFontBytes(plan, opts = {}) {
|
|
|
12242
12252
|
out.hostProvided.push(r.family);
|
|
12243
12253
|
continue;
|
|
12244
12254
|
}
|
|
12245
|
-
const
|
|
12246
|
-
if (
|
|
12247
|
-
out.unavailable.push({ family: r.family, reason:
|
|
12255
|
+
const failed2 = r.faces.find((f) => !f.got.ok);
|
|
12256
|
+
if (failed2 && !failed2.got.ok) {
|
|
12257
|
+
out.unavailable.push({ family: r.family, reason: failed2.got.reason });
|
|
12248
12258
|
continue;
|
|
12249
12259
|
}
|
|
12250
12260
|
out.ready.push({
|
|
@@ -12719,9 +12729,9 @@ __export(fonts_exports, {
|
|
|
12719
12729
|
});
|
|
12720
12730
|
import { existsSync as existsSync19, readFileSync as readFileSync19 } from "node:fs";
|
|
12721
12731
|
import { join as join22 } from "node:path";
|
|
12722
|
-
function readJson(
|
|
12732
|
+
function readJson(path2, fallback) {
|
|
12723
12733
|
try {
|
|
12724
|
-
return JSON.parse(readFileSync19(
|
|
12734
|
+
return JSON.parse(readFileSync19(path2, "utf8"));
|
|
12725
12735
|
} catch {
|
|
12726
12736
|
return fallback;
|
|
12727
12737
|
}
|
|
@@ -12999,22 +13009,22 @@ function lc(h) {
|
|
|
12999
13009
|
for (const [k, v] of Object.entries(h ?? {})) o[k.toLowerCase()] = v;
|
|
13000
13010
|
return o;
|
|
13001
13011
|
}
|
|
13002
|
-
function matchRuleEx(rules, method,
|
|
13012
|
+
function matchRuleEx(rules, method, path2, ctx = {}) {
|
|
13003
13013
|
for (const r of rules) {
|
|
13004
13014
|
if (!r.enabled) continue;
|
|
13005
13015
|
const m = r.matcher;
|
|
13006
13016
|
if (m.method && m.method.toUpperCase() !== method.toUpperCase()) continue;
|
|
13007
13017
|
if (m.host && ctx.host && !globToRegExp(m.host).test(ctx.host)) continue;
|
|
13008
13018
|
if (m.host && !ctx.host) continue;
|
|
13009
|
-
const captures = { path, host: ctx.host ?? "" };
|
|
13019
|
+
const captures = { path: path2, host: ctx.host ?? "" };
|
|
13010
13020
|
if (m.pathRegex) {
|
|
13011
|
-
const mm = new RegExp(m.pathRegex).exec(
|
|
13021
|
+
const mm = new RegExp(m.pathRegex).exec(path2);
|
|
13012
13022
|
if (!mm) continue;
|
|
13013
13023
|
mm.forEach((g, i) => {
|
|
13014
13024
|
captures[String(i)] = g ?? "";
|
|
13015
13025
|
});
|
|
13016
13026
|
} else if (m.pathGlob) {
|
|
13017
|
-
if (!globToRegExp(m.pathGlob).test(
|
|
13027
|
+
if (!globToRegExp(m.pathGlob).test(path2)) continue;
|
|
13018
13028
|
}
|
|
13019
13029
|
if (m.query) {
|
|
13020
13030
|
const q = ctx.query ?? {};
|
|
@@ -13090,15 +13100,15 @@ function isNativePlatform(value) {
|
|
|
13090
13100
|
function isNativeAuditStatus(value) {
|
|
13091
13101
|
return typeof value === "string" && NATIVE_AUDIT_STATUSES.includes(value);
|
|
13092
13102
|
}
|
|
13093
|
-
function readText(
|
|
13103
|
+
function readText(path2) {
|
|
13094
13104
|
try {
|
|
13095
|
-
return existsSync21(
|
|
13105
|
+
return existsSync21(path2) ? readFileSync21(path2, "utf8") : null;
|
|
13096
13106
|
} catch {
|
|
13097
13107
|
return null;
|
|
13098
13108
|
}
|
|
13099
13109
|
}
|
|
13100
|
-
function parseEvidence(
|
|
13101
|
-
const raw = readText(
|
|
13110
|
+
function parseEvidence(path2) {
|
|
13111
|
+
const raw = readText(path2);
|
|
13102
13112
|
if (raw === null) return { evidence: null };
|
|
13103
13113
|
try {
|
|
13104
13114
|
const value = JSON.parse(raw);
|
|
@@ -13126,9 +13136,9 @@ function recordedRenderWidths(content) {
|
|
|
13126
13136
|
const { evidence } = parseEvidence(uxEvidencePath(content));
|
|
13127
13137
|
return renderEvidenceEntries(evidence).map((entry) => entry.width);
|
|
13128
13138
|
}
|
|
13129
|
-
function writeEvidence(
|
|
13130
|
-
mkdirSync10(dirname13(
|
|
13131
|
-
writeFileSync9(
|
|
13139
|
+
function writeEvidence(path2, evidence) {
|
|
13140
|
+
mkdirSync10(dirname13(path2), { recursive: true });
|
|
13141
|
+
writeFileSync9(path2, JSON.stringify(evidence, null, 2) + "\n");
|
|
13132
13142
|
}
|
|
13133
13143
|
function recordedFilePath(dir, file) {
|
|
13134
13144
|
const rel = relative3(dir, resolve15(file));
|
|
@@ -13138,8 +13148,8 @@ function recordRenderWidth(content, entry) {
|
|
|
13138
13148
|
try {
|
|
13139
13149
|
if (!entry.screenId || !Number.isFinite(entry.width) || entry.width <= 0) return null;
|
|
13140
13150
|
const dir = resolve15(content);
|
|
13141
|
-
const
|
|
13142
|
-
const parsed = parseEvidence(
|
|
13151
|
+
const path2 = join24(dir, UX_EVIDENCE_PATH);
|
|
13152
|
+
const parsed = parseEvidence(path2);
|
|
13143
13153
|
if (parsed.error) return null;
|
|
13144
13154
|
const evidence = parsed.evidence ?? { version: 1, platforms: {} };
|
|
13145
13155
|
const width = entry.width;
|
|
@@ -13155,7 +13165,7 @@ function recordRenderWidth(content, entry) {
|
|
|
13155
13165
|
if (at >= 0) renders[at] = written;
|
|
13156
13166
|
else renders.push(written);
|
|
13157
13167
|
evidence.renders = renders;
|
|
13158
|
-
writeEvidence(
|
|
13168
|
+
writeEvidence(path2, evidence);
|
|
13159
13169
|
return written;
|
|
13160
13170
|
} catch {
|
|
13161
13171
|
return null;
|
|
@@ -13168,8 +13178,8 @@ function recordNativeAudit(content, platform, status, checks, reason, release) {
|
|
|
13168
13178
|
}
|
|
13169
13179
|
if (status === "unavailable" && !reason?.trim()) throw new Error("--reason is required when --status unavailable");
|
|
13170
13180
|
const dir = resolve15(content);
|
|
13171
|
-
const
|
|
13172
|
-
const parsed = parseEvidence(
|
|
13181
|
+
const path2 = join24(dir, UX_EVIDENCE_PATH);
|
|
13182
|
+
const parsed = parseEvidence(path2);
|
|
13173
13183
|
if (parsed.error) throw new Error(`${UX_EVIDENCE_PATH} ${parsed.error}`);
|
|
13174
13184
|
const evidence = parsed.evidence ?? { version: 1, platforms: {} };
|
|
13175
13185
|
evidence.platforms[platform] = {
|
|
@@ -13179,12 +13189,12 @@ function recordNativeAudit(content, platform, status, checks, reason, release) {
|
|
|
13179
13189
|
...release?.releaseId && release.releaseHash ? { releaseId: release.releaseId, releaseHash: release.releaseHash } : {},
|
|
13180
13190
|
recordedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
13181
13191
|
};
|
|
13182
|
-
writeEvidence(
|
|
13192
|
+
writeEvidence(path2, evidence);
|
|
13183
13193
|
return evidence;
|
|
13184
13194
|
}
|
|
13185
13195
|
function uxEvidenceForRelease(content, release) {
|
|
13186
13196
|
const { releaseId, releaseHash } = release;
|
|
13187
|
-
const
|
|
13197
|
+
const path2 = uxEvidencePath(content);
|
|
13188
13198
|
const base = {
|
|
13189
13199
|
path: UX_EVIDENCE_PATH,
|
|
13190
13200
|
platforms: [],
|
|
@@ -13194,8 +13204,8 @@ function uxEvidenceForRelease(content, release) {
|
|
|
13194
13204
|
inheritedScreens: [],
|
|
13195
13205
|
malformed: []
|
|
13196
13206
|
};
|
|
13197
|
-
if (!existsSync21(
|
|
13198
|
-
const parsed = parseEvidence(
|
|
13207
|
+
if (!existsSync21(path2)) return { ...base, state: "absent" };
|
|
13208
|
+
const parsed = parseEvidence(path2);
|
|
13199
13209
|
if (parsed.error) return { ...base, state: "unreadable", error: parsed.error };
|
|
13200
13210
|
if (!parsed.evidence) return { ...base, state: "absent" };
|
|
13201
13211
|
const recorded = [];
|
|
@@ -14248,9 +14258,9 @@ function placeholderHashes() {
|
|
|
14248
14258
|
const current = templateIconSha256();
|
|
14249
14259
|
return current ? [LEGACY_PLACEHOLDER_SHA256, current] : [LEGACY_PLACEHOLDER_SHA256];
|
|
14250
14260
|
}
|
|
14251
|
-
function fileSha256(
|
|
14261
|
+
function fileSha256(path2) {
|
|
14252
14262
|
try {
|
|
14253
|
-
return createHash7("sha256").update(readFileSync24(
|
|
14263
|
+
return createHash7("sha256").update(readFileSync24(path2)).digest("hex");
|
|
14254
14264
|
} catch {
|
|
14255
14265
|
return null;
|
|
14256
14266
|
}
|
|
@@ -14699,12 +14709,12 @@ function hostAppliesDeferredWidgetActions(app) {
|
|
|
14699
14709
|
const dir = stack.pop();
|
|
14700
14710
|
for (const entry of readdirSync13(dir, { withFileTypes: true })) {
|
|
14701
14711
|
if (entry.name.startsWith(".") || entry.name === "GeneratedLiveActivity") continue;
|
|
14702
|
-
const
|
|
14712
|
+
const path2 = join29(dir, entry.name);
|
|
14703
14713
|
if (entry.isDirectory()) {
|
|
14704
14714
|
if (entry.name.endsWith(".xcodeproj") || entry.name === "build") continue;
|
|
14705
|
-
stack.push(
|
|
14715
|
+
stack.push(path2);
|
|
14706
14716
|
} else if (entry.name.endsWith(".swift")) {
|
|
14707
|
-
if (readFileSync26(
|
|
14717
|
+
if (readFileSync26(path2, "utf8").includes("WidgetActionRelay.drain(")) return true;
|
|
14708
14718
|
}
|
|
14709
14719
|
}
|
|
14710
14720
|
}
|
|
@@ -14735,29 +14745,29 @@ function androidManifestPath2(app) {
|
|
|
14735
14745
|
function automotiveAppDescPath(app) {
|
|
14736
14746
|
return join29(dirname16(androidManifestPath2(app)), "res", "xml", "automotive_app_desc.xml");
|
|
14737
14747
|
}
|
|
14738
|
-
function applyToFile(
|
|
14739
|
-
if (!existsSync26(
|
|
14740
|
-
const before = readFileSync26(
|
|
14741
|
-
if (!hasMarkers(before, kind, label2)) return { path, outcome: "skipped" };
|
|
14748
|
+
function applyToFile(path2, kind, label2, render, check) {
|
|
14749
|
+
if (!existsSync26(path2)) return { path: path2, outcome: "skipped" };
|
|
14750
|
+
const before = readFileSync26(path2, "utf8");
|
|
14751
|
+
if (!hasMarkers(before, kind, label2)) return { path: path2, outcome: "skipped" };
|
|
14742
14752
|
const after = injectBlock(before, kind, label2, render);
|
|
14743
|
-
if (after === before) return { path, outcome: "unchanged" };
|
|
14744
|
-
if (check) return { path, outcome: "drift" };
|
|
14745
|
-
writeFileSync11(
|
|
14746
|
-
return { path, outcome: "written" };
|
|
14747
|
-
}
|
|
14748
|
-
function applyWholeFile(
|
|
14749
|
-
const current = existsSync26(
|
|
14750
|
-
if (current === content) return { path, outcome: "unchanged" };
|
|
14751
|
-
if (check) return { path, outcome: "drift" };
|
|
14752
|
-
mkdirSync12(dirname16(
|
|
14753
|
-
writeFileSync11(
|
|
14754
|
-
return { path, outcome: "written" };
|
|
14755
|
-
}
|
|
14756
|
-
function removeWholeFile(
|
|
14757
|
-
if (!existsSync26(
|
|
14758
|
-
if (check) return { path, outcome: "drift" };
|
|
14759
|
-
rmSync4(
|
|
14760
|
-
return { path, outcome: "removed" };
|
|
14753
|
+
if (after === before) return { path: path2, outcome: "unchanged" };
|
|
14754
|
+
if (check) return { path: path2, outcome: "drift" };
|
|
14755
|
+
writeFileSync11(path2, after);
|
|
14756
|
+
return { path: path2, outcome: "written" };
|
|
14757
|
+
}
|
|
14758
|
+
function applyWholeFile(path2, content, check) {
|
|
14759
|
+
const current = existsSync26(path2) ? readFileSync26(path2, "utf8") : null;
|
|
14760
|
+
if (current === content) return { path: path2, outcome: "unchanged" };
|
|
14761
|
+
if (check) return { path: path2, outcome: "drift" };
|
|
14762
|
+
mkdirSync12(dirname16(path2), { recursive: true });
|
|
14763
|
+
writeFileSync11(path2, content);
|
|
14764
|
+
return { path: path2, outcome: "written" };
|
|
14765
|
+
}
|
|
14766
|
+
function removeWholeFile(path2, check) {
|
|
14767
|
+
if (!existsSync26(path2)) return { path: path2, outcome: "skipped" };
|
|
14768
|
+
if (check) return { path: path2, outcome: "drift" };
|
|
14769
|
+
rmSync4(path2);
|
|
14770
|
+
return { path: path2, outcome: "removed" };
|
|
14761
14771
|
}
|
|
14762
14772
|
function genNativeConfig(app, opts = {}) {
|
|
14763
14773
|
const check = opts.check ?? false;
|
|
@@ -15003,15 +15013,15 @@ function collectBrandFonts(appDir2) {
|
|
|
15003
15013
|
const rel = typeof raw?.file === "string" ? raw.file : "";
|
|
15004
15014
|
if (!family || !postscriptName || !rel) continue;
|
|
15005
15015
|
if (rel.startsWith("/") || rel.split("/").includes("..")) continue;
|
|
15006
|
-
const
|
|
15016
|
+
const path2 = join30(appDir2, rel);
|
|
15007
15017
|
try {
|
|
15008
|
-
if (!lstatSync4(
|
|
15018
|
+
if (!lstatSync4(path2).isFile()) continue;
|
|
15009
15019
|
const root = realpathSync3(appDir2);
|
|
15010
|
-
if (!realpathSync3(
|
|
15020
|
+
if (!realpathSync3(path2).startsWith(root + sep6)) continue;
|
|
15011
15021
|
} catch {
|
|
15012
15022
|
continue;
|
|
15013
15023
|
}
|
|
15014
|
-
out.push({ family, postscriptName, weight, path });
|
|
15024
|
+
out.push({ family, postscriptName, weight, path: path2 });
|
|
15015
15025
|
}
|
|
15016
15026
|
return out;
|
|
15017
15027
|
}
|
|
@@ -15200,7 +15210,7 @@ async function loadContainedDevModule(name, entry, dir) {
|
|
|
15200
15210
|
// Both throw synchronously; `handleWant` awaits them inside its own try, so the guest sees an
|
|
15201
15211
|
// ordinary rejection exactly as it would from any failing transport — while the host keeps the
|
|
15202
15212
|
// record the guest's `catch` cannot erase.
|
|
15203
|
-
wixCall: (method,
|
|
15213
|
+
wixCall: (method, path2) => refuseHost("himalaya.wixApi.call", `${method} ${path2}`),
|
|
15204
15214
|
dispatch: (action) => refuseHost("himalaya.dispatch", action)
|
|
15205
15215
|
});
|
|
15206
15216
|
const session = ran.session;
|
|
@@ -15303,7 +15313,7 @@ async function loadContainedDevModule(name, entry, dir) {
|
|
|
15303
15313
|
createStore: () => storeStub,
|
|
15304
15314
|
...meta.dataRoutes?.length ? {
|
|
15305
15315
|
dataRoutes: Object.fromEntries(
|
|
15306
|
-
meta.dataRoutes.map((
|
|
15316
|
+
meta.dataRoutes.map((path2) => [path2, () => refuse(name, `the app data route ${JSON.stringify(path2)}`)])
|
|
15307
15317
|
)
|
|
15308
15318
|
} : {},
|
|
15309
15319
|
// NOT defaulted. An absent seed crosses as absent and the proxy carries `undefined`, which is
|
|
@@ -16095,8 +16105,8 @@ import { createHash as createHash9, randomBytes as randomBytes3 } from "node:cry
|
|
|
16095
16105
|
function b64url(buf) {
|
|
16096
16106
|
return buf.toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
16097
16107
|
}
|
|
16098
|
-
async function postJson(
|
|
16099
|
-
const res = await fetch(`${API}${
|
|
16108
|
+
async function postJson(path2, body, auth) {
|
|
16109
|
+
const res = await fetch(`${API}${path2}`, {
|
|
16100
16110
|
method: "POST",
|
|
16101
16111
|
headers: { "Content-Type": "application/json", ...auth ? { Authorization: auth } : {} },
|
|
16102
16112
|
body: JSON.stringify(body)
|
|
@@ -16111,11 +16121,11 @@ async function mintVisitor(clientId) {
|
|
|
16111
16121
|
}
|
|
16112
16122
|
function isRedirectCallback(url, redirectUri) {
|
|
16113
16123
|
if (url.startsWith(redirectUri)) return true;
|
|
16114
|
-
const
|
|
16124
|
+
const path2 = (u) => u.pathname.replace(/\/+$/, "") || "/";
|
|
16115
16125
|
try {
|
|
16116
16126
|
const got = new URL(url);
|
|
16117
16127
|
const want = new URL(redirectUri);
|
|
16118
|
-
return got.protocol === want.protocol && got.host === want.host &&
|
|
16128
|
+
return got.protocol === want.protocol && got.host === want.host && path2(got) === path2(want);
|
|
16119
16129
|
} catch {
|
|
16120
16130
|
return false;
|
|
16121
16131
|
}
|
|
@@ -16205,8 +16215,8 @@ async function memberDirectRegister(clientId, redirectUri, email, password, firs
|
|
|
16205
16215
|
const memberToken = await exchangeSessionToken(clientId, redirectUri, visitorToken, sessionToken);
|
|
16206
16216
|
return { memberToken, visitorToken };
|
|
16207
16217
|
}
|
|
16208
|
-
async function webWixCall(method,
|
|
16209
|
-
const url = /^https?:\/\//i.test(
|
|
16218
|
+
async function webWixCall(method, path2, body, token, cookie, forwardedHeaders = {}) {
|
|
16219
|
+
const url = /^https?:\/\//i.test(path2) ? path2 : `${API}${path2.startsWith("/") ? path2 : "/" + path2}`;
|
|
16210
16220
|
if (!isWixTarget(url)) {
|
|
16211
16221
|
throw new Error(`refusing to send Wix credentials to a non-Wix host (${targetHost(url) || "no host"})`);
|
|
16212
16222
|
}
|
|
@@ -16276,10 +16286,10 @@ function resolveNetMocks(fileMocks, appDeclared) {
|
|
|
16276
16286
|
if (declared.length > 0) return { mocks: { mode: appDeclared?.mode, rules: declared }, source: "app" };
|
|
16277
16287
|
return null;
|
|
16278
16288
|
}
|
|
16279
|
-
function readNetMocksFile(
|
|
16289
|
+
function readNetMocksFile(path2) {
|
|
16280
16290
|
try {
|
|
16281
|
-
if (!existsSync30(
|
|
16282
|
-
const raw = JSON.parse(readFileSync30(
|
|
16291
|
+
if (!existsSync30(path2)) return null;
|
|
16292
|
+
const raw = JSON.parse(readFileSync30(path2, "utf-8"));
|
|
16283
16293
|
if (Array.isArray(raw)) return wixMockRuleErrors(raw).length ? null : { rules: raw };
|
|
16284
16294
|
if (raw && typeof raw === "object") {
|
|
16285
16295
|
const o = raw;
|
|
@@ -16357,20 +16367,20 @@ function parseTarget(target) {
|
|
|
16357
16367
|
});
|
|
16358
16368
|
return { host: u.host, path: u.pathname, query };
|
|
16359
16369
|
} catch {
|
|
16360
|
-
const
|
|
16370
|
+
const path2 = target.split("?")[0];
|
|
16361
16371
|
const query = {};
|
|
16362
16372
|
new URLSearchParams(target.split("?")[1] ?? "").forEach((v, k) => {
|
|
16363
16373
|
query[k] = v;
|
|
16364
16374
|
});
|
|
16365
|
-
return { host: "", path, query };
|
|
16375
|
+
return { host: "", path: path2, query };
|
|
16366
16376
|
}
|
|
16367
16377
|
}
|
|
16368
16378
|
async function handleWixGateway(gw, app, adminUrl, req, res, wixClientId) {
|
|
16369
16379
|
const url = req.url ?? "";
|
|
16370
|
-
const
|
|
16371
|
-
const scope =
|
|
16380
|
+
const path2 = url.split("?")[0];
|
|
16381
|
+
const scope = path2.startsWith("/__dev/wix/") ? "wix" : path2.startsWith("/__dev/net/") ? "net" : null;
|
|
16372
16382
|
if (!scope) return false;
|
|
16373
|
-
const suffix =
|
|
16383
|
+
const suffix = path2.slice(scope === "wix" ? "/__dev/wix/".length : "/__dev/net/".length);
|
|
16374
16384
|
const method = (req.method ?? "GET").toUpperCase();
|
|
16375
16385
|
if (suffix === "events" && method === "GET") {
|
|
16376
16386
|
res.writeHead(200, {
|
|
@@ -16784,17 +16794,17 @@ var init_sha256 = __esm({
|
|
|
16784
16794
|
});
|
|
16785
16795
|
|
|
16786
16796
|
// ../../core/serve-runtime/src/wix-bridge.ts
|
|
16787
|
-
function absoluteUrlRejection(
|
|
16797
|
+
function absoluteUrlRejection(path2) {
|
|
16788
16798
|
let host = "";
|
|
16789
16799
|
try {
|
|
16790
|
-
host = new URL(
|
|
16800
|
+
host = new URL(path2).host;
|
|
16791
16801
|
} catch {
|
|
16792
16802
|
}
|
|
16793
16803
|
return OWNER_SCOPED_WIX_HOST.test(host) ? "owner-only" : "open-proxy";
|
|
16794
16804
|
}
|
|
16795
|
-
async function wixVisitorCall(method,
|
|
16796
|
-
if (/^[a-z][a-z0-9+.-]*:\/\//i.test(
|
|
16797
|
-
const url = `${WIX_API}${
|
|
16805
|
+
async function wixVisitorCall(method, path2, body, token, fetchImpl = fetch, forwardedHeaders = {}) {
|
|
16806
|
+
if (/^[a-z][a-z0-9+.-]*:\/\//i.test(path2)) throw new Error("absolute URLs are not allowed");
|
|
16807
|
+
const url = `${WIX_API}${path2.startsWith("/") ? path2 : `/${path2}`}`;
|
|
16798
16808
|
const res = await fetchImpl(url, {
|
|
16799
16809
|
method,
|
|
16800
16810
|
// Same header shape the dev-server bridge has always sent (wixapis accepts the
|
|
@@ -16825,13 +16835,13 @@ function normalizeWixForwardedHeaders(input) {
|
|
|
16825
16835
|
function isSafeMsid(msid) {
|
|
16826
16836
|
return /^[0-9a-fA-F-]{10,64}$/.test(msid);
|
|
16827
16837
|
}
|
|
16828
|
-
function isOwnerSitesPath(
|
|
16829
|
-
return
|
|
16838
|
+
function isOwnerSitesPath(path2) {
|
|
16839
|
+
return path2 === OWNER_SITES_QUERY_PATH || path2 === OWNER_SITES_COUNT_PATH;
|
|
16830
16840
|
}
|
|
16831
|
-
async function wixOwnerSitesCall(
|
|
16832
|
-
if (!isOwnerSitesPath(
|
|
16841
|
+
async function wixOwnerSitesCall(path2, cookieHeader, body, fetchImpl = fetch) {
|
|
16842
|
+
if (!isOwnerSitesPath(path2)) throw new Error("not an owner-sites path");
|
|
16833
16843
|
const xsrf = /(?:^|;\s*)XSRF-TOKEN=([^;]+)/.exec(cookieHeader)?.[1];
|
|
16834
|
-
const res = await fetchImpl(`${WIX_API}${
|
|
16844
|
+
const res = await fetchImpl(`${WIX_API}${path2}`, {
|
|
16835
16845
|
method: "POST",
|
|
16836
16846
|
headers: {
|
|
16837
16847
|
Cookie: cookieHeader,
|
|
@@ -17106,8 +17116,8 @@ import { resolve as resolve24 } from "node:path";
|
|
|
17106
17116
|
import { fileURLToPath as fileURLToPath14 } from "node:url";
|
|
17107
17117
|
function loadCatalog2(tag) {
|
|
17108
17118
|
if (catalogCache.has(tag)) return catalogCache.get(tag);
|
|
17109
|
-
const
|
|
17110
|
-
const map = existsSync31(
|
|
17119
|
+
const path2 = resolve24(ROOT4, `tools/l10n/catalog.${tag}.json`);
|
|
17120
|
+
const map = existsSync31(path2) ? sourceMap(parseCatalog(readFileSync31(path2, "utf8"))) : /* @__PURE__ */ new Map();
|
|
17111
17121
|
catalogCache.set(tag, map);
|
|
17112
17122
|
return map;
|
|
17113
17123
|
}
|
|
@@ -17116,8 +17126,8 @@ function pickLocale(acceptLanguage) {
|
|
|
17116
17126
|
const tags = acceptLanguage.split(",").map((s) => s.split(";")[0].trim().toLowerCase()).map((s) => s.split("-")[0]).filter((s) => s.length > 0);
|
|
17117
17127
|
for (const tag of tags) {
|
|
17118
17128
|
if (tag === "en") continue;
|
|
17119
|
-
const
|
|
17120
|
-
if (existsSync31(
|
|
17129
|
+
const path2 = resolve24(ROOT4, `tools/l10n/catalog.${tag}.json`);
|
|
17130
|
+
if (existsSync31(path2)) return tag;
|
|
17121
17131
|
}
|
|
17122
17132
|
return null;
|
|
17123
17133
|
}
|
|
@@ -17213,8 +17223,8 @@ function assignStableIds(descriptor) {
|
|
|
17213
17223
|
used.add(out);
|
|
17214
17224
|
return out;
|
|
17215
17225
|
};
|
|
17216
|
-
const assign2 = (node,
|
|
17217
|
-
const base = node.id && node.id.length > 0 ? node.id :
|
|
17226
|
+
const assign2 = (node, path2) => {
|
|
17227
|
+
const base = node.id && node.id.length > 0 ? node.id : path2;
|
|
17218
17228
|
node.id = uniquify(base);
|
|
17219
17229
|
const typeCounts = {};
|
|
17220
17230
|
forEachChildComponent(node, (child) => {
|
|
@@ -17222,7 +17232,7 @@ function assignStableIds(descriptor) {
|
|
|
17222
17232
|
const n = typeCounts[t] ?? 0;
|
|
17223
17233
|
typeCounts[t] = n + 1;
|
|
17224
17234
|
const seg = n === 0 ? t : `${t}.${n}`;
|
|
17225
|
-
assign2(child, `${
|
|
17235
|
+
assign2(child, `${path2}/${seg}`);
|
|
17226
17236
|
});
|
|
17227
17237
|
};
|
|
17228
17238
|
if (isNode(descriptor.payload)) assign2(descriptor.payload, descriptor.screenId);
|
|
@@ -18142,8 +18152,8 @@ var init_tier4_verifier = __esm({
|
|
|
18142
18152
|
async verifyServedFile(bundleId, relPath, providedBytes) {
|
|
18143
18153
|
const expected = this.expectedSri(bundleId, relPath);
|
|
18144
18154
|
if (!expected) return { ok: true };
|
|
18145
|
-
const
|
|
18146
|
-
const bytes2 = providedBytes ?? (existsSync33(
|
|
18155
|
+
const path2 = resolve25(this.tier4Root, bundleId, relPath);
|
|
18156
|
+
const bytes2 = providedBytes ?? (existsSync33(path2) ? readFileSync33(path2) : null);
|
|
18147
18157
|
if (!bytes2) return { ok: false, reason: "file not found" };
|
|
18148
18158
|
if (computeSri(bytes2) !== expected) return { ok: false, reason: "sri mismatch" };
|
|
18149
18159
|
return { ok: true };
|
|
@@ -18235,9 +18245,9 @@ function targetTenant(url, headers2, hostApp) {
|
|
|
18235
18245
|
const hdr = headers2["x-himalaya-app"];
|
|
18236
18246
|
const headerApp = Array.isArray(hdr) ? hdr[0] : hdr;
|
|
18237
18247
|
let app = headerApp && headerApp.trim() ? headerApp.trim() : void 0;
|
|
18238
|
-
const [
|
|
18248
|
+
const [path2, query] = url.split("?");
|
|
18239
18249
|
if (!app) {
|
|
18240
|
-
const m = /^\/v1\/(?:app-config|action-handlers)\/([^/?]+)/.exec(
|
|
18250
|
+
const m = /^\/v1\/(?:app-config|action-handlers)\/([^/?]+)/.exec(path2);
|
|
18241
18251
|
if (m) app = decodeURIComponent(m[1]);
|
|
18242
18252
|
}
|
|
18243
18253
|
if (!app && query) {
|
|
@@ -18249,9 +18259,9 @@ function targetTenant(url, headers2, hostApp) {
|
|
|
18249
18259
|
return app;
|
|
18250
18260
|
}
|
|
18251
18261
|
function shouldServeFromPlane(url, headers2, hostApp) {
|
|
18252
|
-
const
|
|
18253
|
-
if (
|
|
18254
|
-
if (!
|
|
18262
|
+
const path2 = url.split("?")[0];
|
|
18263
|
+
if (path2 === "/v1/apps" || path2 === "/v1/templates") return true;
|
|
18264
|
+
if (!path2.startsWith("/v1/")) return false;
|
|
18255
18265
|
return targetTenant(url, headers2, hostApp) !== null;
|
|
18256
18266
|
}
|
|
18257
18267
|
async function proxyToServe(base, req, res) {
|
|
@@ -18511,8 +18521,8 @@ var init_FakeServiceProvider = __esm({
|
|
|
18511
18521
|
constructor(services) {
|
|
18512
18522
|
this.services = services;
|
|
18513
18523
|
}
|
|
18514
|
-
value(
|
|
18515
|
-
const raw =
|
|
18524
|
+
value(path2) {
|
|
18525
|
+
const raw = path2.startsWith("$service:") ? path2.slice("$service:".length) : path2;
|
|
18516
18526
|
const dot = raw.indexOf(".");
|
|
18517
18527
|
const name = dot < 0 ? raw : raw.slice(0, dot);
|
|
18518
18528
|
const tail = dot < 0 ? "" : raw.slice(dot + 1);
|
|
@@ -18524,8 +18534,8 @@ var init_FakeServiceProvider = __esm({
|
|
|
18524
18534
|
}
|
|
18525
18535
|
return cur;
|
|
18526
18536
|
}
|
|
18527
|
-
subscribe(
|
|
18528
|
-
cb(this.value(
|
|
18537
|
+
subscribe(path2, cb) {
|
|
18538
|
+
cb(this.value(path2));
|
|
18529
18539
|
return () => {
|
|
18530
18540
|
};
|
|
18531
18541
|
}
|
|
@@ -19025,21 +19035,21 @@ function useResolvedScalar(v, ctx) {
|
|
|
19025
19035
|
return bound ?? void 0;
|
|
19026
19036
|
}
|
|
19027
19037
|
function useBoundValue(ctx, binding2) {
|
|
19028
|
-
const
|
|
19038
|
+
const path2 = servicePath(binding2);
|
|
19029
19039
|
const active = !!ctx.provider && !!binding2;
|
|
19030
19040
|
const [state, setState] = useState(() => ({
|
|
19031
|
-
path,
|
|
19032
|
-
v: active ? ctx.provider.value(
|
|
19041
|
+
path: path2,
|
|
19042
|
+
v: active ? ctx.provider.value(path2) : void 0
|
|
19033
19043
|
}));
|
|
19034
|
-
const current = state.path ===
|
|
19035
|
-
if (state.path !==
|
|
19044
|
+
const current = state.path === path2 ? state.v : active ? ctx.provider.value(path2) : void 0;
|
|
19045
|
+
if (state.path !== path2) setState({ path: path2, v: current });
|
|
19036
19046
|
useEffect(() => {
|
|
19037
19047
|
if (!ctx.provider || !binding2) return;
|
|
19038
19048
|
return ctx.provider.subscribe(
|
|
19039
|
-
|
|
19040
|
-
(nv) => setState((prev) => prev.path ===
|
|
19049
|
+
path2,
|
|
19050
|
+
(nv) => setState((prev) => prev.path === path2 && Object.is(prev.v, nv) ? prev : { path: path2, v: nv })
|
|
19041
19051
|
);
|
|
19042
|
-
}, [ctx.provider,
|
|
19052
|
+
}, [ctx.provider, path2, binding2]);
|
|
19043
19053
|
return active ? current : void 0;
|
|
19044
19054
|
}
|
|
19045
19055
|
function useBoundValues(ctx, bindings) {
|
|
@@ -19050,16 +19060,16 @@ function useBoundValues(ctx, bindings) {
|
|
|
19050
19060
|
[key2]
|
|
19051
19061
|
);
|
|
19052
19062
|
const [values, setValues] = useState(
|
|
19053
|
-
() => paths.map((
|
|
19063
|
+
() => paths.map((path2) => ctx.provider && path2 ? ctx.provider.value(path2) : void 0)
|
|
19054
19064
|
);
|
|
19055
19065
|
useEffect(() => {
|
|
19056
19066
|
if (!ctx.provider) {
|
|
19057
19067
|
setValues(paths.map(() => void 0));
|
|
19058
19068
|
return;
|
|
19059
19069
|
}
|
|
19060
|
-
setValues(paths.map((
|
|
19070
|
+
setValues(paths.map((path2) => path2 ? ctx.provider.value(path2) : void 0));
|
|
19061
19071
|
const disposers = paths.map(
|
|
19062
|
-
(
|
|
19072
|
+
(path2, i) => path2 ? ctx.provider.subscribe(path2, (v) => setValues((prev) => {
|
|
19063
19073
|
const next = prev.slice();
|
|
19064
19074
|
next[i] = v;
|
|
19065
19075
|
return next;
|
|
@@ -22623,9 +22633,9 @@ var init_worker_subtree_safe_types_generated = __esm({
|
|
|
22623
22633
|
function isRecord(value) {
|
|
22624
22634
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
22625
22635
|
}
|
|
22626
|
-
function valueAtPath(value,
|
|
22636
|
+
function valueAtPath(value, path2) {
|
|
22627
22637
|
let current = value;
|
|
22628
|
-
for (const segment of
|
|
22638
|
+
for (const segment of path2.split(".")) {
|
|
22629
22639
|
if (!isRecord(current)) return void 0;
|
|
22630
22640
|
current = current[segment];
|
|
22631
22641
|
}
|
|
@@ -22839,8 +22849,8 @@ function validateWorkerSubtree(raw, slotId, policy, actionCatalog) {
|
|
|
22839
22849
|
return;
|
|
22840
22850
|
}
|
|
22841
22851
|
const props = node.body.props;
|
|
22842
|
-
for (const
|
|
22843
|
-
for (const
|
|
22852
|
+
for (const path2 of rule.actions) checkAction(valueAtPath(props, path2));
|
|
22853
|
+
for (const path2 of WORKER_SUBTREE_COMMON_ACTION_PATHS) checkAction(valueAtPath(node, path2));
|
|
22844
22854
|
for (const childRule of rule.children) {
|
|
22845
22855
|
const value = valueAtPath(props, childRule.path);
|
|
22846
22856
|
if (value === void 0 || value === null) {
|
|
@@ -22893,9 +22903,9 @@ var init_worker_subtree = __esm({
|
|
|
22893
22903
|
// ../../core/web-renderer/src/renderNode.tsx
|
|
22894
22904
|
import React5 from "react";
|
|
22895
22905
|
import { Fragment as Fragment3, jsx as jsx6, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
22896
|
-
function boundTokenName(
|
|
22897
|
-
if (typeof
|
|
22898
|
-
const r = resolveScalarStatic(
|
|
22906
|
+
function boundTokenName(path2, fallback, ctx) {
|
|
22907
|
+
if (typeof path2 === "string" && path2) {
|
|
22908
|
+
const r = resolveScalarStatic(path2, ctx);
|
|
22899
22909
|
if (typeof r === "string" && r) return r;
|
|
22900
22910
|
}
|
|
22901
22911
|
return fallback;
|
|
@@ -24201,8 +24211,8 @@ function renderNodeInner(node, ctx) {
|
|
|
24201
24211
|
}
|
|
24202
24212
|
}
|
|
24203
24213
|
const bind = {};
|
|
24204
|
-
const addBind = (cssProp,
|
|
24205
|
-
const k = measureKey(
|
|
24214
|
+
const addBind = (cssProp, path2) => {
|
|
24215
|
+
const k = measureKey(path2);
|
|
24206
24216
|
if (k) bind[cssProp] = k;
|
|
24207
24217
|
};
|
|
24208
24218
|
addBind("height", m?.heightPath ?? m?.height_path);
|
|
@@ -24293,9 +24303,9 @@ function renderNodeInner(node, ctx) {
|
|
|
24293
24303
|
}
|
|
24294
24304
|
return out;
|
|
24295
24305
|
}
|
|
24296
|
-
function boundModNumber(
|
|
24297
|
-
if (typeof
|
|
24298
|
-
const r = resolveScalarStatic(
|
|
24306
|
+
function boundModNumber(path2, ctx) {
|
|
24307
|
+
if (typeof path2 !== "string" || !path2 || measureKey(path2) != null || !isBinding(path2)) return void 0;
|
|
24308
|
+
const r = resolveScalarStatic(path2, ctx);
|
|
24299
24309
|
const n = typeof r === "number" ? r : typeof r === "string" && r.trim() !== "" ? Number(r) : NaN;
|
|
24300
24310
|
return Number.isFinite(n) ? n : void 0;
|
|
24301
24311
|
}
|
|
@@ -25242,8 +25252,8 @@ var init_renderNode = __esm({
|
|
|
25242
25252
|
WorkerSubtreeNode = withExtras("WorkerSubtreeNode", ({ props, ctx, wrap, nodeId }) => {
|
|
25243
25253
|
const slotId = nodeId;
|
|
25244
25254
|
const extra = wrap;
|
|
25245
|
-
const
|
|
25246
|
-
const value = useBoundValue(ctx, typeof
|
|
25255
|
+
const path2 = props.treeJsonPath ?? props.tree_json_path;
|
|
25256
|
+
const value = useBoundValue(ctx, typeof path2 === "string" ? path2 : "");
|
|
25247
25257
|
const policy = props.policy;
|
|
25248
25258
|
const catalog = ctx.provider && typeof ctx.provider.listActions === "function" ? ctx.provider : null;
|
|
25249
25259
|
const validation = React5.useMemo(() => {
|
|
@@ -25672,8 +25682,8 @@ var init_renderNode = __esm({
|
|
|
25672
25682
|
this.state = state;
|
|
25673
25683
|
for (const cb of this.listeners) cb(this.value("media"));
|
|
25674
25684
|
}
|
|
25675
|
-
value(
|
|
25676
|
-
const bare =
|
|
25685
|
+
value(path2) {
|
|
25686
|
+
const bare = path2.replace(/^\$service:/, "");
|
|
25677
25687
|
const parts = bare.split(".").filter(Boolean);
|
|
25678
25688
|
if (parts[0] === "media") parts.shift();
|
|
25679
25689
|
let value = this.state;
|
|
@@ -25683,8 +25693,8 @@ var init_renderNode = __esm({
|
|
|
25683
25693
|
}
|
|
25684
25694
|
return value;
|
|
25685
25695
|
}
|
|
25686
|
-
subscribe(
|
|
25687
|
-
const wrapped = () => cb(this.value(
|
|
25696
|
+
subscribe(path2, cb) {
|
|
25697
|
+
const wrapped = () => cb(this.value(path2));
|
|
25688
25698
|
this.listeners.add(wrapped);
|
|
25689
25699
|
wrapped();
|
|
25690
25700
|
return () => this.listeners.delete(wrapped);
|
|
@@ -26935,9 +26945,9 @@ var init_renderNode = __esm({
|
|
|
26935
26945
|
});
|
|
26936
26946
|
AvatarStripNode = withExtras("AvatarStripNode", ({ props, ctx, wrap }) => {
|
|
26937
26947
|
const C = ctx.color;
|
|
26938
|
-
const
|
|
26939
|
-
const bound = useResolvedScalar(
|
|
26940
|
-
const raw =
|
|
26948
|
+
const path2 = props.avatarsPath ?? props.avatars_path;
|
|
26949
|
+
const bound = useResolvedScalar(path2, ctx);
|
|
26950
|
+
const raw = path2 != null ? bound : props.avatars;
|
|
26941
26951
|
const avatars = Array.isArray(raw) ? raw : [];
|
|
26942
26952
|
const size = props.size ?? 36;
|
|
26943
26953
|
const maxVisible = props.maxVisible ?? 4;
|
|
@@ -28568,27 +28578,27 @@ function resolveTreeScalar(v, provider, itemScope) {
|
|
|
28568
28578
|
if (v.startsWith("$service:")) return provider.value(v) ?? void 0;
|
|
28569
28579
|
return v;
|
|
28570
28580
|
}
|
|
28571
|
-
function collectResolvedMediaRecord(record2,
|
|
28572
|
-
if (typeof record2.actionId === "string" ||
|
|
28581
|
+
function collectResolvedMediaRecord(record2, path2, context) {
|
|
28582
|
+
if (typeof record2.actionId === "string" || path2 && typeof record2.body === "object") return;
|
|
28573
28583
|
for (const [key2, child] of Object.entries(record2)) {
|
|
28574
|
-
collectResolvedMediaValues(child,
|
|
28584
|
+
collectResolvedMediaValues(child, path2 ? `${path2}.${key2}` : key2, {
|
|
28575
28585
|
...context,
|
|
28576
28586
|
insideMediaProperty: context.insideMediaProperty || isMediaValueProperty(key2)
|
|
28577
28587
|
});
|
|
28578
28588
|
}
|
|
28579
28589
|
}
|
|
28580
|
-
function collectResolvedMediaValues(value,
|
|
28590
|
+
function collectResolvedMediaValues(value, path2, context) {
|
|
28581
28591
|
const resolved2 = typeof value === "string" ? resolveTreeScalar(value, context.provider, context.itemScope) : value;
|
|
28582
28592
|
if (typeof resolved2 === "string") {
|
|
28583
|
-
if (context.insideMediaProperty) context.values[
|
|
28593
|
+
if (context.insideMediaProperty) context.values[path2] = resolved2;
|
|
28584
28594
|
return;
|
|
28585
28595
|
}
|
|
28586
28596
|
if (Array.isArray(resolved2)) {
|
|
28587
|
-
resolved2.forEach((item, index) => collectResolvedMediaValues(item, `${
|
|
28597
|
+
resolved2.forEach((item, index) => collectResolvedMediaValues(item, `${path2}[${index}]`, context));
|
|
28588
28598
|
return;
|
|
28589
28599
|
}
|
|
28590
28600
|
if (resolved2 && typeof resolved2 === "object") {
|
|
28591
|
-
collectResolvedMediaRecord(resolved2,
|
|
28601
|
+
collectResolvedMediaRecord(resolved2, path2, context);
|
|
28592
28602
|
}
|
|
28593
28603
|
}
|
|
28594
28604
|
function collectComponentMediaValues(type, props, context) {
|
|
@@ -28609,12 +28619,12 @@ function collectNativeOnly(node) {
|
|
|
28609
28619
|
walk2(node);
|
|
28610
28620
|
return [...found].sort();
|
|
28611
28621
|
}
|
|
28612
|
-
function buildRenderTree(node,
|
|
28622
|
+
function buildRenderTree(node, path2 = "$", provider = null, itemScope = void 0, includeRawProps = false, env = null) {
|
|
28613
28623
|
if (!node || typeof node !== "object") return null;
|
|
28614
28624
|
const obj2 = node;
|
|
28615
28625
|
const body = obj2.body ?? {};
|
|
28616
28626
|
const type = typeof body.type === "string" ? body.type : "Unknown";
|
|
28617
|
-
const id = typeof obj2.id === "string" && obj2.id ? obj2.id :
|
|
28627
|
+
const id = typeof obj2.id === "string" && obj2.id ? obj2.id : path2;
|
|
28618
28628
|
const out = { id, type };
|
|
28619
28629
|
if (typeof body.package === "string") out.package = body.package;
|
|
28620
28630
|
const props = body.props ?? {};
|
|
@@ -28723,7 +28733,7 @@ async function renderDescriptorWeb(descriptor, tokens, scheme, wantPng, services
|
|
|
28723
28733
|
const stickyHeader = isSduiNode(desc.stickyHeader) ? desc.stickyHeader : void 0;
|
|
28724
28734
|
const stickyFooter = isSduiNode(desc.stickyFooter) ? desc.stickyFooter : void 0;
|
|
28725
28735
|
const clientEnv = clientEnvFor(scheme, width, isRTL);
|
|
28726
|
-
const treeOf = (node,
|
|
28736
|
+
const treeOf = (node, path2, prov) => buildRenderTree(node, path2, prov, void 0, true, clientEnv);
|
|
28727
28737
|
const renderTree = composeStickyTree(
|
|
28728
28738
|
treeOf(payload, "$", null) ?? void 0,
|
|
28729
28739
|
stickyHeader ? treeOf(stickyHeader, "$.stickyHeader", null) : null,
|
|
@@ -28923,8 +28933,8 @@ function declaredFamilies(tokens) {
|
|
|
28923
28933
|
async function faceBytes(face, catalog, opts) {
|
|
28924
28934
|
try {
|
|
28925
28935
|
if (opts.source) {
|
|
28926
|
-
const
|
|
28927
|
-
return
|
|
28936
|
+
const path2 = opts.source(face.file, face.sha256);
|
|
28937
|
+
return path2 ? readFileSync34(path2) : null;
|
|
28928
28938
|
}
|
|
28929
28939
|
const bytes2 = await catalogFaceBytes(face.sha256, { catalog, ...opts.fetchFace ? { fetchFace: opts.fetchFace } : {} });
|
|
28930
28940
|
return bytes2 ?? null;
|
|
@@ -29431,13 +29441,13 @@ function validateName(name) {
|
|
|
29431
29441
|
if (typeof name !== "string") fail("name must be a string");
|
|
29432
29442
|
if (!/^[a-z][a-z0-9]*(?:[-_.][a-z0-9]+)*$/.test(name)) fail(`name must be lowercase kebab-case: "${name}"`);
|
|
29433
29443
|
}
|
|
29434
|
-
function validateFunctionRoute(method,
|
|
29444
|
+
function validateFunctionRoute(method, path2) {
|
|
29435
29445
|
if (!HTTP_METHODS.includes(method)) fail(`method must be one of ${HTTP_METHODS.join(", ")}`);
|
|
29436
|
-
if (
|
|
29437
|
-
fail(`path must be an absolute, normalized route without query syntax: "${
|
|
29446
|
+
if (path2 !== "/" && (!/^\/[A-Za-z0-9._~!$&'()*+,;=:@%/-]+$/.test(path2) || path2.includes("//") || path2.endsWith("/"))) {
|
|
29447
|
+
fail(`path must be an absolute, normalized route without query syntax: "${path2}"`);
|
|
29438
29448
|
}
|
|
29439
|
-
const params = [...
|
|
29440
|
-
if (new Set(params).size !== params.length) fail(`path contains duplicate parameter names: "${
|
|
29449
|
+
const params = [...path2.matchAll(/:([A-Za-z][A-Za-z0-9_]*)/g)].map((match) => match[1]);
|
|
29450
|
+
if (new Set(params).size !== params.length) fail(`path contains duplicate parameter names: "${path2}"`);
|
|
29441
29451
|
}
|
|
29442
29452
|
function validateFunctionDefinition(definition) {
|
|
29443
29453
|
validateName(definition.name);
|
|
@@ -30846,9 +30856,9 @@ function nativeSourceFiles(directory, extension, buildDirMaxDepth, depth = 1) {
|
|
|
30846
30856
|
return entries.flatMap((entry) => {
|
|
30847
30857
|
if (NATIVE_SCRATCH_DIRS.has(entry.name)) return [];
|
|
30848
30858
|
if (entry.name === BUILD_OUTPUT_DIR && depth <= buildDirMaxDepth) return [];
|
|
30849
|
-
const
|
|
30850
|
-
if (entry.isDirectory()) return nativeSourceFiles(
|
|
30851
|
-
return entry.name.endsWith(extension) ? [
|
|
30859
|
+
const path2 = resolve28(directory, entry.name);
|
|
30860
|
+
if (entry.isDirectory()) return nativeSourceFiles(path2, extension, buildDirMaxDepth, depth + 1);
|
|
30861
|
+
return entry.name.endsWith(extension) ? [path2] : [];
|
|
30852
30862
|
});
|
|
30853
30863
|
}
|
|
30854
30864
|
function registeredActions(source) {
|
|
@@ -31111,10 +31121,10 @@ function readJsonAt(app, file, root) {
|
|
|
31111
31121
|
}
|
|
31112
31122
|
}
|
|
31113
31123
|
function writeJsonAt(app, file, root, value) {
|
|
31114
|
-
const
|
|
31115
|
-
mkdirSync15(dirname20(
|
|
31116
|
-
writeFileSync12(
|
|
31117
|
-
return
|
|
31124
|
+
const path2 = appConfigPath(app, file, root);
|
|
31125
|
+
mkdirSync15(dirname20(path2), { recursive: true });
|
|
31126
|
+
writeFileSync12(path2, JSON.stringify(value, null, 2) + "\n");
|
|
31127
|
+
return path2;
|
|
31118
31128
|
}
|
|
31119
31129
|
function sanitizeOverlay(raw) {
|
|
31120
31130
|
if (!("appIconBadgeSources" in raw)) return raw;
|
|
@@ -31350,8 +31360,8 @@ function handleL10nRequest(req, res, state) {
|
|
|
31350
31360
|
if (!state.app || app !== state.app.name) {
|
|
31351
31361
|
return sendJson(res, 404, { error: "unknown_app", app }, cors);
|
|
31352
31362
|
}
|
|
31353
|
-
const
|
|
31354
|
-
if (!existsSync36(
|
|
31363
|
+
const path2 = resolve30(state.app.dir, "l10n", `${tag}.json`);
|
|
31364
|
+
if (!existsSync36(path2)) {
|
|
31355
31365
|
res.writeHead(204, cors);
|
|
31356
31366
|
res.end();
|
|
31357
31367
|
return;
|
|
@@ -31360,7 +31370,7 @@ function handleL10nRequest(req, res, state) {
|
|
|
31360
31370
|
let messages;
|
|
31361
31371
|
try {
|
|
31362
31372
|
messages = Object.fromEntries(
|
|
31363
|
-
keyMap(parseCatalog(readFileSync39(
|
|
31373
|
+
keyMap(parseCatalog(readFileSync39(path2, "utf8")), { sourceFallback: tag === sourceLocale })
|
|
31364
31374
|
);
|
|
31365
31375
|
} catch {
|
|
31366
31376
|
return sendJson(res, 500, { error: "catalog_unreadable", app, tag }, cors);
|
|
@@ -31590,16 +31600,16 @@ async function handleOwnerSitesRequest(req, res) {
|
|
|
31590
31600
|
async function handleOwnerChatRequest(req, res) {
|
|
31591
31601
|
const cors = { "access-control-allow-origin": "*" };
|
|
31592
31602
|
const u = new URL(req.url ?? "", "http://localhost");
|
|
31593
|
-
const
|
|
31603
|
+
const path2 = u.pathname;
|
|
31594
31604
|
const { resolveMetaSiteId, listChatroomsLive, sendChatMessageLive } = await import("./apps/wix-owner-clone-live.js");
|
|
31595
|
-
if (
|
|
31605
|
+
if (path2 === "/v1/owner-chat/chatrooms" && req.method === "GET") {
|
|
31596
31606
|
const metaSiteId = u.searchParams.get("metaSiteId") || await resolveMetaSiteId();
|
|
31597
31607
|
if (!metaSiteId) return sendJson(res, 400, { error: "no_meta_site" }, cors);
|
|
31598
31608
|
const rooms = await listChatroomsLive(metaSiteId);
|
|
31599
31609
|
if (rooms == null) return sendJson(res, 502, { error: "chatrooms_unavailable" }, cors);
|
|
31600
31610
|
return sendJson(res, 200, { chatrooms: rooms }, cors);
|
|
31601
31611
|
}
|
|
31602
|
-
if (
|
|
31612
|
+
if (path2 === "/v1/owner-chat/send" && req.method === "POST") {
|
|
31603
31613
|
let parsed;
|
|
31604
31614
|
try {
|
|
31605
31615
|
parsed = JSON.parse(await readBody2(req) || "{}");
|
|
@@ -32318,7 +32328,7 @@ function webWixSession(req, res, state) {
|
|
|
32318
32328
|
async function handleWebWix(req, res, state) {
|
|
32319
32329
|
const session = webWixSession(req, res, state);
|
|
32320
32330
|
const auth = resolveWebWixAuth(state.app);
|
|
32321
|
-
const
|
|
32331
|
+
const path2 = new URL(req.url ?? "", "http://localhost").pathname;
|
|
32322
32332
|
const readJson3 = async () => {
|
|
32323
32333
|
const chunks = [];
|
|
32324
32334
|
for await (const c of req) chunks.push(c);
|
|
@@ -32335,7 +32345,7 @@ async function handleWebWix(req, res, state) {
|
|
|
32335
32345
|
res.setHeader("access-control-allow-origin", "*");
|
|
32336
32346
|
res.end(JSON.stringify(obj2));
|
|
32337
32347
|
};
|
|
32338
|
-
if (
|
|
32348
|
+
if (path2 === "/v1/__webwix/login" && req.method === "POST") {
|
|
32339
32349
|
const b = await readJson3();
|
|
32340
32350
|
try {
|
|
32341
32351
|
const { memberToken, visitorToken } = await memberDirectLogin(
|
|
@@ -32352,7 +32362,7 @@ async function handleWebWix(req, res, state) {
|
|
|
32352
32362
|
return reply(200, { ok: false, error: String(e?.message ?? e) });
|
|
32353
32363
|
}
|
|
32354
32364
|
}
|
|
32355
|
-
if (
|
|
32365
|
+
if (path2 === "/v1/__webwix/call" && req.method === "POST") {
|
|
32356
32366
|
const b = await readJson3();
|
|
32357
32367
|
if (b.ownerMsid !== void 0 || b.checkOwnerSession === true) {
|
|
32358
32368
|
const msid = String(b.ownerMsid ?? "");
|
|
@@ -32439,12 +32449,12 @@ async function handleWebWix(req, res, state) {
|
|
|
32439
32449
|
return reply(200, { status: 0, body: JSON.stringify({ error: String(e?.message ?? e) }) });
|
|
32440
32450
|
}
|
|
32441
32451
|
}
|
|
32442
|
-
if (
|
|
32452
|
+
if (path2 === "/v1/__webwix/logout" && req.method === "POST") {
|
|
32443
32453
|
session.memberToken = void 0;
|
|
32444
32454
|
session.email = void 0;
|
|
32445
32455
|
return reply(200, { ok: true });
|
|
32446
32456
|
}
|
|
32447
|
-
if (
|
|
32457
|
+
if (path2 === "/v1/__webwix/identity" && (req.method === "GET" || req.method === "POST")) {
|
|
32448
32458
|
if (!session.memberToken) return reply(200, { authenticated: false, userId: null, email: "" });
|
|
32449
32459
|
let userId = null;
|
|
32450
32460
|
try {
|
|
@@ -32468,7 +32478,7 @@ async function handleWebWix(req, res, state) {
|
|
|
32468
32478
|
} : null
|
|
32469
32479
|
});
|
|
32470
32480
|
}
|
|
32471
|
-
if (
|
|
32481
|
+
if (path2 === "/v1/__webwix/register" && req.method === "POST") {
|
|
32472
32482
|
const b = await readJson3();
|
|
32473
32483
|
try {
|
|
32474
32484
|
const { memberToken, visitorToken } = await memberDirectRegister(
|
|
@@ -32885,8 +32895,8 @@ async function handleDev(req, res, state) {
|
|
|
32885
32895
|
}
|
|
32886
32896
|
async function handleAdminPlayground(req, res, state) {
|
|
32887
32897
|
const url = req.url ?? "";
|
|
32888
|
-
const
|
|
32889
|
-
const sampleMatch = /^\/v1\/admin\/sdui-samples\/([^/]+)$/.exec(
|
|
32898
|
+
const path2 = url.split("?")[0];
|
|
32899
|
+
const sampleMatch = /^\/v1\/admin\/sdui-samples\/([^/]+)$/.exec(path2);
|
|
32890
32900
|
if (sampleMatch && req.method === "GET") {
|
|
32891
32901
|
const name = decodeURIComponent(sampleMatch[1]);
|
|
32892
32902
|
if (!/^[a-zA-Z0-9._-]+$/.test(name)) return sendJson(res, 400, { error: "bad_name" });
|
|
@@ -32897,7 +32907,7 @@ async function handleAdminPlayground(req, res, state) {
|
|
|
32897
32907
|
return sendJson(res, 404, { error: "sample_not_found", name });
|
|
32898
32908
|
}
|
|
32899
32909
|
}
|
|
32900
|
-
if (
|
|
32910
|
+
if (path2 === "/v1/admin/sdui-samples" && req.method === "GET") {
|
|
32901
32911
|
try {
|
|
32902
32912
|
const { readdir } = await import("node:fs/promises");
|
|
32903
32913
|
const files = (await readdir(SAMPLES_ROOT)).filter((f) => f.endsWith(".json"));
|
|
@@ -32906,7 +32916,7 @@ async function handleAdminPlayground(req, res, state) {
|
|
|
32906
32916
|
return sendJson(res, 500, { error: err.message });
|
|
32907
32917
|
}
|
|
32908
32918
|
}
|
|
32909
|
-
if (
|
|
32919
|
+
if (path2 === "/v1/admin/screens" && req.method === "GET") {
|
|
32910
32920
|
const meta = state.app.meta;
|
|
32911
32921
|
const fixedIds = meta.screenIds;
|
|
32912
32922
|
const fixedSet = new Set(fixedIds);
|
|
@@ -32955,12 +32965,12 @@ async function handleAdminPlayground(req, res, state) {
|
|
|
32955
32965
|
templatedPatterns: meta.templatedPatterns
|
|
32956
32966
|
});
|
|
32957
32967
|
}
|
|
32958
|
-
const historyMatch = /^\/v1\/admin\/screens\/(.+?)\/history(?:\?|$)/.exec(
|
|
32968
|
+
const historyMatch = /^\/v1\/admin\/screens\/(.+?)\/history(?:\?|$)/.exec(path2);
|
|
32959
32969
|
if (historyMatch && req.method === "GET") {
|
|
32960
32970
|
const screenId = decodeURIComponent(historyMatch[1]);
|
|
32961
32971
|
return sendJson(res, 200, { screenId, history: state.localOverrideHistory.get(screenId) ?? [] });
|
|
32962
32972
|
}
|
|
32963
|
-
const revertMatch = /^\/v1\/admin\/screens\/(.+?)\/revert(?:\?|$)/.exec(
|
|
32973
|
+
const revertMatch = /^\/v1\/admin\/screens\/(.+?)\/revert(?:\?|$)/.exec(path2);
|
|
32964
32974
|
if (revertMatch && req.method === "POST") {
|
|
32965
32975
|
const screenId = decodeURIComponent(revertMatch[1]);
|
|
32966
32976
|
const historyId = Number(new URLSearchParams(url.split("?")[1] ?? "").get("historyId"));
|
|
@@ -32976,7 +32986,7 @@ async function handleAdminPlayground(req, res, state) {
|
|
|
32976
32986
|
invalidate(state, screenId);
|
|
32977
32987
|
return sendJson(res, 200, { status: "ok", screenId, revertedTo: historyId });
|
|
32978
32988
|
}
|
|
32979
|
-
if (
|
|
32989
|
+
if (path2 === "/v1/admin/tab-badge" && req.method === "POST") {
|
|
32980
32990
|
let body;
|
|
32981
32991
|
try {
|
|
32982
32992
|
body = JSON.parse(await readBody2(req));
|
|
@@ -32995,7 +33005,7 @@ async function handleAdminPlayground(req, res, state) {
|
|
|
32995
33005
|
);
|
|
32996
33006
|
return sendJson(res, 200, { status: "ok", tabId: body.tabId, count: clearing ? null : body.count });
|
|
32997
33007
|
}
|
|
32998
|
-
const validateMatch = /^\/v1\/admin\/screens\/(.+?)\/validate(?:\?|$)/.exec(
|
|
33008
|
+
const validateMatch = /^\/v1\/admin\/screens\/(.+?)\/validate(?:\?|$)/.exec(path2);
|
|
32999
33009
|
if (validateMatch && req.method === "GET") {
|
|
33000
33010
|
const screenId = decodeURIComponent(validateMatch[1]);
|
|
33001
33011
|
const strict = /[?&]strict=1(?:&|$)/.test(url);
|
|
@@ -33023,7 +33033,7 @@ async function handleAdminPlayground(req, res, state) {
|
|
|
33023
33033
|
});
|
|
33024
33034
|
return sendJson(res, report2.ok ? 200 : 422, report2);
|
|
33025
33035
|
}
|
|
33026
|
-
const detailMatch = /^\/v1\/admin\/screens\/([^/]+)$/.exec(
|
|
33036
|
+
const detailMatch = /^\/v1\/admin\/screens\/([^/]+)$/.exec(path2);
|
|
33027
33037
|
if (detailMatch && req.method === "GET") {
|
|
33028
33038
|
const screenId = decodeURIComponent(detailMatch[1]);
|
|
33029
33039
|
const wantBuilt = /[?&]source=built(?:&|$)/.test(url);
|
|
@@ -33060,7 +33070,7 @@ async function handleAdminPlayground(req, res, state) {
|
|
|
33060
33070
|
invalidate(state, screenId);
|
|
33061
33071
|
return sendJson(res, existed ? 200 : 404, { status: existed ? "ok" : "not_found" });
|
|
33062
33072
|
}
|
|
33063
|
-
if (
|
|
33073
|
+
if (path2 === "/v1/admin/app-config" && state.app) {
|
|
33064
33074
|
const built = deriveNavigationConfig(state.app.meta);
|
|
33065
33075
|
if (req.method === "GET") {
|
|
33066
33076
|
const effective = state.appConfigOverride ? deepMerge3(built, state.appConfigOverride) : built;
|
|
@@ -33085,7 +33095,7 @@ async function handleAdminPlayground(req, res, state) {
|
|
|
33085
33095
|
return sendJson(res, existed ? 200 : 404, { status: existed ? "ok" : "not_found" });
|
|
33086
33096
|
}
|
|
33087
33097
|
}
|
|
33088
|
-
if (
|
|
33098
|
+
if (path2 === "/v1/admin/tokens" && state.app) {
|
|
33089
33099
|
const built = readAppTokens(state) ?? {};
|
|
33090
33100
|
if (req.method === "GET") {
|
|
33091
33101
|
const effective = state.tokensOverride ? deepMerge3(built, state.tokensOverride) : built;
|
|
@@ -33110,7 +33120,7 @@ async function handleAdminPlayground(req, res, state) {
|
|
|
33110
33120
|
return sendJson(res, existed ? 200 : 404, { status: existed ? "ok" : "not_found" });
|
|
33111
33121
|
}
|
|
33112
33122
|
}
|
|
33113
|
-
return sendJson(res, 404, { error: "unknown_admin_route", path });
|
|
33123
|
+
return sendJson(res, 404, { error: "unknown_admin_route", path: path2 });
|
|
33114
33124
|
}
|
|
33115
33125
|
function isNavControlPatch(patch) {
|
|
33116
33126
|
if (!patch || typeof patch !== "object") return false;
|
|
@@ -33165,10 +33175,10 @@ async function readBundleFile(name, dir) {
|
|
|
33165
33175
|
resolve30(root, `${name}.js`),
|
|
33166
33176
|
resolve30(root, name)
|
|
33167
33177
|
]);
|
|
33168
|
-
for (const
|
|
33169
|
-
if (!roots.some((root) =>
|
|
33178
|
+
for (const path2 of candidates) {
|
|
33179
|
+
if (!roots.some((root) => path2.startsWith(root))) continue;
|
|
33170
33180
|
try {
|
|
33171
|
-
const bytes2 = await readFile(
|
|
33181
|
+
const bytes2 = await readFile(path2);
|
|
33172
33182
|
const integrity2 = "sha256-" + createHash15("sha256").update(bytes2).digest("base64");
|
|
33173
33183
|
return { bytes: bytes2, integrity: integrity2 };
|
|
33174
33184
|
} catch {
|
|
@@ -33348,10 +33358,10 @@ function handleActionHandlersManifest(res, app) {
|
|
|
33348
33358
|
}
|
|
33349
33359
|
async function handleActionHandlerBundleGet(res, app) {
|
|
33350
33360
|
if (!/^[A-Za-z0-9_.\-]+$/.test(app)) return sendJson(res, 404, { error: "not_found" });
|
|
33351
|
-
const
|
|
33352
|
-
if (!
|
|
33361
|
+
const path2 = resolve30(ACTION_HANDLERS_ROOT, `${app}.handlers.js`);
|
|
33362
|
+
if (!path2.startsWith(ACTION_HANDLERS_ROOT)) return sendJson(res, 404, { error: "not_found" });
|
|
33353
33363
|
try {
|
|
33354
|
-
const bytes2 = await readFile(
|
|
33364
|
+
const bytes2 = await readFile(path2);
|
|
33355
33365
|
const integrity2 = "sha256-" + createHash15("sha256").update(bytes2).digest("base64");
|
|
33356
33366
|
res.setHeader("content-type", "application/javascript; charset=utf-8");
|
|
33357
33367
|
res.setHeader("cache-control", "max-age=300");
|
|
@@ -34125,13 +34135,13 @@ var init_capability_fixtures = __esm({
|
|
|
34125
34135
|
};
|
|
34126
34136
|
MEDIA_EXT = (url) => {
|
|
34127
34137
|
if (typeof url !== "string") return null;
|
|
34128
|
-
let
|
|
34138
|
+
let path2;
|
|
34129
34139
|
try {
|
|
34130
|
-
|
|
34140
|
+
path2 = new URL(url).pathname;
|
|
34131
34141
|
} catch {
|
|
34132
|
-
|
|
34142
|
+
path2 = url.split("#")[0].split("?")[0];
|
|
34133
34143
|
}
|
|
34134
|
-
const segment =
|
|
34144
|
+
const segment = path2.split("/").pop() ?? "";
|
|
34135
34145
|
const m = /\.([a-z0-9]{2,5})$/i.exec(segment);
|
|
34136
34146
|
return m ? m[1].toLowerCase() : null;
|
|
34137
34147
|
};
|
|
@@ -34292,9 +34302,9 @@ var init_capability_fixtures = __esm({
|
|
|
34292
34302
|
// made every write resolve to the same file, and a consumer passing that handle onward (an export
|
|
34293
34303
|
// writing `exports/<id>.gpx`) referenced something that does not exist.
|
|
34294
34304
|
"capability.files.write": (p, ctx) => {
|
|
34295
|
-
const
|
|
34296
|
-
const name =
|
|
34297
|
-
return { uri: `file:///${
|
|
34305
|
+
const path2 = typeof p.path === "string" && p.path ? p.path : "crawl/written.txt";
|
|
34306
|
+
const name = path2.split("/").pop() || path2;
|
|
34307
|
+
return { uri: `file:///${path2.replace(/^\/+/, "")}`, name, mimeType: typeof p.mimeType === "string" ? p.mimeType : "application/octet-stream", sizeBytes: 1024, modifiedAt: ctx.clock };
|
|
34298
34308
|
},
|
|
34299
34309
|
"capability.files.remove": () => ({ removed: true })
|
|
34300
34310
|
};
|
|
@@ -34581,14 +34591,14 @@ function relationalSignature(state) {
|
|
|
34581
34591
|
}
|
|
34582
34592
|
function listLengths(state, depth = 4) {
|
|
34583
34593
|
const out = {};
|
|
34584
|
-
const walk2 = (node,
|
|
34594
|
+
const walk2 = (node, path2, left) => {
|
|
34585
34595
|
if (left < 0 || node === null || typeof node !== "object") return;
|
|
34586
34596
|
if (Array.isArray(node)) {
|
|
34587
|
-
out[
|
|
34597
|
+
out[path2] = node.length;
|
|
34588
34598
|
return;
|
|
34589
34599
|
}
|
|
34590
34600
|
for (const [k, v] of Object.entries(node)) {
|
|
34591
|
-
walk2(v,
|
|
34601
|
+
walk2(v, path2 ? `${path2}.${k}` : k, left - 1);
|
|
34592
34602
|
}
|
|
34593
34603
|
};
|
|
34594
34604
|
walk2(state, "", depth);
|
|
@@ -34609,26 +34619,26 @@ function summarizeDiff(aSig, bSig, limit = 3) {
|
|
|
34609
34619
|
if (t === void 0) return "undefined";
|
|
34610
34620
|
return t.length > 80 ? `${t.slice(0, 77)}\u2026` : t;
|
|
34611
34621
|
};
|
|
34612
|
-
const walk2 = (x, y,
|
|
34622
|
+
const walk2 = (x, y, path2) => {
|
|
34613
34623
|
if (diffs.length >= limit) return;
|
|
34614
34624
|
const bothObjects = x !== null && y !== null && typeof x === "object" && typeof y === "object" && !Array.isArray(x) && !Array.isArray(y);
|
|
34615
34625
|
if (bothObjects) {
|
|
34616
34626
|
for (const k of /* @__PURE__ */ new Set([...Object.keys(x), ...Object.keys(y)])) {
|
|
34617
|
-
walk2(x[k], y[k],
|
|
34627
|
+
walk2(x[k], y[k], path2 ? `${path2}.${k}` : k);
|
|
34618
34628
|
}
|
|
34619
34629
|
return;
|
|
34620
34630
|
}
|
|
34621
34631
|
if (Array.isArray(x) && Array.isArray(y)) {
|
|
34622
34632
|
if (x.length !== y.length) {
|
|
34623
|
-
diffs.push(`${
|
|
34633
|
+
diffs.push(`${path2 || "state"}: ${x.length} \u2192 ${y.length} items`);
|
|
34624
34634
|
return;
|
|
34625
34635
|
}
|
|
34626
|
-
for (let i = 0; i < x.length && diffs.length < limit; i++) walk2(x[i], y[i], `${
|
|
34636
|
+
for (let i = 0; i < x.length && diffs.length < limit; i++) walk2(x[i], y[i], `${path2}[${i}]`);
|
|
34627
34637
|
return;
|
|
34628
34638
|
}
|
|
34629
34639
|
const xs = brief(x);
|
|
34630
34640
|
const ys = brief(y);
|
|
34631
|
-
if (xs !== ys) diffs.push(`${
|
|
34641
|
+
if (xs !== ys) diffs.push(`${path2 || "state"}: ${xs} \u2192 ${ys}`);
|
|
34632
34642
|
};
|
|
34633
34643
|
walk2(a, b, "");
|
|
34634
34644
|
return diffs.slice(0, limit).join("; ");
|
|
@@ -34717,6 +34727,7 @@ function actionSites(payload) {
|
|
|
34717
34727
|
actionId: a.actionId,
|
|
34718
34728
|
params: a.params ?? {},
|
|
34719
34729
|
...a.args ? { args: a.args } : {},
|
|
34730
|
+
...a.presentation ? { presentation: a.presentation } : {},
|
|
34720
34731
|
...ambient ? { itemsPath: ambient } : {},
|
|
34721
34732
|
// `rec` IS the prop bag that carries this callback — for a plain node that is
|
|
34722
34733
|
// `body.props`, and for a FormField variant the nested `text`/`picker`/… object, which
|
|
@@ -34835,8 +34846,8 @@ function sourceOfStack(stack, bundleMap) {
|
|
|
34835
34846
|
return mapBundleFrame(bundleMap, Number(m[1]), Number(m[2]) - 1) ?? void 0;
|
|
34836
34847
|
}
|
|
34837
34848
|
function netTransport(rules) {
|
|
34838
|
-
return async (method,
|
|
34839
|
-
const [bare, search] = String(
|
|
34849
|
+
return async (method, path2, body) => {
|
|
34850
|
+
const [bare, search] = String(path2).split("?", 2);
|
|
34840
34851
|
const query = {};
|
|
34841
34852
|
if (search) for (const [k, v] of new URLSearchParams(search)) query[k] = v;
|
|
34842
34853
|
const res = resolveScenario(rules, {
|
|
@@ -34883,9 +34894,9 @@ function layeredTransport(layers) {
|
|
|
34883
34894
|
const cms = layers.cmsSeed && Object.keys(layers.cmsSeed).length ? layers.cmsSeed : null;
|
|
34884
34895
|
const canned = layers.canned && Object.keys(layers.canned).length ? layers.canned : null;
|
|
34885
34896
|
const label2 = [rules && "mocked", cms && "cms", canned && "canned"].filter(Boolean).join("+") || "offline";
|
|
34886
|
-
const call = async (method,
|
|
34897
|
+
const call = async (method, path2, body) => {
|
|
34887
34898
|
const m = String(method).toUpperCase();
|
|
34888
|
-
const p = String(
|
|
34899
|
+
const p = String(path2);
|
|
34889
34900
|
const [bare, search] = p.split("?", 2);
|
|
34890
34901
|
if (rules) {
|
|
34891
34902
|
const query = {};
|
|
@@ -35364,9 +35375,9 @@ async function crawlScreenInner(opts) {
|
|
|
35364
35375
|
const resolveItem = (v) => {
|
|
35365
35376
|
if (typeof v !== "string" || !v.startsWith("$item")) return v;
|
|
35366
35377
|
if (!row0) return v;
|
|
35367
|
-
const
|
|
35368
|
-
if (!
|
|
35369
|
-
return pathValue(row0,
|
|
35378
|
+
const path2 = v === "$item" ? "" : v.startsWith("$item.") ? v.slice("$item.".length) : "";
|
|
35379
|
+
if (!path2) return v;
|
|
35380
|
+
return pathValue(row0, path2);
|
|
35370
35381
|
};
|
|
35371
35382
|
const target = resolveItem(merged.screenId);
|
|
35372
35383
|
if (typeof target !== "string" || !target || target.includes("$")) continue;
|
|
@@ -35466,6 +35477,23 @@ async function crawlScreenInner(opts) {
|
|
|
35466
35477
|
actionsSkipped.push({ action: s.actionId, why: "embedded-preview" });
|
|
35467
35478
|
return false;
|
|
35468
35479
|
});
|
|
35480
|
+
if (!opts.capabilitySuccess) {
|
|
35481
|
+
for (const site of sites) {
|
|
35482
|
+
if (site.actionId !== "himi.open") continue;
|
|
35483
|
+
if (["back", "dismiss", "alert", "snackbar"].includes(site.presentation ?? "")) continue;
|
|
35484
|
+
const target = site.args?.screenId ?? site.params.screenId;
|
|
35485
|
+
if (target != null && target !== "") continue;
|
|
35486
|
+
findings.push({
|
|
35487
|
+
screen: screenId,
|
|
35488
|
+
trigger: "boot",
|
|
35489
|
+
invariant: "nav-target-absent",
|
|
35490
|
+
severity: "error",
|
|
35491
|
+
at: site.componentId ?? void 0,
|
|
35492
|
+
message: '"himi.open" has no screenId \u2014 the tap opens nothing',
|
|
35493
|
+
hint: 'Pass { screenId: "detail", id: "selected-id" } in params. "screen" is not a routing key; put destination input alongside screenId.'
|
|
35494
|
+
});
|
|
35495
|
+
}
|
|
35496
|
+
}
|
|
35469
35497
|
const boot = (skipAppear = false) => bundleJs ? bootScreenWorker({ bundleJs, descriptor, wixCall, screenId, inputOverride: opts.inputOverride, budgetMs: opts.budgetMs, clock: opts.clock, seed: opts.seed, skipAppear, localDbSchema: opts.localDbSchema, capabilitySuccess: opts.capabilitySuccess === true, ...opts.evaluator ? { evaluator: opts.evaluator } : {} }) : null;
|
|
35470
35498
|
const check = (trigger, state, errors, defects = {}) => {
|
|
35471
35499
|
for (const [svc, paths] of Object.entries(defects)) {
|
|
@@ -35787,8 +35815,8 @@ async function crawlScreenHostileInner(opts, variant) {
|
|
|
35787
35815
|
const base = layeredTransport({ rules: opts.rules, cmsSeed: opts.cmsSeed, canned: opts.canned });
|
|
35788
35816
|
if (base.label === "offline") return [];
|
|
35789
35817
|
const axis = `hostile:${variant}`;
|
|
35790
|
-
const wixCall = variant === "empty" ? async (method,
|
|
35791
|
-
throw new Error(`Wix 500 for ${String(method).toUpperCase()} ${String(
|
|
35818
|
+
const wixCall = variant === "empty" ? async (method, path2, body) => emptiedArrays(await base.call(method, path2, body)) : async (method, path2) => {
|
|
35819
|
+
throw new Error(`Wix 500 for ${String(method).toUpperCase()} ${String(path2).split("?")[0]}`);
|
|
35792
35820
|
};
|
|
35793
35821
|
let w;
|
|
35794
35822
|
try {
|
|
@@ -35991,17 +36019,17 @@ async function crawlScreenDeep(opts, deep) {
|
|
|
35991
36019
|
localDbSchema: opts.localDbSchema,
|
|
35992
36020
|
capabilitySuccess: opts.capabilitySuccess === true
|
|
35993
36021
|
});
|
|
35994
|
-
const pathLabel = (
|
|
36022
|
+
const pathLabel = (path2) => path2.map((i) => sites[i].actionId.replace(/^tier5\./, "")).join(" \u2192 ");
|
|
35995
36023
|
while (queue.length) {
|
|
35996
36024
|
if (visited.size >= maxNodes || dispatches >= maxDispatches) {
|
|
35997
36025
|
capped = true;
|
|
35998
36026
|
break;
|
|
35999
36027
|
}
|
|
36000
|
-
const
|
|
36028
|
+
const path2 = queue.shift();
|
|
36001
36029
|
const w = await boot();
|
|
36002
36030
|
try {
|
|
36003
36031
|
let threwAt = null;
|
|
36004
|
-
for (const [step, siteIdx] of
|
|
36032
|
+
for (const [step, siteIdx] of path2.entries()) {
|
|
36005
36033
|
const site = sites[siteIdx];
|
|
36006
36034
|
const parsed = parseWorkerAction(site.actionId);
|
|
36007
36035
|
const handle = w.handles[parsed.service];
|
|
@@ -36023,7 +36051,7 @@ async function crawlScreenDeep(opts, deep) {
|
|
|
36023
36051
|
try {
|
|
36024
36052
|
await handle.dispatch(parsed.action, ...workerArgs(effective));
|
|
36025
36053
|
} catch (e) {
|
|
36026
|
-
if (step ===
|
|
36054
|
+
if (step === path2.length - 1 && path2.length >= 2) {
|
|
36027
36055
|
const source = sourceOfStack(e.stack, opts.bundleMap);
|
|
36028
36056
|
findings.push({
|
|
36029
36057
|
screen: screenId,
|
|
@@ -36032,7 +36060,7 @@ async function crawlScreenDeep(opts, deep) {
|
|
|
36032
36060
|
severity: "error",
|
|
36033
36061
|
axis: "deep",
|
|
36034
36062
|
...source ? { source } : {},
|
|
36035
|
-
message: `after ${pathLabel(
|
|
36063
|
+
message: `after ${pathLabel(path2)}: ${parsed.action}: ${errText(e)}`,
|
|
36036
36064
|
hint: "this chain of taps crashes the worker \u2014 each step passed alone, the SEQUENCE is the bug"
|
|
36037
36065
|
});
|
|
36038
36066
|
}
|
|
@@ -36046,8 +36074,8 @@ async function crawlScreenDeep(opts, deep) {
|
|
|
36046
36074
|
const hash = deepStateSignature(state, defects);
|
|
36047
36075
|
if (visited.has(hash)) continue;
|
|
36048
36076
|
visited.add(hash);
|
|
36049
|
-
if (
|
|
36050
|
-
const last = sites[
|
|
36077
|
+
if (path2.length >= 2) {
|
|
36078
|
+
const last = sites[path2[path2.length - 1]];
|
|
36051
36079
|
const lastTrigger = { tap: last.componentId, key: last.key, action: last.actionId };
|
|
36052
36080
|
for (const [svc, paths] of Object.entries(defects)) {
|
|
36053
36081
|
for (const p of paths) {
|
|
@@ -36057,7 +36085,7 @@ async function crawlScreenDeep(opts, deep) {
|
|
|
36057
36085
|
invariant: "non-finite-number",
|
|
36058
36086
|
severity: "error",
|
|
36059
36087
|
axis: "deep",
|
|
36060
|
-
message: `after ${pathLabel(
|
|
36088
|
+
message: `after ${pathLabel(path2)}: ${svc} state holds a non-finite number: ${p}`,
|
|
36061
36089
|
at: `${svc}.${p.split(" = ")[0]}`,
|
|
36062
36090
|
hint: "a chain of taps produced the bad arithmetic \u2014 each step alone was fine; check what the SEQUENCE accumulates"
|
|
36063
36091
|
});
|
|
@@ -36071,7 +36099,7 @@ async function crawlScreenDeep(opts, deep) {
|
|
|
36071
36099
|
invariant: d.kind,
|
|
36072
36100
|
severity: "error",
|
|
36073
36101
|
axis: "deep",
|
|
36074
|
-
message: `after ${pathLabel(
|
|
36102
|
+
message: `after ${pathLabel(path2)}: ${resolvedDefectMessage(d)}`,
|
|
36075
36103
|
at,
|
|
36076
36104
|
field,
|
|
36077
36105
|
hint: resolvedDefectHint(d)
|
|
@@ -36079,8 +36107,8 @@ async function crawlScreenDeep(opts, deep) {
|
|
|
36079
36107
|
});
|
|
36080
36108
|
}
|
|
36081
36109
|
}
|
|
36082
|
-
if (
|
|
36083
|
-
for (let i = 0; i < sites.length; i++) queue.push([...
|
|
36110
|
+
if (path2.length < deep.depth) {
|
|
36111
|
+
for (let i = 0; i < sites.length; i++) queue.push([...path2, i]);
|
|
36084
36112
|
}
|
|
36085
36113
|
} finally {
|
|
36086
36114
|
w.dispose();
|
|
@@ -36171,13 +36199,13 @@ async function crawlScreenRelations(opts) {
|
|
|
36171
36199
|
capabilitySuccess: opts.capabilitySuccess === true,
|
|
36172
36200
|
...opts.evaluator ? { evaluator: opts.evaluator } : {}
|
|
36173
36201
|
});
|
|
36174
|
-
const replay = async (
|
|
36202
|
+
const replay = async (path2, rowFor = () => null) => {
|
|
36175
36203
|
const w = await boot();
|
|
36176
36204
|
try {
|
|
36177
36205
|
if (w.errors.length) return null;
|
|
36178
36206
|
let prev = snapshot(w).state;
|
|
36179
36207
|
const bootState = prev;
|
|
36180
|
-
for (const [i, site] of
|
|
36208
|
+
for (const [i, site] of path2.entries()) {
|
|
36181
36209
|
const parsed = parseWorkerAction(site.actionId);
|
|
36182
36210
|
const h = w.handles[parsed.service];
|
|
36183
36211
|
if (!h || !h.actionNames().includes(parsed.action)) return null;
|
|
@@ -36533,9 +36561,9 @@ function routesOverlap(left, right) {
|
|
|
36533
36561
|
return segment.startsWith(":") || other.startsWith(":") || segment === other;
|
|
36534
36562
|
});
|
|
36535
36563
|
}
|
|
36536
|
-
function validateRouteConflicts(
|
|
36564
|
+
function validateRouteConflicts(definitions2) {
|
|
36537
36565
|
const seen = [];
|
|
36538
|
-
for (const definition of
|
|
36566
|
+
for (const definition of definitions2) {
|
|
36539
36567
|
validateFunctionDefinition(definition);
|
|
36540
36568
|
const previous = seen.find((route) => route.method === definition.method && routesOverlap(route.path, definition.path));
|
|
36541
36569
|
if (previous) throw new Error(`duplicate or ambiguous function route: ${definition.name} conflicts with ${previous.name} at ${definition.method} ${definition.path}`);
|
|
@@ -36589,13 +36617,13 @@ function rejectUnsafeSource(name, source) {
|
|
|
36589
36617
|
throw new Error(`function ${name} must export handler`);
|
|
36590
36618
|
}
|
|
36591
36619
|
}
|
|
36592
|
-
async function buildFunctions(
|
|
36593
|
-
validateRouteConflicts(
|
|
36620
|
+
async function buildFunctions(definitions2, sources, options = {}) {
|
|
36621
|
+
validateRouteConflicts(definitions2);
|
|
36594
36622
|
validateDependencyPolicy(options.dependencies ?? [], options.dependencyPolicy);
|
|
36595
36623
|
const sbom = createFunctionSbom(options.dependencies ?? []);
|
|
36596
36624
|
const runBuild = await (_buildP ??= loadBuild());
|
|
36597
36625
|
const built = [];
|
|
36598
|
-
for (const definition of
|
|
36626
|
+
for (const definition of definitions2) {
|
|
36599
36627
|
const source = sources[definition.name];
|
|
36600
36628
|
if (typeof source !== "string") throw new Error(`missing source for function ${definition.name}`);
|
|
36601
36629
|
assertStaticDependencySource(source);
|
|
@@ -36747,10 +36775,10 @@ function l10nLintOptions(locale, appDir2) {
|
|
|
36747
36775
|
const tags = (locale.translations ?? []).filter((t) => t !== locale.default);
|
|
36748
36776
|
const catalog = /* @__PURE__ */ new Set();
|
|
36749
36777
|
for (const tag of tags) {
|
|
36750
|
-
const
|
|
36751
|
-
if (!existsSync37(
|
|
36778
|
+
const path2 = join34(appDir2, "l10n", `${tag}.json`);
|
|
36779
|
+
if (!existsSync37(path2)) continue;
|
|
36752
36780
|
try {
|
|
36753
|
-
const parsed = JSON.parse(readFileSync40(
|
|
36781
|
+
const parsed = JSON.parse(readFileSync40(path2, "utf8"));
|
|
36754
36782
|
for (const m of Object.values(parsed.messages ?? {})) {
|
|
36755
36783
|
if (typeof m?.source === "string" && typeof m.translation === "string" && m.translation.length > 0) {
|
|
36756
36784
|
catalog.add(m.source);
|
|
@@ -37020,8 +37048,8 @@ async function buildRelease(app, dest, opts = {}) {
|
|
|
37020
37048
|
function countingWixCall(base) {
|
|
37021
37049
|
let returned = 0;
|
|
37022
37050
|
return {
|
|
37023
|
-
call: async (method,
|
|
37024
|
-
const out = await base(method,
|
|
37051
|
+
call: async (method, path2, body) => {
|
|
37052
|
+
const out = await base(method, path2, body);
|
|
37025
37053
|
returned += 1;
|
|
37026
37054
|
return out;
|
|
37027
37055
|
},
|
|
@@ -37112,9 +37140,9 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
37112
37140
|
);
|
|
37113
37141
|
}
|
|
37114
37142
|
const token = await mintVisitor(clientId);
|
|
37115
|
-
liveWixCall = async (method,
|
|
37143
|
+
liveWixCall = async (method, path2, body) => {
|
|
37116
37144
|
const bodyStr = body === void 0 ? void 0 : typeof body === "string" ? body : JSON.stringify(body);
|
|
37117
|
-
const r = await webWixCall(method,
|
|
37145
|
+
const r = await webWixCall(method, path2, bodyStr, token);
|
|
37118
37146
|
if (r.status < 200 || r.status >= 300) throw new Error(`HTTP ${r.status}: ${String(r.body).slice(0, 300)}`);
|
|
37119
37147
|
try {
|
|
37120
37148
|
return r.body ? JSON.parse(r.body) : {};
|
|
@@ -37211,9 +37239,9 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
37211
37239
|
const MAX_AUTHORING_DOC_BYTES = 128 * 1024;
|
|
37212
37240
|
if (store.putDoc) {
|
|
37213
37241
|
for (const [name, file] of [["spec", "SPEC.md"], ["mobile-ux", "MOBILE-UX.md"]]) {
|
|
37214
|
-
const
|
|
37215
|
-
if (!existsSync37(
|
|
37216
|
-
const bytes2 = readFileSync40(
|
|
37242
|
+
const path2 = join34(preloaded.dir, file);
|
|
37243
|
+
if (!existsSync37(path2)) continue;
|
|
37244
|
+
const bytes2 = readFileSync40(path2);
|
|
37217
37245
|
if (bytes2.length === 0 || bytes2.length > MAX_AUTHORING_DOC_BYTES) {
|
|
37218
37246
|
throw new Error(`${file} must be non-empty and at most ${MAX_AUTHORING_DOC_BYTES} bytes to ship with a release.`);
|
|
37219
37247
|
}
|
|
@@ -37641,7 +37669,7 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
37641
37669
|
}
|
|
37642
37670
|
if (store.putWidget) {
|
|
37643
37671
|
const bakedWidgets = await bakeWidgets(
|
|
37644
|
-
(
|
|
37672
|
+
(path2) => devFetch(`${base}${path2}`, { headers: { "X-Himalaya-App": app } }),
|
|
37645
37673
|
(widgetId, json5) => store.putWidget(app, widgetId, json5),
|
|
37646
37674
|
// `opts.tier5Dir`, NOT the `tier5Dir` local — that one falls back to the
|
|
37647
37675
|
// repo-global dir, where this package's widgets cannot be told from anyone
|
|
@@ -38400,8 +38428,8 @@ async function captchaRequest(options) {
|
|
|
38400
38428
|
}
|
|
38401
38429
|
const setup = options.operation === "setup";
|
|
38402
38430
|
const base = options.target.control.replace(/\/+$/, "");
|
|
38403
|
-
const
|
|
38404
|
-
const response = await (options.fetchImpl ?? fetch)(base +
|
|
38431
|
+
const path2 = setup ? "/v1/admin/captcha/setup" : `/v1/admin/captcha?app=${encodeURIComponent(options.input.app)}`;
|
|
38432
|
+
const response = await (options.fetchImpl ?? fetch)(base + path2, {
|
|
38405
38433
|
method: setup ? "POST" : "GET",
|
|
38406
38434
|
redirect: "error",
|
|
38407
38435
|
signal: AbortSignal.timeout(6e4),
|
|
@@ -38453,9 +38481,9 @@ __export(captcha_exports, {
|
|
|
38453
38481
|
});
|
|
38454
38482
|
import { readFileSync as readFileSync41 } from "node:fs";
|
|
38455
38483
|
import { resolve as resolve32 } from "node:path";
|
|
38456
|
-
function readObject(
|
|
38484
|
+
function readObject(path2) {
|
|
38457
38485
|
try {
|
|
38458
|
-
return JSON.parse(readFileSync41(
|
|
38486
|
+
return JSON.parse(readFileSync41(path2, "utf8"));
|
|
38459
38487
|
} catch {
|
|
38460
38488
|
return {};
|
|
38461
38489
|
}
|
|
@@ -38533,11 +38561,11 @@ async function pushSetupRequest(options) {
|
|
|
38533
38561
|
return refuse3("push_setup_body_too_large");
|
|
38534
38562
|
}
|
|
38535
38563
|
const base = options.target.control.replace(/\/+$/, "");
|
|
38536
|
-
let
|
|
38564
|
+
let path2 = "/v1/admin/push/setup";
|
|
38537
38565
|
if (!setup) {
|
|
38538
38566
|
const q = new URLSearchParams({ app: options.query.app, site: options.query.site });
|
|
38539
38567
|
if (options.query.verify) q.set("verify", options.query.verify);
|
|
38540
|
-
|
|
38568
|
+
path2 += `?${q.toString()}`;
|
|
38541
38569
|
}
|
|
38542
38570
|
const headers2 = {
|
|
38543
38571
|
"x-control-token": options.target.controlToken,
|
|
@@ -38548,7 +38576,7 @@ async function pushSetupRequest(options) {
|
|
|
38548
38576
|
...options.previewTag ? { "x-wix-route-serve": options.previewTag } : {}
|
|
38549
38577
|
};
|
|
38550
38578
|
try {
|
|
38551
|
-
const response = await (options.fetchImpl ?? fetch)(base +
|
|
38579
|
+
const response = await (options.fetchImpl ?? fetch)(base + path2, {
|
|
38552
38580
|
method: setup ? "POST" : "GET",
|
|
38553
38581
|
headers: headers2,
|
|
38554
38582
|
redirect: "error",
|
|
@@ -38601,9 +38629,9 @@ var init_push_setup_apple_credentials = __esm({
|
|
|
38601
38629
|
// src/push-onboarding.ts
|
|
38602
38630
|
import { existsSync as existsSync38, mkdirSync as mkdirSync17, readFileSync as readFileSync42, statSync as statSync7, writeFileSync as writeFileSync13, chmodSync as chmodSync2 } from "node:fs";
|
|
38603
38631
|
import { basename as basename9, dirname as dirname22, join as join35, resolve as resolve33 } from "node:path";
|
|
38604
|
-
function readJson2(
|
|
38632
|
+
function readJson2(path2) {
|
|
38605
38633
|
try {
|
|
38606
|
-
const parsed = JSON.parse(readFileSync42(
|
|
38634
|
+
const parsed = JSON.parse(readFileSync42(path2, "utf8"));
|
|
38607
38635
|
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
|
|
38608
38636
|
} catch {
|
|
38609
38637
|
return {};
|
|
@@ -38676,10 +38704,10 @@ function localIdentityRefusal(i) {
|
|
|
38676
38704
|
}
|
|
38677
38705
|
return null;
|
|
38678
38706
|
}
|
|
38679
|
-
function readKeyFile(
|
|
38707
|
+
function readKeyFile(path2) {
|
|
38680
38708
|
let size;
|
|
38681
38709
|
try {
|
|
38682
|
-
size = statSync7(
|
|
38710
|
+
size = statSync7(path2).size;
|
|
38683
38711
|
} catch {
|
|
38684
38712
|
return { ok: false, code: "key_file_unreadable", reason: "cannot read the selected key file; check its path and file permissions" };
|
|
38685
38713
|
}
|
|
@@ -38688,7 +38716,7 @@ function readKeyFile(path) {
|
|
|
38688
38716
|
}
|
|
38689
38717
|
let body;
|
|
38690
38718
|
try {
|
|
38691
|
-
body = readFileSync42(
|
|
38719
|
+
body = readFileSync42(path2, "utf8");
|
|
38692
38720
|
} catch {
|
|
38693
38721
|
return { ok: false, code: "key_file_unreadable", reason: "cannot read the selected key file; check its path and file permissions" };
|
|
38694
38722
|
}
|
|
@@ -38742,20 +38770,20 @@ function buildPushSetupBody(i, keys) {
|
|
|
38742
38770
|
};
|
|
38743
38771
|
}
|
|
38744
38772
|
function readPushOnboarding(dir) {
|
|
38745
|
-
const
|
|
38746
|
-
if (!existsSync38(
|
|
38747
|
-
const parsed = readJson2(
|
|
38773
|
+
const path2 = join35(resolve33(dir), PUSH_ONBOARDING_PATH);
|
|
38774
|
+
if (!existsSync38(path2)) return { version: 1 };
|
|
38775
|
+
const parsed = readJson2(path2);
|
|
38748
38776
|
return { version: 1, ...parsed };
|
|
38749
38777
|
}
|
|
38750
38778
|
function writeFile(dir, file) {
|
|
38751
|
-
const
|
|
38752
|
-
mkdirSync17(dirname22(
|
|
38753
|
-
writeFileSync13(
|
|
38779
|
+
const path2 = join35(resolve33(dir), PUSH_ONBOARDING_PATH);
|
|
38780
|
+
mkdirSync17(dirname22(path2), { recursive: true, mode: 448 });
|
|
38781
|
+
writeFileSync13(path2, JSON.stringify(file, null, 2) + "\n", { mode: 384 });
|
|
38754
38782
|
try {
|
|
38755
|
-
chmodSync2(
|
|
38783
|
+
chmodSync2(path2, 384);
|
|
38756
38784
|
} catch {
|
|
38757
38785
|
}
|
|
38758
|
-
return
|
|
38786
|
+
return path2;
|
|
38759
38787
|
}
|
|
38760
38788
|
function recordPushDeferral(dir, d) {
|
|
38761
38789
|
const identity = {};
|
|
@@ -38777,8 +38805,8 @@ function recordPushDeferral(dir, d) {
|
|
|
38777
38805
|
return push;
|
|
38778
38806
|
}
|
|
38779
38807
|
function clearPushDeferral(dir) {
|
|
38780
|
-
const
|
|
38781
|
-
if (!existsSync38(
|
|
38808
|
+
const path2 = join35(resolve33(dir), PUSH_ONBOARDING_PATH);
|
|
38809
|
+
if (!existsSync38(path2)) return;
|
|
38782
38810
|
const { push: _dropped, ...rest } = readPushOnboarding(dir);
|
|
38783
38811
|
writeFile(dir, { ...rest, version: 1 });
|
|
38784
38812
|
}
|
|
@@ -39405,13 +39433,13 @@ function packagePathFor(pathname) {
|
|
|
39405
39433
|
}
|
|
39406
39434
|
return UNSUPPORTED;
|
|
39407
39435
|
}
|
|
39408
|
-
function parseJson(read,
|
|
39409
|
-
const bytes2 = read(
|
|
39436
|
+
function parseJson(read, path2, errors) {
|
|
39437
|
+
const bytes2 = read(path2);
|
|
39410
39438
|
if (!bytes2) return null;
|
|
39411
39439
|
try {
|
|
39412
39440
|
return JSON.parse(utf82(bytes2));
|
|
39413
39441
|
} catch (e) {
|
|
39414
|
-
errors.push(`${
|
|
39442
|
+
errors.push(`${path2} is not valid JSON: ${e.message}`);
|
|
39415
39443
|
return null;
|
|
39416
39444
|
}
|
|
39417
39445
|
}
|
|
@@ -39832,8 +39860,8 @@ function inflateEntry(buf, entry) {
|
|
|
39832
39860
|
verifyZipEntry(entry, bytes2);
|
|
39833
39861
|
return bytes2;
|
|
39834
39862
|
}
|
|
39835
|
-
function readIf(
|
|
39836
|
-
return existsSync39(
|
|
39863
|
+
function readIf(path2) {
|
|
39864
|
+
return existsSync39(path2) && statSync8(path2).isFile() ? readFileSync43(path2) : null;
|
|
39837
39865
|
}
|
|
39838
39866
|
function listDir(dir) {
|
|
39839
39867
|
return existsSync39(dir) ? readdirSync20(dir).filter((f) => statSync8(join36(dir, f)).isFile()) : [];
|
|
@@ -39969,7 +39997,7 @@ function packReleaseToDir(releaseRoot, app, outDir, opts = {}) {
|
|
|
39969
39997
|
}
|
|
39970
39998
|
function openFromEntries(entries, opts) {
|
|
39971
39999
|
const read = (p) => entries.get(p) ?? null;
|
|
39972
|
-
const contentHash = computeContentHash(Array.from(entries, ([
|
|
40000
|
+
const contentHash = computeContentHash(Array.from(entries, ([path2, bytes2]) => ({ path: path2, bytes: bytes2 })));
|
|
39973
40001
|
const validation = validatePackage(read, { requireHeader: opts.requireHeader, contentHash });
|
|
39974
40002
|
return {
|
|
39975
40003
|
header: validation.header,
|
|
@@ -40140,7 +40168,7 @@ function zipAppSource(entries) {
|
|
|
40140
40168
|
return writeZip(entries.map((e) => ({ path: e.path, bytes: e.bytes })));
|
|
40141
40169
|
}
|
|
40142
40170
|
function readAppSource(zip) {
|
|
40143
|
-
return [...readZip(zip)].map(([
|
|
40171
|
+
return [...readZip(zip)].map(([path2, bytes2]) => ({ path: path2, bytes: bytes2 }));
|
|
40144
40172
|
}
|
|
40145
40173
|
function pathKind(p) {
|
|
40146
40174
|
try {
|
|
@@ -40453,24 +40481,24 @@ function readTestConfig(dir) {
|
|
|
40453
40481
|
}
|
|
40454
40482
|
return { ...skip ? { skip } : {}, ...journeys ? { journeys } : {} };
|
|
40455
40483
|
}
|
|
40456
|
-
function readNetRules(
|
|
40484
|
+
function readNetRules(path2) {
|
|
40457
40485
|
let parsed;
|
|
40458
40486
|
try {
|
|
40459
|
-
parsed = JSON.parse(readFileSync46(
|
|
40487
|
+
parsed = JSON.parse(readFileSync46(path2, "utf8"));
|
|
40460
40488
|
} catch (e) {
|
|
40461
|
-
throw new Error(`--net ${
|
|
40489
|
+
throw new Error(`--net ${path2} could not be read as JSON \u2014 ${e.message}`);
|
|
40462
40490
|
}
|
|
40463
40491
|
const rules = parsed?.rules;
|
|
40464
40492
|
if (!Array.isArray(rules)) {
|
|
40465
|
-
throw new Error(`--net ${
|
|
40493
|
+
throw new Error(`--net ${path2} has no "rules" array \u2014 expected the net-mocks shape { "rules": [ { "matcher": {...}, "response": {...} } ] }`);
|
|
40466
40494
|
}
|
|
40467
40495
|
const active = rules.filter((r) => r.enabled !== false);
|
|
40468
40496
|
const shapeErrors = wixMockRuleErrors(active);
|
|
40469
40497
|
if (shapeErrors.length) {
|
|
40470
|
-
throw new Error(`${
|
|
40498
|
+
throw new Error(`${path2}: invalid net-mocks fixture \u2014 ${shapeErrors.join("; ")}`);
|
|
40471
40499
|
}
|
|
40472
40500
|
if (active.length && !active.some((r) => r.matcher && typeof r.matcher === "object")) {
|
|
40473
|
-
throw new Error(`${
|
|
40501
|
+
throw new Error(`${path2}: none of the ${active.length} rule(s) has a "matcher" \u2014 the net-mocks shape is { "rules": [ { "matcher": {...}, "response": {...} } ] }; a file that matches nothing must not report as "mocked"`);
|
|
40474
40502
|
}
|
|
40475
40503
|
return active;
|
|
40476
40504
|
}
|
|
@@ -40509,21 +40537,21 @@ function makeRecordingWixCall(send2, token, app) {
|
|
|
40509
40537
|
const events = [];
|
|
40510
40538
|
const refused = [];
|
|
40511
40539
|
let id = 0;
|
|
40512
|
-
const call = async (method,
|
|
40540
|
+
const call = async (method, path2, body) => {
|
|
40513
40541
|
const verb = method.toUpperCase();
|
|
40514
|
-
if (/[#\x00-\x1F\x7F]/.test(
|
|
40515
|
-
refused.push(`${verb} ${
|
|
40516
|
-
throw new Error(`--record refused ${verb} ${
|
|
40542
|
+
if (/[#\x00-\x1F\x7F]/.test(path2)) {
|
|
40543
|
+
refused.push(`${verb} ${path2}`);
|
|
40544
|
+
throw new Error(`--record refused ${verb} ${path2}: the path carries a fragment or control character \u2014 not a provable read`);
|
|
40517
40545
|
}
|
|
40518
|
-
const bare =
|
|
40546
|
+
const bare = path2.split("?")[0].replace(/\/+$/, "");
|
|
40519
40547
|
const readShaped = verb === "GET" || verb === "POST" && /\/(query|search|list[^/]*|get[^/]*|count|aggregate|facets|connections)$/i.test(bare);
|
|
40520
40548
|
if (!readShaped) {
|
|
40521
|
-
refused.push(`${verb} ${
|
|
40522
|
-
throw new Error(`--record refused ${verb} ${
|
|
40549
|
+
refused.push(`${verb} ${path2}`);
|
|
40550
|
+
throw new Error(`--record refused ${verb} ${path2}: recording sends only proven reads (GET, or POST ending in /query, /search, /list*, /get*, /count, /aggregate, /facets, /connections) \u2014 if this IS a read, add its rule to dev/net-mocks.json by hand`);
|
|
40523
40551
|
}
|
|
40524
40552
|
const bodyStr = body === void 0 ? void 0 : typeof body === "string" ? body : JSON.stringify(body);
|
|
40525
40553
|
const started = Date.now();
|
|
40526
|
-
const r = await send2(method,
|
|
40554
|
+
const r = await send2(method, path2, bodyStr, token);
|
|
40527
40555
|
events.push({
|
|
40528
40556
|
id: ++id,
|
|
40529
40557
|
ts: started,
|
|
@@ -40531,8 +40559,8 @@ function makeRecordingWixCall(send2, token, app) {
|
|
|
40531
40559
|
source: "observe",
|
|
40532
40560
|
host: "www.wixapis.com",
|
|
40533
40561
|
method,
|
|
40534
|
-
url: `https://www.wixapis.com${
|
|
40535
|
-
path,
|
|
40562
|
+
url: `https://www.wixapis.com${path2}`,
|
|
40563
|
+
path: path2,
|
|
40536
40564
|
status: r.status,
|
|
40537
40565
|
durationMs: Date.now() - started,
|
|
40538
40566
|
...bodyStr !== void 0 ? { reqBody: bodyStr } : {},
|
|
@@ -41163,9 +41191,9 @@ var init_auth = __esm({
|
|
|
41163
41191
|
});
|
|
41164
41192
|
|
|
41165
41193
|
// ../../core/functions-runtime/src/wix-transport.ts
|
|
41166
|
-
function rejectSiteOverride(
|
|
41194
|
+
function rejectSiteOverride(path2) {
|
|
41167
41195
|
try {
|
|
41168
|
-
if (new URL(
|
|
41196
|
+
if (new URL(path2, "https://wix.invalid").searchParams.has("msid")) {
|
|
41169
41197
|
throw new Error("request cannot override the bound Wix site identity");
|
|
41170
41198
|
}
|
|
41171
41199
|
} catch (error) {
|
|
@@ -41176,8 +41204,8 @@ function createWixApiCapability(options) {
|
|
|
41176
41204
|
const permissions = [...options.permissions ?? []].sort();
|
|
41177
41205
|
let installation;
|
|
41178
41206
|
return {
|
|
41179
|
-
async call(method,
|
|
41180
|
-
rejectSiteOverride(
|
|
41207
|
+
async call(method, path2, body) {
|
|
41208
|
+
rejectSiteOverride(path2);
|
|
41181
41209
|
let identity;
|
|
41182
41210
|
if (options.identity.kind === "caller") {
|
|
41183
41211
|
identity = { ...options.identity };
|
|
@@ -41188,9 +41216,9 @@ function createWixApiCapability(options) {
|
|
|
41188
41216
|
throw new Error("installation identity is not authorized for the configured Wix site");
|
|
41189
41217
|
}
|
|
41190
41218
|
identity = { kind: "installation", installationId: installation.installationId };
|
|
41191
|
-
options.audit?.({ app: options.app, siteId: options.siteId, identity: "installation", method, path });
|
|
41219
|
+
options.audit?.({ app: options.app, siteId: options.siteId, identity: "installation", method, path: path2 });
|
|
41192
41220
|
}
|
|
41193
|
-
return options.transport.call({ app: options.app, siteId: options.siteId, identity, ...permissions.length ? { permissions } : {}, method, path, ...body === void 0 ? {} : { body } });
|
|
41221
|
+
return options.transport.call({ app: options.app, siteId: options.siteId, identity, ...permissions.length ? { permissions } : {}, method, path: path2, ...body === void 0 ? {} : { body } });
|
|
41194
41222
|
}
|
|
41195
41223
|
};
|
|
41196
41224
|
}
|
|
@@ -41782,11 +41810,11 @@ var init_sandbox = __esm({
|
|
|
41782
41810
|
});
|
|
41783
41811
|
|
|
41784
41812
|
// ../../core/functions-runtime/src/openapi.ts
|
|
41785
|
-
function makeFunctionsOpenApi(manifest,
|
|
41813
|
+
function makeFunctionsOpenApi(manifest, definitions2 = []) {
|
|
41786
41814
|
const paths = {};
|
|
41787
41815
|
for (const record2 of manifest.functions ?? []) {
|
|
41788
41816
|
if (record2.internal) continue;
|
|
41789
|
-
const definition =
|
|
41817
|
+
const definition = definitions2.find((item) => item.name === record2.name);
|
|
41790
41818
|
const method = record2.method.toLowerCase();
|
|
41791
41819
|
paths[record2.path] = {
|
|
41792
41820
|
...paths[record2.path] ?? {},
|
|
@@ -42413,9 +42441,9 @@ function resolveTarget2(pathname) {
|
|
|
42413
42441
|
return null;
|
|
42414
42442
|
}
|
|
42415
42443
|
}
|
|
42416
|
-
function chooseFunction(records, method,
|
|
42444
|
+
function chooseFunction(records, method, path2) {
|
|
42417
42445
|
for (const record2 of records) {
|
|
42418
|
-
const params = routeMatch(record2.path,
|
|
42446
|
+
const params = routeMatch(record2.path, path2);
|
|
42419
42447
|
if (params && record2.method === method) return { record: record2, params };
|
|
42420
42448
|
}
|
|
42421
42449
|
return null;
|
|
@@ -42424,8 +42452,8 @@ async function contentFromBundle(bytes2, record2) {
|
|
|
42424
42452
|
const actual = await integrity(bytes2);
|
|
42425
42453
|
return actual.hash === record2.bundleHash && actual.sri === record2.sri ? utf8Decode(bytes2) : null;
|
|
42426
42454
|
}
|
|
42427
|
-
function definitionFor(
|
|
42428
|
-
return
|
|
42455
|
+
function definitionFor(definitions2, name) {
|
|
42456
|
+
return definitions2?.find((definition) => definition.name === name);
|
|
42429
42457
|
}
|
|
42430
42458
|
async function bodyValue(request, record2) {
|
|
42431
42459
|
const length = Number(request.headers.get("content-length") ?? "0");
|
|
@@ -42676,8 +42704,8 @@ function makeFunctionsHandler(options) {
|
|
|
42676
42704
|
}
|
|
42677
42705
|
};
|
|
42678
42706
|
}
|
|
42679
|
-
function functionsOpenApi(manifest,
|
|
42680
|
-
return makeFunctionsOpenApi(manifest,
|
|
42707
|
+
function functionsOpenApi(manifest, definitions2 = []) {
|
|
42708
|
+
return makeFunctionsOpenApi(manifest, definitions2);
|
|
42681
42709
|
}
|
|
42682
42710
|
var MAX_LOG_MESSAGE;
|
|
42683
42711
|
var init_gateway = __esm({
|
|
@@ -42743,19 +42771,19 @@ async function loadFunctionsApp(dir) {
|
|
|
42743
42771
|
if (dataErrors.length) throw new Error(`invalid data declaration: ${dataErrors.map((issue2) => issue2.message).join("; ")}`);
|
|
42744
42772
|
return { app: loaded.name, dir: loaded.dir, definitions: config.functions.functions, sources, siteBinding: config.functions.siteBinding, schedules: config.functions.schedules, ...data ? { data } : {} };
|
|
42745
42773
|
}
|
|
42746
|
-
function listFunctions(
|
|
42747
|
-
return
|
|
42774
|
+
function listFunctions(definitions2) {
|
|
42775
|
+
return definitions2.map((definition) => ({ name: definition.name, method: definition.method, path: definition.path, auth: definition.auth, internal: definition.internal, limits: definition.limits }));
|
|
42748
42776
|
}
|
|
42749
|
-
function describeFunction(
|
|
42750
|
-
const definition =
|
|
42777
|
+
function describeFunction(definitions2, name) {
|
|
42778
|
+
const definition = definitions2.find((item) => item.name === name);
|
|
42751
42779
|
return definition ? { ...listFunctions([definition])[0], wixIdentity: definition.wixIdentity, wixPermissions: [...definition.wixPermissions], capabilities: [...definition.capabilities], secrets: [...definition.secrets], outboundHosts: [...definition.outboundHosts], inputSchema: definition.input?.kind ?? null, outputSchema: definition.output?.kind ?? null } : null;
|
|
42752
42780
|
}
|
|
42753
|
-
function materializeFunctionPath(
|
|
42754
|
-
const names = [...
|
|
42781
|
+
function materializeFunctionPath(path2, params = {}) {
|
|
42782
|
+
const names = [...path2.matchAll(/:([A-Za-z][A-Za-z0-9_]*)/g)].map((match) => match[1]);
|
|
42755
42783
|
for (const name of names) {
|
|
42756
42784
|
if (typeof params[name] !== "string" || params[name] === "") throw new Error(`missing route parameter "${name}"; pass --params {"${name}":"value"}`);
|
|
42757
42785
|
}
|
|
42758
|
-
return
|
|
42786
|
+
return path2.replace(/:([A-Za-z][A-Za-z0-9_]*)/g, (_match, name) => encodeURIComponent(params[name]));
|
|
42759
42787
|
}
|
|
42760
42788
|
function memoryStore(manifest, built) {
|
|
42761
42789
|
const bytes2 = new Map(built.map((item) => [item.bundleHash, item.bytes]));
|
|
@@ -42839,8 +42867,8 @@ async function invokeRemoteFunction(input) {
|
|
|
42839
42867
|
});
|
|
42840
42868
|
return { response, url: url.toString() };
|
|
42841
42869
|
}
|
|
42842
|
-
function openApiForFunctions(manifest,
|
|
42843
|
-
return functionsOpenApi(manifest,
|
|
42870
|
+
function openApiForFunctions(manifest, definitions2) {
|
|
42871
|
+
return functionsOpenApi(manifest, definitions2);
|
|
42844
42872
|
}
|
|
42845
42873
|
async function runRemoteFunctionOperation(input) {
|
|
42846
42874
|
const environment2 = input.environment ?? "production";
|
|
@@ -43092,9 +43120,9 @@ function runAndroidNativeDecode(options) {
|
|
|
43092
43120
|
rmSync8(descriptorDir, { recursive: true, force: true });
|
|
43093
43121
|
}
|
|
43094
43122
|
}
|
|
43095
|
-
function fieldAt(
|
|
43096
|
-
if (
|
|
43097
|
-
return
|
|
43123
|
+
function fieldAt(path2) {
|
|
43124
|
+
if (path2 === null) return void 0;
|
|
43125
|
+
return path2.match(/\.([^.[\]]+)$/)?.[1];
|
|
43098
43126
|
}
|
|
43099
43127
|
function mergeNativeDecode(report2, run2) {
|
|
43100
43128
|
const platformLabel = run2.platform === "ios" ? "iOS" : "Android";
|
|
@@ -44084,8 +44112,8 @@ var init_wix_member_auth = __esm({
|
|
|
44084
44112
|
function json3(status, body, headers2 = {}) {
|
|
44085
44113
|
return new Response(JSON.stringify(body), { status, headers: { "content-type": JSON_CT, ...headers2 } });
|
|
44086
44114
|
}
|
|
44087
|
-
function isCookieAuthorizedPath(
|
|
44088
|
-
return
|
|
44115
|
+
function isCookieAuthorizedPath(path2) {
|
|
44116
|
+
return path2 === "/v1/__webwix/call" || path2 === "/v1/owner" || path2.startsWith("/v1/owner/") || path2 === "/v1/__webwix/identity" || path2 === "/v1/__webwix/login" || path2 === "/v1/__webwix/register" || path2 === "/v1/__webwix/logout" || path2 === MEMBER_CALLBACK_PATH;
|
|
44089
44117
|
}
|
|
44090
44118
|
function makeServeHandler(opts) {
|
|
44091
44119
|
let storePromise = null;
|
|
@@ -44265,9 +44293,9 @@ ${releaseId}`;
|
|
|
44265
44293
|
const handle = async (request) => {
|
|
44266
44294
|
try {
|
|
44267
44295
|
const url = new URL(request.url);
|
|
44268
|
-
const
|
|
44296
|
+
const path2 = url.pathname;
|
|
44269
44297
|
if (opts.devControl && request.method === "PUT") {
|
|
44270
|
-
const dcMatch = /^\/v1\/dev-control\/([^/]+)$/.exec(
|
|
44298
|
+
const dcMatch = /^\/v1\/dev-control\/([^/]+)$/.exec(path2);
|
|
44271
44299
|
if (dcMatch) {
|
|
44272
44300
|
const dcApp = dcMatch[1];
|
|
44273
44301
|
let body = {};
|
|
@@ -44283,16 +44311,16 @@ ${releaseId}`;
|
|
|
44283
44311
|
}
|
|
44284
44312
|
}
|
|
44285
44313
|
const memberRungApp = memberAuthOn() ? memberApp(request) : null;
|
|
44286
|
-
if (memberRungApp && (
|
|
44314
|
+
if (memberRungApp && (path2 === "/v1/__webwix/login" || path2 === "/v1/__webwix/register" || path2 === MEMBER_CALLBACK_PATH || path2 === "/v1/__webwix/logout")) {
|
|
44287
44315
|
const store2 = memberSessions();
|
|
44288
44316
|
if (!store2) return json3(503, { error: "member_auth_unconfigured" });
|
|
44289
44317
|
const sessionId = readSessionCookie(request.headers.get("cookie"));
|
|
44290
|
-
if (
|
|
44318
|
+
if (path2 === "/v1/__webwix/logout") {
|
|
44291
44319
|
if (request.method !== "POST") return json3(405, { error: "method_not_allowed" });
|
|
44292
44320
|
if (sessionId) await store2.delete(sessionId);
|
|
44293
44321
|
return json3(200, { ok: true }, { "set-cookie": clearSessionCookie(), "cache-control": "no-store" });
|
|
44294
44322
|
}
|
|
44295
|
-
if (
|
|
44323
|
+
if (path2 === MEMBER_CALLBACK_PATH) {
|
|
44296
44324
|
if (request.method !== "GET") return json3(405, { error: "method_not_allowed" });
|
|
44297
44325
|
const code = url.searchParams.get("code");
|
|
44298
44326
|
const state2 = url.searchParams.get("state");
|
|
@@ -44352,7 +44380,7 @@ ${releaseId}`;
|
|
|
44352
44380
|
try {
|
|
44353
44381
|
const visitor = await webwixTokens.token(resolved2.config.clientId);
|
|
44354
44382
|
authUrl = await hostedAuthUrl(
|
|
44355
|
-
{ ...resolved2.config, mode:
|
|
44383
|
+
{ ...resolved2.config, mode: path2.endsWith("/register") ? "signup" : "login", state, challenge: pkce.challenge },
|
|
44356
44384
|
visitor,
|
|
44357
44385
|
webwixFetch
|
|
44358
44386
|
);
|
|
@@ -44379,7 +44407,7 @@ ${releaseId}`;
|
|
|
44379
44407
|
}
|
|
44380
44408
|
});
|
|
44381
44409
|
}
|
|
44382
|
-
if ((request.method === "GET" || request.method === "HEAD") &&
|
|
44410
|
+
if ((request.method === "GET" || request.method === "HEAD") && path2 === "/v1/__webwix/identity") {
|
|
44383
44411
|
const headers2 = { "content-type": JSON_CT, "cache-control": "no-store" };
|
|
44384
44412
|
if (request.method === "HEAD") return new Response(null, { status: 200, headers: headers2 });
|
|
44385
44413
|
const webwixDirect = opts.webwixBridge !== false;
|
|
@@ -44393,7 +44421,7 @@ ${releaseId}`;
|
|
|
44393
44421
|
}
|
|
44394
44422
|
return json3(200, { authenticated: false, userId: null, email: null, webwixDirect }, { "cache-control": "no-store" });
|
|
44395
44423
|
}
|
|
44396
|
-
if (request.method === "POST" &&
|
|
44424
|
+
if (request.method === "POST" && path2 === "/v1/__webwix/call") {
|
|
44397
44425
|
if (opts.webwixBridge === false) {
|
|
44398
44426
|
return json3(503, { error: "webwix_bridge_disabled" });
|
|
44399
44427
|
}
|
|
@@ -44496,8 +44524,8 @@ ${releaseId}`;
|
|
|
44496
44524
|
}
|
|
44497
44525
|
}
|
|
44498
44526
|
if (request.method !== "GET") return json3(405, { error: "method_not_allowed" });
|
|
44499
|
-
if (
|
|
44500
|
-
const packageShare = /^\/p\/([a-f0-9]{64})$/.exec(
|
|
44527
|
+
if (path2 === "/__health") return json3(200, { ok: true });
|
|
44528
|
+
const packageShare = /^\/p\/([a-f0-9]{64})$/.exec(path2);
|
|
44501
44529
|
if (packageShare) {
|
|
44502
44530
|
const shareId = packageShare[1];
|
|
44503
44531
|
const wantsMetadata = url.searchParams.get("metadata") === "1";
|
|
@@ -44526,7 +44554,7 @@ ${releaseId}`;
|
|
|
44526
44554
|
}
|
|
44527
44555
|
});
|
|
44528
44556
|
}
|
|
44529
|
-
if (
|
|
44557
|
+
if (path2 === "/v1/owner/instance") {
|
|
44530
44558
|
if (opts.webwixBridge === false) return json3(503, { error: "webwix_bridge_disabled" });
|
|
44531
44559
|
if (!webwixOwnerRungOn()) return json3(503, { error: "webwix_owner_disabled" });
|
|
44532
44560
|
const msid = url.searchParams.get("msid") ?? "";
|
|
@@ -44542,7 +44570,7 @@ ${releaseId}`;
|
|
|
44542
44570
|
return json3(403, { error: "webwix_owner_mint_failed" });
|
|
44543
44571
|
}
|
|
44544
44572
|
}
|
|
44545
|
-
if (
|
|
44573
|
+
if (path2 === "/v1/owner/sites") {
|
|
44546
44574
|
if (!webwixOwnerRungOn()) return json3(503, { error: "webwix_owner_disabled" });
|
|
44547
44575
|
const cookie = request.headers.get("cookie") ?? "";
|
|
44548
44576
|
if (!/wixSession2=/.test(cookie)) return json3(200, { sites: [] });
|
|
@@ -44556,7 +44584,7 @@ ${releaseId}`;
|
|
|
44556
44584
|
}
|
|
44557
44585
|
}
|
|
44558
44586
|
const store = await getStore();
|
|
44559
|
-
if (
|
|
44587
|
+
if (path2 === "/v1/apps") {
|
|
44560
44588
|
if (opts.authorizeList && !await opts.authorizeList(request)) {
|
|
44561
44589
|
return json3(401, { error: "unauthorized" });
|
|
44562
44590
|
}
|
|
@@ -44620,7 +44648,7 @@ ${releaseId}`;
|
|
|
44620
44648
|
headers: { "content-type": JSON_CT, ...listHeaders }
|
|
44621
44649
|
});
|
|
44622
44650
|
}
|
|
44623
|
-
if (
|
|
44651
|
+
if (path2 === "/v1/templates") {
|
|
44624
44652
|
if (opts.authorizeList && !await opts.authorizeList(request)) {
|
|
44625
44653
|
return json3(401, { error: "unauthorized" });
|
|
44626
44654
|
}
|
|
@@ -44655,7 +44683,7 @@ ${releaseId}`;
|
|
|
44655
44683
|
}
|
|
44656
44684
|
const app = resolveApp(request, url);
|
|
44657
44685
|
const pin = resolvePin(request, url);
|
|
44658
|
-
if (
|
|
44686
|
+
if (path2 === "/v1/template-source") {
|
|
44659
44687
|
if (!app) return json3(400, { error: "missing_app" });
|
|
44660
44688
|
if (!store.getSource) return json3(501, { error: "templates_unsupported" });
|
|
44661
44689
|
const m = pin ? await pinnedManifest(app, pin) : await manifest(app);
|
|
@@ -44675,12 +44703,12 @@ ${releaseId}`;
|
|
|
44675
44703
|
const denied = await authorizePinnedRead(request, url, app, pin);
|
|
44676
44704
|
if (denied) return denied;
|
|
44677
44705
|
}
|
|
44678
|
-
if (
|
|
44706
|
+
if (path2 === "/v1/authoring-docs" || /^\/v1\/authoring-docs\/(spec|mobile-ux)$/.test(path2)) {
|
|
44679
44707
|
if (!app) return json3(400, { error: "missing_app" });
|
|
44680
44708
|
const m = pin ? await pinnedManifest(app, pin) : await manifest(app);
|
|
44681
44709
|
if (!m) return json3(404, { error: pin ? "release_not_found" : "no_release", app });
|
|
44682
44710
|
const docs = m.authoringDocs ?? {};
|
|
44683
|
-
const match = /^\/v1\/authoring-docs\/(spec|mobile-ux)$/.exec(
|
|
44711
|
+
const match = /^\/v1\/authoring-docs\/(spec|mobile-ux)$/.exec(path2);
|
|
44684
44712
|
if (!match) {
|
|
44685
44713
|
return json3(200, {
|
|
44686
44714
|
app,
|
|
@@ -44708,7 +44736,7 @@ ${releaseId}`;
|
|
|
44708
44736
|
}
|
|
44709
44737
|
});
|
|
44710
44738
|
}
|
|
44711
|
-
if (
|
|
44739
|
+
if (path2 === "/v1/release/current") {
|
|
44712
44740
|
if (pin) {
|
|
44713
44741
|
const m2 = app ? await pinnedManifest(app, pin) : null;
|
|
44714
44742
|
if (!m2) return json3(404, { error: "release_not_found", app, releaseId: pin });
|
|
@@ -44718,7 +44746,7 @@ ${releaseId}`;
|
|
|
44718
44746
|
if (!m) return json3(404, { error: "no_release", app });
|
|
44719
44747
|
return json3(200, { releaseId: m.releaseId, app: m.app, ...m.minBinaryVersion ? { minBinaryVersion: m.minBinaryVersion } : {}, ...m.playerRequirements ? { playerRequirements: m.playerRequirements } : {}, ...m.platforms ? { platforms: m.platforms } : {} });
|
|
44720
44748
|
}
|
|
44721
|
-
const bundleMatch = /^\/v1\/bundles\/([a-f0-9]{64})\.bundle\.js$/.exec(
|
|
44749
|
+
const bundleMatch = /^\/v1\/bundles\/([a-f0-9]{64})\.bundle\.js$/.exec(path2);
|
|
44722
44750
|
if (bundleMatch) {
|
|
44723
44751
|
const hash = bundleMatch[1];
|
|
44724
44752
|
const m = app ? pin ? await pinnedManifest(app, pin) : await manifest(app) : null;
|
|
@@ -44735,7 +44763,7 @@ ${releaseId}`;
|
|
|
44735
44763
|
}
|
|
44736
44764
|
});
|
|
44737
44765
|
}
|
|
44738
|
-
if (
|
|
44766
|
+
if (path2 === "/v1/boot") {
|
|
44739
44767
|
if (!app) return json3(400, { error: "missing_app" });
|
|
44740
44768
|
let m;
|
|
44741
44769
|
if (pin) {
|
|
@@ -44804,7 +44832,7 @@ ${releaseId}`;
|
|
|
44804
44832
|
}
|
|
44805
44833
|
return json3(200, { releaseId: mm.releaseId, app, appConfig, tokens, homeScreenId, screen, homeBundle }, { etag, "cache-control": cache, ...vary });
|
|
44806
44834
|
}
|
|
44807
|
-
if (
|
|
44835
|
+
if (path2 === "/v1/tokens") {
|
|
44808
44836
|
if (!app) return json3(400, { error: "missing_app" });
|
|
44809
44837
|
if (pin) {
|
|
44810
44838
|
const m = await pinnedManifest(app, pin);
|
|
@@ -44817,7 +44845,7 @@ ${releaseId}`;
|
|
|
44817
44845
|
if (!bytes2) return json3(404, { error: "tokens_not_found", app });
|
|
44818
44846
|
return sendDoc(request, bytes2);
|
|
44819
44847
|
}
|
|
44820
|
-
if (
|
|
44848
|
+
if (path2 === "/v1/l10n") {
|
|
44821
44849
|
if (!app) return json3(400, { error: "missing_app" });
|
|
44822
44850
|
const tag = (url.searchParams.get("tag") ?? "").trim();
|
|
44823
44851
|
if (!/^[a-z]{2}(-[A-Za-z0-9]+)?$/.test(tag)) {
|
|
@@ -44832,7 +44860,7 @@ ${releaseId}`;
|
|
|
44832
44860
|
if (!bytes2) return new Response(null, { status: 204 });
|
|
44833
44861
|
return sendDoc(request, bytes2, Boolean(pin));
|
|
44834
44862
|
}
|
|
44835
|
-
if (
|
|
44863
|
+
if (path2 === "/v1/app-icon") {
|
|
44836
44864
|
if (!app) return json3(400, { error: "missing_app" });
|
|
44837
44865
|
if (!store.getIcon) return json3(501, { error: "icons_unsupported" });
|
|
44838
44866
|
const m = pin ? await pinnedManifest(app, pin) : await manifest(app);
|
|
@@ -44849,7 +44877,7 @@ ${releaseId}`;
|
|
|
44849
44877
|
headers: { "content-type": "image/png", etag, "cache-control": BUNDLE_CACHE_CONTROL, "x-himalaya-app": app }
|
|
44850
44878
|
});
|
|
44851
44879
|
}
|
|
44852
|
-
const assetMatch = /^\/v1\/asset\/([^/?]+)$/.exec(
|
|
44880
|
+
const assetMatch = /^\/v1\/asset\/([^/?]+)$/.exec(path2);
|
|
44853
44881
|
if (assetMatch) {
|
|
44854
44882
|
if (!app) return json3(400, { error: "missing_app" });
|
|
44855
44883
|
if (!store.getAsset) return json3(501, { error: "assets_unsupported" });
|
|
@@ -44878,7 +44906,7 @@ ${releaseId}`;
|
|
|
44878
44906
|
}
|
|
44879
44907
|
});
|
|
44880
44908
|
}
|
|
44881
|
-
const ahMatch = /^\/v1\/action-handlers\/([^/]+)$/.exec(
|
|
44909
|
+
const ahMatch = /^\/v1\/action-handlers\/([^/]+)$/.exec(path2);
|
|
44882
44910
|
if (ahMatch) {
|
|
44883
44911
|
const ahApp = ahMatch[1];
|
|
44884
44912
|
const m = await manifest(ahApp);
|
|
@@ -44891,7 +44919,7 @@ ${releaseId}`;
|
|
|
44891
44919
|
}));
|
|
44892
44920
|
return json3(200, { handlers });
|
|
44893
44921
|
}
|
|
44894
|
-
const cfgMatch = /^\/v1\/app-config\/([^/]+)$/.exec(
|
|
44922
|
+
const cfgMatch = /^\/v1\/app-config\/([^/]+)$/.exec(path2);
|
|
44895
44923
|
if (cfgMatch) {
|
|
44896
44924
|
const cfgApp = cfgMatch[1];
|
|
44897
44925
|
if (pin) {
|
|
@@ -44911,7 +44939,7 @@ ${releaseId}`;
|
|
|
44911
44939
|
}
|
|
44912
44940
|
return sendDoc(request, bytes2);
|
|
44913
44941
|
}
|
|
44914
|
-
const screenMatch = /^\/v1\/screen\/([^/]+)$/.exec(
|
|
44942
|
+
const screenMatch = /^\/v1\/screen\/([^/]+)$/.exec(path2);
|
|
44915
44943
|
if (screenMatch) {
|
|
44916
44944
|
const screenId = screenMatch[1];
|
|
44917
44945
|
if (!app || !isSafeSegment(screenId)) return json3(404, { error: "screen_not_found", screenId });
|
|
@@ -44943,14 +44971,14 @@ ${releaseId}`;
|
|
|
44943
44971
|
headers: { "content-type": JSON_CT, etag, "cache-control": DOC_CACHE_CONTROL, "x-himalaya-app": app }
|
|
44944
44972
|
});
|
|
44945
44973
|
}
|
|
44946
|
-
if (
|
|
44974
|
+
if (path2 === "/v1/widgets") {
|
|
44947
44975
|
if (!app) return json3(400, { error: "missing_app" });
|
|
44948
44976
|
const m = pin ? await pinnedManifest(app, pin) : await manifest(app);
|
|
44949
44977
|
if (!m) return json3(404, { error: pin ? "release_not_found" : "no_release", app });
|
|
44950
44978
|
const widgets = Object.entries(m.widgets ?? {}).map(([widgetId, meta]) => ({ widgetId, contentEtag: meta.contentEtag }));
|
|
44951
44979
|
return json3(200, { widgets });
|
|
44952
44980
|
}
|
|
44953
|
-
const widgetMatch = /^\/v1\/widget\/([^/]+)$/.exec(
|
|
44981
|
+
const widgetMatch = /^\/v1\/widget\/([^/]+)$/.exec(path2);
|
|
44954
44982
|
if (widgetMatch) {
|
|
44955
44983
|
const widgetId = widgetMatch[1];
|
|
44956
44984
|
if (!app || !isSafeSegment(widgetId)) return json3(404, { error: "widget_not_found", widgetId });
|
|
@@ -45151,25 +45179,25 @@ function makeRunHandler(opts) {
|
|
|
45151
45179
|
});
|
|
45152
45180
|
return async (request) => {
|
|
45153
45181
|
const url = new URL(request.url);
|
|
45154
|
-
const
|
|
45155
|
-
if (
|
|
45182
|
+
const path2 = url.pathname;
|
|
45183
|
+
if (path2 === "/v1/release/resolve") {
|
|
45156
45184
|
return json4(
|
|
45157
45185
|
200,
|
|
45158
45186
|
{ app: opts.app, releaseId: opts.header?.releaseId ?? null, source: "local" },
|
|
45159
45187
|
{ "cache-control": "no-store" }
|
|
45160
45188
|
);
|
|
45161
45189
|
}
|
|
45162
|
-
if (
|
|
45190
|
+
if (path2 === "/v1/revocations") {
|
|
45163
45191
|
return json4(
|
|
45164
45192
|
200,
|
|
45165
45193
|
{ app: opts.app, revokedIntegrities: [], version: 0, ttlSeconds: 30 },
|
|
45166
45194
|
{ "cache-control": "max-age=30" }
|
|
45167
45195
|
);
|
|
45168
45196
|
}
|
|
45169
|
-
if (
|
|
45197
|
+
if (path2.startsWith("/v1/flags/")) {
|
|
45170
45198
|
return json4(200, { app: opts.app, definitions: {} }, { "cache-control": "no-store" });
|
|
45171
45199
|
}
|
|
45172
|
-
if (
|
|
45200
|
+
if (path2 === "/v1/telemetry/ingest") {
|
|
45173
45201
|
if (request.method !== "POST") return json4(405, { error: "method_not_allowed" });
|
|
45174
45202
|
try {
|
|
45175
45203
|
const body = await request.json();
|
|
@@ -45179,33 +45207,33 @@ function makeRunHandler(opts) {
|
|
|
45179
45207
|
}
|
|
45180
45208
|
return new Response(null, { status: 204 });
|
|
45181
45209
|
}
|
|
45182
|
-
if (
|
|
45210
|
+
if (path2 === "/v1/screen-events") {
|
|
45183
45211
|
return new Response(new ReadableStream({ start() {
|
|
45184
45212
|
} }), {
|
|
45185
45213
|
status: 200,
|
|
45186
45214
|
headers: { "content-type": "text/event-stream", "cache-control": "no-store", connection: "keep-alive" }
|
|
45187
45215
|
});
|
|
45188
45216
|
}
|
|
45189
|
-
if (
|
|
45217
|
+
if (path2.startsWith("/v1/__webwix/") && path2 !== "/v1/__webwix/call" && path2 !== "/v1/__webwix/identity" && !(opts.serve?.webwixMemberAuth === true && opts.serve?.webwixMemberSessions)) {
|
|
45190
45218
|
return json4(501, { error: "webwix_member_auth_unavailable" });
|
|
45191
45219
|
}
|
|
45192
|
-
if (
|
|
45220
|
+
if (path2 === "/v1/app-config" || path2.startsWith("/v1/app-config/")) {
|
|
45193
45221
|
return localizeConfigResponse(await serve(request), "app-config", opts.header ?? null);
|
|
45194
45222
|
}
|
|
45195
|
-
if (
|
|
45223
|
+
if (path2 === "/v1/boot") {
|
|
45196
45224
|
return localizeConfigResponse(await serve(request), "boot", opts.header ?? null);
|
|
45197
45225
|
}
|
|
45198
|
-
if (
|
|
45226
|
+
if (path2 === "/v1" || path2.startsWith("/v1/") || path2 === "/__health") {
|
|
45199
45227
|
return serve(request);
|
|
45200
45228
|
}
|
|
45201
|
-
if (
|
|
45229
|
+
if (path2 === "/" || path2 === "") {
|
|
45202
45230
|
const target = `${mount}/a/${encodeURIComponent(opts.app)}${url.search}`;
|
|
45203
45231
|
return new Response(null, { status: 302, headers: { location: target } });
|
|
45204
45232
|
}
|
|
45205
|
-
if (
|
|
45206
|
-
return previewResponse(
|
|
45233
|
+
if (path2 === mount || path2.startsWith(`${mount}/`)) {
|
|
45234
|
+
return previewResponse(path2, opts.assets, mount);
|
|
45207
45235
|
}
|
|
45208
|
-
return json4(404, { error: "not_found", path });
|
|
45236
|
+
return json4(404, { error: "not_found", path: path2 });
|
|
45209
45237
|
};
|
|
45210
45238
|
}
|
|
45211
45239
|
var json4;
|
|
@@ -45414,9 +45442,9 @@ async function loadPreviewAssets() {
|
|
|
45414
45442
|
join46(here, "../../../packages/serve/src/preview-assets.generated.bin")
|
|
45415
45443
|
// in-repo checkout
|
|
45416
45444
|
];
|
|
45417
|
-
for (const
|
|
45418
|
-
if (!existsSync49(
|
|
45419
|
-
const blob = readFileSync54(
|
|
45445
|
+
for (const path2 of candidates) {
|
|
45446
|
+
if (!existsSync49(path2)) continue;
|
|
45447
|
+
const blob = readFileSync54(path2);
|
|
45420
45448
|
return mod.assemblePreviewAssetsFromBlob(new Uint8Array(blob.buffer, blob.byteOffset, blob.byteLength));
|
|
45421
45449
|
}
|
|
45422
45450
|
return /* @__PURE__ */ new Map();
|
|
@@ -45426,9 +45454,9 @@ async function loadPreviewAssets() {
|
|
|
45426
45454
|
}
|
|
45427
45455
|
function packageUrl(origin, app, opts = {}) {
|
|
45428
45456
|
const mount = opts.chrome === "app" ? "/app" : "/preview";
|
|
45429
|
-
const
|
|
45457
|
+
const path2 = `${mount}/a/${encodeURIComponent(app)}${opts.screen ? `/screen/${encodeURIComponent(opts.screen)}` : ""}`;
|
|
45430
45458
|
const query = opts.surface ? `?surface=${encodeURIComponent(opts.surface)}` : "";
|
|
45431
|
-
return `${origin.replace(/\/$/, "")}${
|
|
45459
|
+
return `${origin.replace(/\/$/, "")}${path2}${query}`;
|
|
45432
45460
|
}
|
|
45433
45461
|
function openBrowser(url) {
|
|
45434
45462
|
const cmd = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
|
|
@@ -45588,13 +45616,13 @@ async function runInBrowser(releaseRoot, app, header, opts = {}) {
|
|
|
45588
45616
|
const body = JSON.stringify(payload);
|
|
45589
45617
|
const missed = [];
|
|
45590
45618
|
const server = createServer5((req, res) => {
|
|
45591
|
-
const
|
|
45592
|
-
if (
|
|
45619
|
+
const path2 = (req.url ?? "/").split("?")[0];
|
|
45620
|
+
if (path2 === "/release.json") {
|
|
45593
45621
|
res.writeHead(200, { "content-type": "application/json", "cache-control": "no-store" });
|
|
45594
45622
|
res.end(body);
|
|
45595
45623
|
return;
|
|
45596
45624
|
}
|
|
45597
|
-
const name =
|
|
45625
|
+
const name = path2 === "/" || path2 === "/index.html" ? "host.html" : path2.slice(1);
|
|
45598
45626
|
if (SERVED.has(name)) {
|
|
45599
45627
|
if (!existsSync50(resolve40(stagedDir(), name))) {
|
|
45600
45628
|
const restaged = ensureBrowserPlaneStaged();
|
|
@@ -45621,9 +45649,9 @@ async function runInBrowser(releaseRoot, app, header, opts = {}) {
|
|
|
45621
45649
|
res.end(bytes2);
|
|
45622
45650
|
return;
|
|
45623
45651
|
}
|
|
45624
|
-
missed.push(
|
|
45652
|
+
missed.push(path2);
|
|
45625
45653
|
res.writeHead(404, { "content-type": "application/json" });
|
|
45626
|
-
res.end(JSON.stringify({ error: "reached_the_cli_not_the_worker", path }));
|
|
45654
|
+
res.end(JSON.stringify({ error: "reached_the_cli_not_the_worker", path: path2 }));
|
|
45627
45655
|
});
|
|
45628
45656
|
await new Promise((r) => server.listen(opts.port ?? 0, "127.0.0.1", () => r()));
|
|
45629
45657
|
const port = server.address().port;
|
|
@@ -46833,8 +46861,8 @@ function client(creds) {
|
|
|
46833
46861
|
const env = creds ?? requireEnv(["ASC_KEY_ID", "ASC_ISSUER_ID", "ASC_KEY_PATH"]);
|
|
46834
46862
|
assertCredentialOutsideRepo("ASC_KEY_PATH", env.ASC_KEY_PATH);
|
|
46835
46863
|
const jwt = ascJwt(env.ASC_KEY_ID, env.ASC_ISSUER_ID, readFileSync61(env.ASC_KEY_PATH, "utf8"), Math.floor(Date.now() / 1e3));
|
|
46836
|
-
return async (
|
|
46837
|
-
const r = await fetch(`${ASC}${
|
|
46864
|
+
return async (path2) => {
|
|
46865
|
+
const r = await fetch(`${ASC}${path2}`, { headers: { Authorization: `Bearer ${jwt}` } });
|
|
46838
46866
|
return { status: r.status, json: await r.json().catch(() => ({})) };
|
|
46839
46867
|
};
|
|
46840
46868
|
}
|
|
@@ -47094,24 +47122,24 @@ import { dirname as dirname29, join as join49 } from "node:path";
|
|
|
47094
47122
|
function defaultSessionsPath() {
|
|
47095
47123
|
return process.env.HIMI_ADMIN_SESSIONS_FILE ?? join49(homedir6(), ".himalaya", "admin-sessions.json");
|
|
47096
47124
|
}
|
|
47097
|
-
function loadSessionsFile(
|
|
47125
|
+
function loadSessionsFile(path2 = defaultSessionsPath()) {
|
|
47098
47126
|
try {
|
|
47099
|
-
return JSON.parse(readFileSync63(
|
|
47127
|
+
return JSON.parse(readFileSync63(path2, "utf8"));
|
|
47100
47128
|
} catch {
|
|
47101
47129
|
return {};
|
|
47102
47130
|
}
|
|
47103
47131
|
}
|
|
47104
|
-
function saveAdminSession(adminUrl, session,
|
|
47105
|
-
const file = loadSessionsFile(
|
|
47132
|
+
function saveAdminSession(adminUrl, session, path2 = defaultSessionsPath()) {
|
|
47133
|
+
const file = loadSessionsFile(path2);
|
|
47106
47134
|
file.sessions = { ...file.sessions, [adminUrl]: session };
|
|
47107
|
-
mkdirSync24(dirname29(
|
|
47108
|
-
writeFileSync21(
|
|
47135
|
+
mkdirSync24(dirname29(path2), { recursive: true, mode: 448 });
|
|
47136
|
+
writeFileSync21(path2, JSON.stringify(file, null, 2) + "\n", { mode: 384 });
|
|
47109
47137
|
try {
|
|
47110
|
-
chmodSync3(dirname29(
|
|
47111
|
-
chmodSync3(
|
|
47138
|
+
chmodSync3(dirname29(path2), 448);
|
|
47139
|
+
chmodSync3(path2, 384);
|
|
47112
47140
|
} catch {
|
|
47113
47141
|
}
|
|
47114
|
-
return
|
|
47142
|
+
return path2;
|
|
47115
47143
|
}
|
|
47116
47144
|
function resolveAuth(opts = {}) {
|
|
47117
47145
|
const env = opts.env ?? process.env;
|
|
@@ -47417,9 +47445,9 @@ var init_types2 = __esm({
|
|
|
47417
47445
|
});
|
|
47418
47446
|
|
|
47419
47447
|
// src/site-analyze/rest.ts
|
|
47420
|
-
function resolveWixUrl(
|
|
47421
|
-
if (/^https?:\/\//i.test(
|
|
47422
|
-
return `${WIX_API3}${
|
|
47448
|
+
function resolveWixUrl(path2) {
|
|
47449
|
+
if (/^https?:\/\//i.test(path2)) return path2;
|
|
47450
|
+
return `${WIX_API3}${path2}`;
|
|
47423
47451
|
}
|
|
47424
47452
|
function classifyHttp(status, count) {
|
|
47425
47453
|
if (status === 428) return "not-installed";
|
|
@@ -47428,12 +47456,12 @@ function classifyHttp(status, count) {
|
|
|
47428
47456
|
return count > 0 ? "ok" : "empty";
|
|
47429
47457
|
}
|
|
47430
47458
|
function makeTransport(fetchImpl, auth, timeoutMs = DEFAULT_TIMEOUT_MS4) {
|
|
47431
|
-
return async (method,
|
|
47459
|
+
return async (method, path2, body) => {
|
|
47432
47460
|
const headers2 = { Accept: "application/json" };
|
|
47433
47461
|
if (auth?.token) headers2.Authorization = auth.token;
|
|
47434
47462
|
if (auth?.msid) headers2["wix-site-id"] = auth.msid;
|
|
47435
47463
|
if (body !== void 0) headers2["Content-Type"] = "application/json";
|
|
47436
|
-
const res = await fetchImpl(resolveWixUrl(
|
|
47464
|
+
const res = await fetchImpl(resolveWixUrl(path2), {
|
|
47437
47465
|
method,
|
|
47438
47466
|
headers: headers2,
|
|
47439
47467
|
body: body === void 0 ? void 0 : JSON.stringify(body),
|
|
@@ -47445,7 +47473,7 @@ function makeTransport(fetchImpl, auth, timeoutMs = DEFAULT_TIMEOUT_MS4) {
|
|
|
47445
47473
|
parsed = text4 ? JSON.parse(text4) : null;
|
|
47446
47474
|
} catch {
|
|
47447
47475
|
}
|
|
47448
|
-
if (!res.ok) throw new WixApiError2(res.status, method,
|
|
47476
|
+
if (!res.ok) throw new WixApiError2(res.status, method, path2, parsed);
|
|
47449
47477
|
return parsed;
|
|
47450
47478
|
};
|
|
47451
47479
|
}
|
|
@@ -47455,9 +47483,9 @@ function ownerTransportFrom(fetchImpl, owner) {
|
|
|
47455
47483
|
function visitorTransportFrom(fetchImpl, token, msid) {
|
|
47456
47484
|
return makeTransport(fetchImpl, { token, msid });
|
|
47457
47485
|
}
|
|
47458
|
-
async function probeCall(call, method,
|
|
47486
|
+
async function probeCall(call, method, path2, body) {
|
|
47459
47487
|
try {
|
|
47460
|
-
return { data: await call(method,
|
|
47488
|
+
return { data: await call(method, path2, body), err: null };
|
|
47461
47489
|
} catch (e) {
|
|
47462
47490
|
if (e instanceof WixApiError2) return { data: null, err: e };
|
|
47463
47491
|
throw e;
|
|
@@ -47519,11 +47547,11 @@ var init_rest = __esm({
|
|
|
47519
47547
|
WIX_API3 = "https://www.wixapis.com";
|
|
47520
47548
|
DEFAULT_TIMEOUT_MS4 = 8e3;
|
|
47521
47549
|
WixApiError2 = class extends Error {
|
|
47522
|
-
constructor(status, method,
|
|
47523
|
-
super(`${method} ${
|
|
47550
|
+
constructor(status, method, path2, body) {
|
|
47551
|
+
super(`${method} ${path2} \u2192 ${status}`);
|
|
47524
47552
|
this.status = status;
|
|
47525
47553
|
this.method = method;
|
|
47526
|
-
this.path =
|
|
47554
|
+
this.path = path2;
|
|
47527
47555
|
this.body = body;
|
|
47528
47556
|
this.name = "WixApiError";
|
|
47529
47557
|
}
|
|
@@ -47731,8 +47759,8 @@ function toItems(def, raw) {
|
|
|
47731
47759
|
description: copyOrDrop(def.descriptionOf ? def.descriptionOf(it) : genericDescription(it), 240) || void 0
|
|
47732
47760
|
}));
|
|
47733
47761
|
}
|
|
47734
|
-
async function runDualProbes(owner, visitor) {
|
|
47735
|
-
const rows = await Promise.all(
|
|
47762
|
+
async function runDualProbes(owner, visitor, definitions2 = ALL) {
|
|
47763
|
+
const rows = await Promise.all(definitions2.map(async (def) => {
|
|
47736
47764
|
const [o, vis] = await Promise.all([side(owner, def), side(visitor, def)]);
|
|
47737
47765
|
const imageless = def.imageOf ? o.items.filter((it) => !def.imageOf(it)).length : void 0;
|
|
47738
47766
|
return {
|
|
@@ -47794,7 +47822,7 @@ function sampleTitle(data) {
|
|
|
47794
47822
|
}
|
|
47795
47823
|
return void 0;
|
|
47796
47824
|
}
|
|
47797
|
-
async function readCms(call) {
|
|
47825
|
+
async function readCms(call, opts = {}) {
|
|
47798
47826
|
if (!call) return { collections: [], status: "skipped" };
|
|
47799
47827
|
const { data, err } = await probeCall(call, "GET", "/data/v2/collections");
|
|
47800
47828
|
if (err) {
|
|
@@ -47819,7 +47847,7 @@ async function readCms(call) {
|
|
|
47819
47847
|
...f.encrypted === true ? { encrypted: true } : {}
|
|
47820
47848
|
})).filter((f) => f.key);
|
|
47821
47849
|
const perms = c.permissions && typeof c.permissions === "object" ? c.permissions : void 0;
|
|
47822
|
-
const q = await probeCall(call, "POST", "/wix-data/v2/items/query", {
|
|
47850
|
+
const q = opts.samples === false ? { data: null, err: null } : await probeCall(call, "POST", "/wix-data/v2/items/query", {
|
|
47823
47851
|
dataCollectionId: id,
|
|
47824
47852
|
query: { paging: { limit: 5 } }
|
|
47825
47853
|
});
|
|
@@ -47856,8 +47884,8 @@ async function readInstalledApps(call) {
|
|
|
47856
47884
|
"/site-apps/v1/apps",
|
|
47857
47885
|
"/devcenter/v1/apps"
|
|
47858
47886
|
];
|
|
47859
|
-
for (const
|
|
47860
|
-
const { data } = await probeCall(call, "GET",
|
|
47887
|
+
for (const path2 of paths) {
|
|
47888
|
+
const { data } = await probeCall(call, "GET", path2);
|
|
47861
47889
|
if (!data) continue;
|
|
47862
47890
|
const raw = asArr(data.apps ?? data.siteApps ?? data.items);
|
|
47863
47891
|
const apps = raw.map((a) => ({
|
|
@@ -47873,8 +47901,8 @@ async function readMemberRoles(call) {
|
|
|
47873
47901
|
const paths = ["/members/v1/roles", "/members/v2/roles", "/authorization/v1/roles"];
|
|
47874
47902
|
let sawAuthError = false;
|
|
47875
47903
|
let sawEmptyPayload = false;
|
|
47876
|
-
for (const
|
|
47877
|
-
const { data, err } = await probeCall(call, "GET",
|
|
47904
|
+
for (const path2 of paths) {
|
|
47905
|
+
const { data, err } = await probeCall(call, "GET", path2);
|
|
47878
47906
|
if (err) {
|
|
47879
47907
|
if (err.status === 401 || err.status === 403 || err.status >= 500) sawAuthError = true;
|
|
47880
47908
|
continue;
|
|
@@ -48345,15 +48373,15 @@ function pagePathForRole(url) {
|
|
|
48345
48373
|
}
|
|
48346
48374
|
}
|
|
48347
48375
|
function classifyPageRole(url, title, _nav = "") {
|
|
48348
|
-
const { path, isHome } = pagePathForRole(url);
|
|
48376
|
+
const { path: path2, isHome } = pagePathForRole(url);
|
|
48349
48377
|
if (isHome) return "home";
|
|
48350
|
-
const hay = `${
|
|
48378
|
+
const hay = `${path2} ${title}`.toLowerCase();
|
|
48351
48379
|
if (/\b(faq|help|support)\b/.test(hay)) return "faq";
|
|
48352
48380
|
if (/\b(pricing|membership|member-plan|plans?)\b/.test(hay)) return "plans";
|
|
48353
48381
|
if (/\b(drill|library|resource|session-builder|session-generator)\b/.test(hay)) return "library";
|
|
48354
48382
|
if (/\b(members?|account|login|profile)\b/.test(hay) && !/\bmembership\b/.test(hay)) return "members";
|
|
48355
48383
|
if (/\b(shop|store|product|cart)\b/.test(hay)) return "shop";
|
|
48356
|
-
if (/(^|\/)(book|book-online|bookings?)(\/|$)/.test(
|
|
48384
|
+
if (/(^|\/)(book|book-online|bookings?)(\/|$)/.test(path2) || /\b(book-online|bookings?|appoint)\b/.test(hay)) return "book";
|
|
48357
48385
|
if (/\b(menu|dining|restaurant)\b/.test(hay)) return "menu";
|
|
48358
48386
|
if (/\b(blog|journal|news|posts?|ebooks?|insight)\b/.test(hay)) return "blog";
|
|
48359
48387
|
if (/\b(about|story|our-story)\b/.test(hay)) return "about";
|
|
@@ -49007,12 +49035,12 @@ function veloListFilesPath(gridAppId, layout) {
|
|
|
49007
49035
|
async function gridAppIdFromSiteHtml(fetchImpl, siteUrl) {
|
|
49008
49036
|
return (await readPublishedHtml(fetchImpl, siteUrl)).gridAppId;
|
|
49009
49037
|
}
|
|
49010
|
-
function assertSafeVeloPath(
|
|
49011
|
-
if (VELO_INVOKE_RE.test(
|
|
49012
|
-
throw new Error(`refusing to call Velo invoke path: ${
|
|
49038
|
+
function assertSafeVeloPath(path2, method = "GET") {
|
|
49039
|
+
if (VELO_INVOKE_RE.test(path2)) {
|
|
49040
|
+
throw new Error(`refusing to call Velo invoke path: ${path2}`);
|
|
49013
49041
|
}
|
|
49014
|
-
if (method !== "GET" && VELO_WRITE_RE.test(
|
|
49015
|
-
throw new Error(`refusing to call Velo write path: ${method} ${
|
|
49042
|
+
if (method !== "GET" && VELO_WRITE_RE.test(path2.split("?")[0] ?? path2)) {
|
|
49043
|
+
throw new Error(`refusing to call Velo write path: ${method} ${path2}`);
|
|
49016
49044
|
}
|
|
49017
49045
|
}
|
|
49018
49046
|
function parseHttpFunctions(source) {
|
|
@@ -49031,8 +49059,8 @@ function parseHttpFunctions(source) {
|
|
|
49031
49059
|
}
|
|
49032
49060
|
return out;
|
|
49033
49061
|
}
|
|
49034
|
-
function classifyVeloFile(
|
|
49035
|
-
const p =
|
|
49062
|
+
function classifyVeloFile(path2) {
|
|
49063
|
+
const p = path2.replace(/\\/g, "/").toLowerCase();
|
|
49036
49064
|
const base = p.split("/").pop() ?? p;
|
|
49037
49065
|
if (base === "http-functions.js" || base === "http-functions.ts") return "http-functions";
|
|
49038
49066
|
if (base === "data.js" || base === "data.ts") return "data-hooks";
|
|
@@ -49044,8 +49072,8 @@ function classifyVeloFile(path) {
|
|
|
49044
49072
|
if (/(^|\/)public\//.test(p)) return "public";
|
|
49045
49073
|
return "other";
|
|
49046
49074
|
}
|
|
49047
|
-
function isSecretVeloPath(
|
|
49048
|
-
const p =
|
|
49075
|
+
function isSecretVeloPath(path2) {
|
|
49076
|
+
const p = path2.replace(/\\/g, "/").toLowerCase();
|
|
49049
49077
|
return /secrets-backend|\/secrets\/|\.env(?:\.|$)/.test(p);
|
|
49050
49078
|
}
|
|
49051
49079
|
function redactSecrets(source) {
|
|
@@ -49075,7 +49103,7 @@ function str4(x) {
|
|
|
49075
49103
|
function asArr2(x) {
|
|
49076
49104
|
return Array.isArray(x) ? x : [];
|
|
49077
49105
|
}
|
|
49078
|
-
function filesFromOwnerPayload(data) {
|
|
49106
|
+
function filesFromOwnerPayload(data, redact = redactSecrets) {
|
|
49079
49107
|
if (!data || typeof data !== "object") return [];
|
|
49080
49108
|
const root = data;
|
|
49081
49109
|
const raw = [
|
|
@@ -49087,17 +49115,17 @@ function filesFromOwnerPayload(data) {
|
|
|
49087
49115
|
for (const item of raw) {
|
|
49088
49116
|
if (!item || typeof item !== "object") continue;
|
|
49089
49117
|
const f = item;
|
|
49090
|
-
const
|
|
49091
|
-
if (!
|
|
49118
|
+
const path2 = str4(f.path || f.relativePath || f.fileName || f.name);
|
|
49119
|
+
if (!path2 || isSecretVeloPath(path2)) continue;
|
|
49092
49120
|
const content = str4(f.content ?? f.source ?? f.code ?? f.body);
|
|
49093
49121
|
const bytes2 = typeof f.bytes === "number" ? f.bytes : typeof f.size === "number" ? f.size : content.length;
|
|
49094
|
-
const redacted = content ?
|
|
49122
|
+
const redacted = content ? redact(content) : "";
|
|
49095
49123
|
const forDisk = redacted.length > VELO_FILE_CAP ? redacted.slice(0, VELO_FILE_CAP) + "\n/* \u2026truncated */" : redacted;
|
|
49096
49124
|
out.push({
|
|
49097
|
-
path,
|
|
49098
|
-
kind: classifyVeloFile(
|
|
49125
|
+
path: path2,
|
|
49126
|
+
kind: classifyVeloFile(path2),
|
|
49099
49127
|
bytes: bytes2,
|
|
49100
|
-
excerpt: content ? redactExcerpt(
|
|
49128
|
+
excerpt: content ? redactExcerpt(redacted) : void 0,
|
|
49101
49129
|
...forDisk ? { content: forDisk } : {}
|
|
49102
49130
|
});
|
|
49103
49131
|
}
|
|
@@ -49140,8 +49168,8 @@ function veloHintFromEval(evaled, page) {
|
|
|
49140
49168
|
pages: [{ url: page.url, title: page.title, hasCode: wixRendered && hasCode, ...pageId ? { pageId } : {} }]
|
|
49141
49169
|
};
|
|
49142
49170
|
}
|
|
49143
|
-
function pageIdFromVeloPath(
|
|
49144
|
-
const m =
|
|
49171
|
+
function pageIdFromVeloPath(path2) {
|
|
49172
|
+
const m = path2.replace(/\\/g, "/").match(/\/pages\/([A-Za-z0-9_-]+)\.(js|ts|jsx|tsx)$/i);
|
|
49145
49173
|
return m?.[1];
|
|
49146
49174
|
}
|
|
49147
49175
|
function bindVeloFiles(files, pages) {
|
|
@@ -49186,13 +49214,13 @@ function gridAppIdsFromPayload(data) {
|
|
|
49186
49214
|
}
|
|
49187
49215
|
return ids;
|
|
49188
49216
|
}
|
|
49189
|
-
async function listFilesForApp(call, gridAppId) {
|
|
49217
|
+
async function listFilesForApp(call, gridAppId, redact) {
|
|
49190
49218
|
for (const layout of VELO_LAYOUTS) {
|
|
49191
|
-
const
|
|
49192
|
-
assertSafeVeloPath(
|
|
49193
|
-
const { data } = await probeCall(call, "GET",
|
|
49219
|
+
const path2 = veloListFilesPath(gridAppId, layout);
|
|
49220
|
+
assertSafeVeloPath(path2, "GET");
|
|
49221
|
+
const { data } = await probeCall(call, "GET", path2);
|
|
49194
49222
|
if (!data) continue;
|
|
49195
|
-
const files = filesFromOwnerPayload(data);
|
|
49223
|
+
const files = filesFromOwnerPayload(data, redact);
|
|
49196
49224
|
if (files.length) return files;
|
|
49197
49225
|
}
|
|
49198
49226
|
return [];
|
|
@@ -49214,7 +49242,7 @@ async function readOwnerVelo(call, opts) {
|
|
|
49214
49242
|
if (probe.path.includes("git-repo") && (data.repo || data.repository || data.gitRepo || data.url)) git2 = true;
|
|
49215
49243
|
}
|
|
49216
49244
|
for (const id of ids) {
|
|
49217
|
-
const listed = await listFilesForApp(call, id);
|
|
49245
|
+
const listed = await listFilesForApp(call, id, opts?.redact);
|
|
49218
49246
|
for (const f of listed) {
|
|
49219
49247
|
if (!files.some((x) => x.path === f.path)) files.push(f);
|
|
49220
49248
|
}
|
|
@@ -49551,14 +49579,14 @@ function parseAuthorizationConfig(source) {
|
|
|
49551
49579
|
const defaultAnonymousInvoke = invokeFlag(starDefault, "anonymous") ?? true;
|
|
49552
49580
|
const defaultSiteMemberInvoke = invokeFlag(starDefault, "siteMember") ?? true;
|
|
49553
49581
|
const modules = [];
|
|
49554
|
-
for (const [
|
|
49555
|
-
if (
|
|
49582
|
+
for (const [path2, entry] of Object.entries(web)) {
|
|
49583
|
+
if (path2 === "*") continue;
|
|
49556
49584
|
const star = methodStar(entry);
|
|
49557
49585
|
const anonymousInvoke = invokeFlag(star, "anonymous") ?? defaultAnonymousInvoke;
|
|
49558
49586
|
const siteMemberInvoke = invokeFlag(star, "siteMember") ?? defaultSiteMemberInvoke;
|
|
49559
|
-
const jsw = /\.(jsw|web\.js)$/i.test(
|
|
49587
|
+
const jsw = /\.(jsw|web\.js)$/i.test(path2);
|
|
49560
49588
|
modules.push({
|
|
49561
|
-
path,
|
|
49589
|
+
path: path2,
|
|
49562
49590
|
anonymousInvoke,
|
|
49563
49591
|
siteMemberInvoke,
|
|
49564
49592
|
...jsw ? { note: "worker-unreachable" } : {}
|
|
@@ -50697,12 +50725,12 @@ function attachVeloSources(book, sources, put) {
|
|
|
50697
50725
|
}
|
|
50698
50726
|
}
|
|
50699
50727
|
function extOf2(url) {
|
|
50700
|
-
const
|
|
50701
|
-
if (/\.png$/i.test(
|
|
50702
|
-
if (/\.webp$/i.test(
|
|
50703
|
-
if (/\.gif$/i.test(
|
|
50704
|
-
if (/\.svg$/i.test(
|
|
50705
|
-
if (/\.ico$/i.test(
|
|
50728
|
+
const path2 = url.split("?")[0] ?? url;
|
|
50729
|
+
if (/\.png$/i.test(path2)) return "png";
|
|
50730
|
+
if (/\.webp$/i.test(path2)) return "webp";
|
|
50731
|
+
if (/\.gif$/i.test(path2)) return "gif";
|
|
50732
|
+
if (/\.svg$/i.test(path2)) return "svg";
|
|
50733
|
+
if (/\.ico$/i.test(path2)) return "ico";
|
|
50706
50734
|
return "jpg";
|
|
50707
50735
|
}
|
|
50708
50736
|
async function readCapped(res, cap) {
|
|
@@ -51273,8 +51301,8 @@ function unpairedRedirectNote(overlay) {
|
|
|
51273
51301
|
function posix2(p) {
|
|
51274
51302
|
return resolve42(p).replace(/\\/g, "/");
|
|
51275
51303
|
}
|
|
51276
|
-
function committedShellProvisioning(
|
|
51277
|
-
return committedShellFor(posix2(
|
|
51304
|
+
function committedShellProvisioning(path2) {
|
|
51305
|
+
return committedShellFor(posix2(path2));
|
|
51278
51306
|
}
|
|
51279
51307
|
function findRepoRoot(cwd) {
|
|
51280
51308
|
let dir = cwd;
|
|
@@ -51298,14 +51326,14 @@ function deepMerge4(a, b) {
|
|
|
51298
51326
|
}
|
|
51299
51327
|
return out;
|
|
51300
51328
|
}
|
|
51301
|
-
function assertNotCommitted(
|
|
51302
|
-
const committed = committedShellProvisioning(
|
|
51329
|
+
function assertNotCommitted(path2, forbidden) {
|
|
51330
|
+
const committed = committedShellProvisioning(path2);
|
|
51303
51331
|
if (committed) {
|
|
51304
51332
|
throw new Error(
|
|
51305
51333
|
`refusing to overwrite committed ${committedProvisioningPath(committed)} \u2014 use prepare:customer --contract`
|
|
51306
51334
|
);
|
|
51307
51335
|
}
|
|
51308
|
-
if (forbidden && resolve42(
|
|
51336
|
+
if (forbidden && resolve42(path2) === resolve42(forbidden)) {
|
|
51309
51337
|
const named = committedShellProvisioning(forbidden);
|
|
51310
51338
|
throw new Error(
|
|
51311
51339
|
`refusing to overwrite committed ${named ? committedProvisioningPath(named) : forbidden} \u2014 pass a content-package provisioning.json or use prepare:customer --contract`
|
|
@@ -51411,13 +51439,13 @@ function buildMergedContract(options) {
|
|
|
51411
51439
|
merged.branding = branding;
|
|
51412
51440
|
const body = `${JSON.stringify(merged, null, 2)}
|
|
51413
51441
|
`;
|
|
51414
|
-
const
|
|
51415
|
-
writeFileSync23(
|
|
51442
|
+
const path2 = join51(packageDir, "provisioning.contract.json");
|
|
51443
|
+
writeFileSync23(path2, body);
|
|
51416
51444
|
const localPath = join51(appDir2, LOCAL_CONTRACT_REL);
|
|
51417
51445
|
mkdirSync26(dirname30(localPath), { recursive: true });
|
|
51418
51446
|
writeFileSync23(localPath, body);
|
|
51419
51447
|
staged.push(localPath);
|
|
51420
|
-
return { path, staged };
|
|
51448
|
+
return { path: path2, staged };
|
|
51421
51449
|
}
|
|
51422
51450
|
async function applyOverlays(input) {
|
|
51423
51451
|
const cwd = resolve42(input.cwd);
|
|
@@ -52849,18 +52877,18 @@ function cookieCompare(a, b) {
|
|
|
52849
52877
|
cmp = (a.creationIndex || 0) - (b.creationIndex || 0);
|
|
52850
52878
|
return cmp;
|
|
52851
52879
|
}
|
|
52852
|
-
function defaultPath(
|
|
52853
|
-
if (!
|
|
52880
|
+
function defaultPath(path2) {
|
|
52881
|
+
if (!path2 || path2.slice(0, 1) !== "/") {
|
|
52854
52882
|
return "/";
|
|
52855
52883
|
}
|
|
52856
|
-
if (
|
|
52857
|
-
return
|
|
52884
|
+
if (path2 === "/") {
|
|
52885
|
+
return path2;
|
|
52858
52886
|
}
|
|
52859
|
-
const rightSlash =
|
|
52887
|
+
const rightSlash = path2.lastIndexOf("/");
|
|
52860
52888
|
if (rightSlash === 0) {
|
|
52861
52889
|
return "/";
|
|
52862
52890
|
}
|
|
52863
|
-
return
|
|
52891
|
+
return path2.slice(0, rightSlash);
|
|
52864
52892
|
}
|
|
52865
52893
|
function domainMatch(domain, cookieDomain, canonicalize) {
|
|
52866
52894
|
if (domain == null || cookieDomain == null) {
|
|
@@ -53088,18 +53116,18 @@ var init_dist = __esm({
|
|
|
53088
53116
|
/**
|
|
53089
53117
|
* @internal No doc because this is an overload that supports the implementation
|
|
53090
53118
|
*/
|
|
53091
|
-
findCookie(domain,
|
|
53119
|
+
findCookie(domain, path2, key2, callback) {
|
|
53092
53120
|
const promiseCallback = createPromiseCallback(callback);
|
|
53093
|
-
if (domain == null ||
|
|
53121
|
+
if (domain == null || path2 == null || key2 == null) {
|
|
53094
53122
|
return promiseCallback.resolve(void 0);
|
|
53095
53123
|
}
|
|
53096
|
-
const result = this.idx[domain]?.[
|
|
53124
|
+
const result = this.idx[domain]?.[path2]?.[key2];
|
|
53097
53125
|
return promiseCallback.resolve(result);
|
|
53098
53126
|
}
|
|
53099
53127
|
/**
|
|
53100
53128
|
* @internal No doc because this is an overload that supports the implementation
|
|
53101
53129
|
*/
|
|
53102
|
-
findCookies(domain,
|
|
53130
|
+
findCookies(domain, path2, allowSpecialUseDomain = false, callback) {
|
|
53103
53131
|
if (typeof allowSpecialUseDomain === "function") {
|
|
53104
53132
|
callback = allowSpecialUseDomain;
|
|
53105
53133
|
allowSpecialUseDomain = true;
|
|
@@ -53110,7 +53138,7 @@ var init_dist = __esm({
|
|
|
53110
53138
|
return promiseCallback.resolve([]);
|
|
53111
53139
|
}
|
|
53112
53140
|
let pathMatcher;
|
|
53113
|
-
if (!
|
|
53141
|
+
if (!path2) {
|
|
53114
53142
|
pathMatcher = function matchAll(domainIndex) {
|
|
53115
53143
|
for (const curPath in domainIndex) {
|
|
53116
53144
|
const pathIndex = domainIndex[curPath];
|
|
@@ -53125,7 +53153,7 @@ var init_dist = __esm({
|
|
|
53125
53153
|
} else {
|
|
53126
53154
|
pathMatcher = function matchRFC(domainIndex) {
|
|
53127
53155
|
for (const cookiePath in domainIndex) {
|
|
53128
|
-
if (pathMatch(
|
|
53156
|
+
if (pathMatch(path2, cookiePath)) {
|
|
53129
53157
|
const pathIndex = domainIndex[cookiePath];
|
|
53130
53158
|
for (const key2 in pathIndex) {
|
|
53131
53159
|
const value = pathIndex[key2];
|
|
@@ -53153,14 +53181,14 @@ var init_dist = __esm({
|
|
|
53153
53181
|
*/
|
|
53154
53182
|
putCookie(cookie, callback) {
|
|
53155
53183
|
const promiseCallback = createPromiseCallback(callback);
|
|
53156
|
-
const { domain, path, key: key2 } = cookie;
|
|
53157
|
-
if (domain == null ||
|
|
53184
|
+
const { domain, path: path2, key: key2 } = cookie;
|
|
53185
|
+
if (domain == null || path2 == null || key2 == null) {
|
|
53158
53186
|
return promiseCallback.resolve(void 0);
|
|
53159
53187
|
}
|
|
53160
53188
|
const domainEntry = this.idx[domain] ?? /* @__PURE__ */ Object.create(null);
|
|
53161
53189
|
this.idx[domain] = domainEntry;
|
|
53162
|
-
const pathEntry = domainEntry[
|
|
53163
|
-
domainEntry[
|
|
53190
|
+
const pathEntry = domainEntry[path2] ?? /* @__PURE__ */ Object.create(null);
|
|
53191
|
+
domainEntry[path2] = pathEntry;
|
|
53164
53192
|
pathEntry[key2] = cookie;
|
|
53165
53193
|
return promiseCallback.resolve(void 0);
|
|
53166
53194
|
}
|
|
@@ -53174,20 +53202,20 @@ var init_dist = __esm({
|
|
|
53174
53202
|
/**
|
|
53175
53203
|
* @internal No doc because this is an overload that supports the implementation
|
|
53176
53204
|
*/
|
|
53177
|
-
removeCookie(domain,
|
|
53205
|
+
removeCookie(domain, path2, key2, callback) {
|
|
53178
53206
|
const promiseCallback = createPromiseCallback(callback);
|
|
53179
|
-
delete this.idx[domain]?.[
|
|
53207
|
+
delete this.idx[domain]?.[path2]?.[key2];
|
|
53180
53208
|
return promiseCallback.resolve(void 0);
|
|
53181
53209
|
}
|
|
53182
53210
|
/**
|
|
53183
53211
|
* @internal No doc because this is an overload that supports the implementation
|
|
53184
53212
|
*/
|
|
53185
|
-
removeCookies(domain,
|
|
53213
|
+
removeCookies(domain, path2, callback) {
|
|
53186
53214
|
const promiseCallback = createPromiseCallback(callback);
|
|
53187
53215
|
const domainEntry = this.idx[domain];
|
|
53188
53216
|
if (domainEntry) {
|
|
53189
|
-
if (
|
|
53190
|
-
delete domainEntry[
|
|
53217
|
+
if (path2) {
|
|
53218
|
+
delete domainEntry[path2];
|
|
53191
53219
|
} else {
|
|
53192
53220
|
delete this.idx[domain];
|
|
53193
53221
|
}
|
|
@@ -53213,8 +53241,8 @@ var init_dist = __esm({
|
|
|
53213
53241
|
domains.forEach((domain) => {
|
|
53214
53242
|
const domainEntry = idx[domain] ?? {};
|
|
53215
53243
|
const paths = Object.keys(domainEntry);
|
|
53216
|
-
paths.forEach((
|
|
53217
|
-
const pathEntry = domainEntry[
|
|
53244
|
+
paths.forEach((path2) => {
|
|
53245
|
+
const pathEntry = domainEntry[path2] ?? {};
|
|
53218
53246
|
const keys = Object.keys(pathEntry);
|
|
53219
53247
|
keys.forEach((key2) => {
|
|
53220
53248
|
const keyEntry = pathEntry[key2];
|
|
@@ -53982,7 +54010,7 @@ var init_dist = __esm({
|
|
|
53982
54010
|
return promiseCallback.reject(parameterError);
|
|
53983
54011
|
}
|
|
53984
54012
|
const host = canonicalDomain(context.hostname);
|
|
53985
|
-
const
|
|
54013
|
+
const path2 = context.pathname || "/";
|
|
53986
54014
|
const potentiallyTrustworthy = isPotentiallyTrustworthy(
|
|
53987
54015
|
url,
|
|
53988
54016
|
this.allowSecureOnLocal
|
|
@@ -54013,7 +54041,7 @@ var init_dist = __esm({
|
|
|
54013
54041
|
return false;
|
|
54014
54042
|
}
|
|
54015
54043
|
}
|
|
54016
|
-
if (!allPaths && typeof c.path === "string" && !pathMatch(
|
|
54044
|
+
if (!allPaths && typeof c.path === "string" && !pathMatch(path2, c.path)) {
|
|
54017
54045
|
return false;
|
|
54018
54046
|
}
|
|
54019
54047
|
if (c.secure && !potentiallyTrustworthy) {
|
|
@@ -54045,7 +54073,7 @@ var init_dist = __esm({
|
|
|
54045
54073
|
}
|
|
54046
54074
|
store.findCookies(
|
|
54047
54075
|
host,
|
|
54048
|
-
allPaths ? null :
|
|
54076
|
+
allPaths ? null : path2,
|
|
54049
54077
|
this.allowSpecialUseDomain,
|
|
54050
54078
|
(err, cookies) => {
|
|
54051
54079
|
if (err) {
|
|
@@ -55423,9 +55451,9 @@ function filesFromList(data) {
|
|
|
55423
55451
|
if (!Array.isArray(files)) return [];
|
|
55424
55452
|
return files.flatMap((f) => {
|
|
55425
55453
|
if (!f || typeof f !== "object") return [];
|
|
55426
|
-
const
|
|
55454
|
+
const path2 = String(f.path ?? "");
|
|
55427
55455
|
const content = String(f.content ?? "");
|
|
55428
|
-
return
|
|
55456
|
+
return path2 ? [{ path: path2, content }] : [];
|
|
55429
55457
|
});
|
|
55430
55458
|
}
|
|
55431
55459
|
async function resolveGridAppId(fetchImpl, token, msid, siteUrl) {
|
|
@@ -55852,14 +55880,14 @@ function apiKeyAuth(env = process.env) {
|
|
|
55852
55880
|
return key2 && accountId ? { key: key2, accountId } : void 0;
|
|
55853
55881
|
}
|
|
55854
55882
|
function accountTransport(fetchImpl = fetch, timeoutMs = DEFAULT_TIMEOUT_MS5, spawnImpl = spawn4) {
|
|
55855
|
-
return async (method,
|
|
55883
|
+
return async (method, path2, body) => {
|
|
55856
55884
|
const viaKey = apiKeyAuth();
|
|
55857
55885
|
const headers2 = viaKey ? { Authorization: viaKey.key, "wix-account-id": viaKey.accountId, Accept: "application/json" } : { Authorization: await accountToken2(spawnImpl), Accept: "application/json" };
|
|
55858
55886
|
if (body !== void 0) headers2["Content-Type"] = "application/json";
|
|
55859
55887
|
const started = Date.now();
|
|
55860
55888
|
let res;
|
|
55861
55889
|
try {
|
|
55862
|
-
res = await fetchImpl(`${API_BASE2}${
|
|
55890
|
+
res = await fetchImpl(`${API_BASE2}${path2}`, {
|
|
55863
55891
|
method,
|
|
55864
55892
|
headers: headers2,
|
|
55865
55893
|
body: body === void 0 ? void 0 : JSON.stringify(body),
|
|
@@ -55869,10 +55897,10 @@ function accountTransport(fetchImpl = fetch, timeoutMs = DEFAULT_TIMEOUT_MS5, sp
|
|
|
55869
55897
|
const err = e;
|
|
55870
55898
|
if (err?.name === "TimeoutError" || /aborted due to timeout/i.test(err?.message ?? "")) {
|
|
55871
55899
|
throw new Error(
|
|
55872
|
-
`${method} ${
|
|
55900
|
+
`${method} ${path2} timed out after ${Date.now() - started}ms (limit ${timeoutMs}ms). Raise the ceiling with HIMI_WIX_TIMEOUT_MS=<ms>, or check the VPN.`
|
|
55873
55901
|
);
|
|
55874
55902
|
}
|
|
55875
|
-
throw new Error(`${method} ${
|
|
55903
|
+
throw new Error(`${method} ${path2} failed: ${err?.message ?? String(e)}`);
|
|
55876
55904
|
}
|
|
55877
55905
|
const text4 = await res.text();
|
|
55878
55906
|
let parsed = text4;
|
|
@@ -55880,7 +55908,7 @@ function accountTransport(fetchImpl = fetch, timeoutMs = DEFAULT_TIMEOUT_MS5, sp
|
|
|
55880
55908
|
parsed = text4 ? JSON.parse(text4) : null;
|
|
55881
55909
|
} catch {
|
|
55882
55910
|
}
|
|
55883
|
-
if (!res.ok) throw new WixApiError(res.status, method,
|
|
55911
|
+
if (!res.ok) throw new WixApiError(res.status, method, path2, parsed);
|
|
55884
55912
|
return parsed;
|
|
55885
55913
|
};
|
|
55886
55914
|
}
|
|
@@ -56159,27 +56187,27 @@ async function runSiteCreate(opts) {
|
|
|
56159
56187
|
}
|
|
56160
56188
|
function writeProvisioningBinding(target, binding2, fs = { existsSync: existsSync55, readFileSync: readFileSync66, writeFileSync: writeFileSync24 }) {
|
|
56161
56189
|
const msid = binding2.siteId;
|
|
56162
|
-
const
|
|
56163
|
-
const committed = committedShellProvisioning(
|
|
56190
|
+
const path2 = resolvePath2(target);
|
|
56191
|
+
const committed = committedShellProvisioning(path2);
|
|
56164
56192
|
if (committed) {
|
|
56165
56193
|
throw new Error(
|
|
56166
56194
|
`refusing to overwrite committed ${committedProvisioningPath(committed)} \u2014 pass a content-package provisioning.json, or use \`prepare:customer --contract\``
|
|
56167
56195
|
);
|
|
56168
56196
|
}
|
|
56169
|
-
if (!fs.existsSync(
|
|
56197
|
+
if (!fs.existsSync(path2)) {
|
|
56170
56198
|
throw new Error(
|
|
56171
|
-
`no provisioning.json at ${
|
|
56199
|
+
`no provisioning.json at ${path2}. --write-provisioning updates an EXISTING manifest (it needs identity/branding/installedVerticals, which this command cannot invent). Run it from a content package, or pass --write-provisioning <path>.`
|
|
56172
56200
|
);
|
|
56173
56201
|
}
|
|
56174
|
-
const raw = fs.readFileSync(
|
|
56202
|
+
const raw = fs.readFileSync(path2, "utf8");
|
|
56175
56203
|
let manifest;
|
|
56176
56204
|
try {
|
|
56177
56205
|
manifest = JSON.parse(raw);
|
|
56178
56206
|
} catch (e) {
|
|
56179
|
-
throw new Error(`${
|
|
56207
|
+
throw new Error(`${path2} is not valid JSON (${e?.message ?? e}) \u2014 not touching it`);
|
|
56180
56208
|
}
|
|
56181
56209
|
if (manifest === null || typeof manifest !== "object" || Array.isArray(manifest)) {
|
|
56182
|
-
throw new Error(`${
|
|
56210
|
+
throw new Error(`${path2} must contain a JSON object \u2014 not touching it`);
|
|
56183
56211
|
}
|
|
56184
56212
|
if (binding2.siteUrl !== void 0) assertAbsoluteHttpUrl(binding2.siteUrl);
|
|
56185
56213
|
if (binding2.redirectUri !== void 0) assertRedirectUri(binding2.redirectUri);
|
|
@@ -56197,9 +56225,9 @@ function writeProvisioningBinding(target, binding2, fs = { existsSync: existsSyn
|
|
|
56197
56225
|
const indentMatch = /^[ \t]*[{[][\r\n]+([ \t]+)/.exec(raw);
|
|
56198
56226
|
const indent = indentMatch ? indentMatch[1] : " ";
|
|
56199
56227
|
const trailingNewline = /\n$/.test(raw) ? "\n" : "";
|
|
56200
|
-
fs.writeFileSync(
|
|
56228
|
+
fs.writeFileSync(path2, `${JSON.stringify(manifest, null, indent)}${trailingNewline}`, "utf8");
|
|
56201
56229
|
return {
|
|
56202
|
-
path,
|
|
56230
|
+
path: path2,
|
|
56203
56231
|
siteId: msid,
|
|
56204
56232
|
...binding2.clientId ? { clientId: binding2.clientId } : {},
|
|
56205
56233
|
...binding2.siteUrl ? { siteUrl: binding2.siteUrl } : {},
|
|
@@ -56488,6 +56516,347 @@ var init_site_oauth_client = __esm({
|
|
|
56488
56516
|
}
|
|
56489
56517
|
});
|
|
56490
56518
|
|
|
56519
|
+
// src/site-analyze/velo-source.ts
|
|
56520
|
+
import path from "node:path";
|
|
56521
|
+
import ts from "typescript";
|
|
56522
|
+
function applySourceEdits(source, edits) {
|
|
56523
|
+
const chunks = [];
|
|
56524
|
+
let cursor = 0;
|
|
56525
|
+
for (const edit of edits.sort((a, b) => a.start - b.start || b.end - a.end)) {
|
|
56526
|
+
if (edit.start < cursor) continue;
|
|
56527
|
+
chunks.push(source.slice(cursor, edit.start), edit.text);
|
|
56528
|
+
cursor = edit.end;
|
|
56529
|
+
}
|
|
56530
|
+
chunks.push(source.slice(cursor));
|
|
56531
|
+
return chunks.join("");
|
|
56532
|
+
}
|
|
56533
|
+
function redactVeloSource(source, knownSecrets = []) {
|
|
56534
|
+
for (const secret of knownSecrets.filter(Boolean)) source = source.split(secret).join(REDACTED2);
|
|
56535
|
+
source = source.replace(/-----BEGIN [^-]*PRIVATE KEY-----[\s\S]*?-----END [^-]*PRIVATE KEY-----/g, REDACTED2).replace(
|
|
56536
|
+
/\b(?:IST\.[\w.-]+|eyJ[\w-]+\.[\w-]+\.[\w-]+|(?:sk|rk)_(?:live|test)_[\w-]+|gh[pousr]_[\w]+|github_pat_[\w]+|AKIA[A-Z0-9]{16})\b/g,
|
|
56537
|
+
REDACTED2
|
|
56538
|
+
).replace(/\b(?:Bearer|Basic)\s+[A-Za-z0-9._~+/=-]+/gi, REDACTED2).replace(/\b([a-z][a-z0-9+.-]*:\/\/)[^\s/'"`]+:[^\s/'"`]+@/gi, "$1[REDACTED]@").replace(/([?&](?:api[-_]?key|token|secret|password|signature)=)[^&#\s'"`]+/gi, "$1[REDACTED]");
|
|
56539
|
+
const parsed = ts.createSourceFile("backend.ts", source, ts.ScriptTarget.Latest, true);
|
|
56540
|
+
const comments = /* @__PURE__ */ new Map();
|
|
56541
|
+
const visitComments = (node) => {
|
|
56542
|
+
for (const range of [
|
|
56543
|
+
...ts.getLeadingCommentRanges(source, node.pos) ?? [],
|
|
56544
|
+
...ts.getTrailingCommentRanges(source, node.pos) ?? [],
|
|
56545
|
+
...ts.getTrailingCommentRanges(source, node.end) ?? []
|
|
56546
|
+
]) comments.set(range.pos, range.end);
|
|
56547
|
+
for (const child of node.getChildren(parsed)) visitComments(child);
|
|
56548
|
+
};
|
|
56549
|
+
visitComments(parsed);
|
|
56550
|
+
source = applySourceEdits(source, [...comments].map(([start, end]) => ({ start, end, text: " " })));
|
|
56551
|
+
const redactLiteral = (token, offset) => {
|
|
56552
|
+
const before = assignmentContext.slice(Math.max(0, offset - 200), offset);
|
|
56553
|
+
if (/^\s*:/.test(source.slice(offset + token.length)) && /[{,]\s*$/.test(before)) return token;
|
|
56554
|
+
const statement = before.slice(before.lastIndexOf(";") + 1);
|
|
56555
|
+
const sensitiveAssignment = [
|
|
56556
|
+
...statement.matchAll(/([\w$-]+|"[^"\n]+"|'[^'\n]+')\s*(?:\]\s*)?[:=]/g)
|
|
56557
|
+
].some((match) => sensitiveName.test(match[1]));
|
|
56558
|
+
const headerArgument = /(?:set|append)\s*\(\s*["']([^"']+)["']\s*,\s*$/.exec(before);
|
|
56559
|
+
if (sensitiveAssignment || sensitiveName.test(headerArgument?.[1] ?? ""))
|
|
56560
|
+
return JSON.stringify(REDACTED2);
|
|
56561
|
+
if (/^["'`][A-Za-z0-9_+/=-]{24,}["'`]$/.test(token)) return JSON.stringify(REDACTED2);
|
|
56562
|
+
return token;
|
|
56563
|
+
};
|
|
56564
|
+
const clean2 = ts.createSourceFile("backend.ts", source, ts.ScriptTarget.Latest, true);
|
|
56565
|
+
const masks = [];
|
|
56566
|
+
const collectMasks = (node) => {
|
|
56567
|
+
const start = node.getStart(clean2);
|
|
56568
|
+
if (ts.isRegularExpressionLiteral(node)) {
|
|
56569
|
+
masks.push({ start, end: node.end, text: " ".repeat(node.end - start) });
|
|
56570
|
+
} else if (ts.isStringLiteral(node) || ts.isTemplateLiteralToken(node)) {
|
|
56571
|
+
masks.push({ start, end: node.end, text: source.slice(start, node.end).replace(/;/g, " ") });
|
|
56572
|
+
}
|
|
56573
|
+
ts.forEachChild(node, collectMasks);
|
|
56574
|
+
};
|
|
56575
|
+
collectMasks(clean2);
|
|
56576
|
+
const assignmentContext = applySourceEdits(source, masks);
|
|
56577
|
+
const edits = [];
|
|
56578
|
+
const visitLiterals = (node) => {
|
|
56579
|
+
if (ts.isStringLiteral(node) || ts.isNoSubstitutionTemplateLiteral(node) || ts.isTemplateExpression(node)) {
|
|
56580
|
+
const start = node.getStart(clean2);
|
|
56581
|
+
const text4 = source.slice(start, node.end);
|
|
56582
|
+
const redacted = redactLiteral(text4, start);
|
|
56583
|
+
if (redacted !== text4) {
|
|
56584
|
+
edits.push({ start, end: node.end, text: redacted });
|
|
56585
|
+
return;
|
|
56586
|
+
}
|
|
56587
|
+
}
|
|
56588
|
+
ts.forEachChild(node, visitLiterals);
|
|
56589
|
+
};
|
|
56590
|
+
visitLiterals(clean2);
|
|
56591
|
+
return applySourceEdits(source, edits);
|
|
56592
|
+
}
|
|
56593
|
+
function backendSourcePath(filename) {
|
|
56594
|
+
const normalized = filename.replace(/\\/g, "/").replace(/^\.\//, "");
|
|
56595
|
+
if (!/^(?:src\/)?backend\//.test(normalized) || normalized.split("/").includes("..")) return;
|
|
56596
|
+
if (/(?:secret|credential|\.env|\.pem|\.key|node_modules|__tests__|\.test\.|\.spec\.)/i.test(
|
|
56597
|
+
normalized
|
|
56598
|
+
))
|
|
56599
|
+
return;
|
|
56600
|
+
return /\.(?:js|ts|jsw)$/.test(normalized) ? normalized : void 0;
|
|
56601
|
+
}
|
|
56602
|
+
function selectVeloSource(files, request, knownSecrets = []) {
|
|
56603
|
+
const candidates = files.flatMap((file) => {
|
|
56604
|
+
const normalized = backendSourcePath(file.path);
|
|
56605
|
+
return normalized && file.content.trim() ? [{ ...file, path: normalized }] : [];
|
|
56606
|
+
});
|
|
56607
|
+
const byPath = new Map(candidates.map((file) => [file.path, file]));
|
|
56608
|
+
const words = [...new Set(request.toLowerCase().match(/[a-z][a-z0-9_]{3,}/g) ?? [])].filter(
|
|
56609
|
+
(word) => !["with", "that", "this", "from", "have", "want", "app", "site", "backend"].includes(word)
|
|
56610
|
+
).slice(0, 80);
|
|
56611
|
+
const score = (file) => {
|
|
56612
|
+
const names = file.path + " " + [...file.content.matchAll(/export\s+(?:async\s+)?(?:function|const)\s+(\w+)/g)].map((m) => m[1]).join(" ");
|
|
56613
|
+
return words.reduce((sum, word) => sum + (names.toLowerCase().includes(word) ? 10 : 0), 0) + (/http-functions\.[jt]s$|\.web\.[jt]s$|\.jsw$/.test(file.path) ? 1 : 0);
|
|
56614
|
+
};
|
|
56615
|
+
const queue = candidates.filter((file) => score(file) > 0).sort((a, b) => score(b) - score(a) || a.path.localeCompare(b.path));
|
|
56616
|
+
const selected = /* @__PURE__ */ new Map();
|
|
56617
|
+
let remaining = MAX_TOTAL_CHARS;
|
|
56618
|
+
while (queue.length && selected.size < MAX_FILES && remaining > 0) {
|
|
56619
|
+
const file = queue.shift();
|
|
56620
|
+
if (!file) break;
|
|
56621
|
+
if (selected.has(file.path)) continue;
|
|
56622
|
+
const redacted = redactVeloSource(file.content, knownSecrets);
|
|
56623
|
+
const excerpt = redacted.slice(0, Math.min(MAX_FILE_CHARS, remaining));
|
|
56624
|
+
selected.set(file.path, { source: excerpt, sourceTruncated: excerpt.length < redacted.length });
|
|
56625
|
+
remaining -= excerpt.length;
|
|
56626
|
+
const dependencies = [];
|
|
56627
|
+
const parsed = ts.createSourceFile(file.path, file.content, ts.ScriptTarget.Latest, true);
|
|
56628
|
+
const specifiers = [];
|
|
56629
|
+
const collectImports = (node) => {
|
|
56630
|
+
let specifier;
|
|
56631
|
+
if (ts.isImportDeclaration(node) || ts.isExportDeclaration(node)) {
|
|
56632
|
+
specifier = node.moduleSpecifier;
|
|
56633
|
+
} else if (ts.isImportEqualsDeclaration(node) && ts.isExternalModuleReference(node.moduleReference)) {
|
|
56634
|
+
specifier = node.moduleReference.expression;
|
|
56635
|
+
} else if (ts.isCallExpression(node) && (node.expression.kind === ts.SyntaxKind.ImportKeyword || ts.isIdentifier(node.expression) && node.expression.text === "require")) {
|
|
56636
|
+
specifier = node.arguments[0];
|
|
56637
|
+
}
|
|
56638
|
+
if (specifier && ts.isStringLiteralLike(specifier)) specifiers.push(specifier.text);
|
|
56639
|
+
ts.forEachChild(node, collectImports);
|
|
56640
|
+
};
|
|
56641
|
+
collectImports(parsed);
|
|
56642
|
+
for (const specifier of specifiers) {
|
|
56643
|
+
const target = specifier.startsWith(".") ? path.posix.join(path.posix.dirname(file.path), specifier) : specifier.startsWith("backend/") ? (file.path.startsWith("src/") ? "src/" : "") + specifier : "";
|
|
56644
|
+
const dependency = [
|
|
56645
|
+
target,
|
|
56646
|
+
target + ".js",
|
|
56647
|
+
target + ".ts",
|
|
56648
|
+
target + ".jsw",
|
|
56649
|
+
target + "/index.js",
|
|
56650
|
+
target + "/index.ts"
|
|
56651
|
+
].map((name) => byPath.get(name)).find(Boolean);
|
|
56652
|
+
if (dependency) dependencies.push(dependency);
|
|
56653
|
+
}
|
|
56654
|
+
queue.unshift(...dependencies);
|
|
56655
|
+
}
|
|
56656
|
+
return selected;
|
|
56657
|
+
}
|
|
56658
|
+
var MAX_FILES, MAX_FILE_CHARS, MAX_TOTAL_CHARS, REDACTED2, sensitiveName;
|
|
56659
|
+
var init_velo_source = __esm({
|
|
56660
|
+
"src/site-analyze/velo-source.ts"() {
|
|
56661
|
+
MAX_FILES = 6;
|
|
56662
|
+
MAX_FILE_CHARS = 8e3;
|
|
56663
|
+
MAX_TOTAL_CHARS = 24e3;
|
|
56664
|
+
REDACTED2 = "[REDACTED]";
|
|
56665
|
+
sensitiveName = /(?:secret|password|passwd|token|authorization|cookie|api[-_]?key|private[-_]?key|access[-_]?key|credential)/i;
|
|
56666
|
+
}
|
|
56667
|
+
});
|
|
56668
|
+
|
|
56669
|
+
// src/site-analyze/context.ts
|
|
56670
|
+
var context_exports = {};
|
|
56671
|
+
__export(context_exports, {
|
|
56672
|
+
collectSiteContext: () => collectSiteContext,
|
|
56673
|
+
contextFetch: () => contextFetch
|
|
56674
|
+
});
|
|
56675
|
+
function contextFetch(fetchImpl, signal) {
|
|
56676
|
+
return async (input, init) => {
|
|
56677
|
+
const url = new URL(String(input));
|
|
56678
|
+
const method = init?.method ?? "GET";
|
|
56679
|
+
const apiRead = url.origin === "https://www.wixapis.com" && reads.has(`${method} ${url.pathname}`);
|
|
56680
|
+
const veloRead = url.origin === new URL(VELO_IDE_ORIGIN).origin && method === "GET" && /^\/_api\/wix-code-ide-server-ng\/v1\/apps\/[\w-]+\/files$/.test(url.pathname) && ["ONLINE", "GITHUB"].includes(url.searchParams.get("layout") ?? "");
|
|
56681
|
+
if (!apiRead && !veloRead || url.username || url.password) throw new Error("Not a site-analysis read");
|
|
56682
|
+
if (url.pathname === "/oauth2/token" && JSON.parse(String(init?.body)).grantType !== "anonymous") {
|
|
56683
|
+
throw new Error("Only anonymous visitor authentication is allowed");
|
|
56684
|
+
}
|
|
56685
|
+
const response = await fetchImpl(input, { ...init, redirect: "error", signal });
|
|
56686
|
+
const reader = response.body?.getReader();
|
|
56687
|
+
if (!reader) return response;
|
|
56688
|
+
const chunks = [];
|
|
56689
|
+
let size = 0;
|
|
56690
|
+
for (; ; ) {
|
|
56691
|
+
const chunk = await reader.read();
|
|
56692
|
+
if (chunk.done) break;
|
|
56693
|
+
size += chunk.value.byteLength;
|
|
56694
|
+
if (size > 2e6) {
|
|
56695
|
+
await reader.cancel();
|
|
56696
|
+
throw new Error("Site-analysis response exceeds 2 MB");
|
|
56697
|
+
}
|
|
56698
|
+
chunks.push(chunk.value);
|
|
56699
|
+
}
|
|
56700
|
+
return new Response(Buffer.concat(chunks), { status: response.status, headers: response.headers });
|
|
56701
|
+
};
|
|
56702
|
+
}
|
|
56703
|
+
async function collectSiteContext(opts) {
|
|
56704
|
+
const fetcher = contextFetch(opts.fetchImpl ?? fetch, AbortSignal.timeout(opts.timeoutMs ?? 15e3));
|
|
56705
|
+
const owner = opts.ownerToken ? makeTransport(fetcher, { token: opts.ownerToken, msid: opts.siteId }) : void 0;
|
|
56706
|
+
let visitorToken;
|
|
56707
|
+
let visitorAuth = { status: "skipped" };
|
|
56708
|
+
if (opts.clientId) {
|
|
56709
|
+
try {
|
|
56710
|
+
visitorToken = await mintVisitorToken(fetcher, opts.clientId);
|
|
56711
|
+
visitorAuth = { status: "ok" };
|
|
56712
|
+
} catch (e) {
|
|
56713
|
+
visitorAuth = failed(e);
|
|
56714
|
+
}
|
|
56715
|
+
}
|
|
56716
|
+
const visitor = visitorToken ? makeTransport(fetcher, { token: visitorToken, msid: opts.siteId }) : void 0;
|
|
56717
|
+
const identityRead = async () => {
|
|
56718
|
+
if (!owner) return { status: "skipped" };
|
|
56719
|
+
try {
|
|
56720
|
+
const identity2 = parseSiteProperties(await owner("GET", "/site-properties/v4/properties"), "");
|
|
56721
|
+
return { status: "ok", values: {
|
|
56722
|
+
businessName: identity2.businessName,
|
|
56723
|
+
siteDisplayName: identity2.siteDisplayName,
|
|
56724
|
+
description: identity2.description,
|
|
56725
|
+
logo: identity2.logoUrl,
|
|
56726
|
+
language: identity2.locale.languageCode,
|
|
56727
|
+
currency: identity2.locale.currency
|
|
56728
|
+
} };
|
|
56729
|
+
} catch (e) {
|
|
56730
|
+
return failed(e);
|
|
56731
|
+
}
|
|
56732
|
+
};
|
|
56733
|
+
const cmsRead = async () => {
|
|
56734
|
+
try {
|
|
56735
|
+
let failure;
|
|
56736
|
+
const observed = owner ? async (method, path2, body) => {
|
|
56737
|
+
try {
|
|
56738
|
+
const data = await owner(method, path2, body);
|
|
56739
|
+
if (!Array.isArray(data?.collections)) throw new Error("Malformed CMS inventory");
|
|
56740
|
+
return data;
|
|
56741
|
+
} catch (e) {
|
|
56742
|
+
const code = e instanceof WixApiError2 ? e.body?.details?.applicationError?.code : void 0;
|
|
56743
|
+
failure = code === "WDE0110" ? { status: "unavailable", httpStatus: 400 } : failed(e);
|
|
56744
|
+
throw e;
|
|
56745
|
+
}
|
|
56746
|
+
} : void 0;
|
|
56747
|
+
const cms2 = await readCms(observed, { samples: false });
|
|
56748
|
+
return { ...cms2, ...failure, collections: cms2.collections.map((c) => ({
|
|
56749
|
+
id: c.id,
|
|
56750
|
+
readRole: c.readRole,
|
|
56751
|
+
visitorReadable: c.readRole === "ANYONE",
|
|
56752
|
+
ownership: "existing"
|
|
56753
|
+
})) };
|
|
56754
|
+
} catch {
|
|
56755
|
+
return { status: "error", collections: [] };
|
|
56756
|
+
}
|
|
56757
|
+
};
|
|
56758
|
+
const veloRead = async () => {
|
|
56759
|
+
if (!owner) return { status: "skipped", files: [], sourceIncluded: false };
|
|
56760
|
+
let readFailure;
|
|
56761
|
+
const observed = async (method, path2, body) => {
|
|
56762
|
+
try {
|
|
56763
|
+
return await owner(method, path2, body);
|
|
56764
|
+
} catch (e) {
|
|
56765
|
+
readFailure = failed(e);
|
|
56766
|
+
throw e;
|
|
56767
|
+
}
|
|
56768
|
+
};
|
|
56769
|
+
try {
|
|
56770
|
+
const velo2 = await readOwnerVelo(observed, { redact: (source) => redactVeloSource(source, [opts.ownerToken ?? "", visitorToken ?? ""]) });
|
|
56771
|
+
const files = velo2.files.flatMap((f) => {
|
|
56772
|
+
const normalized = backendSourcePath(f.path);
|
|
56773
|
+
return normalized ? [{ ...f, path: normalized }] : [];
|
|
56774
|
+
});
|
|
56775
|
+
const selected = selectVeloSource(
|
|
56776
|
+
files.map((f) => ({ path: f.path, content: f.content ?? "" })),
|
|
56777
|
+
opts.request ?? "",
|
|
56778
|
+
[opts.ownerToken ?? "", visitorToken ?? ""]
|
|
56779
|
+
);
|
|
56780
|
+
return {
|
|
56781
|
+
...files.length ? { status: "ok" } : readFailure ?? { status: "unavailable" },
|
|
56782
|
+
files: files.map((f) => ({
|
|
56783
|
+
path: f.path,
|
|
56784
|
+
kind: f.kind,
|
|
56785
|
+
exports: [...(f.content ?? "").matchAll(/export\s+(?:async\s+)?(?:function|const)\s+([A-Za-z_$][\w$]*)/g)].slice(0, 20).map((m) => m[1]),
|
|
56786
|
+
...selected.get(f.path)
|
|
56787
|
+
})),
|
|
56788
|
+
sourceIncluded: selected.size > 0,
|
|
56789
|
+
truncated: files.length > selected.size || [...selected.values()].some((f) => f.sourceTruncated)
|
|
56790
|
+
};
|
|
56791
|
+
} catch (e) {
|
|
56792
|
+
return { ...failed(e), files: [], sourceIncluded: false };
|
|
56793
|
+
}
|
|
56794
|
+
};
|
|
56795
|
+
const [identity, cms, velo, probes] = await Promise.all([
|
|
56796
|
+
identityRead(),
|
|
56797
|
+
cmsRead(),
|
|
56798
|
+
veloRead(),
|
|
56799
|
+
runDualProbes(owner, visitor, definitions)
|
|
56800
|
+
]);
|
|
56801
|
+
const probeRead = (p, available, auth) => {
|
|
56802
|
+
if (!available) return auth;
|
|
56803
|
+
if (p.httpStatus) return { ...failed(new WixApiError2(p.httpStatus, "", "", null)), count: p.count };
|
|
56804
|
+
return { status: p.status === "ok" || p.status === "empty" ? p.status : "error", count: p.count };
|
|
56805
|
+
};
|
|
56806
|
+
return {
|
|
56807
|
+
schemaVersion: 1,
|
|
56808
|
+
mode: "read-only",
|
|
56809
|
+
identity,
|
|
56810
|
+
cms,
|
|
56811
|
+
velo,
|
|
56812
|
+
verticals: probes.map((p) => ({
|
|
56813
|
+
name: p.vertical,
|
|
56814
|
+
owner: probeRead(p.owner, !!owner, { status: "skipped" }),
|
|
56815
|
+
visitor: probeRead(p.visitor, !!visitor, visitorAuth)
|
|
56816
|
+
}))
|
|
56817
|
+
};
|
|
56818
|
+
}
|
|
56819
|
+
var responseKeys, definitions, reads, failed;
|
|
56820
|
+
var init_context = __esm({
|
|
56821
|
+
"src/site-analyze/context.ts"() {
|
|
56822
|
+
init_probes();
|
|
56823
|
+
init_rest();
|
|
56824
|
+
init_site_properties();
|
|
56825
|
+
init_visitor_auth();
|
|
56826
|
+
init_velo();
|
|
56827
|
+
init_velo_source();
|
|
56828
|
+
responseKeys = {
|
|
56829
|
+
store: "products",
|
|
56830
|
+
bookings: "services",
|
|
56831
|
+
events: "events",
|
|
56832
|
+
blog: "posts"
|
|
56833
|
+
};
|
|
56834
|
+
definitions = [...CORE_PROBES, ...OPTIONAL_PROBES].filter((p) => p.vertical in responseKeys).map((p) => {
|
|
56835
|
+
const checked = (read, path2) => (data) => {
|
|
56836
|
+
const rows = path2 === "/catalog/v1/products/query" ? data.products ?? data.items : data[responseKeys[p.vertical]];
|
|
56837
|
+
if (!Array.isArray(rows)) throw new Error("Malformed catalog response");
|
|
56838
|
+
return read(data);
|
|
56839
|
+
};
|
|
56840
|
+
return {
|
|
56841
|
+
...p,
|
|
56842
|
+
itemsOf: checked(p.itemsOf, p.path),
|
|
56843
|
+
fallbacks: p.fallbacks?.map((f) => ({ ...f, itemsOf: checked(f.itemsOf ?? p.itemsOf, f.path) }))
|
|
56844
|
+
};
|
|
56845
|
+
});
|
|
56846
|
+
reads = /* @__PURE__ */ new Set([
|
|
56847
|
+
"POST /oauth2/token",
|
|
56848
|
+
"GET /site-properties/v4/properties",
|
|
56849
|
+
"GET /data/v2/collections",
|
|
56850
|
+
...OWNER_VELO_PROBES.map((p) => `${p.method} ${p.path}`),
|
|
56851
|
+
...definitions.flatMap((p) => [p, ...p.fallbacks ?? []].map((a) => `${a.method} ${a.path}`))
|
|
56852
|
+
]);
|
|
56853
|
+
failed = (e) => {
|
|
56854
|
+
const httpStatus = e instanceof WixApiError2 ? e.status : void 0;
|
|
56855
|
+
return { status: httpStatus === 401 ? "unauthorized" : httpStatus === 403 ? "forbidden" : httpStatus === 404 || httpStatus === 428 ? "unavailable" : "error", ...httpStatus ? { httpStatus } : {} };
|
|
56856
|
+
};
|
|
56857
|
+
}
|
|
56858
|
+
});
|
|
56859
|
+
|
|
56491
56860
|
// src/cli.ts
|
|
56492
56861
|
import { mkdtempSync as mkdtempSync4, readFileSync as readFileSync67, mkdirSync as mkdirSync27, writeFileSync as writeFileSync25, existsSync as existsSync56, rmSync as rmSync10, readdirSync as readdirSync25, statSync as statSync13, lstatSync as lstatSync6, accessSync, constants } from "node:fs";
|
|
56493
56862
|
import { execFileSync as execFileSync7, spawnSync as spawnSync5, spawn as spawn5 } from "node:child_process";
|
|
@@ -56520,11 +56889,11 @@ var ServeCliClient = class {
|
|
|
56520
56889
|
if (!url) throw new Error(`no ${plane} URL configured for this target`);
|
|
56521
56890
|
return url.replace(/\/+$/, "");
|
|
56522
56891
|
}
|
|
56523
|
-
async request(plane, method,
|
|
56892
|
+
async request(plane, method, path2, opts = {}) {
|
|
56524
56893
|
const headers2 = { ...opts.headers };
|
|
56525
56894
|
if (opts.body !== void 0) headers2["content-type"] = "application/json";
|
|
56526
56895
|
const carriesCredential = Object.keys(headers2).some((h2) => CREDENTIAL_HEADERS.has(h2.toLowerCase()));
|
|
56527
|
-
const res = await this.fetchImpl(this.baseFor(plane) +
|
|
56896
|
+
const res = await this.fetchImpl(this.baseFor(plane) + path2, {
|
|
56528
56897
|
method,
|
|
56529
56898
|
headers: headers2,
|
|
56530
56899
|
...carriesCredential ? { redirect: "error" } : {},
|
|
@@ -56737,12 +57106,12 @@ var ServeCliClient = class {
|
|
|
56737
57106
|
if (o.since !== void 0) q.set("since", String(o.since));
|
|
56738
57107
|
if (o.limit) q.set("limit", String(o.limit));
|
|
56739
57108
|
if (o.crashesOnly) q.set("crashesOnly", "1");
|
|
56740
|
-
const
|
|
56741
|
-
return this.request("telemetry", "GET",
|
|
57109
|
+
const path2 = `/v1/telemetry/events?${q}`;
|
|
57110
|
+
return this.request("telemetry", "GET", path2, { headers: this.telHeaders() }).then(async (res) => {
|
|
56742
57111
|
if (res.status !== 404 || this.target.telemetry.replace(/\/+$/, "") === this.target.serve.replace(/\/+$/, "")) {
|
|
56743
57112
|
return res;
|
|
56744
57113
|
}
|
|
56745
|
-
return this.request("serve", "GET",
|
|
57114
|
+
return this.request("serve", "GET", path2, { headers: this.telHeaders() });
|
|
56746
57115
|
});
|
|
56747
57116
|
}
|
|
56748
57117
|
/** Retained worker console lines (oldest first; `since` = seq cursor for tailing). */
|
|
@@ -56752,12 +57121,12 @@ var ServeCliClient = class {
|
|
|
56752
57121
|
if (o.screenId) q.set("screen", o.screenId);
|
|
56753
57122
|
if (o.since !== void 0) q.set("since", String(o.since));
|
|
56754
57123
|
if (o.limit) q.set("limit", String(o.limit));
|
|
56755
|
-
const
|
|
56756
|
-
return this.request("telemetry", "GET",
|
|
57124
|
+
const path2 = `/v1/telemetry/logs?${q}`;
|
|
57125
|
+
return this.request("telemetry", "GET", path2, { headers: this.telHeaders() }).then(async (res) => {
|
|
56757
57126
|
if (res.status !== 404 || this.target.telemetry.replace(/\/+$/, "") === this.target.serve.replace(/\/+$/, "")) {
|
|
56758
57127
|
return res;
|
|
56759
57128
|
}
|
|
56760
|
-
return this.request("serve", "GET",
|
|
57129
|
+
return this.request("serve", "GET", path2, { headers: this.telHeaders() });
|
|
56761
57130
|
});
|
|
56762
57131
|
}
|
|
56763
57132
|
// ---- serve-control (publish / rollout / kill-switch — the mutable plane) ----
|
|
@@ -56815,8 +57184,8 @@ var ServeCliClient = class {
|
|
|
56815
57184
|
}
|
|
56816
57185
|
/** RFC 0012 release history: list the ledger (GET /v1/releases) or one manifest (…/{releaseId}). */
|
|
56817
57186
|
releases(app, releaseId) {
|
|
56818
|
-
const
|
|
56819
|
-
return this.request("control", "GET",
|
|
57187
|
+
const path2 = releaseId ? `/v1/releases/${encodeURIComponent(releaseId)}?app=${encodeURIComponent(app)}` : `/v1/releases?app=${encodeURIComponent(app)}`;
|
|
57188
|
+
return this.request("control", "GET", path2, { headers: this.ctrlHeaders() });
|
|
56820
57189
|
}
|
|
56821
57190
|
/** Select a published releaseId for a ring (POST /v1/admin/promote); optional rollout %. */
|
|
56822
57191
|
promote(app, ring, releaseId, percent, force = false) {
|
|
@@ -57173,8 +57542,8 @@ var VALIDATION_METADATA = /* @__PURE__ */ new Set([
|
|
|
57173
57542
|
".claude/.validation-baseline.json",
|
|
57174
57543
|
".claude/.validation-evidence.json"
|
|
57175
57544
|
]);
|
|
57176
|
-
function isValidationMetadata(
|
|
57177
|
-
return VALIDATION_METADATA.has(
|
|
57545
|
+
function isValidationMetadata(path2) {
|
|
57546
|
+
return VALIDATION_METADATA.has(path2) || /(^|[\\/])\.himi([\\/]|$)/.test(path2);
|
|
57178
57547
|
}
|
|
57179
57548
|
function tryGit(args, root) {
|
|
57180
57549
|
try {
|
|
@@ -57190,10 +57559,10 @@ function committedRecords(raw) {
|
|
|
57190
57559
|
const records = [];
|
|
57191
57560
|
for (let i = 0; i < fields.length; i += 2) {
|
|
57192
57561
|
const metadata2 = fields[i];
|
|
57193
|
-
const
|
|
57194
|
-
if (!metadata2.startsWith(":") ||
|
|
57195
|
-
if (isValidationMetadata(
|
|
57196
|
-
records.push(`${Buffer.byteLength(
|
|
57562
|
+
const path2 = fields[i + 1];
|
|
57563
|
+
if (!metadata2.startsWith(":") || path2 === "") return null;
|
|
57564
|
+
if (isValidationMetadata(path2)) continue;
|
|
57565
|
+
records.push(`${Buffer.byteLength(path2)}:${path2}\0${metadata2}\0`);
|
|
57197
57566
|
}
|
|
57198
57567
|
return records.sort().join("");
|
|
57199
57568
|
}
|
|
@@ -57253,12 +57622,12 @@ function validationDiffHash(cwd = process.cwd()) {
|
|
|
57253
57622
|
trustFilesystemMode = git(["config", "--bool", "--get", "core.fileMode"], { cwd: root }).trim() !== "false";
|
|
57254
57623
|
} catch {
|
|
57255
57624
|
}
|
|
57256
|
-
const paths = [.../* @__PURE__ */ new Set([...staged, ...unstaged, ...untracked])].filter((
|
|
57257
|
-
const identity = paths.map((
|
|
57258
|
-
const absolute = resolve5(root,
|
|
57259
|
-
const headEntry = headEntries.get(
|
|
57260
|
-
const indexEntry = indexEntries.get(
|
|
57261
|
-
const deletedRecord = () => [`${Buffer.byteLength(
|
|
57625
|
+
const paths = [.../* @__PURE__ */ new Set([...staged, ...unstaged, ...untracked])].filter((path2) => !isValidationMetadata(path2)).sort();
|
|
57626
|
+
const identity = paths.map((path2) => {
|
|
57627
|
+
const absolute = resolve5(root, path2);
|
|
57628
|
+
const headEntry = headEntries.get(path2);
|
|
57629
|
+
const indexEntry = indexEntries.get(path2);
|
|
57630
|
+
const deletedRecord = () => [`${Buffer.byteLength(path2)}:${path2}`, "deleted", stagedIdentity(headEntry, indexEntry, void 0), ""].join("\0");
|
|
57262
57631
|
let stat2;
|
|
57263
57632
|
try {
|
|
57264
57633
|
stat2 = lstatSync2(absolute);
|
|
@@ -57272,7 +57641,7 @@ function validationDiffHash(cwd = process.cwd()) {
|
|
|
57272
57641
|
const worktreeEntry = { mode: "120000", oid: blobOid(target, objectAlgorithm) };
|
|
57273
57642
|
const stagedState2 = stagedIdentity(headEntry, indexEntry, worktreeEntry);
|
|
57274
57643
|
return [
|
|
57275
|
-
`${Buffer.byteLength(
|
|
57644
|
+
`${Buffer.byteLength(path2)}:${path2}`,
|
|
57276
57645
|
"symlink",
|
|
57277
57646
|
"120000",
|
|
57278
57647
|
diffHash(target),
|
|
@@ -57283,11 +57652,11 @@ function validationDiffHash(cwd = process.cwd()) {
|
|
|
57283
57652
|
if (stat2.isFile()) {
|
|
57284
57653
|
const filesystemMode = stat2.mode & 73 ? "100755" : "100644";
|
|
57285
57654
|
const worktreeMode = trustFilesystemMode ? filesystemMode : indexEntry?.mode ?? headEntry?.mode ?? "100644";
|
|
57286
|
-
const worktreeOid = git(["hash-object", `--path=${
|
|
57655
|
+
const worktreeOid = git(["hash-object", `--path=${path2}`, "--", path2], { cwd: root }).trim();
|
|
57287
57656
|
const worktreeEntry = { mode: worktreeMode, oid: worktreeOid };
|
|
57288
57657
|
const stagedState2 = stagedIdentity(headEntry, indexEntry, worktreeEntry);
|
|
57289
57658
|
return [
|
|
57290
|
-
`${Buffer.byteLength(
|
|
57659
|
+
`${Buffer.byteLength(path2)}:${path2}`,
|
|
57291
57660
|
"file",
|
|
57292
57661
|
worktreeMode,
|
|
57293
57662
|
diffHash(readFileSync4(absolute)),
|
|
@@ -57306,7 +57675,7 @@ function validationDiffHash(cwd = process.cwd()) {
|
|
|
57306
57675
|
const type = stat2.isDirectory() ? "directory" : "other";
|
|
57307
57676
|
const stagedState = stagedIdentity(headEntry, indexEntry, void 0);
|
|
57308
57677
|
return [
|
|
57309
|
-
`${Buffer.byteLength(
|
|
57678
|
+
`${Buffer.byteLength(path2)}:${path2}`,
|
|
57310
57679
|
type,
|
|
57311
57680
|
stat2.mode.toString(8),
|
|
57312
57681
|
stagedState,
|
|
@@ -57413,7 +57782,7 @@ var SELF_TEST_CASES = [
|
|
|
57413
57782
|
}
|
|
57414
57783
|
];
|
|
57415
57784
|
function runSelfTest() {
|
|
57416
|
-
let
|
|
57785
|
+
let failed2 = 0;
|
|
57417
57786
|
for (const testCase of SELF_TEST_CASES) {
|
|
57418
57787
|
let ok = false;
|
|
57419
57788
|
let thrown = null;
|
|
@@ -57427,20 +57796,20 @@ function runSelfTest() {
|
|
|
57427
57796
|
`);
|
|
57428
57797
|
continue;
|
|
57429
57798
|
}
|
|
57430
|
-
|
|
57799
|
+
failed2++;
|
|
57431
57800
|
process.stderr.write(` \u2717 ${testCase.name}
|
|
57432
57801
|
${thrown ?? testCase.reason}
|
|
57433
57802
|
`);
|
|
57434
57803
|
}
|
|
57435
|
-
return
|
|
57804
|
+
return failed2;
|
|
57436
57805
|
}
|
|
57437
57806
|
if (process.argv[1] && basename(process.argv[1]) === "diff-hash.mjs" && import.meta.url === pathToFileURL(process.argv[1]).href) {
|
|
57438
57807
|
if (process.argv.slice(2).includes("--self-test")) {
|
|
57439
57808
|
process.stdout.write("\u25B8 diff-hash --self-test: proving the identity can change, and can hold\n");
|
|
57440
|
-
const
|
|
57441
|
-
if (
|
|
57809
|
+
const failed2 = runSelfTest();
|
|
57810
|
+
if (failed2) {
|
|
57442
57811
|
process.stderr.write(
|
|
57443
|
-
`\u2717 diff-hash self-test FAILED (${
|
|
57812
|
+
`\u2717 diff-hash self-test FAILED (${failed2} case(s)) \u2014 the evidence record's diff identity cannot be trusted
|
|
57444
57813
|
`
|
|
57445
57814
|
);
|
|
57446
57815
|
process.exit(1);
|
|
@@ -57533,16 +57902,16 @@ function currentGitUntrackedHash(contentDir2) {
|
|
|
57533
57902
|
maxBuffer: GIT_HASH_MAX_BUFFER
|
|
57534
57903
|
});
|
|
57535
57904
|
const hash = createHash3("sha256");
|
|
57536
|
-
for (const
|
|
57537
|
-
const local = relative(absolute, join6(root,
|
|
57905
|
+
for (const path2 of listed.split("\0").filter(Boolean).sort()) {
|
|
57906
|
+
const local = relative(absolute, join6(root, path2));
|
|
57538
57907
|
if (local.split(/[\\/]/)[0] === ".himi") continue;
|
|
57539
|
-
const full = join6(root,
|
|
57908
|
+
const full = join6(root, path2);
|
|
57540
57909
|
const stats = lstatSync3(full, { throwIfNoEntry: false });
|
|
57541
57910
|
if (!stats) continue;
|
|
57542
57911
|
const kind = stats.isSymbolicLink() ? "link" : stats.isDirectory() ? "dir" : stats.isFile() ? "file" : null;
|
|
57543
57912
|
if (!kind) continue;
|
|
57544
57913
|
const payload = kind === "link" ? Buffer.from(readlinkSync2(full)) : kind === "file" ? readFileSync5(full) : Buffer.alloc(0);
|
|
57545
|
-
const pathBytes = Buffer.from(
|
|
57914
|
+
const pathBytes = Buffer.from(path2);
|
|
57546
57915
|
hash.update(`${kind} ${pathBytes.length} ${payload.length}
|
|
57547
57916
|
`).update(pathBytes).update(payload);
|
|
57548
57917
|
}
|
|
@@ -57553,11 +57922,11 @@ function sourceTreeHash(root) {
|
|
|
57553
57922
|
const visit = (dir) => {
|
|
57554
57923
|
for (const entry of readdirSync3(dir, { withFileTypes: true }).sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0)) {
|
|
57555
57924
|
if (entry.isDirectory() && [".git", ".himi", "node_modules"].includes(entry.name)) continue;
|
|
57556
|
-
const
|
|
57557
|
-
const local = relative(root,
|
|
57558
|
-
if (entry.isDirectory()) visit(
|
|
57559
|
-
else if (entry.isFile()) hash.update(local).update("\0").update(readFileSync5(
|
|
57560
|
-
else if (entry.isSymbolicLink()) hash.update(local).update("\0link\0").update(readlinkSync2(
|
|
57925
|
+
const path2 = join6(dir, entry.name);
|
|
57926
|
+
const local = relative(root, path2);
|
|
57927
|
+
if (entry.isDirectory()) visit(path2);
|
|
57928
|
+
else if (entry.isFile()) hash.update(local).update("\0").update(readFileSync5(path2)).update("\0");
|
|
57929
|
+
else if (entry.isSymbolicLink()) hash.update(local).update("\0link\0").update(readlinkSync2(path2)).update("\0");
|
|
57561
57930
|
}
|
|
57562
57931
|
};
|
|
57563
57932
|
visit(root);
|
|
@@ -57605,9 +57974,9 @@ function readRetainedAttestations(contentDir2) {
|
|
|
57605
57974
|
for (const run2 of parsedRuns) {
|
|
57606
57975
|
if (selfHashFor(run2) !== run2.selfHash) errors.push(`selfHash does not match retained run ${run2.runId}`);
|
|
57607
57976
|
for (const expected of Object.values(run2.screenshots)) {
|
|
57608
|
-
const
|
|
57609
|
-
if (!existsSync3(
|
|
57610
|
-
else if (sha256(readFileSync5(
|
|
57977
|
+
const path2 = screenshotArtifactPath(contentDir2, expected);
|
|
57978
|
+
if (!existsSync3(path2)) errors.push(`missing screenshot for retained run ${run2.runId}: ${basename2(path2)}`);
|
|
57979
|
+
else if (sha256(readFileSync5(path2)) !== expected) errors.push(`screenshot hash does not match retained run ${run2.runId}: ${basename2(path2)}`);
|
|
57611
57980
|
}
|
|
57612
57981
|
}
|
|
57613
57982
|
const runs = [];
|
|
@@ -57668,8 +58037,8 @@ function writeAttestation(input, opts = {}) {
|
|
|
57668
58037
|
const descriptorHashes = Object.fromEntries(
|
|
57669
58038
|
Object.entries(input.descriptors).sort(([a], [b]) => a.localeCompare(b)).map(([screen, bytes2]) => [screen, sha256(bytes2)])
|
|
57670
58039
|
);
|
|
57671
|
-
const screenshotEntries = Object.entries(input.screenshots ?? {}).sort(([a], [b]) => a.localeCompare(b)).filter(([,
|
|
57672
|
-
const bytes2 = readFileSync5(
|
|
58040
|
+
const screenshotEntries = Object.entries(input.screenshots ?? {}).sort(([a], [b]) => a.localeCompare(b)).filter(([, path2]) => existsSync3(path2)).map(([screen, path2]) => {
|
|
58041
|
+
const bytes2 = readFileSync5(path2);
|
|
57673
58042
|
return { screen, bytes: bytes2, hash: sha256(bytes2) };
|
|
57674
58043
|
});
|
|
57675
58044
|
const screenshots = Object.fromEntries(screenshotEntries.map(({ screen, hash }) => [screen, hash]));
|
|
@@ -57796,12 +58165,12 @@ function verifyAttestation(attestation, contentDir2, descriptors, expectedApp, r
|
|
|
57796
58165
|
if (sha256(bytes2) !== expected) errors.push(`descriptor hash does not match for ${screen}`);
|
|
57797
58166
|
}
|
|
57798
58167
|
for (const [screen, expected] of Object.entries(attestation.screenshots)) {
|
|
57799
|
-
const
|
|
57800
|
-
if (!existsSync3(
|
|
57801
|
-
errors.push(`missing screenshot for ${screen}: ${basename2(
|
|
58168
|
+
const path2 = screenshotArtifactPath(contentDir2, expected);
|
|
58169
|
+
if (!existsSync3(path2)) {
|
|
58170
|
+
errors.push(`missing screenshot for ${screen}: ${basename2(path2)}`);
|
|
57802
58171
|
continue;
|
|
57803
58172
|
}
|
|
57804
|
-
if (sha256(readFileSync5(
|
|
58173
|
+
if (sha256(readFileSync5(path2)) !== expected) errors.push(`screenshot hash does not match for ${screen}: ${basename2(path2)}`);
|
|
57805
58174
|
}
|
|
57806
58175
|
return { ok: errors.length === 0, errors };
|
|
57807
58176
|
}
|
|
@@ -58128,9 +58497,9 @@ function dpxSessionTokenPath() {
|
|
|
58128
58497
|
return process.env.HIMI_DPX_TOKEN ?? join7(homedir2(), ".dpx", "session", "token");
|
|
58129
58498
|
}
|
|
58130
58499
|
var DPX_SESSION_PORT = 5151;
|
|
58131
|
-
function dpxSessionPresent(
|
|
58500
|
+
function dpxSessionPresent(path2 = dpxSessionTokenPath()) {
|
|
58132
58501
|
try {
|
|
58133
|
-
return existsSync4(
|
|
58502
|
+
return existsSync4(path2) && readFileSync6(path2, "utf8").trim().length > 0;
|
|
58134
58503
|
} catch {
|
|
58135
58504
|
return false;
|
|
58136
58505
|
}
|
|
@@ -58309,10 +58678,10 @@ async function listCollections(call) {
|
|
|
58309
58678
|
let total;
|
|
58310
58679
|
let reachedEnd = false;
|
|
58311
58680
|
for (let page = 0; page < MAX_COLLECTION_PAGES; page++) {
|
|
58312
|
-
const
|
|
58681
|
+
const path2 = offset ? `/data/v2/collections?paging.offset=${offset}` : "/data/v2/collections";
|
|
58313
58682
|
const r = await withRetry(
|
|
58314
58683
|
"list collections",
|
|
58315
|
-
() => call("GET",
|
|
58684
|
+
() => call("GET", path2)
|
|
58316
58685
|
);
|
|
58317
58686
|
const batch = r.collections ?? [];
|
|
58318
58687
|
const t = r.pagingMetadata?.total;
|
|
@@ -59302,9 +59671,9 @@ function storesV1Issues(contentDir2, strict) {
|
|
|
59302
59671
|
const files = [];
|
|
59303
59672
|
const visit = (dir) => {
|
|
59304
59673
|
for (const entry of readdirSync10(dir, { withFileTypes: true })) {
|
|
59305
|
-
const
|
|
59306
|
-
if (entry.isDirectory()) visit(
|
|
59307
|
-
else if (/\.(?:[cm]?[jt]sx?)$/i.test(entry.name)) files.push(
|
|
59674
|
+
const path2 = join23(dir, entry.name);
|
|
59675
|
+
if (entry.isDirectory()) visit(path2);
|
|
59676
|
+
else if (/\.(?:[cm]?[jt]sx?)$/i.test(entry.name)) files.push(path2);
|
|
59308
59677
|
}
|
|
59309
59678
|
};
|
|
59310
59679
|
roots.forEach(visit);
|
|
@@ -59328,12 +59697,12 @@ import { existsSync as existsSync22, readFileSync as readFileSync22, readdirSync
|
|
|
59328
59697
|
import { join as join25, relative as relative4, resolve as resolve16 } from "node:path";
|
|
59329
59698
|
var SOURCE_EXTENSIONS = /* @__PURE__ */ new Set([".ts", ".tsx", ".js", ".jsx", ".json"]);
|
|
59330
59699
|
var IGNORED_DIRECTORIES = /* @__PURE__ */ new Set([".git", "node_modules", "dist", ".himi", "coverage"]);
|
|
59331
|
-
function issue(issues, strict, code, message,
|
|
59332
|
-
issues.push({ code, message, ...
|
|
59700
|
+
function issue(issues, strict, code, message, path2) {
|
|
59701
|
+
issues.push({ code, message, ...path2 ? { path: path2 } : {}, severity: strict ? "error" : "warning" });
|
|
59333
59702
|
}
|
|
59334
|
-
function readText2(
|
|
59703
|
+
function readText2(path2) {
|
|
59335
59704
|
try {
|
|
59336
|
-
return existsSync22(
|
|
59705
|
+
return existsSync22(path2) ? readFileSync22(path2, "utf8") : null;
|
|
59337
59706
|
} catch {
|
|
59338
59707
|
return null;
|
|
59339
59708
|
}
|
|
@@ -59643,6 +60012,7 @@ var BOOLEAN_FLAGS = /* @__PURE__ */ new Set([
|
|
|
59643
60012
|
"json",
|
|
59644
60013
|
"deep",
|
|
59645
60014
|
"quiet",
|
|
60015
|
+
"read-only",
|
|
59646
60016
|
"force",
|
|
59647
60017
|
"replace",
|
|
59648
60018
|
"watch",
|
|
@@ -59770,10 +60140,10 @@ var str5 = (v) => typeof v === "string" ? v : void 0;
|
|
|
59770
60140
|
var num = (v) => typeof v === "string" && v !== "" && Number.isFinite(Number(v)) ? Number(v) : void 0;
|
|
59771
60141
|
function embeddedTemplateCatalog() {
|
|
59772
60142
|
return availableTemplates().map((name) => {
|
|
59773
|
-
const
|
|
59774
|
-
const meta = JSON.parse(readFileSync67(
|
|
60143
|
+
const path2 = join52(templateSourceDir(name), TEMPLATE_META_FILE);
|
|
60144
|
+
const meta = JSON.parse(readFileSync67(path2, "utf8"));
|
|
59775
60145
|
if (!meta || typeof meta.title !== "string" || typeof meta.description !== "string" || !Array.isArray(meta.tags)) {
|
|
59776
|
-
throw new Error(`${
|
|
60146
|
+
throw new Error(`${path2} must be { title: string, description: string, tags: string[], category?: string }`);
|
|
59777
60147
|
}
|
|
59778
60148
|
return { name, ...meta, source: "embedded" };
|
|
59779
60149
|
});
|
|
@@ -60260,6 +60630,7 @@ var USAGE = `himi \u2014 the Himalaya authoring CLI (remote dev loop)
|
|
|
60260
60630
|
also requires a MOBILE applicationType, because ensure
|
|
60261
60631
|
refuses a WEB client \u2014 so a WEB one carrying your
|
|
60262
60632
|
redirect looks right and is not a candidate.
|
|
60633
|
+
himi site analyze --read-only --site <msid> [--client-id <id>] [--json]
|
|
60263
60634
|
himi site analyze --client-id <id> --url <https://\u2026> [--site <msid>] [--out <dir>] [--apply]
|
|
60264
60635
|
[--shell ${SHELL_ENUM}]
|
|
60265
60636
|
collect a Wix business book (APIs + Playwright look) and
|
|
@@ -60373,7 +60744,7 @@ var COMMANDS = [
|
|
|
60373
60744
|
{ name: "login", summary: "obtain a scoped serve-control token from Wix identity and store it in ~/.himalaya/serve-targets.json (so push/promote need no hand-pasted token). Three modes: --browser (your own Wix account, no VPN/BO), --wix (HEADLESS \u2014 the machine's own Wix CLI credential; the mode a CI pod or agent container can satisfy), --dpx (Wix employee, reads ~/.dpx/session/token). RFC 0026 WS3.", required: "[--browser|--wix|--dpx] [--target <t>] [--issue-url <url>]" },
|
|
60374
60745
|
{ name: "logout", summary: "remove the stored control token for a target", required: "[--target <t>]" },
|
|
60375
60746
|
{ name: "notify", summary: "`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. NOT `himi push`, which publishes a release.", required: "setup|status [--content <dir>] [--target <t>] [--refresh] [--yes] [--no-push-setup] | 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]" },
|
|
60376
|
-
{ 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` reads a site into a business-book folder (REST + Playwright, GET-only); `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; `--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. 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 --client-id <id> --url <https> [--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]" },
|
|
60747
|
+
{ 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 URL/browser and never uploads or applies anything. `analyze` reads a site into a business-book folder (REST + Playwright, GET-only); `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; `--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. 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>] [--json] | analyze --client-id <id> --url <https> [--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]" },
|
|
60377
60748
|
{ 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>]" },
|
|
60378
60749
|
{ 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]" },
|
|
60379
60750
|
{ name: "push", summary: "lint + build + publish a release (default --draft: servable via ?release= but NOT live). REFUSES to publish on any error unless --force; --strict promotes warnings. Prints preview + agent-context links. The published slug is NAMESPACED per owner \u2014 `<ownerPrefix>.<name>`, composed offline from the control token's ownerPrefix claim, so the CLI and the server derive the identical string and himalaya.content.json is NOT rewritten (a legacy token with no ownerPrefix publishes the declared name unchanged). An app claimed BEFORE namespacing is stored under its FLAT slug, so the claim route answers `alreadyYours` naming that slug and the push adopts it \u2014 reported as `adoptedSlug`, since it is the one case where the published `app` differs from what the declared name composes to. `--no-claim` skips the route that knows this, so a pre-namespacing app pushed with it still fails 403. --visibility public|unlisted decides whether /v1/apps + the Himi Player picker LIST the app (also declarable as `visibility` in himalaya.content.json; omitted, a brand-new app defaults to unlisted \u2014 share by link \u2014 and an existing setting is kept). --account-id names which account owns the app when your Wix session resolves to several (the auto-claim of a brand-new slug cannot guess \u2014 without it a multi-account caller is told to name one). An unforced push of a release that carries SCREENS also refuses when `.himi/ux-audit.json` holds no mobile-UX drive recorded against that release id, or holds one that FAILED (#2955) \u2014 a published draft IS the owner-private preview a customer is handed; `himi ux record` clears it and `--force` overrides it, which the success envelope then says out loud. `--only <selector>` publishes ONLY the named items as a release derived from the app's live release (or `--from-release <id>`), running the identical build + lint gate and simply publishing less; it requires an explicit `--draft` or `--live` because a partial publish has no safe default, never claims a slug, and carries neither attestation nor a source archive (both named in the output). Selectors are comma-separated in ONE `--only`: `changed` (every item whose bytes differ from the base), `screen:<id|glob>`, `bundle:<name>`, `tokens`, `app-config` \u2014 a selected screen drags its logic bundle and a selected bundle drags the screens that reference it, or the bytes land under a key nothing reads.", required: "[--content <dir>] [--draft] [--live] [--force] [--strict] [--label] [--notes] [--visibility public|unlisted] [--no-claim] [--account-id <id>] [--only <selector>] [--from-release <id>] [--accept-regressions] [--accept-partial] [--app <slug>] (--control-token)" },
|
|
@@ -60506,9 +60877,9 @@ function ageInDays(publishedAt, now = Date.now()) {
|
|
|
60506
60877
|
if (!Number.isFinite(at)) return void 0;
|
|
60507
60878
|
return Math.max(0, (now - at) / 864e5);
|
|
60508
60879
|
}
|
|
60509
|
-
function packageVersion(
|
|
60880
|
+
function packageVersion(path2) {
|
|
60510
60881
|
try {
|
|
60511
|
-
const version2 = JSON.parse(readFileSync67(
|
|
60882
|
+
const version2 = JSON.parse(readFileSync67(path2, "utf8")).version;
|
|
60512
60883
|
return typeof version2 === "string" && version2 ? version2 : void 0;
|
|
60513
60884
|
} catch {
|
|
60514
60885
|
return void 0;
|
|
@@ -60576,18 +60947,18 @@ var UPDATE_REEXEC_ENV = "HIMI_UPDATED_ONCE";
|
|
|
60576
60947
|
function updateCachePath(env = process.env) {
|
|
60577
60948
|
return env.HIMI_UPDATE_CACHE_FILE ?? join52(homedir7(), ".himalaya", "update-check.json");
|
|
60578
60949
|
}
|
|
60579
|
-
function readUpdateCache(
|
|
60950
|
+
function readUpdateCache(path2) {
|
|
60580
60951
|
try {
|
|
60581
|
-
const parsed = JSON.parse(readFileSync67(
|
|
60952
|
+
const parsed = JSON.parse(readFileSync67(path2, "utf8"));
|
|
60582
60953
|
return parsed && typeof parsed === "object" ? parsed : {};
|
|
60583
60954
|
} catch {
|
|
60584
60955
|
return {};
|
|
60585
60956
|
}
|
|
60586
60957
|
}
|
|
60587
|
-
function writeUpdateCache(
|
|
60958
|
+
function writeUpdateCache(path2, cache) {
|
|
60588
60959
|
try {
|
|
60589
|
-
mkdirSync27(dirname31(
|
|
60590
|
-
writeFileSync25(
|
|
60960
|
+
mkdirSync27(dirname31(path2), { recursive: true, mode: 448 });
|
|
60961
|
+
writeFileSync25(path2, JSON.stringify(cache, null, 2) + "\n", { mode: 384 });
|
|
60591
60962
|
} catch {
|
|
60592
60963
|
}
|
|
60593
60964
|
}
|
|
@@ -60695,10 +61066,10 @@ function isAbandoned(content) {
|
|
|
60695
61066
|
return Number.isFinite(owner) && owner > 0 && host === thisHost() && !processAlive(owner);
|
|
60696
61067
|
}
|
|
60697
61068
|
function staleUpdateLockFile(cachePath, now) {
|
|
60698
|
-
for (const
|
|
61069
|
+
for (const path2 of [`${cachePath}.lock.break`, `${cachePath}.lock`]) {
|
|
60699
61070
|
let content;
|
|
60700
61071
|
try {
|
|
60701
|
-
content = readFileSync67(
|
|
61072
|
+
content = readFileSync67(path2, "utf8");
|
|
60702
61073
|
} catch {
|
|
60703
61074
|
continue;
|
|
60704
61075
|
}
|
|
@@ -60706,12 +61077,12 @@ function staleUpdateLockFile(cachePath, now) {
|
|
|
60706
61077
|
let since = stamped;
|
|
60707
61078
|
if (!Number.isFinite(since)) {
|
|
60708
61079
|
try {
|
|
60709
|
-
since = statSync13(
|
|
61080
|
+
since = statSync13(path2).mtimeMs;
|
|
60710
61081
|
} catch {
|
|
60711
61082
|
continue;
|
|
60712
61083
|
}
|
|
60713
61084
|
}
|
|
60714
|
-
if (now - since >= UPDATE_LOCK_REPORT_AFTER_MS) return
|
|
61085
|
+
if (now - since >= UPDATE_LOCK_REPORT_AFTER_MS) return path2;
|
|
60715
61086
|
}
|
|
60716
61087
|
return void 0;
|
|
60717
61088
|
}
|
|
@@ -60719,24 +61090,24 @@ function acquireUpdateLock(cachePath, now, hooks = {}) {
|
|
|
60719
61090
|
const lockPath = `${cachePath}.lock`;
|
|
60720
61091
|
const breakPath = `${cachePath}.lock.break`;
|
|
60721
61092
|
const mine = lockStamp(now);
|
|
60722
|
-
const readLock = (
|
|
61093
|
+
const readLock = (path2) => {
|
|
60723
61094
|
try {
|
|
60724
|
-
return readFileSync67(
|
|
61095
|
+
return readFileSync67(path2, "utf8");
|
|
60725
61096
|
} catch {
|
|
60726
61097
|
return void 0;
|
|
60727
61098
|
}
|
|
60728
61099
|
};
|
|
60729
|
-
const tryCreate = (
|
|
61100
|
+
const tryCreate = (path2) => {
|
|
60730
61101
|
try {
|
|
60731
|
-
writeFileSync25(
|
|
61102
|
+
writeFileSync25(path2, mine, { flag: "wx", mode: 384 });
|
|
60732
61103
|
return true;
|
|
60733
61104
|
} catch {
|
|
60734
61105
|
return false;
|
|
60735
61106
|
}
|
|
60736
61107
|
};
|
|
60737
|
-
const removeIfMine = (
|
|
61108
|
+
const removeIfMine = (path2) => {
|
|
60738
61109
|
try {
|
|
60739
|
-
if (readLock(
|
|
61110
|
+
if (readLock(path2) === mine) rmSync10(path2, { force: true });
|
|
60740
61111
|
} catch {
|
|
60741
61112
|
}
|
|
60742
61113
|
};
|
|
@@ -60957,9 +61328,9 @@ function helpJson() {
|
|
|
60957
61328
|
}
|
|
60958
61329
|
function previewWebUrl(serveBase, app, release, screenId, surface, previewToken, handover) {
|
|
60959
61330
|
const base = serveBase.replace(/\/$/, "");
|
|
60960
|
-
const
|
|
61331
|
+
const path2 = screenId ? `/preview/a/${app}/screen/${screenId}` : `/preview/a/${app}`;
|
|
60961
61332
|
const query = handover ? `?h=${encodeURIComponent(handover)}` : `?release=${encodeURIComponent(release)}`;
|
|
60962
|
-
return `${base}${
|
|
61333
|
+
return `${base}${path2}${query}${surface ? `&surface=${encodeURIComponent(surface)}` : ""}${!handover && previewToken ? `&pvt=${encodeURIComponent(previewToken)}` : ""}`;
|
|
60963
61334
|
}
|
|
60964
61335
|
function renderDeviceWidths() {
|
|
60965
61336
|
return {
|
|
@@ -61380,10 +61751,10 @@ function readConfigSource(dir) {
|
|
|
61380
61751
|
return null;
|
|
61381
61752
|
}
|
|
61382
61753
|
}
|
|
61383
|
-
function writePngFile(
|
|
61384
|
-
mkdirSync27(dirname31(
|
|
61385
|
-
writeFileSync25(
|
|
61386
|
-
return
|
|
61754
|
+
function writePngFile(path2, base64) {
|
|
61755
|
+
mkdirSync27(dirname31(path2), { recursive: true });
|
|
61756
|
+
writeFileSync25(path2, Buffer.from(base64, "base64"));
|
|
61757
|
+
return path2;
|
|
61387
61758
|
}
|
|
61388
61759
|
async function initFromRemoteTemplate(name, parentDir, template, c) {
|
|
61389
61760
|
const dir = resolve44(parentDir, name);
|
|
@@ -61577,9 +61948,9 @@ async function loadCms(dir) {
|
|
|
61577
61948
|
return data ? { collections: data.collections ?? [], ...data.memberGated ? { memberGated: true } : {} } : void 0;
|
|
61578
61949
|
}
|
|
61579
61950
|
var ConfigLoadError = class extends Error {
|
|
61580
|
-
constructor(
|
|
61581
|
-
super(`could not load ${
|
|
61582
|
-
this.path =
|
|
61951
|
+
constructor(path2, cause) {
|
|
61952
|
+
super(`could not load ${path2}: ${cause.message}`);
|
|
61953
|
+
this.path = path2;
|
|
61583
61954
|
this.cause = cause;
|
|
61584
61955
|
this.name = "ConfigLoadError";
|
|
61585
61956
|
}
|
|
@@ -62553,17 +62924,17 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
62553
62924
|
const dir = contentDir(flags);
|
|
62554
62925
|
const { buildContentBundles: buildContentBundles2 } = await loadAuthoring();
|
|
62555
62926
|
const res = await buildContentBundles2(dir, { resolution: resolutionFlag(flags) });
|
|
62556
|
-
const
|
|
62927
|
+
const failed2 = res.compileErrors;
|
|
62557
62928
|
print({
|
|
62558
|
-
ok:
|
|
62929
|
+
ok: failed2.length === 0,
|
|
62559
62930
|
outDir: res.outDir,
|
|
62560
62931
|
built: res.built,
|
|
62561
|
-
...
|
|
62932
|
+
...failed2.length ? { compileErrors: failed2 } : {},
|
|
62562
62933
|
// #642.1b — a stale @wix/himalaya is advisory on `build` (the bundles may
|
|
62563
62934
|
// still compile); `validate --strict` is where it hard-fails.
|
|
62564
62935
|
...res.sdkVersionIssue ? { warnings: [res.sdkVersionIssue] } : {}
|
|
62565
62936
|
});
|
|
62566
|
-
return
|
|
62937
|
+
return failed2.length ? 1 : 0;
|
|
62567
62938
|
}
|
|
62568
62939
|
case "eject": {
|
|
62569
62940
|
const mod = String(pos[1] ?? "");
|
|
@@ -62644,12 +63015,12 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
62644
63015
|
const { buildLocalFunctions: buildLocalFunctions2, describeFunction: describeFunction2, invokeLocalFunction: invokeLocalFunction2, invokeRemoteFunction: invokeRemoteFunction2, listFunctions: listFunctions2, loadFunctionsApp: loadFunctionsApp2, openApiForFunctions: openApiForFunctions2, resolveFunctionsTarget: resolveFunctionsTarget2, runRemoteFunctionOperation: runRemoteFunctionOperation2 } = await Promise.resolve().then(() => (init_functions(), functions_exports));
|
|
62645
63016
|
const remoteTarget = str5(flags.target);
|
|
62646
63017
|
const boCookie = () => {
|
|
62647
|
-
const
|
|
63018
|
+
const path2 = dpxSessionTokenPath();
|
|
62648
63019
|
let raw;
|
|
62649
63020
|
try {
|
|
62650
|
-
raw = readFileSync67(
|
|
63021
|
+
raw = readFileSync67(path2, "utf8");
|
|
62651
63022
|
} catch {
|
|
62652
|
-
throw new Error(`no DPX BO session at ${
|
|
63023
|
+
throw new Error(`no DPX BO session at ${path2}; run dpx auth login, write dpx auth token to that path, then himi login --dpx --target bo`);
|
|
62653
63024
|
}
|
|
62654
63025
|
return dpxCookieHeader(raw);
|
|
62655
63026
|
};
|
|
@@ -63119,7 +63490,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
63119
63490
|
bootAndSnapshotState: bootAndSnapshotState2,
|
|
63120
63491
|
renderDescriptorWeb: renderDescriptorWeb2,
|
|
63121
63492
|
renderPngBatch: renderPngBatch2,
|
|
63122
|
-
writePng: (
|
|
63493
|
+
writePng: (path2, base64) => writePngFile(path2, base64),
|
|
63123
63494
|
clearDir: (d) => rmSync10(d, { recursive: true, force: true })
|
|
63124
63495
|
}
|
|
63125
63496
|
});
|
|
@@ -66554,12 +66925,12 @@ ${report2.ok ? "OK \u2014 data + serve plane reachable." : typeof report2.hint =
|
|
|
66554
66925
|
return 1;
|
|
66555
66926
|
}
|
|
66556
66927
|
if (secretTarget.mode === "remote") {
|
|
66557
|
-
const
|
|
66928
|
+
const path2 = dpxSessionTokenPath();
|
|
66558
66929
|
let raw;
|
|
66559
66930
|
try {
|
|
66560
|
-
raw = readFileSync67(
|
|
66931
|
+
raw = readFileSync67(path2, "utf8");
|
|
66561
66932
|
} catch {
|
|
66562
|
-
io.error(JSON.stringify({ error: `no DPX BO session at ${
|
|
66933
|
+
io.error(JSON.stringify({ error: `no DPX BO session at ${path2}` }));
|
|
66563
66934
|
return 1;
|
|
66564
66935
|
}
|
|
66565
66936
|
const { runRemoteSecretsCommand: runRemoteSecretsCommand2 } = await Promise.resolve().then(() => (init_secrets2(), secrets_exports));
|
|
@@ -66829,6 +67200,34 @@ ${report2.ok ? "OK \u2014 data + serve plane reachable." : typeof report2.hint =
|
|
|
66829
67200
|
}
|
|
66830
67201
|
const clientId = str5(flags["client-id"]) ?? process.env.WIX_CLIENT_ID;
|
|
66831
67202
|
const siteUrl = str5(flags.url) ?? str5(flags["site-url"]);
|
|
67203
|
+
if (flags["read-only"] === true) {
|
|
67204
|
+
if (flags.apply || flags.out || flags.shell || flags["redirect-uri"]) {
|
|
67205
|
+
io.error(JSON.stringify({ error: "--read-only returns API context only; it cannot be combined with --apply, --out, --shell, or --redirect-uri" }));
|
|
67206
|
+
return 2;
|
|
67207
|
+
}
|
|
67208
|
+
const siteId = str5(flags.site) ?? process.env.WIX_SITE_ID;
|
|
67209
|
+
if (!clientId && !siteId && !process.env.WIX_TEST_TOKEN?.trim()) {
|
|
67210
|
+
io.error(JSON.stringify({ error: "--read-only needs --site, --client-id, or a site-scoped WIX_TEST_TOKEN" }));
|
|
67211
|
+
return 2;
|
|
67212
|
+
}
|
|
67213
|
+
const { collectSiteContext: collectSiteContext2 } = await Promise.resolve().then(() => (init_context(), context_exports));
|
|
67214
|
+
const { siteToken: siteToken2 } = await Promise.resolve().then(() => (init_wix_owner(), wix_owner_exports));
|
|
67215
|
+
let ownerToken = process.env.WIX_TEST_TOKEN?.trim() || void 0;
|
|
67216
|
+
if (!ownerToken && siteId) {
|
|
67217
|
+
try {
|
|
67218
|
+
ownerToken = await siteToken2(siteId);
|
|
67219
|
+
} catch {
|
|
67220
|
+
}
|
|
67221
|
+
}
|
|
67222
|
+
const context = await collectSiteContext2({
|
|
67223
|
+
siteId,
|
|
67224
|
+
clientId,
|
|
67225
|
+
ownerToken,
|
|
67226
|
+
request: process.env.HIMI_ANALYZE_REQUEST
|
|
67227
|
+
});
|
|
67228
|
+
print({ ok: true, context });
|
|
67229
|
+
return 0;
|
|
67230
|
+
}
|
|
66832
67231
|
if (!clientId || !siteUrl) {
|
|
66833
67232
|
io.error(JSON.stringify({
|
|
66834
67233
|
error: "himi site analyze needs --client-id and --url",
|