@wix/himalaya-cli 0.1001.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 +1137 -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;
|
|
@@ -19450,6 +19460,7 @@ function shouldRevealError(args) {
|
|
|
19450
19460
|
var EMAIL_RE, URL_HOST_RE, INTEGER_RE, NUMBER_RE;
|
|
19451
19461
|
var init_validation = __esm({
|
|
19452
19462
|
"../../core/ts/src/validation.ts"() {
|
|
19463
|
+
"use strict";
|
|
19453
19464
|
EMAIL_RE = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*\.[A-Za-z]{2,}$/;
|
|
19454
19465
|
URL_HOST_RE = /^[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*(:[0-9]+)?$/;
|
|
19455
19466
|
INTEGER_RE = /^[+-]?[0-9]+$/;
|
|
@@ -22622,9 +22633,9 @@ var init_worker_subtree_safe_types_generated = __esm({
|
|
|
22622
22633
|
function isRecord(value) {
|
|
22623
22634
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
22624
22635
|
}
|
|
22625
|
-
function valueAtPath(value,
|
|
22636
|
+
function valueAtPath(value, path2) {
|
|
22626
22637
|
let current = value;
|
|
22627
|
-
for (const segment of
|
|
22638
|
+
for (const segment of path2.split(".")) {
|
|
22628
22639
|
if (!isRecord(current)) return void 0;
|
|
22629
22640
|
current = current[segment];
|
|
22630
22641
|
}
|
|
@@ -22838,8 +22849,8 @@ function validateWorkerSubtree(raw, slotId, policy, actionCatalog) {
|
|
|
22838
22849
|
return;
|
|
22839
22850
|
}
|
|
22840
22851
|
const props = node.body.props;
|
|
22841
|
-
for (const
|
|
22842
|
-
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));
|
|
22843
22854
|
for (const childRule of rule.children) {
|
|
22844
22855
|
const value = valueAtPath(props, childRule.path);
|
|
22845
22856
|
if (value === void 0 || value === null) {
|
|
@@ -22874,6 +22885,7 @@ function validateWorkerSubtree(raw, slotId, policy, actionCatalog) {
|
|
|
22874
22885
|
var WORKER_SUBTREE_CEILINGS, ID_PART, ACTION_ID;
|
|
22875
22886
|
var init_worker_subtree = __esm({
|
|
22876
22887
|
"../../core/ts/src/worker-subtree.ts"() {
|
|
22888
|
+
"use strict";
|
|
22877
22889
|
init_worker_subtree_safe_types_generated();
|
|
22878
22890
|
WORKER_SUBTREE_CEILINGS = Object.freeze({
|
|
22879
22891
|
maxEncodedBytes: 65536,
|
|
@@ -22891,9 +22903,9 @@ var init_worker_subtree = __esm({
|
|
|
22891
22903
|
// ../../core/web-renderer/src/renderNode.tsx
|
|
22892
22904
|
import React5 from "react";
|
|
22893
22905
|
import { Fragment as Fragment3, jsx as jsx6, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
22894
|
-
function boundTokenName(
|
|
22895
|
-
if (typeof
|
|
22896
|
-
const r = resolveScalarStatic(
|
|
22906
|
+
function boundTokenName(path2, fallback, ctx) {
|
|
22907
|
+
if (typeof path2 === "string" && path2) {
|
|
22908
|
+
const r = resolveScalarStatic(path2, ctx);
|
|
22897
22909
|
if (typeof r === "string" && r) return r;
|
|
22898
22910
|
}
|
|
22899
22911
|
return fallback;
|
|
@@ -24199,8 +24211,8 @@ function renderNodeInner(node, ctx) {
|
|
|
24199
24211
|
}
|
|
24200
24212
|
}
|
|
24201
24213
|
const bind = {};
|
|
24202
|
-
const addBind = (cssProp,
|
|
24203
|
-
const k = measureKey(
|
|
24214
|
+
const addBind = (cssProp, path2) => {
|
|
24215
|
+
const k = measureKey(path2);
|
|
24204
24216
|
if (k) bind[cssProp] = k;
|
|
24205
24217
|
};
|
|
24206
24218
|
addBind("height", m?.heightPath ?? m?.height_path);
|
|
@@ -24291,9 +24303,9 @@ function renderNodeInner(node, ctx) {
|
|
|
24291
24303
|
}
|
|
24292
24304
|
return out;
|
|
24293
24305
|
}
|
|
24294
|
-
function boundModNumber(
|
|
24295
|
-
if (typeof
|
|
24296
|
-
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);
|
|
24297
24309
|
const n = typeof r === "number" ? r : typeof r === "string" && r.trim() !== "" ? Number(r) : NaN;
|
|
24298
24310
|
return Number.isFinite(n) ? n : void 0;
|
|
24299
24311
|
}
|
|
@@ -25240,8 +25252,8 @@ var init_renderNode = __esm({
|
|
|
25240
25252
|
WorkerSubtreeNode = withExtras("WorkerSubtreeNode", ({ props, ctx, wrap, nodeId }) => {
|
|
25241
25253
|
const slotId = nodeId;
|
|
25242
25254
|
const extra = wrap;
|
|
25243
|
-
const
|
|
25244
|
-
const value = useBoundValue(ctx, typeof
|
|
25255
|
+
const path2 = props.treeJsonPath ?? props.tree_json_path;
|
|
25256
|
+
const value = useBoundValue(ctx, typeof path2 === "string" ? path2 : "");
|
|
25245
25257
|
const policy = props.policy;
|
|
25246
25258
|
const catalog = ctx.provider && typeof ctx.provider.listActions === "function" ? ctx.provider : null;
|
|
25247
25259
|
const validation = React5.useMemo(() => {
|
|
@@ -25670,8 +25682,8 @@ var init_renderNode = __esm({
|
|
|
25670
25682
|
this.state = state;
|
|
25671
25683
|
for (const cb of this.listeners) cb(this.value("media"));
|
|
25672
25684
|
}
|
|
25673
|
-
value(
|
|
25674
|
-
const bare =
|
|
25685
|
+
value(path2) {
|
|
25686
|
+
const bare = path2.replace(/^\$service:/, "");
|
|
25675
25687
|
const parts = bare.split(".").filter(Boolean);
|
|
25676
25688
|
if (parts[0] === "media") parts.shift();
|
|
25677
25689
|
let value = this.state;
|
|
@@ -25681,8 +25693,8 @@ var init_renderNode = __esm({
|
|
|
25681
25693
|
}
|
|
25682
25694
|
return value;
|
|
25683
25695
|
}
|
|
25684
|
-
subscribe(
|
|
25685
|
-
const wrapped = () => cb(this.value(
|
|
25696
|
+
subscribe(path2, cb) {
|
|
25697
|
+
const wrapped = () => cb(this.value(path2));
|
|
25686
25698
|
this.listeners.add(wrapped);
|
|
25687
25699
|
wrapped();
|
|
25688
25700
|
return () => this.listeners.delete(wrapped);
|
|
@@ -26933,9 +26945,9 @@ var init_renderNode = __esm({
|
|
|
26933
26945
|
});
|
|
26934
26946
|
AvatarStripNode = withExtras("AvatarStripNode", ({ props, ctx, wrap }) => {
|
|
26935
26947
|
const C = ctx.color;
|
|
26936
|
-
const
|
|
26937
|
-
const bound = useResolvedScalar(
|
|
26938
|
-
const raw =
|
|
26948
|
+
const path2 = props.avatarsPath ?? props.avatars_path;
|
|
26949
|
+
const bound = useResolvedScalar(path2, ctx);
|
|
26950
|
+
const raw = path2 != null ? bound : props.avatars;
|
|
26939
26951
|
const avatars = Array.isArray(raw) ? raw : [];
|
|
26940
26952
|
const size = props.size ?? 36;
|
|
26941
26953
|
const maxVisible = props.maxVisible ?? 4;
|
|
@@ -28566,27 +28578,27 @@ function resolveTreeScalar(v, provider, itemScope) {
|
|
|
28566
28578
|
if (v.startsWith("$service:")) return provider.value(v) ?? void 0;
|
|
28567
28579
|
return v;
|
|
28568
28580
|
}
|
|
28569
|
-
function collectResolvedMediaRecord(record2,
|
|
28570
|
-
if (typeof record2.actionId === "string" ||
|
|
28581
|
+
function collectResolvedMediaRecord(record2, path2, context) {
|
|
28582
|
+
if (typeof record2.actionId === "string" || path2 && typeof record2.body === "object") return;
|
|
28571
28583
|
for (const [key2, child] of Object.entries(record2)) {
|
|
28572
|
-
collectResolvedMediaValues(child,
|
|
28584
|
+
collectResolvedMediaValues(child, path2 ? `${path2}.${key2}` : key2, {
|
|
28573
28585
|
...context,
|
|
28574
28586
|
insideMediaProperty: context.insideMediaProperty || isMediaValueProperty(key2)
|
|
28575
28587
|
});
|
|
28576
28588
|
}
|
|
28577
28589
|
}
|
|
28578
|
-
function collectResolvedMediaValues(value,
|
|
28590
|
+
function collectResolvedMediaValues(value, path2, context) {
|
|
28579
28591
|
const resolved2 = typeof value === "string" ? resolveTreeScalar(value, context.provider, context.itemScope) : value;
|
|
28580
28592
|
if (typeof resolved2 === "string") {
|
|
28581
|
-
if (context.insideMediaProperty) context.values[
|
|
28593
|
+
if (context.insideMediaProperty) context.values[path2] = resolved2;
|
|
28582
28594
|
return;
|
|
28583
28595
|
}
|
|
28584
28596
|
if (Array.isArray(resolved2)) {
|
|
28585
|
-
resolved2.forEach((item, index) => collectResolvedMediaValues(item, `${
|
|
28597
|
+
resolved2.forEach((item, index) => collectResolvedMediaValues(item, `${path2}[${index}]`, context));
|
|
28586
28598
|
return;
|
|
28587
28599
|
}
|
|
28588
28600
|
if (resolved2 && typeof resolved2 === "object") {
|
|
28589
|
-
collectResolvedMediaRecord(resolved2,
|
|
28601
|
+
collectResolvedMediaRecord(resolved2, path2, context);
|
|
28590
28602
|
}
|
|
28591
28603
|
}
|
|
28592
28604
|
function collectComponentMediaValues(type, props, context) {
|
|
@@ -28607,12 +28619,12 @@ function collectNativeOnly(node) {
|
|
|
28607
28619
|
walk2(node);
|
|
28608
28620
|
return [...found].sort();
|
|
28609
28621
|
}
|
|
28610
|
-
function buildRenderTree(node,
|
|
28622
|
+
function buildRenderTree(node, path2 = "$", provider = null, itemScope = void 0, includeRawProps = false, env = null) {
|
|
28611
28623
|
if (!node || typeof node !== "object") return null;
|
|
28612
28624
|
const obj2 = node;
|
|
28613
28625
|
const body = obj2.body ?? {};
|
|
28614
28626
|
const type = typeof body.type === "string" ? body.type : "Unknown";
|
|
28615
|
-
const id = typeof obj2.id === "string" && obj2.id ? obj2.id :
|
|
28627
|
+
const id = typeof obj2.id === "string" && obj2.id ? obj2.id : path2;
|
|
28616
28628
|
const out = { id, type };
|
|
28617
28629
|
if (typeof body.package === "string") out.package = body.package;
|
|
28618
28630
|
const props = body.props ?? {};
|
|
@@ -28721,7 +28733,7 @@ async function renderDescriptorWeb(descriptor, tokens, scheme, wantPng, services
|
|
|
28721
28733
|
const stickyHeader = isSduiNode(desc.stickyHeader) ? desc.stickyHeader : void 0;
|
|
28722
28734
|
const stickyFooter = isSduiNode(desc.stickyFooter) ? desc.stickyFooter : void 0;
|
|
28723
28735
|
const clientEnv = clientEnvFor(scheme, width, isRTL);
|
|
28724
|
-
const treeOf = (node,
|
|
28736
|
+
const treeOf = (node, path2, prov) => buildRenderTree(node, path2, prov, void 0, true, clientEnv);
|
|
28725
28737
|
const renderTree = composeStickyTree(
|
|
28726
28738
|
treeOf(payload, "$", null) ?? void 0,
|
|
28727
28739
|
stickyHeader ? treeOf(stickyHeader, "$.stickyHeader", null) : null,
|
|
@@ -28921,8 +28933,8 @@ function declaredFamilies(tokens) {
|
|
|
28921
28933
|
async function faceBytes(face, catalog, opts) {
|
|
28922
28934
|
try {
|
|
28923
28935
|
if (opts.source) {
|
|
28924
|
-
const
|
|
28925
|
-
return
|
|
28936
|
+
const path2 = opts.source(face.file, face.sha256);
|
|
28937
|
+
return path2 ? readFileSync34(path2) : null;
|
|
28926
28938
|
}
|
|
28927
28939
|
const bytes2 = await catalogFaceBytes(face.sha256, { catalog, ...opts.fetchFace ? { fetchFace: opts.fetchFace } : {} });
|
|
28928
28940
|
return bytes2 ?? null;
|
|
@@ -29429,13 +29441,13 @@ function validateName(name) {
|
|
|
29429
29441
|
if (typeof name !== "string") fail("name must be a string");
|
|
29430
29442
|
if (!/^[a-z][a-z0-9]*(?:[-_.][a-z0-9]+)*$/.test(name)) fail(`name must be lowercase kebab-case: "${name}"`);
|
|
29431
29443
|
}
|
|
29432
|
-
function validateFunctionRoute(method,
|
|
29444
|
+
function validateFunctionRoute(method, path2) {
|
|
29433
29445
|
if (!HTTP_METHODS.includes(method)) fail(`method must be one of ${HTTP_METHODS.join(", ")}`);
|
|
29434
|
-
if (
|
|
29435
|
-
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}"`);
|
|
29436
29448
|
}
|
|
29437
|
-
const params = [...
|
|
29438
|
-
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}"`);
|
|
29439
29451
|
}
|
|
29440
29452
|
function validateFunctionDefinition(definition) {
|
|
29441
29453
|
validateName(definition.name);
|
|
@@ -30844,9 +30856,9 @@ function nativeSourceFiles(directory, extension, buildDirMaxDepth, depth = 1) {
|
|
|
30844
30856
|
return entries.flatMap((entry) => {
|
|
30845
30857
|
if (NATIVE_SCRATCH_DIRS.has(entry.name)) return [];
|
|
30846
30858
|
if (entry.name === BUILD_OUTPUT_DIR && depth <= buildDirMaxDepth) return [];
|
|
30847
|
-
const
|
|
30848
|
-
if (entry.isDirectory()) return nativeSourceFiles(
|
|
30849
|
-
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] : [];
|
|
30850
30862
|
});
|
|
30851
30863
|
}
|
|
30852
30864
|
function registeredActions(source) {
|
|
@@ -31109,10 +31121,10 @@ function readJsonAt(app, file, root) {
|
|
|
31109
31121
|
}
|
|
31110
31122
|
}
|
|
31111
31123
|
function writeJsonAt(app, file, root, value) {
|
|
31112
|
-
const
|
|
31113
|
-
mkdirSync15(dirname20(
|
|
31114
|
-
writeFileSync12(
|
|
31115
|
-
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;
|
|
31116
31128
|
}
|
|
31117
31129
|
function sanitizeOverlay(raw) {
|
|
31118
31130
|
if (!("appIconBadgeSources" in raw)) return raw;
|
|
@@ -31348,8 +31360,8 @@ function handleL10nRequest(req, res, state) {
|
|
|
31348
31360
|
if (!state.app || app !== state.app.name) {
|
|
31349
31361
|
return sendJson(res, 404, { error: "unknown_app", app }, cors);
|
|
31350
31362
|
}
|
|
31351
|
-
const
|
|
31352
|
-
if (!existsSync36(
|
|
31363
|
+
const path2 = resolve30(state.app.dir, "l10n", `${tag}.json`);
|
|
31364
|
+
if (!existsSync36(path2)) {
|
|
31353
31365
|
res.writeHead(204, cors);
|
|
31354
31366
|
res.end();
|
|
31355
31367
|
return;
|
|
@@ -31358,7 +31370,7 @@ function handleL10nRequest(req, res, state) {
|
|
|
31358
31370
|
let messages;
|
|
31359
31371
|
try {
|
|
31360
31372
|
messages = Object.fromEntries(
|
|
31361
|
-
keyMap(parseCatalog(readFileSync39(
|
|
31373
|
+
keyMap(parseCatalog(readFileSync39(path2, "utf8")), { sourceFallback: tag === sourceLocale })
|
|
31362
31374
|
);
|
|
31363
31375
|
} catch {
|
|
31364
31376
|
return sendJson(res, 500, { error: "catalog_unreadable", app, tag }, cors);
|
|
@@ -31588,16 +31600,16 @@ async function handleOwnerSitesRequest(req, res) {
|
|
|
31588
31600
|
async function handleOwnerChatRequest(req, res) {
|
|
31589
31601
|
const cors = { "access-control-allow-origin": "*" };
|
|
31590
31602
|
const u = new URL(req.url ?? "", "http://localhost");
|
|
31591
|
-
const
|
|
31603
|
+
const path2 = u.pathname;
|
|
31592
31604
|
const { resolveMetaSiteId, listChatroomsLive, sendChatMessageLive } = await import("./apps/wix-owner-clone-live.js");
|
|
31593
|
-
if (
|
|
31605
|
+
if (path2 === "/v1/owner-chat/chatrooms" && req.method === "GET") {
|
|
31594
31606
|
const metaSiteId = u.searchParams.get("metaSiteId") || await resolveMetaSiteId();
|
|
31595
31607
|
if (!metaSiteId) return sendJson(res, 400, { error: "no_meta_site" }, cors);
|
|
31596
31608
|
const rooms = await listChatroomsLive(metaSiteId);
|
|
31597
31609
|
if (rooms == null) return sendJson(res, 502, { error: "chatrooms_unavailable" }, cors);
|
|
31598
31610
|
return sendJson(res, 200, { chatrooms: rooms }, cors);
|
|
31599
31611
|
}
|
|
31600
|
-
if (
|
|
31612
|
+
if (path2 === "/v1/owner-chat/send" && req.method === "POST") {
|
|
31601
31613
|
let parsed;
|
|
31602
31614
|
try {
|
|
31603
31615
|
parsed = JSON.parse(await readBody2(req) || "{}");
|
|
@@ -32316,7 +32328,7 @@ function webWixSession(req, res, state) {
|
|
|
32316
32328
|
async function handleWebWix(req, res, state) {
|
|
32317
32329
|
const session = webWixSession(req, res, state);
|
|
32318
32330
|
const auth = resolveWebWixAuth(state.app);
|
|
32319
|
-
const
|
|
32331
|
+
const path2 = new URL(req.url ?? "", "http://localhost").pathname;
|
|
32320
32332
|
const readJson3 = async () => {
|
|
32321
32333
|
const chunks = [];
|
|
32322
32334
|
for await (const c of req) chunks.push(c);
|
|
@@ -32333,7 +32345,7 @@ async function handleWebWix(req, res, state) {
|
|
|
32333
32345
|
res.setHeader("access-control-allow-origin", "*");
|
|
32334
32346
|
res.end(JSON.stringify(obj2));
|
|
32335
32347
|
};
|
|
32336
|
-
if (
|
|
32348
|
+
if (path2 === "/v1/__webwix/login" && req.method === "POST") {
|
|
32337
32349
|
const b = await readJson3();
|
|
32338
32350
|
try {
|
|
32339
32351
|
const { memberToken, visitorToken } = await memberDirectLogin(
|
|
@@ -32350,7 +32362,7 @@ async function handleWebWix(req, res, state) {
|
|
|
32350
32362
|
return reply(200, { ok: false, error: String(e?.message ?? e) });
|
|
32351
32363
|
}
|
|
32352
32364
|
}
|
|
32353
|
-
if (
|
|
32365
|
+
if (path2 === "/v1/__webwix/call" && req.method === "POST") {
|
|
32354
32366
|
const b = await readJson3();
|
|
32355
32367
|
if (b.ownerMsid !== void 0 || b.checkOwnerSession === true) {
|
|
32356
32368
|
const msid = String(b.ownerMsid ?? "");
|
|
@@ -32437,12 +32449,12 @@ async function handleWebWix(req, res, state) {
|
|
|
32437
32449
|
return reply(200, { status: 0, body: JSON.stringify({ error: String(e?.message ?? e) }) });
|
|
32438
32450
|
}
|
|
32439
32451
|
}
|
|
32440
|
-
if (
|
|
32452
|
+
if (path2 === "/v1/__webwix/logout" && req.method === "POST") {
|
|
32441
32453
|
session.memberToken = void 0;
|
|
32442
32454
|
session.email = void 0;
|
|
32443
32455
|
return reply(200, { ok: true });
|
|
32444
32456
|
}
|
|
32445
|
-
if (
|
|
32457
|
+
if (path2 === "/v1/__webwix/identity" && (req.method === "GET" || req.method === "POST")) {
|
|
32446
32458
|
if (!session.memberToken) return reply(200, { authenticated: false, userId: null, email: "" });
|
|
32447
32459
|
let userId = null;
|
|
32448
32460
|
try {
|
|
@@ -32466,7 +32478,7 @@ async function handleWebWix(req, res, state) {
|
|
|
32466
32478
|
} : null
|
|
32467
32479
|
});
|
|
32468
32480
|
}
|
|
32469
|
-
if (
|
|
32481
|
+
if (path2 === "/v1/__webwix/register" && req.method === "POST") {
|
|
32470
32482
|
const b = await readJson3();
|
|
32471
32483
|
try {
|
|
32472
32484
|
const { memberToken, visitorToken } = await memberDirectRegister(
|
|
@@ -32883,8 +32895,8 @@ async function handleDev(req, res, state) {
|
|
|
32883
32895
|
}
|
|
32884
32896
|
async function handleAdminPlayground(req, res, state) {
|
|
32885
32897
|
const url = req.url ?? "";
|
|
32886
|
-
const
|
|
32887
|
-
const sampleMatch = /^\/v1\/admin\/sdui-samples\/([^/]+)$/.exec(
|
|
32898
|
+
const path2 = url.split("?")[0];
|
|
32899
|
+
const sampleMatch = /^\/v1\/admin\/sdui-samples\/([^/]+)$/.exec(path2);
|
|
32888
32900
|
if (sampleMatch && req.method === "GET") {
|
|
32889
32901
|
const name = decodeURIComponent(sampleMatch[1]);
|
|
32890
32902
|
if (!/^[a-zA-Z0-9._-]+$/.test(name)) return sendJson(res, 400, { error: "bad_name" });
|
|
@@ -32895,7 +32907,7 @@ async function handleAdminPlayground(req, res, state) {
|
|
|
32895
32907
|
return sendJson(res, 404, { error: "sample_not_found", name });
|
|
32896
32908
|
}
|
|
32897
32909
|
}
|
|
32898
|
-
if (
|
|
32910
|
+
if (path2 === "/v1/admin/sdui-samples" && req.method === "GET") {
|
|
32899
32911
|
try {
|
|
32900
32912
|
const { readdir } = await import("node:fs/promises");
|
|
32901
32913
|
const files = (await readdir(SAMPLES_ROOT)).filter((f) => f.endsWith(".json"));
|
|
@@ -32904,7 +32916,7 @@ async function handleAdminPlayground(req, res, state) {
|
|
|
32904
32916
|
return sendJson(res, 500, { error: err.message });
|
|
32905
32917
|
}
|
|
32906
32918
|
}
|
|
32907
|
-
if (
|
|
32919
|
+
if (path2 === "/v1/admin/screens" && req.method === "GET") {
|
|
32908
32920
|
const meta = state.app.meta;
|
|
32909
32921
|
const fixedIds = meta.screenIds;
|
|
32910
32922
|
const fixedSet = new Set(fixedIds);
|
|
@@ -32953,12 +32965,12 @@ async function handleAdminPlayground(req, res, state) {
|
|
|
32953
32965
|
templatedPatterns: meta.templatedPatterns
|
|
32954
32966
|
});
|
|
32955
32967
|
}
|
|
32956
|
-
const historyMatch = /^\/v1\/admin\/screens\/(.+?)\/history(?:\?|$)/.exec(
|
|
32968
|
+
const historyMatch = /^\/v1\/admin\/screens\/(.+?)\/history(?:\?|$)/.exec(path2);
|
|
32957
32969
|
if (historyMatch && req.method === "GET") {
|
|
32958
32970
|
const screenId = decodeURIComponent(historyMatch[1]);
|
|
32959
32971
|
return sendJson(res, 200, { screenId, history: state.localOverrideHistory.get(screenId) ?? [] });
|
|
32960
32972
|
}
|
|
32961
|
-
const revertMatch = /^\/v1\/admin\/screens\/(.+?)\/revert(?:\?|$)/.exec(
|
|
32973
|
+
const revertMatch = /^\/v1\/admin\/screens\/(.+?)\/revert(?:\?|$)/.exec(path2);
|
|
32962
32974
|
if (revertMatch && req.method === "POST") {
|
|
32963
32975
|
const screenId = decodeURIComponent(revertMatch[1]);
|
|
32964
32976
|
const historyId = Number(new URLSearchParams(url.split("?")[1] ?? "").get("historyId"));
|
|
@@ -32974,7 +32986,7 @@ async function handleAdminPlayground(req, res, state) {
|
|
|
32974
32986
|
invalidate(state, screenId);
|
|
32975
32987
|
return sendJson(res, 200, { status: "ok", screenId, revertedTo: historyId });
|
|
32976
32988
|
}
|
|
32977
|
-
if (
|
|
32989
|
+
if (path2 === "/v1/admin/tab-badge" && req.method === "POST") {
|
|
32978
32990
|
let body;
|
|
32979
32991
|
try {
|
|
32980
32992
|
body = JSON.parse(await readBody2(req));
|
|
@@ -32993,7 +33005,7 @@ async function handleAdminPlayground(req, res, state) {
|
|
|
32993
33005
|
);
|
|
32994
33006
|
return sendJson(res, 200, { status: "ok", tabId: body.tabId, count: clearing ? null : body.count });
|
|
32995
33007
|
}
|
|
32996
|
-
const validateMatch = /^\/v1\/admin\/screens\/(.+?)\/validate(?:\?|$)/.exec(
|
|
33008
|
+
const validateMatch = /^\/v1\/admin\/screens\/(.+?)\/validate(?:\?|$)/.exec(path2);
|
|
32997
33009
|
if (validateMatch && req.method === "GET") {
|
|
32998
33010
|
const screenId = decodeURIComponent(validateMatch[1]);
|
|
32999
33011
|
const strict = /[?&]strict=1(?:&|$)/.test(url);
|
|
@@ -33021,7 +33033,7 @@ async function handleAdminPlayground(req, res, state) {
|
|
|
33021
33033
|
});
|
|
33022
33034
|
return sendJson(res, report2.ok ? 200 : 422, report2);
|
|
33023
33035
|
}
|
|
33024
|
-
const detailMatch = /^\/v1\/admin\/screens\/([^/]+)$/.exec(
|
|
33036
|
+
const detailMatch = /^\/v1\/admin\/screens\/([^/]+)$/.exec(path2);
|
|
33025
33037
|
if (detailMatch && req.method === "GET") {
|
|
33026
33038
|
const screenId = decodeURIComponent(detailMatch[1]);
|
|
33027
33039
|
const wantBuilt = /[?&]source=built(?:&|$)/.test(url);
|
|
@@ -33058,7 +33070,7 @@ async function handleAdminPlayground(req, res, state) {
|
|
|
33058
33070
|
invalidate(state, screenId);
|
|
33059
33071
|
return sendJson(res, existed ? 200 : 404, { status: existed ? "ok" : "not_found" });
|
|
33060
33072
|
}
|
|
33061
|
-
if (
|
|
33073
|
+
if (path2 === "/v1/admin/app-config" && state.app) {
|
|
33062
33074
|
const built = deriveNavigationConfig(state.app.meta);
|
|
33063
33075
|
if (req.method === "GET") {
|
|
33064
33076
|
const effective = state.appConfigOverride ? deepMerge3(built, state.appConfigOverride) : built;
|
|
@@ -33083,7 +33095,7 @@ async function handleAdminPlayground(req, res, state) {
|
|
|
33083
33095
|
return sendJson(res, existed ? 200 : 404, { status: existed ? "ok" : "not_found" });
|
|
33084
33096
|
}
|
|
33085
33097
|
}
|
|
33086
|
-
if (
|
|
33098
|
+
if (path2 === "/v1/admin/tokens" && state.app) {
|
|
33087
33099
|
const built = readAppTokens(state) ?? {};
|
|
33088
33100
|
if (req.method === "GET") {
|
|
33089
33101
|
const effective = state.tokensOverride ? deepMerge3(built, state.tokensOverride) : built;
|
|
@@ -33108,7 +33120,7 @@ async function handleAdminPlayground(req, res, state) {
|
|
|
33108
33120
|
return sendJson(res, existed ? 200 : 404, { status: existed ? "ok" : "not_found" });
|
|
33109
33121
|
}
|
|
33110
33122
|
}
|
|
33111
|
-
return sendJson(res, 404, { error: "unknown_admin_route", path });
|
|
33123
|
+
return sendJson(res, 404, { error: "unknown_admin_route", path: path2 });
|
|
33112
33124
|
}
|
|
33113
33125
|
function isNavControlPatch(patch) {
|
|
33114
33126
|
if (!patch || typeof patch !== "object") return false;
|
|
@@ -33163,10 +33175,10 @@ async function readBundleFile(name, dir) {
|
|
|
33163
33175
|
resolve30(root, `${name}.js`),
|
|
33164
33176
|
resolve30(root, name)
|
|
33165
33177
|
]);
|
|
33166
|
-
for (const
|
|
33167
|
-
if (!roots.some((root) =>
|
|
33178
|
+
for (const path2 of candidates) {
|
|
33179
|
+
if (!roots.some((root) => path2.startsWith(root))) continue;
|
|
33168
33180
|
try {
|
|
33169
|
-
const bytes2 = await readFile(
|
|
33181
|
+
const bytes2 = await readFile(path2);
|
|
33170
33182
|
const integrity2 = "sha256-" + createHash15("sha256").update(bytes2).digest("base64");
|
|
33171
33183
|
return { bytes: bytes2, integrity: integrity2 };
|
|
33172
33184
|
} catch {
|
|
@@ -33346,10 +33358,10 @@ function handleActionHandlersManifest(res, app) {
|
|
|
33346
33358
|
}
|
|
33347
33359
|
async function handleActionHandlerBundleGet(res, app) {
|
|
33348
33360
|
if (!/^[A-Za-z0-9_.\-]+$/.test(app)) return sendJson(res, 404, { error: "not_found" });
|
|
33349
|
-
const
|
|
33350
|
-
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" });
|
|
33351
33363
|
try {
|
|
33352
|
-
const bytes2 = await readFile(
|
|
33364
|
+
const bytes2 = await readFile(path2);
|
|
33353
33365
|
const integrity2 = "sha256-" + createHash15("sha256").update(bytes2).digest("base64");
|
|
33354
33366
|
res.setHeader("content-type", "application/javascript; charset=utf-8");
|
|
33355
33367
|
res.setHeader("cache-control", "max-age=300");
|
|
@@ -34123,13 +34135,13 @@ var init_capability_fixtures = __esm({
|
|
|
34123
34135
|
};
|
|
34124
34136
|
MEDIA_EXT = (url) => {
|
|
34125
34137
|
if (typeof url !== "string") return null;
|
|
34126
|
-
let
|
|
34138
|
+
let path2;
|
|
34127
34139
|
try {
|
|
34128
|
-
|
|
34140
|
+
path2 = new URL(url).pathname;
|
|
34129
34141
|
} catch {
|
|
34130
|
-
|
|
34142
|
+
path2 = url.split("#")[0].split("?")[0];
|
|
34131
34143
|
}
|
|
34132
|
-
const segment =
|
|
34144
|
+
const segment = path2.split("/").pop() ?? "";
|
|
34133
34145
|
const m = /\.([a-z0-9]{2,5})$/i.exec(segment);
|
|
34134
34146
|
return m ? m[1].toLowerCase() : null;
|
|
34135
34147
|
};
|
|
@@ -34290,9 +34302,9 @@ var init_capability_fixtures = __esm({
|
|
|
34290
34302
|
// made every write resolve to the same file, and a consumer passing that handle onward (an export
|
|
34291
34303
|
// writing `exports/<id>.gpx`) referenced something that does not exist.
|
|
34292
34304
|
"capability.files.write": (p, ctx) => {
|
|
34293
|
-
const
|
|
34294
|
-
const name =
|
|
34295
|
-
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 };
|
|
34296
34308
|
},
|
|
34297
34309
|
"capability.files.remove": () => ({ removed: true })
|
|
34298
34310
|
};
|
|
@@ -34579,14 +34591,14 @@ function relationalSignature(state) {
|
|
|
34579
34591
|
}
|
|
34580
34592
|
function listLengths(state, depth = 4) {
|
|
34581
34593
|
const out = {};
|
|
34582
|
-
const walk2 = (node,
|
|
34594
|
+
const walk2 = (node, path2, left) => {
|
|
34583
34595
|
if (left < 0 || node === null || typeof node !== "object") return;
|
|
34584
34596
|
if (Array.isArray(node)) {
|
|
34585
|
-
out[
|
|
34597
|
+
out[path2] = node.length;
|
|
34586
34598
|
return;
|
|
34587
34599
|
}
|
|
34588
34600
|
for (const [k, v] of Object.entries(node)) {
|
|
34589
|
-
walk2(v,
|
|
34601
|
+
walk2(v, path2 ? `${path2}.${k}` : k, left - 1);
|
|
34590
34602
|
}
|
|
34591
34603
|
};
|
|
34592
34604
|
walk2(state, "", depth);
|
|
@@ -34607,26 +34619,26 @@ function summarizeDiff(aSig, bSig, limit = 3) {
|
|
|
34607
34619
|
if (t === void 0) return "undefined";
|
|
34608
34620
|
return t.length > 80 ? `${t.slice(0, 77)}\u2026` : t;
|
|
34609
34621
|
};
|
|
34610
|
-
const walk2 = (x, y,
|
|
34622
|
+
const walk2 = (x, y, path2) => {
|
|
34611
34623
|
if (diffs.length >= limit) return;
|
|
34612
34624
|
const bothObjects = x !== null && y !== null && typeof x === "object" && typeof y === "object" && !Array.isArray(x) && !Array.isArray(y);
|
|
34613
34625
|
if (bothObjects) {
|
|
34614
34626
|
for (const k of /* @__PURE__ */ new Set([...Object.keys(x), ...Object.keys(y)])) {
|
|
34615
|
-
walk2(x[k], y[k],
|
|
34627
|
+
walk2(x[k], y[k], path2 ? `${path2}.${k}` : k);
|
|
34616
34628
|
}
|
|
34617
34629
|
return;
|
|
34618
34630
|
}
|
|
34619
34631
|
if (Array.isArray(x) && Array.isArray(y)) {
|
|
34620
34632
|
if (x.length !== y.length) {
|
|
34621
|
-
diffs.push(`${
|
|
34633
|
+
diffs.push(`${path2 || "state"}: ${x.length} \u2192 ${y.length} items`);
|
|
34622
34634
|
return;
|
|
34623
34635
|
}
|
|
34624
|
-
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}]`);
|
|
34625
34637
|
return;
|
|
34626
34638
|
}
|
|
34627
34639
|
const xs = brief(x);
|
|
34628
34640
|
const ys = brief(y);
|
|
34629
|
-
if (xs !== ys) diffs.push(`${
|
|
34641
|
+
if (xs !== ys) diffs.push(`${path2 || "state"}: ${xs} \u2192 ${ys}`);
|
|
34630
34642
|
};
|
|
34631
34643
|
walk2(a, b, "");
|
|
34632
34644
|
return diffs.slice(0, limit).join("; ");
|
|
@@ -34715,6 +34727,7 @@ function actionSites(payload) {
|
|
|
34715
34727
|
actionId: a.actionId,
|
|
34716
34728
|
params: a.params ?? {},
|
|
34717
34729
|
...a.args ? { args: a.args } : {},
|
|
34730
|
+
...a.presentation ? { presentation: a.presentation } : {},
|
|
34718
34731
|
...ambient ? { itemsPath: ambient } : {},
|
|
34719
34732
|
// `rec` IS the prop bag that carries this callback — for a plain node that is
|
|
34720
34733
|
// `body.props`, and for a FormField variant the nested `text`/`picker`/… object, which
|
|
@@ -34833,8 +34846,8 @@ function sourceOfStack(stack, bundleMap) {
|
|
|
34833
34846
|
return mapBundleFrame(bundleMap, Number(m[1]), Number(m[2]) - 1) ?? void 0;
|
|
34834
34847
|
}
|
|
34835
34848
|
function netTransport(rules) {
|
|
34836
|
-
return async (method,
|
|
34837
|
-
const [bare, search] = String(
|
|
34849
|
+
return async (method, path2, body) => {
|
|
34850
|
+
const [bare, search] = String(path2).split("?", 2);
|
|
34838
34851
|
const query = {};
|
|
34839
34852
|
if (search) for (const [k, v] of new URLSearchParams(search)) query[k] = v;
|
|
34840
34853
|
const res = resolveScenario(rules, {
|
|
@@ -34881,9 +34894,9 @@ function layeredTransport(layers) {
|
|
|
34881
34894
|
const cms = layers.cmsSeed && Object.keys(layers.cmsSeed).length ? layers.cmsSeed : null;
|
|
34882
34895
|
const canned = layers.canned && Object.keys(layers.canned).length ? layers.canned : null;
|
|
34883
34896
|
const label2 = [rules && "mocked", cms && "cms", canned && "canned"].filter(Boolean).join("+") || "offline";
|
|
34884
|
-
const call = async (method,
|
|
34897
|
+
const call = async (method, path2, body) => {
|
|
34885
34898
|
const m = String(method).toUpperCase();
|
|
34886
|
-
const p = String(
|
|
34899
|
+
const p = String(path2);
|
|
34887
34900
|
const [bare, search] = p.split("?", 2);
|
|
34888
34901
|
if (rules) {
|
|
34889
34902
|
const query = {};
|
|
@@ -35362,9 +35375,9 @@ async function crawlScreenInner(opts) {
|
|
|
35362
35375
|
const resolveItem = (v) => {
|
|
35363
35376
|
if (typeof v !== "string" || !v.startsWith("$item")) return v;
|
|
35364
35377
|
if (!row0) return v;
|
|
35365
|
-
const
|
|
35366
|
-
if (!
|
|
35367
|
-
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);
|
|
35368
35381
|
};
|
|
35369
35382
|
const target = resolveItem(merged.screenId);
|
|
35370
35383
|
if (typeof target !== "string" || !target || target.includes("$")) continue;
|
|
@@ -35464,6 +35477,23 @@ async function crawlScreenInner(opts) {
|
|
|
35464
35477
|
actionsSkipped.push({ action: s.actionId, why: "embedded-preview" });
|
|
35465
35478
|
return false;
|
|
35466
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
|
+
}
|
|
35467
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;
|
|
35468
35498
|
const check = (trigger, state, errors, defects = {}) => {
|
|
35469
35499
|
for (const [svc, paths] of Object.entries(defects)) {
|
|
@@ -35785,8 +35815,8 @@ async function crawlScreenHostileInner(opts, variant) {
|
|
|
35785
35815
|
const base = layeredTransport({ rules: opts.rules, cmsSeed: opts.cmsSeed, canned: opts.canned });
|
|
35786
35816
|
if (base.label === "offline") return [];
|
|
35787
35817
|
const axis = `hostile:${variant}`;
|
|
35788
|
-
const wixCall = variant === "empty" ? async (method,
|
|
35789
|
-
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]}`);
|
|
35790
35820
|
};
|
|
35791
35821
|
let w;
|
|
35792
35822
|
try {
|
|
@@ -35989,17 +36019,17 @@ async function crawlScreenDeep(opts, deep) {
|
|
|
35989
36019
|
localDbSchema: opts.localDbSchema,
|
|
35990
36020
|
capabilitySuccess: opts.capabilitySuccess === true
|
|
35991
36021
|
});
|
|
35992
|
-
const pathLabel = (
|
|
36022
|
+
const pathLabel = (path2) => path2.map((i) => sites[i].actionId.replace(/^tier5\./, "")).join(" \u2192 ");
|
|
35993
36023
|
while (queue.length) {
|
|
35994
36024
|
if (visited.size >= maxNodes || dispatches >= maxDispatches) {
|
|
35995
36025
|
capped = true;
|
|
35996
36026
|
break;
|
|
35997
36027
|
}
|
|
35998
|
-
const
|
|
36028
|
+
const path2 = queue.shift();
|
|
35999
36029
|
const w = await boot();
|
|
36000
36030
|
try {
|
|
36001
36031
|
let threwAt = null;
|
|
36002
|
-
for (const [step, siteIdx] of
|
|
36032
|
+
for (const [step, siteIdx] of path2.entries()) {
|
|
36003
36033
|
const site = sites[siteIdx];
|
|
36004
36034
|
const parsed = parseWorkerAction(site.actionId);
|
|
36005
36035
|
const handle = w.handles[parsed.service];
|
|
@@ -36021,7 +36051,7 @@ async function crawlScreenDeep(opts, deep) {
|
|
|
36021
36051
|
try {
|
|
36022
36052
|
await handle.dispatch(parsed.action, ...workerArgs(effective));
|
|
36023
36053
|
} catch (e) {
|
|
36024
|
-
if (step ===
|
|
36054
|
+
if (step === path2.length - 1 && path2.length >= 2) {
|
|
36025
36055
|
const source = sourceOfStack(e.stack, opts.bundleMap);
|
|
36026
36056
|
findings.push({
|
|
36027
36057
|
screen: screenId,
|
|
@@ -36030,7 +36060,7 @@ async function crawlScreenDeep(opts, deep) {
|
|
|
36030
36060
|
severity: "error",
|
|
36031
36061
|
axis: "deep",
|
|
36032
36062
|
...source ? { source } : {},
|
|
36033
|
-
message: `after ${pathLabel(
|
|
36063
|
+
message: `after ${pathLabel(path2)}: ${parsed.action}: ${errText(e)}`,
|
|
36034
36064
|
hint: "this chain of taps crashes the worker \u2014 each step passed alone, the SEQUENCE is the bug"
|
|
36035
36065
|
});
|
|
36036
36066
|
}
|
|
@@ -36044,8 +36074,8 @@ async function crawlScreenDeep(opts, deep) {
|
|
|
36044
36074
|
const hash = deepStateSignature(state, defects);
|
|
36045
36075
|
if (visited.has(hash)) continue;
|
|
36046
36076
|
visited.add(hash);
|
|
36047
|
-
if (
|
|
36048
|
-
const last = sites[
|
|
36077
|
+
if (path2.length >= 2) {
|
|
36078
|
+
const last = sites[path2[path2.length - 1]];
|
|
36049
36079
|
const lastTrigger = { tap: last.componentId, key: last.key, action: last.actionId };
|
|
36050
36080
|
for (const [svc, paths] of Object.entries(defects)) {
|
|
36051
36081
|
for (const p of paths) {
|
|
@@ -36055,7 +36085,7 @@ async function crawlScreenDeep(opts, deep) {
|
|
|
36055
36085
|
invariant: "non-finite-number",
|
|
36056
36086
|
severity: "error",
|
|
36057
36087
|
axis: "deep",
|
|
36058
|
-
message: `after ${pathLabel(
|
|
36088
|
+
message: `after ${pathLabel(path2)}: ${svc} state holds a non-finite number: ${p}`,
|
|
36059
36089
|
at: `${svc}.${p.split(" = ")[0]}`,
|
|
36060
36090
|
hint: "a chain of taps produced the bad arithmetic \u2014 each step alone was fine; check what the SEQUENCE accumulates"
|
|
36061
36091
|
});
|
|
@@ -36069,7 +36099,7 @@ async function crawlScreenDeep(opts, deep) {
|
|
|
36069
36099
|
invariant: d.kind,
|
|
36070
36100
|
severity: "error",
|
|
36071
36101
|
axis: "deep",
|
|
36072
|
-
message: `after ${pathLabel(
|
|
36102
|
+
message: `after ${pathLabel(path2)}: ${resolvedDefectMessage(d)}`,
|
|
36073
36103
|
at,
|
|
36074
36104
|
field,
|
|
36075
36105
|
hint: resolvedDefectHint(d)
|
|
@@ -36077,8 +36107,8 @@ async function crawlScreenDeep(opts, deep) {
|
|
|
36077
36107
|
});
|
|
36078
36108
|
}
|
|
36079
36109
|
}
|
|
36080
|
-
if (
|
|
36081
|
-
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]);
|
|
36082
36112
|
}
|
|
36083
36113
|
} finally {
|
|
36084
36114
|
w.dispose();
|
|
@@ -36169,13 +36199,13 @@ async function crawlScreenRelations(opts) {
|
|
|
36169
36199
|
capabilitySuccess: opts.capabilitySuccess === true,
|
|
36170
36200
|
...opts.evaluator ? { evaluator: opts.evaluator } : {}
|
|
36171
36201
|
});
|
|
36172
|
-
const replay = async (
|
|
36202
|
+
const replay = async (path2, rowFor = () => null) => {
|
|
36173
36203
|
const w = await boot();
|
|
36174
36204
|
try {
|
|
36175
36205
|
if (w.errors.length) return null;
|
|
36176
36206
|
let prev = snapshot(w).state;
|
|
36177
36207
|
const bootState = prev;
|
|
36178
|
-
for (const [i, site] of
|
|
36208
|
+
for (const [i, site] of path2.entries()) {
|
|
36179
36209
|
const parsed = parseWorkerAction(site.actionId);
|
|
36180
36210
|
const h = w.handles[parsed.service];
|
|
36181
36211
|
if (!h || !h.actionNames().includes(parsed.action)) return null;
|
|
@@ -36531,9 +36561,9 @@ function routesOverlap(left, right) {
|
|
|
36531
36561
|
return segment.startsWith(":") || other.startsWith(":") || segment === other;
|
|
36532
36562
|
});
|
|
36533
36563
|
}
|
|
36534
|
-
function validateRouteConflicts(
|
|
36564
|
+
function validateRouteConflicts(definitions2) {
|
|
36535
36565
|
const seen = [];
|
|
36536
|
-
for (const definition of
|
|
36566
|
+
for (const definition of definitions2) {
|
|
36537
36567
|
validateFunctionDefinition(definition);
|
|
36538
36568
|
const previous = seen.find((route) => route.method === definition.method && routesOverlap(route.path, definition.path));
|
|
36539
36569
|
if (previous) throw new Error(`duplicate or ambiguous function route: ${definition.name} conflicts with ${previous.name} at ${definition.method} ${definition.path}`);
|
|
@@ -36587,13 +36617,13 @@ function rejectUnsafeSource(name, source) {
|
|
|
36587
36617
|
throw new Error(`function ${name} must export handler`);
|
|
36588
36618
|
}
|
|
36589
36619
|
}
|
|
36590
|
-
async function buildFunctions(
|
|
36591
|
-
validateRouteConflicts(
|
|
36620
|
+
async function buildFunctions(definitions2, sources, options = {}) {
|
|
36621
|
+
validateRouteConflicts(definitions2);
|
|
36592
36622
|
validateDependencyPolicy(options.dependencies ?? [], options.dependencyPolicy);
|
|
36593
36623
|
const sbom = createFunctionSbom(options.dependencies ?? []);
|
|
36594
36624
|
const runBuild = await (_buildP ??= loadBuild());
|
|
36595
36625
|
const built = [];
|
|
36596
|
-
for (const definition of
|
|
36626
|
+
for (const definition of definitions2) {
|
|
36597
36627
|
const source = sources[definition.name];
|
|
36598
36628
|
if (typeof source !== "string") throw new Error(`missing source for function ${definition.name}`);
|
|
36599
36629
|
assertStaticDependencySource(source);
|
|
@@ -36745,10 +36775,10 @@ function l10nLintOptions(locale, appDir2) {
|
|
|
36745
36775
|
const tags = (locale.translations ?? []).filter((t) => t !== locale.default);
|
|
36746
36776
|
const catalog = /* @__PURE__ */ new Set();
|
|
36747
36777
|
for (const tag of tags) {
|
|
36748
|
-
const
|
|
36749
|
-
if (!existsSync37(
|
|
36778
|
+
const path2 = join34(appDir2, "l10n", `${tag}.json`);
|
|
36779
|
+
if (!existsSync37(path2)) continue;
|
|
36750
36780
|
try {
|
|
36751
|
-
const parsed = JSON.parse(readFileSync40(
|
|
36781
|
+
const parsed = JSON.parse(readFileSync40(path2, "utf8"));
|
|
36752
36782
|
for (const m of Object.values(parsed.messages ?? {})) {
|
|
36753
36783
|
if (typeof m?.source === "string" && typeof m.translation === "string" && m.translation.length > 0) {
|
|
36754
36784
|
catalog.add(m.source);
|
|
@@ -37018,8 +37048,8 @@ async function buildRelease(app, dest, opts = {}) {
|
|
|
37018
37048
|
function countingWixCall(base) {
|
|
37019
37049
|
let returned = 0;
|
|
37020
37050
|
return {
|
|
37021
|
-
call: async (method,
|
|
37022
|
-
const out = await base(method,
|
|
37051
|
+
call: async (method, path2, body) => {
|
|
37052
|
+
const out = await base(method, path2, body);
|
|
37023
37053
|
returned += 1;
|
|
37024
37054
|
return out;
|
|
37025
37055
|
},
|
|
@@ -37110,9 +37140,9 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
37110
37140
|
);
|
|
37111
37141
|
}
|
|
37112
37142
|
const token = await mintVisitor(clientId);
|
|
37113
|
-
liveWixCall = async (method,
|
|
37143
|
+
liveWixCall = async (method, path2, body) => {
|
|
37114
37144
|
const bodyStr = body === void 0 ? void 0 : typeof body === "string" ? body : JSON.stringify(body);
|
|
37115
|
-
const r = await webWixCall(method,
|
|
37145
|
+
const r = await webWixCall(method, path2, bodyStr, token);
|
|
37116
37146
|
if (r.status < 200 || r.status >= 300) throw new Error(`HTTP ${r.status}: ${String(r.body).slice(0, 300)}`);
|
|
37117
37147
|
try {
|
|
37118
37148
|
return r.body ? JSON.parse(r.body) : {};
|
|
@@ -37209,9 +37239,9 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
37209
37239
|
const MAX_AUTHORING_DOC_BYTES = 128 * 1024;
|
|
37210
37240
|
if (store.putDoc) {
|
|
37211
37241
|
for (const [name, file] of [["spec", "SPEC.md"], ["mobile-ux", "MOBILE-UX.md"]]) {
|
|
37212
|
-
const
|
|
37213
|
-
if (!existsSync37(
|
|
37214
|
-
const bytes2 = readFileSync40(
|
|
37242
|
+
const path2 = join34(preloaded.dir, file);
|
|
37243
|
+
if (!existsSync37(path2)) continue;
|
|
37244
|
+
const bytes2 = readFileSync40(path2);
|
|
37215
37245
|
if (bytes2.length === 0 || bytes2.length > MAX_AUTHORING_DOC_BYTES) {
|
|
37216
37246
|
throw new Error(`${file} must be non-empty and at most ${MAX_AUTHORING_DOC_BYTES} bytes to ship with a release.`);
|
|
37217
37247
|
}
|
|
@@ -37639,7 +37669,7 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
37639
37669
|
}
|
|
37640
37670
|
if (store.putWidget) {
|
|
37641
37671
|
const bakedWidgets = await bakeWidgets(
|
|
37642
|
-
(
|
|
37672
|
+
(path2) => devFetch(`${base}${path2}`, { headers: { "X-Himalaya-App": app } }),
|
|
37643
37673
|
(widgetId, json5) => store.putWidget(app, widgetId, json5),
|
|
37644
37674
|
// `opts.tier5Dir`, NOT the `tier5Dir` local — that one falls back to the
|
|
37645
37675
|
// repo-global dir, where this package's widgets cannot be told from anyone
|
|
@@ -38398,8 +38428,8 @@ async function captchaRequest(options) {
|
|
|
38398
38428
|
}
|
|
38399
38429
|
const setup = options.operation === "setup";
|
|
38400
38430
|
const base = options.target.control.replace(/\/+$/, "");
|
|
38401
|
-
const
|
|
38402
|
-
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, {
|
|
38403
38433
|
method: setup ? "POST" : "GET",
|
|
38404
38434
|
redirect: "error",
|
|
38405
38435
|
signal: AbortSignal.timeout(6e4),
|
|
@@ -38451,9 +38481,9 @@ __export(captcha_exports, {
|
|
|
38451
38481
|
});
|
|
38452
38482
|
import { readFileSync as readFileSync41 } from "node:fs";
|
|
38453
38483
|
import { resolve as resolve32 } from "node:path";
|
|
38454
|
-
function readObject(
|
|
38484
|
+
function readObject(path2) {
|
|
38455
38485
|
try {
|
|
38456
|
-
return JSON.parse(readFileSync41(
|
|
38486
|
+
return JSON.parse(readFileSync41(path2, "utf8"));
|
|
38457
38487
|
} catch {
|
|
38458
38488
|
return {};
|
|
38459
38489
|
}
|
|
@@ -38531,11 +38561,11 @@ async function pushSetupRequest(options) {
|
|
|
38531
38561
|
return refuse3("push_setup_body_too_large");
|
|
38532
38562
|
}
|
|
38533
38563
|
const base = options.target.control.replace(/\/+$/, "");
|
|
38534
|
-
let
|
|
38564
|
+
let path2 = "/v1/admin/push/setup";
|
|
38535
38565
|
if (!setup) {
|
|
38536
38566
|
const q = new URLSearchParams({ app: options.query.app, site: options.query.site });
|
|
38537
38567
|
if (options.query.verify) q.set("verify", options.query.verify);
|
|
38538
|
-
|
|
38568
|
+
path2 += `?${q.toString()}`;
|
|
38539
38569
|
}
|
|
38540
38570
|
const headers2 = {
|
|
38541
38571
|
"x-control-token": options.target.controlToken,
|
|
@@ -38546,7 +38576,7 @@ async function pushSetupRequest(options) {
|
|
|
38546
38576
|
...options.previewTag ? { "x-wix-route-serve": options.previewTag } : {}
|
|
38547
38577
|
};
|
|
38548
38578
|
try {
|
|
38549
|
-
const response = await (options.fetchImpl ?? fetch)(base +
|
|
38579
|
+
const response = await (options.fetchImpl ?? fetch)(base + path2, {
|
|
38550
38580
|
method: setup ? "POST" : "GET",
|
|
38551
38581
|
headers: headers2,
|
|
38552
38582
|
redirect: "error",
|
|
@@ -38599,9 +38629,9 @@ var init_push_setup_apple_credentials = __esm({
|
|
|
38599
38629
|
// src/push-onboarding.ts
|
|
38600
38630
|
import { existsSync as existsSync38, mkdirSync as mkdirSync17, readFileSync as readFileSync42, statSync as statSync7, writeFileSync as writeFileSync13, chmodSync as chmodSync2 } from "node:fs";
|
|
38601
38631
|
import { basename as basename9, dirname as dirname22, join as join35, resolve as resolve33 } from "node:path";
|
|
38602
|
-
function readJson2(
|
|
38632
|
+
function readJson2(path2) {
|
|
38603
38633
|
try {
|
|
38604
|
-
const parsed = JSON.parse(readFileSync42(
|
|
38634
|
+
const parsed = JSON.parse(readFileSync42(path2, "utf8"));
|
|
38605
38635
|
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
|
|
38606
38636
|
} catch {
|
|
38607
38637
|
return {};
|
|
@@ -38674,10 +38704,10 @@ function localIdentityRefusal(i) {
|
|
|
38674
38704
|
}
|
|
38675
38705
|
return null;
|
|
38676
38706
|
}
|
|
38677
|
-
function readKeyFile(
|
|
38707
|
+
function readKeyFile(path2) {
|
|
38678
38708
|
let size;
|
|
38679
38709
|
try {
|
|
38680
|
-
size = statSync7(
|
|
38710
|
+
size = statSync7(path2).size;
|
|
38681
38711
|
} catch {
|
|
38682
38712
|
return { ok: false, code: "key_file_unreadable", reason: "cannot read the selected key file; check its path and file permissions" };
|
|
38683
38713
|
}
|
|
@@ -38686,7 +38716,7 @@ function readKeyFile(path) {
|
|
|
38686
38716
|
}
|
|
38687
38717
|
let body;
|
|
38688
38718
|
try {
|
|
38689
|
-
body = readFileSync42(
|
|
38719
|
+
body = readFileSync42(path2, "utf8");
|
|
38690
38720
|
} catch {
|
|
38691
38721
|
return { ok: false, code: "key_file_unreadable", reason: "cannot read the selected key file; check its path and file permissions" };
|
|
38692
38722
|
}
|
|
@@ -38740,20 +38770,20 @@ function buildPushSetupBody(i, keys) {
|
|
|
38740
38770
|
};
|
|
38741
38771
|
}
|
|
38742
38772
|
function readPushOnboarding(dir) {
|
|
38743
|
-
const
|
|
38744
|
-
if (!existsSync38(
|
|
38745
|
-
const parsed = readJson2(
|
|
38773
|
+
const path2 = join35(resolve33(dir), PUSH_ONBOARDING_PATH);
|
|
38774
|
+
if (!existsSync38(path2)) return { version: 1 };
|
|
38775
|
+
const parsed = readJson2(path2);
|
|
38746
38776
|
return { version: 1, ...parsed };
|
|
38747
38777
|
}
|
|
38748
38778
|
function writeFile(dir, file) {
|
|
38749
|
-
const
|
|
38750
|
-
mkdirSync17(dirname22(
|
|
38751
|
-
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 });
|
|
38752
38782
|
try {
|
|
38753
|
-
chmodSync2(
|
|
38783
|
+
chmodSync2(path2, 384);
|
|
38754
38784
|
} catch {
|
|
38755
38785
|
}
|
|
38756
|
-
return
|
|
38786
|
+
return path2;
|
|
38757
38787
|
}
|
|
38758
38788
|
function recordPushDeferral(dir, d) {
|
|
38759
38789
|
const identity = {};
|
|
@@ -38775,8 +38805,8 @@ function recordPushDeferral(dir, d) {
|
|
|
38775
38805
|
return push;
|
|
38776
38806
|
}
|
|
38777
38807
|
function clearPushDeferral(dir) {
|
|
38778
|
-
const
|
|
38779
|
-
if (!existsSync38(
|
|
38808
|
+
const path2 = join35(resolve33(dir), PUSH_ONBOARDING_PATH);
|
|
38809
|
+
if (!existsSync38(path2)) return;
|
|
38780
38810
|
const { push: _dropped, ...rest } = readPushOnboarding(dir);
|
|
38781
38811
|
writeFile(dir, { ...rest, version: 1 });
|
|
38782
38812
|
}
|
|
@@ -39403,13 +39433,13 @@ function packagePathFor(pathname) {
|
|
|
39403
39433
|
}
|
|
39404
39434
|
return UNSUPPORTED;
|
|
39405
39435
|
}
|
|
39406
|
-
function parseJson(read,
|
|
39407
|
-
const bytes2 = read(
|
|
39436
|
+
function parseJson(read, path2, errors) {
|
|
39437
|
+
const bytes2 = read(path2);
|
|
39408
39438
|
if (!bytes2) return null;
|
|
39409
39439
|
try {
|
|
39410
39440
|
return JSON.parse(utf82(bytes2));
|
|
39411
39441
|
} catch (e) {
|
|
39412
|
-
errors.push(`${
|
|
39442
|
+
errors.push(`${path2} is not valid JSON: ${e.message}`);
|
|
39413
39443
|
return null;
|
|
39414
39444
|
}
|
|
39415
39445
|
}
|
|
@@ -39830,8 +39860,8 @@ function inflateEntry(buf, entry) {
|
|
|
39830
39860
|
verifyZipEntry(entry, bytes2);
|
|
39831
39861
|
return bytes2;
|
|
39832
39862
|
}
|
|
39833
|
-
function readIf(
|
|
39834
|
-
return existsSync39(
|
|
39863
|
+
function readIf(path2) {
|
|
39864
|
+
return existsSync39(path2) && statSync8(path2).isFile() ? readFileSync43(path2) : null;
|
|
39835
39865
|
}
|
|
39836
39866
|
function listDir(dir) {
|
|
39837
39867
|
return existsSync39(dir) ? readdirSync20(dir).filter((f) => statSync8(join36(dir, f)).isFile()) : [];
|
|
@@ -39967,7 +39997,7 @@ function packReleaseToDir(releaseRoot, app, outDir, opts = {}) {
|
|
|
39967
39997
|
}
|
|
39968
39998
|
function openFromEntries(entries, opts) {
|
|
39969
39999
|
const read = (p) => entries.get(p) ?? null;
|
|
39970
|
-
const contentHash = computeContentHash(Array.from(entries, ([
|
|
40000
|
+
const contentHash = computeContentHash(Array.from(entries, ([path2, bytes2]) => ({ path: path2, bytes: bytes2 })));
|
|
39971
40001
|
const validation = validatePackage(read, { requireHeader: opts.requireHeader, contentHash });
|
|
39972
40002
|
return {
|
|
39973
40003
|
header: validation.header,
|
|
@@ -40138,7 +40168,7 @@ function zipAppSource(entries) {
|
|
|
40138
40168
|
return writeZip(entries.map((e) => ({ path: e.path, bytes: e.bytes })));
|
|
40139
40169
|
}
|
|
40140
40170
|
function readAppSource(zip) {
|
|
40141
|
-
return [...readZip(zip)].map(([
|
|
40171
|
+
return [...readZip(zip)].map(([path2, bytes2]) => ({ path: path2, bytes: bytes2 }));
|
|
40142
40172
|
}
|
|
40143
40173
|
function pathKind(p) {
|
|
40144
40174
|
try {
|
|
@@ -40451,24 +40481,24 @@ function readTestConfig(dir) {
|
|
|
40451
40481
|
}
|
|
40452
40482
|
return { ...skip ? { skip } : {}, ...journeys ? { journeys } : {} };
|
|
40453
40483
|
}
|
|
40454
|
-
function readNetRules(
|
|
40484
|
+
function readNetRules(path2) {
|
|
40455
40485
|
let parsed;
|
|
40456
40486
|
try {
|
|
40457
|
-
parsed = JSON.parse(readFileSync46(
|
|
40487
|
+
parsed = JSON.parse(readFileSync46(path2, "utf8"));
|
|
40458
40488
|
} catch (e) {
|
|
40459
|
-
throw new Error(`--net ${
|
|
40489
|
+
throw new Error(`--net ${path2} could not be read as JSON \u2014 ${e.message}`);
|
|
40460
40490
|
}
|
|
40461
40491
|
const rules = parsed?.rules;
|
|
40462
40492
|
if (!Array.isArray(rules)) {
|
|
40463
|
-
throw new Error(`--net ${
|
|
40493
|
+
throw new Error(`--net ${path2} has no "rules" array \u2014 expected the net-mocks shape { "rules": [ { "matcher": {...}, "response": {...} } ] }`);
|
|
40464
40494
|
}
|
|
40465
40495
|
const active = rules.filter((r) => r.enabled !== false);
|
|
40466
40496
|
const shapeErrors = wixMockRuleErrors(active);
|
|
40467
40497
|
if (shapeErrors.length) {
|
|
40468
|
-
throw new Error(`${
|
|
40498
|
+
throw new Error(`${path2}: invalid net-mocks fixture \u2014 ${shapeErrors.join("; ")}`);
|
|
40469
40499
|
}
|
|
40470
40500
|
if (active.length && !active.some((r) => r.matcher && typeof r.matcher === "object")) {
|
|
40471
|
-
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"`);
|
|
40472
40502
|
}
|
|
40473
40503
|
return active;
|
|
40474
40504
|
}
|
|
@@ -40507,21 +40537,21 @@ function makeRecordingWixCall(send2, token, app) {
|
|
|
40507
40537
|
const events = [];
|
|
40508
40538
|
const refused = [];
|
|
40509
40539
|
let id = 0;
|
|
40510
|
-
const call = async (method,
|
|
40540
|
+
const call = async (method, path2, body) => {
|
|
40511
40541
|
const verb = method.toUpperCase();
|
|
40512
|
-
if (/[#\x00-\x1F\x7F]/.test(
|
|
40513
|
-
refused.push(`${verb} ${
|
|
40514
|
-
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`);
|
|
40515
40545
|
}
|
|
40516
|
-
const bare =
|
|
40546
|
+
const bare = path2.split("?")[0].replace(/\/+$/, "");
|
|
40517
40547
|
const readShaped = verb === "GET" || verb === "POST" && /\/(query|search|list[^/]*|get[^/]*|count|aggregate|facets|connections)$/i.test(bare);
|
|
40518
40548
|
if (!readShaped) {
|
|
40519
|
-
refused.push(`${verb} ${
|
|
40520
|
-
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`);
|
|
40521
40551
|
}
|
|
40522
40552
|
const bodyStr = body === void 0 ? void 0 : typeof body === "string" ? body : JSON.stringify(body);
|
|
40523
40553
|
const started = Date.now();
|
|
40524
|
-
const r = await send2(method,
|
|
40554
|
+
const r = await send2(method, path2, bodyStr, token);
|
|
40525
40555
|
events.push({
|
|
40526
40556
|
id: ++id,
|
|
40527
40557
|
ts: started,
|
|
@@ -40529,8 +40559,8 @@ function makeRecordingWixCall(send2, token, app) {
|
|
|
40529
40559
|
source: "observe",
|
|
40530
40560
|
host: "www.wixapis.com",
|
|
40531
40561
|
method,
|
|
40532
|
-
url: `https://www.wixapis.com${
|
|
40533
|
-
path,
|
|
40562
|
+
url: `https://www.wixapis.com${path2}`,
|
|
40563
|
+
path: path2,
|
|
40534
40564
|
status: r.status,
|
|
40535
40565
|
durationMs: Date.now() - started,
|
|
40536
40566
|
...bodyStr !== void 0 ? { reqBody: bodyStr } : {},
|
|
@@ -41161,9 +41191,9 @@ var init_auth = __esm({
|
|
|
41161
41191
|
});
|
|
41162
41192
|
|
|
41163
41193
|
// ../../core/functions-runtime/src/wix-transport.ts
|
|
41164
|
-
function rejectSiteOverride(
|
|
41194
|
+
function rejectSiteOverride(path2) {
|
|
41165
41195
|
try {
|
|
41166
|
-
if (new URL(
|
|
41196
|
+
if (new URL(path2, "https://wix.invalid").searchParams.has("msid")) {
|
|
41167
41197
|
throw new Error("request cannot override the bound Wix site identity");
|
|
41168
41198
|
}
|
|
41169
41199
|
} catch (error) {
|
|
@@ -41174,8 +41204,8 @@ function createWixApiCapability(options) {
|
|
|
41174
41204
|
const permissions = [...options.permissions ?? []].sort();
|
|
41175
41205
|
let installation;
|
|
41176
41206
|
return {
|
|
41177
|
-
async call(method,
|
|
41178
|
-
rejectSiteOverride(
|
|
41207
|
+
async call(method, path2, body) {
|
|
41208
|
+
rejectSiteOverride(path2);
|
|
41179
41209
|
let identity;
|
|
41180
41210
|
if (options.identity.kind === "caller") {
|
|
41181
41211
|
identity = { ...options.identity };
|
|
@@ -41186,9 +41216,9 @@ function createWixApiCapability(options) {
|
|
|
41186
41216
|
throw new Error("installation identity is not authorized for the configured Wix site");
|
|
41187
41217
|
}
|
|
41188
41218
|
identity = { kind: "installation", installationId: installation.installationId };
|
|
41189
|
-
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 });
|
|
41190
41220
|
}
|
|
41191
|
-
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 } });
|
|
41192
41222
|
}
|
|
41193
41223
|
};
|
|
41194
41224
|
}
|
|
@@ -41780,11 +41810,11 @@ var init_sandbox = __esm({
|
|
|
41780
41810
|
});
|
|
41781
41811
|
|
|
41782
41812
|
// ../../core/functions-runtime/src/openapi.ts
|
|
41783
|
-
function makeFunctionsOpenApi(manifest,
|
|
41813
|
+
function makeFunctionsOpenApi(manifest, definitions2 = []) {
|
|
41784
41814
|
const paths = {};
|
|
41785
41815
|
for (const record2 of manifest.functions ?? []) {
|
|
41786
41816
|
if (record2.internal) continue;
|
|
41787
|
-
const definition =
|
|
41817
|
+
const definition = definitions2.find((item) => item.name === record2.name);
|
|
41788
41818
|
const method = record2.method.toLowerCase();
|
|
41789
41819
|
paths[record2.path] = {
|
|
41790
41820
|
...paths[record2.path] ?? {},
|
|
@@ -42411,9 +42441,9 @@ function resolveTarget2(pathname) {
|
|
|
42411
42441
|
return null;
|
|
42412
42442
|
}
|
|
42413
42443
|
}
|
|
42414
|
-
function chooseFunction(records, method,
|
|
42444
|
+
function chooseFunction(records, method, path2) {
|
|
42415
42445
|
for (const record2 of records) {
|
|
42416
|
-
const params = routeMatch(record2.path,
|
|
42446
|
+
const params = routeMatch(record2.path, path2);
|
|
42417
42447
|
if (params && record2.method === method) return { record: record2, params };
|
|
42418
42448
|
}
|
|
42419
42449
|
return null;
|
|
@@ -42422,8 +42452,8 @@ async function contentFromBundle(bytes2, record2) {
|
|
|
42422
42452
|
const actual = await integrity(bytes2);
|
|
42423
42453
|
return actual.hash === record2.bundleHash && actual.sri === record2.sri ? utf8Decode(bytes2) : null;
|
|
42424
42454
|
}
|
|
42425
|
-
function definitionFor(
|
|
42426
|
-
return
|
|
42455
|
+
function definitionFor(definitions2, name) {
|
|
42456
|
+
return definitions2?.find((definition) => definition.name === name);
|
|
42427
42457
|
}
|
|
42428
42458
|
async function bodyValue(request, record2) {
|
|
42429
42459
|
const length = Number(request.headers.get("content-length") ?? "0");
|
|
@@ -42674,8 +42704,8 @@ function makeFunctionsHandler(options) {
|
|
|
42674
42704
|
}
|
|
42675
42705
|
};
|
|
42676
42706
|
}
|
|
42677
|
-
function functionsOpenApi(manifest,
|
|
42678
|
-
return makeFunctionsOpenApi(manifest,
|
|
42707
|
+
function functionsOpenApi(manifest, definitions2 = []) {
|
|
42708
|
+
return makeFunctionsOpenApi(manifest, definitions2);
|
|
42679
42709
|
}
|
|
42680
42710
|
var MAX_LOG_MESSAGE;
|
|
42681
42711
|
var init_gateway = __esm({
|
|
@@ -42741,19 +42771,19 @@ async function loadFunctionsApp(dir) {
|
|
|
42741
42771
|
if (dataErrors.length) throw new Error(`invalid data declaration: ${dataErrors.map((issue2) => issue2.message).join("; ")}`);
|
|
42742
42772
|
return { app: loaded.name, dir: loaded.dir, definitions: config.functions.functions, sources, siteBinding: config.functions.siteBinding, schedules: config.functions.schedules, ...data ? { data } : {} };
|
|
42743
42773
|
}
|
|
42744
|
-
function listFunctions(
|
|
42745
|
-
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 }));
|
|
42746
42776
|
}
|
|
42747
|
-
function describeFunction(
|
|
42748
|
-
const definition =
|
|
42777
|
+
function describeFunction(definitions2, name) {
|
|
42778
|
+
const definition = definitions2.find((item) => item.name === name);
|
|
42749
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;
|
|
42750
42780
|
}
|
|
42751
|
-
function materializeFunctionPath(
|
|
42752
|
-
const names = [...
|
|
42781
|
+
function materializeFunctionPath(path2, params = {}) {
|
|
42782
|
+
const names = [...path2.matchAll(/:([A-Za-z][A-Za-z0-9_]*)/g)].map((match) => match[1]);
|
|
42753
42783
|
for (const name of names) {
|
|
42754
42784
|
if (typeof params[name] !== "string" || params[name] === "") throw new Error(`missing route parameter "${name}"; pass --params {"${name}":"value"}`);
|
|
42755
42785
|
}
|
|
42756
|
-
return
|
|
42786
|
+
return path2.replace(/:([A-Za-z][A-Za-z0-9_]*)/g, (_match, name) => encodeURIComponent(params[name]));
|
|
42757
42787
|
}
|
|
42758
42788
|
function memoryStore(manifest, built) {
|
|
42759
42789
|
const bytes2 = new Map(built.map((item) => [item.bundleHash, item.bytes]));
|
|
@@ -42837,8 +42867,8 @@ async function invokeRemoteFunction(input) {
|
|
|
42837
42867
|
});
|
|
42838
42868
|
return { response, url: url.toString() };
|
|
42839
42869
|
}
|
|
42840
|
-
function openApiForFunctions(manifest,
|
|
42841
|
-
return functionsOpenApi(manifest,
|
|
42870
|
+
function openApiForFunctions(manifest, definitions2) {
|
|
42871
|
+
return functionsOpenApi(manifest, definitions2);
|
|
42842
42872
|
}
|
|
42843
42873
|
async function runRemoteFunctionOperation(input) {
|
|
42844
42874
|
const environment2 = input.environment ?? "production";
|
|
@@ -43090,9 +43120,9 @@ function runAndroidNativeDecode(options) {
|
|
|
43090
43120
|
rmSync8(descriptorDir, { recursive: true, force: true });
|
|
43091
43121
|
}
|
|
43092
43122
|
}
|
|
43093
|
-
function fieldAt(
|
|
43094
|
-
if (
|
|
43095
|
-
return
|
|
43123
|
+
function fieldAt(path2) {
|
|
43124
|
+
if (path2 === null) return void 0;
|
|
43125
|
+
return path2.match(/\.([^.[\]]+)$/)?.[1];
|
|
43096
43126
|
}
|
|
43097
43127
|
function mergeNativeDecode(report2, run2) {
|
|
43098
43128
|
const platformLabel = run2.platform === "ios" ? "iOS" : "Android";
|
|
@@ -44082,8 +44112,8 @@ var init_wix_member_auth = __esm({
|
|
|
44082
44112
|
function json3(status, body, headers2 = {}) {
|
|
44083
44113
|
return new Response(JSON.stringify(body), { status, headers: { "content-type": JSON_CT, ...headers2 } });
|
|
44084
44114
|
}
|
|
44085
|
-
function isCookieAuthorizedPath(
|
|
44086
|
-
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;
|
|
44087
44117
|
}
|
|
44088
44118
|
function makeServeHandler(opts) {
|
|
44089
44119
|
let storePromise = null;
|
|
@@ -44263,9 +44293,9 @@ ${releaseId}`;
|
|
|
44263
44293
|
const handle = async (request) => {
|
|
44264
44294
|
try {
|
|
44265
44295
|
const url = new URL(request.url);
|
|
44266
|
-
const
|
|
44296
|
+
const path2 = url.pathname;
|
|
44267
44297
|
if (opts.devControl && request.method === "PUT") {
|
|
44268
|
-
const dcMatch = /^\/v1\/dev-control\/([^/]+)$/.exec(
|
|
44298
|
+
const dcMatch = /^\/v1\/dev-control\/([^/]+)$/.exec(path2);
|
|
44269
44299
|
if (dcMatch) {
|
|
44270
44300
|
const dcApp = dcMatch[1];
|
|
44271
44301
|
let body = {};
|
|
@@ -44281,16 +44311,16 @@ ${releaseId}`;
|
|
|
44281
44311
|
}
|
|
44282
44312
|
}
|
|
44283
44313
|
const memberRungApp = memberAuthOn() ? memberApp(request) : null;
|
|
44284
|
-
if (memberRungApp && (
|
|
44314
|
+
if (memberRungApp && (path2 === "/v1/__webwix/login" || path2 === "/v1/__webwix/register" || path2 === MEMBER_CALLBACK_PATH || path2 === "/v1/__webwix/logout")) {
|
|
44285
44315
|
const store2 = memberSessions();
|
|
44286
44316
|
if (!store2) return json3(503, { error: "member_auth_unconfigured" });
|
|
44287
44317
|
const sessionId = readSessionCookie(request.headers.get("cookie"));
|
|
44288
|
-
if (
|
|
44318
|
+
if (path2 === "/v1/__webwix/logout") {
|
|
44289
44319
|
if (request.method !== "POST") return json3(405, { error: "method_not_allowed" });
|
|
44290
44320
|
if (sessionId) await store2.delete(sessionId);
|
|
44291
44321
|
return json3(200, { ok: true }, { "set-cookie": clearSessionCookie(), "cache-control": "no-store" });
|
|
44292
44322
|
}
|
|
44293
|
-
if (
|
|
44323
|
+
if (path2 === MEMBER_CALLBACK_PATH) {
|
|
44294
44324
|
if (request.method !== "GET") return json3(405, { error: "method_not_allowed" });
|
|
44295
44325
|
const code = url.searchParams.get("code");
|
|
44296
44326
|
const state2 = url.searchParams.get("state");
|
|
@@ -44350,7 +44380,7 @@ ${releaseId}`;
|
|
|
44350
44380
|
try {
|
|
44351
44381
|
const visitor = await webwixTokens.token(resolved2.config.clientId);
|
|
44352
44382
|
authUrl = await hostedAuthUrl(
|
|
44353
|
-
{ ...resolved2.config, mode:
|
|
44383
|
+
{ ...resolved2.config, mode: path2.endsWith("/register") ? "signup" : "login", state, challenge: pkce.challenge },
|
|
44354
44384
|
visitor,
|
|
44355
44385
|
webwixFetch
|
|
44356
44386
|
);
|
|
@@ -44377,7 +44407,7 @@ ${releaseId}`;
|
|
|
44377
44407
|
}
|
|
44378
44408
|
});
|
|
44379
44409
|
}
|
|
44380
|
-
if ((request.method === "GET" || request.method === "HEAD") &&
|
|
44410
|
+
if ((request.method === "GET" || request.method === "HEAD") && path2 === "/v1/__webwix/identity") {
|
|
44381
44411
|
const headers2 = { "content-type": JSON_CT, "cache-control": "no-store" };
|
|
44382
44412
|
if (request.method === "HEAD") return new Response(null, { status: 200, headers: headers2 });
|
|
44383
44413
|
const webwixDirect = opts.webwixBridge !== false;
|
|
@@ -44391,7 +44421,7 @@ ${releaseId}`;
|
|
|
44391
44421
|
}
|
|
44392
44422
|
return json3(200, { authenticated: false, userId: null, email: null, webwixDirect }, { "cache-control": "no-store" });
|
|
44393
44423
|
}
|
|
44394
|
-
if (request.method === "POST" &&
|
|
44424
|
+
if (request.method === "POST" && path2 === "/v1/__webwix/call") {
|
|
44395
44425
|
if (opts.webwixBridge === false) {
|
|
44396
44426
|
return json3(503, { error: "webwix_bridge_disabled" });
|
|
44397
44427
|
}
|
|
@@ -44494,8 +44524,8 @@ ${releaseId}`;
|
|
|
44494
44524
|
}
|
|
44495
44525
|
}
|
|
44496
44526
|
if (request.method !== "GET") return json3(405, { error: "method_not_allowed" });
|
|
44497
|
-
if (
|
|
44498
|
-
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);
|
|
44499
44529
|
if (packageShare) {
|
|
44500
44530
|
const shareId = packageShare[1];
|
|
44501
44531
|
const wantsMetadata = url.searchParams.get("metadata") === "1";
|
|
@@ -44524,7 +44554,7 @@ ${releaseId}`;
|
|
|
44524
44554
|
}
|
|
44525
44555
|
});
|
|
44526
44556
|
}
|
|
44527
|
-
if (
|
|
44557
|
+
if (path2 === "/v1/owner/instance") {
|
|
44528
44558
|
if (opts.webwixBridge === false) return json3(503, { error: "webwix_bridge_disabled" });
|
|
44529
44559
|
if (!webwixOwnerRungOn()) return json3(503, { error: "webwix_owner_disabled" });
|
|
44530
44560
|
const msid = url.searchParams.get("msid") ?? "";
|
|
@@ -44540,7 +44570,7 @@ ${releaseId}`;
|
|
|
44540
44570
|
return json3(403, { error: "webwix_owner_mint_failed" });
|
|
44541
44571
|
}
|
|
44542
44572
|
}
|
|
44543
|
-
if (
|
|
44573
|
+
if (path2 === "/v1/owner/sites") {
|
|
44544
44574
|
if (!webwixOwnerRungOn()) return json3(503, { error: "webwix_owner_disabled" });
|
|
44545
44575
|
const cookie = request.headers.get("cookie") ?? "";
|
|
44546
44576
|
if (!/wixSession2=/.test(cookie)) return json3(200, { sites: [] });
|
|
@@ -44554,7 +44584,7 @@ ${releaseId}`;
|
|
|
44554
44584
|
}
|
|
44555
44585
|
}
|
|
44556
44586
|
const store = await getStore();
|
|
44557
|
-
if (
|
|
44587
|
+
if (path2 === "/v1/apps") {
|
|
44558
44588
|
if (opts.authorizeList && !await opts.authorizeList(request)) {
|
|
44559
44589
|
return json3(401, { error: "unauthorized" });
|
|
44560
44590
|
}
|
|
@@ -44618,7 +44648,7 @@ ${releaseId}`;
|
|
|
44618
44648
|
headers: { "content-type": JSON_CT, ...listHeaders }
|
|
44619
44649
|
});
|
|
44620
44650
|
}
|
|
44621
|
-
if (
|
|
44651
|
+
if (path2 === "/v1/templates") {
|
|
44622
44652
|
if (opts.authorizeList && !await opts.authorizeList(request)) {
|
|
44623
44653
|
return json3(401, { error: "unauthorized" });
|
|
44624
44654
|
}
|
|
@@ -44653,7 +44683,7 @@ ${releaseId}`;
|
|
|
44653
44683
|
}
|
|
44654
44684
|
const app = resolveApp(request, url);
|
|
44655
44685
|
const pin = resolvePin(request, url);
|
|
44656
|
-
if (
|
|
44686
|
+
if (path2 === "/v1/template-source") {
|
|
44657
44687
|
if (!app) return json3(400, { error: "missing_app" });
|
|
44658
44688
|
if (!store.getSource) return json3(501, { error: "templates_unsupported" });
|
|
44659
44689
|
const m = pin ? await pinnedManifest(app, pin) : await manifest(app);
|
|
@@ -44673,12 +44703,12 @@ ${releaseId}`;
|
|
|
44673
44703
|
const denied = await authorizePinnedRead(request, url, app, pin);
|
|
44674
44704
|
if (denied) return denied;
|
|
44675
44705
|
}
|
|
44676
|
-
if (
|
|
44706
|
+
if (path2 === "/v1/authoring-docs" || /^\/v1\/authoring-docs\/(spec|mobile-ux)$/.test(path2)) {
|
|
44677
44707
|
if (!app) return json3(400, { error: "missing_app" });
|
|
44678
44708
|
const m = pin ? await pinnedManifest(app, pin) : await manifest(app);
|
|
44679
44709
|
if (!m) return json3(404, { error: pin ? "release_not_found" : "no_release", app });
|
|
44680
44710
|
const docs = m.authoringDocs ?? {};
|
|
44681
|
-
const match = /^\/v1\/authoring-docs\/(spec|mobile-ux)$/.exec(
|
|
44711
|
+
const match = /^\/v1\/authoring-docs\/(spec|mobile-ux)$/.exec(path2);
|
|
44682
44712
|
if (!match) {
|
|
44683
44713
|
return json3(200, {
|
|
44684
44714
|
app,
|
|
@@ -44706,7 +44736,7 @@ ${releaseId}`;
|
|
|
44706
44736
|
}
|
|
44707
44737
|
});
|
|
44708
44738
|
}
|
|
44709
|
-
if (
|
|
44739
|
+
if (path2 === "/v1/release/current") {
|
|
44710
44740
|
if (pin) {
|
|
44711
44741
|
const m2 = app ? await pinnedManifest(app, pin) : null;
|
|
44712
44742
|
if (!m2) return json3(404, { error: "release_not_found", app, releaseId: pin });
|
|
@@ -44716,7 +44746,7 @@ ${releaseId}`;
|
|
|
44716
44746
|
if (!m) return json3(404, { error: "no_release", app });
|
|
44717
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 } : {} });
|
|
44718
44748
|
}
|
|
44719
|
-
const bundleMatch = /^\/v1\/bundles\/([a-f0-9]{64})\.bundle\.js$/.exec(
|
|
44749
|
+
const bundleMatch = /^\/v1\/bundles\/([a-f0-9]{64})\.bundle\.js$/.exec(path2);
|
|
44720
44750
|
if (bundleMatch) {
|
|
44721
44751
|
const hash = bundleMatch[1];
|
|
44722
44752
|
const m = app ? pin ? await pinnedManifest(app, pin) : await manifest(app) : null;
|
|
@@ -44733,7 +44763,7 @@ ${releaseId}`;
|
|
|
44733
44763
|
}
|
|
44734
44764
|
});
|
|
44735
44765
|
}
|
|
44736
|
-
if (
|
|
44766
|
+
if (path2 === "/v1/boot") {
|
|
44737
44767
|
if (!app) return json3(400, { error: "missing_app" });
|
|
44738
44768
|
let m;
|
|
44739
44769
|
if (pin) {
|
|
@@ -44802,7 +44832,7 @@ ${releaseId}`;
|
|
|
44802
44832
|
}
|
|
44803
44833
|
return json3(200, { releaseId: mm.releaseId, app, appConfig, tokens, homeScreenId, screen, homeBundle }, { etag, "cache-control": cache, ...vary });
|
|
44804
44834
|
}
|
|
44805
|
-
if (
|
|
44835
|
+
if (path2 === "/v1/tokens") {
|
|
44806
44836
|
if (!app) return json3(400, { error: "missing_app" });
|
|
44807
44837
|
if (pin) {
|
|
44808
44838
|
const m = await pinnedManifest(app, pin);
|
|
@@ -44815,7 +44845,7 @@ ${releaseId}`;
|
|
|
44815
44845
|
if (!bytes2) return json3(404, { error: "tokens_not_found", app });
|
|
44816
44846
|
return sendDoc(request, bytes2);
|
|
44817
44847
|
}
|
|
44818
|
-
if (
|
|
44848
|
+
if (path2 === "/v1/l10n") {
|
|
44819
44849
|
if (!app) return json3(400, { error: "missing_app" });
|
|
44820
44850
|
const tag = (url.searchParams.get("tag") ?? "").trim();
|
|
44821
44851
|
if (!/^[a-z]{2}(-[A-Za-z0-9]+)?$/.test(tag)) {
|
|
@@ -44830,7 +44860,7 @@ ${releaseId}`;
|
|
|
44830
44860
|
if (!bytes2) return new Response(null, { status: 204 });
|
|
44831
44861
|
return sendDoc(request, bytes2, Boolean(pin));
|
|
44832
44862
|
}
|
|
44833
|
-
if (
|
|
44863
|
+
if (path2 === "/v1/app-icon") {
|
|
44834
44864
|
if (!app) return json3(400, { error: "missing_app" });
|
|
44835
44865
|
if (!store.getIcon) return json3(501, { error: "icons_unsupported" });
|
|
44836
44866
|
const m = pin ? await pinnedManifest(app, pin) : await manifest(app);
|
|
@@ -44847,7 +44877,7 @@ ${releaseId}`;
|
|
|
44847
44877
|
headers: { "content-type": "image/png", etag, "cache-control": BUNDLE_CACHE_CONTROL, "x-himalaya-app": app }
|
|
44848
44878
|
});
|
|
44849
44879
|
}
|
|
44850
|
-
const assetMatch = /^\/v1\/asset\/([^/?]+)$/.exec(
|
|
44880
|
+
const assetMatch = /^\/v1\/asset\/([^/?]+)$/.exec(path2);
|
|
44851
44881
|
if (assetMatch) {
|
|
44852
44882
|
if (!app) return json3(400, { error: "missing_app" });
|
|
44853
44883
|
if (!store.getAsset) return json3(501, { error: "assets_unsupported" });
|
|
@@ -44876,7 +44906,7 @@ ${releaseId}`;
|
|
|
44876
44906
|
}
|
|
44877
44907
|
});
|
|
44878
44908
|
}
|
|
44879
|
-
const ahMatch = /^\/v1\/action-handlers\/([^/]+)$/.exec(
|
|
44909
|
+
const ahMatch = /^\/v1\/action-handlers\/([^/]+)$/.exec(path2);
|
|
44880
44910
|
if (ahMatch) {
|
|
44881
44911
|
const ahApp = ahMatch[1];
|
|
44882
44912
|
const m = await manifest(ahApp);
|
|
@@ -44889,7 +44919,7 @@ ${releaseId}`;
|
|
|
44889
44919
|
}));
|
|
44890
44920
|
return json3(200, { handlers });
|
|
44891
44921
|
}
|
|
44892
|
-
const cfgMatch = /^\/v1\/app-config\/([^/]+)$/.exec(
|
|
44922
|
+
const cfgMatch = /^\/v1\/app-config\/([^/]+)$/.exec(path2);
|
|
44893
44923
|
if (cfgMatch) {
|
|
44894
44924
|
const cfgApp = cfgMatch[1];
|
|
44895
44925
|
if (pin) {
|
|
@@ -44909,7 +44939,7 @@ ${releaseId}`;
|
|
|
44909
44939
|
}
|
|
44910
44940
|
return sendDoc(request, bytes2);
|
|
44911
44941
|
}
|
|
44912
|
-
const screenMatch = /^\/v1\/screen\/([^/]+)$/.exec(
|
|
44942
|
+
const screenMatch = /^\/v1\/screen\/([^/]+)$/.exec(path2);
|
|
44913
44943
|
if (screenMatch) {
|
|
44914
44944
|
const screenId = screenMatch[1];
|
|
44915
44945
|
if (!app || !isSafeSegment(screenId)) return json3(404, { error: "screen_not_found", screenId });
|
|
@@ -44941,14 +44971,14 @@ ${releaseId}`;
|
|
|
44941
44971
|
headers: { "content-type": JSON_CT, etag, "cache-control": DOC_CACHE_CONTROL, "x-himalaya-app": app }
|
|
44942
44972
|
});
|
|
44943
44973
|
}
|
|
44944
|
-
if (
|
|
44974
|
+
if (path2 === "/v1/widgets") {
|
|
44945
44975
|
if (!app) return json3(400, { error: "missing_app" });
|
|
44946
44976
|
const m = pin ? await pinnedManifest(app, pin) : await manifest(app);
|
|
44947
44977
|
if (!m) return json3(404, { error: pin ? "release_not_found" : "no_release", app });
|
|
44948
44978
|
const widgets = Object.entries(m.widgets ?? {}).map(([widgetId, meta]) => ({ widgetId, contentEtag: meta.contentEtag }));
|
|
44949
44979
|
return json3(200, { widgets });
|
|
44950
44980
|
}
|
|
44951
|
-
const widgetMatch = /^\/v1\/widget\/([^/]+)$/.exec(
|
|
44981
|
+
const widgetMatch = /^\/v1\/widget\/([^/]+)$/.exec(path2);
|
|
44952
44982
|
if (widgetMatch) {
|
|
44953
44983
|
const widgetId = widgetMatch[1];
|
|
44954
44984
|
if (!app || !isSafeSegment(widgetId)) return json3(404, { error: "widget_not_found", widgetId });
|
|
@@ -45149,25 +45179,25 @@ function makeRunHandler(opts) {
|
|
|
45149
45179
|
});
|
|
45150
45180
|
return async (request) => {
|
|
45151
45181
|
const url = new URL(request.url);
|
|
45152
|
-
const
|
|
45153
|
-
if (
|
|
45182
|
+
const path2 = url.pathname;
|
|
45183
|
+
if (path2 === "/v1/release/resolve") {
|
|
45154
45184
|
return json4(
|
|
45155
45185
|
200,
|
|
45156
45186
|
{ app: opts.app, releaseId: opts.header?.releaseId ?? null, source: "local" },
|
|
45157
45187
|
{ "cache-control": "no-store" }
|
|
45158
45188
|
);
|
|
45159
45189
|
}
|
|
45160
|
-
if (
|
|
45190
|
+
if (path2 === "/v1/revocations") {
|
|
45161
45191
|
return json4(
|
|
45162
45192
|
200,
|
|
45163
45193
|
{ app: opts.app, revokedIntegrities: [], version: 0, ttlSeconds: 30 },
|
|
45164
45194
|
{ "cache-control": "max-age=30" }
|
|
45165
45195
|
);
|
|
45166
45196
|
}
|
|
45167
|
-
if (
|
|
45197
|
+
if (path2.startsWith("/v1/flags/")) {
|
|
45168
45198
|
return json4(200, { app: opts.app, definitions: {} }, { "cache-control": "no-store" });
|
|
45169
45199
|
}
|
|
45170
|
-
if (
|
|
45200
|
+
if (path2 === "/v1/telemetry/ingest") {
|
|
45171
45201
|
if (request.method !== "POST") return json4(405, { error: "method_not_allowed" });
|
|
45172
45202
|
try {
|
|
45173
45203
|
const body = await request.json();
|
|
@@ -45177,33 +45207,33 @@ function makeRunHandler(opts) {
|
|
|
45177
45207
|
}
|
|
45178
45208
|
return new Response(null, { status: 204 });
|
|
45179
45209
|
}
|
|
45180
|
-
if (
|
|
45210
|
+
if (path2 === "/v1/screen-events") {
|
|
45181
45211
|
return new Response(new ReadableStream({ start() {
|
|
45182
45212
|
} }), {
|
|
45183
45213
|
status: 200,
|
|
45184
45214
|
headers: { "content-type": "text/event-stream", "cache-control": "no-store", connection: "keep-alive" }
|
|
45185
45215
|
});
|
|
45186
45216
|
}
|
|
45187
|
-
if (
|
|
45217
|
+
if (path2.startsWith("/v1/__webwix/") && path2 !== "/v1/__webwix/call" && path2 !== "/v1/__webwix/identity" && !(opts.serve?.webwixMemberAuth === true && opts.serve?.webwixMemberSessions)) {
|
|
45188
45218
|
return json4(501, { error: "webwix_member_auth_unavailable" });
|
|
45189
45219
|
}
|
|
45190
|
-
if (
|
|
45220
|
+
if (path2 === "/v1/app-config" || path2.startsWith("/v1/app-config/")) {
|
|
45191
45221
|
return localizeConfigResponse(await serve(request), "app-config", opts.header ?? null);
|
|
45192
45222
|
}
|
|
45193
|
-
if (
|
|
45223
|
+
if (path2 === "/v1/boot") {
|
|
45194
45224
|
return localizeConfigResponse(await serve(request), "boot", opts.header ?? null);
|
|
45195
45225
|
}
|
|
45196
|
-
if (
|
|
45226
|
+
if (path2 === "/v1" || path2.startsWith("/v1/") || path2 === "/__health") {
|
|
45197
45227
|
return serve(request);
|
|
45198
45228
|
}
|
|
45199
|
-
if (
|
|
45229
|
+
if (path2 === "/" || path2 === "") {
|
|
45200
45230
|
const target = `${mount}/a/${encodeURIComponent(opts.app)}${url.search}`;
|
|
45201
45231
|
return new Response(null, { status: 302, headers: { location: target } });
|
|
45202
45232
|
}
|
|
45203
|
-
if (
|
|
45204
|
-
return previewResponse(
|
|
45233
|
+
if (path2 === mount || path2.startsWith(`${mount}/`)) {
|
|
45234
|
+
return previewResponse(path2, opts.assets, mount);
|
|
45205
45235
|
}
|
|
45206
|
-
return json4(404, { error: "not_found", path });
|
|
45236
|
+
return json4(404, { error: "not_found", path: path2 });
|
|
45207
45237
|
};
|
|
45208
45238
|
}
|
|
45209
45239
|
var json4;
|
|
@@ -45412,9 +45442,9 @@ async function loadPreviewAssets() {
|
|
|
45412
45442
|
join46(here, "../../../packages/serve/src/preview-assets.generated.bin")
|
|
45413
45443
|
// in-repo checkout
|
|
45414
45444
|
];
|
|
45415
|
-
for (const
|
|
45416
|
-
if (!existsSync49(
|
|
45417
|
-
const blob = readFileSync54(
|
|
45445
|
+
for (const path2 of candidates) {
|
|
45446
|
+
if (!existsSync49(path2)) continue;
|
|
45447
|
+
const blob = readFileSync54(path2);
|
|
45418
45448
|
return mod.assemblePreviewAssetsFromBlob(new Uint8Array(blob.buffer, blob.byteOffset, blob.byteLength));
|
|
45419
45449
|
}
|
|
45420
45450
|
return /* @__PURE__ */ new Map();
|
|
@@ -45424,9 +45454,9 @@ async function loadPreviewAssets() {
|
|
|
45424
45454
|
}
|
|
45425
45455
|
function packageUrl(origin, app, opts = {}) {
|
|
45426
45456
|
const mount = opts.chrome === "app" ? "/app" : "/preview";
|
|
45427
|
-
const
|
|
45457
|
+
const path2 = `${mount}/a/${encodeURIComponent(app)}${opts.screen ? `/screen/${encodeURIComponent(opts.screen)}` : ""}`;
|
|
45428
45458
|
const query = opts.surface ? `?surface=${encodeURIComponent(opts.surface)}` : "";
|
|
45429
|
-
return `${origin.replace(/\/$/, "")}${
|
|
45459
|
+
return `${origin.replace(/\/$/, "")}${path2}${query}`;
|
|
45430
45460
|
}
|
|
45431
45461
|
function openBrowser(url) {
|
|
45432
45462
|
const cmd = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
|
|
@@ -45586,13 +45616,13 @@ async function runInBrowser(releaseRoot, app, header, opts = {}) {
|
|
|
45586
45616
|
const body = JSON.stringify(payload);
|
|
45587
45617
|
const missed = [];
|
|
45588
45618
|
const server = createServer5((req, res) => {
|
|
45589
|
-
const
|
|
45590
|
-
if (
|
|
45619
|
+
const path2 = (req.url ?? "/").split("?")[0];
|
|
45620
|
+
if (path2 === "/release.json") {
|
|
45591
45621
|
res.writeHead(200, { "content-type": "application/json", "cache-control": "no-store" });
|
|
45592
45622
|
res.end(body);
|
|
45593
45623
|
return;
|
|
45594
45624
|
}
|
|
45595
|
-
const name =
|
|
45625
|
+
const name = path2 === "/" || path2 === "/index.html" ? "host.html" : path2.slice(1);
|
|
45596
45626
|
if (SERVED.has(name)) {
|
|
45597
45627
|
if (!existsSync50(resolve40(stagedDir(), name))) {
|
|
45598
45628
|
const restaged = ensureBrowserPlaneStaged();
|
|
@@ -45619,9 +45649,9 @@ async function runInBrowser(releaseRoot, app, header, opts = {}) {
|
|
|
45619
45649
|
res.end(bytes2);
|
|
45620
45650
|
return;
|
|
45621
45651
|
}
|
|
45622
|
-
missed.push(
|
|
45652
|
+
missed.push(path2);
|
|
45623
45653
|
res.writeHead(404, { "content-type": "application/json" });
|
|
45624
|
-
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 }));
|
|
45625
45655
|
});
|
|
45626
45656
|
await new Promise((r) => server.listen(opts.port ?? 0, "127.0.0.1", () => r()));
|
|
45627
45657
|
const port = server.address().port;
|
|
@@ -46831,8 +46861,8 @@ function client(creds) {
|
|
|
46831
46861
|
const env = creds ?? requireEnv(["ASC_KEY_ID", "ASC_ISSUER_ID", "ASC_KEY_PATH"]);
|
|
46832
46862
|
assertCredentialOutsideRepo("ASC_KEY_PATH", env.ASC_KEY_PATH);
|
|
46833
46863
|
const jwt = ascJwt(env.ASC_KEY_ID, env.ASC_ISSUER_ID, readFileSync61(env.ASC_KEY_PATH, "utf8"), Math.floor(Date.now() / 1e3));
|
|
46834
|
-
return async (
|
|
46835
|
-
const r = await fetch(`${ASC}${
|
|
46864
|
+
return async (path2) => {
|
|
46865
|
+
const r = await fetch(`${ASC}${path2}`, { headers: { Authorization: `Bearer ${jwt}` } });
|
|
46836
46866
|
return { status: r.status, json: await r.json().catch(() => ({})) };
|
|
46837
46867
|
};
|
|
46838
46868
|
}
|
|
@@ -47092,24 +47122,24 @@ import { dirname as dirname29, join as join49 } from "node:path";
|
|
|
47092
47122
|
function defaultSessionsPath() {
|
|
47093
47123
|
return process.env.HIMI_ADMIN_SESSIONS_FILE ?? join49(homedir6(), ".himalaya", "admin-sessions.json");
|
|
47094
47124
|
}
|
|
47095
|
-
function loadSessionsFile(
|
|
47125
|
+
function loadSessionsFile(path2 = defaultSessionsPath()) {
|
|
47096
47126
|
try {
|
|
47097
|
-
return JSON.parse(readFileSync63(
|
|
47127
|
+
return JSON.parse(readFileSync63(path2, "utf8"));
|
|
47098
47128
|
} catch {
|
|
47099
47129
|
return {};
|
|
47100
47130
|
}
|
|
47101
47131
|
}
|
|
47102
|
-
function saveAdminSession(adminUrl, session,
|
|
47103
|
-
const file = loadSessionsFile(
|
|
47132
|
+
function saveAdminSession(adminUrl, session, path2 = defaultSessionsPath()) {
|
|
47133
|
+
const file = loadSessionsFile(path2);
|
|
47104
47134
|
file.sessions = { ...file.sessions, [adminUrl]: session };
|
|
47105
|
-
mkdirSync24(dirname29(
|
|
47106
|
-
writeFileSync21(
|
|
47135
|
+
mkdirSync24(dirname29(path2), { recursive: true, mode: 448 });
|
|
47136
|
+
writeFileSync21(path2, JSON.stringify(file, null, 2) + "\n", { mode: 384 });
|
|
47107
47137
|
try {
|
|
47108
|
-
chmodSync3(dirname29(
|
|
47109
|
-
chmodSync3(
|
|
47138
|
+
chmodSync3(dirname29(path2), 448);
|
|
47139
|
+
chmodSync3(path2, 384);
|
|
47110
47140
|
} catch {
|
|
47111
47141
|
}
|
|
47112
|
-
return
|
|
47142
|
+
return path2;
|
|
47113
47143
|
}
|
|
47114
47144
|
function resolveAuth(opts = {}) {
|
|
47115
47145
|
const env = opts.env ?? process.env;
|
|
@@ -47415,9 +47445,9 @@ var init_types2 = __esm({
|
|
|
47415
47445
|
});
|
|
47416
47446
|
|
|
47417
47447
|
// src/site-analyze/rest.ts
|
|
47418
|
-
function resolveWixUrl(
|
|
47419
|
-
if (/^https?:\/\//i.test(
|
|
47420
|
-
return `${WIX_API3}${
|
|
47448
|
+
function resolveWixUrl(path2) {
|
|
47449
|
+
if (/^https?:\/\//i.test(path2)) return path2;
|
|
47450
|
+
return `${WIX_API3}${path2}`;
|
|
47421
47451
|
}
|
|
47422
47452
|
function classifyHttp(status, count) {
|
|
47423
47453
|
if (status === 428) return "not-installed";
|
|
@@ -47426,12 +47456,12 @@ function classifyHttp(status, count) {
|
|
|
47426
47456
|
return count > 0 ? "ok" : "empty";
|
|
47427
47457
|
}
|
|
47428
47458
|
function makeTransport(fetchImpl, auth, timeoutMs = DEFAULT_TIMEOUT_MS4) {
|
|
47429
|
-
return async (method,
|
|
47459
|
+
return async (method, path2, body) => {
|
|
47430
47460
|
const headers2 = { Accept: "application/json" };
|
|
47431
47461
|
if (auth?.token) headers2.Authorization = auth.token;
|
|
47432
47462
|
if (auth?.msid) headers2["wix-site-id"] = auth.msid;
|
|
47433
47463
|
if (body !== void 0) headers2["Content-Type"] = "application/json";
|
|
47434
|
-
const res = await fetchImpl(resolveWixUrl(
|
|
47464
|
+
const res = await fetchImpl(resolveWixUrl(path2), {
|
|
47435
47465
|
method,
|
|
47436
47466
|
headers: headers2,
|
|
47437
47467
|
body: body === void 0 ? void 0 : JSON.stringify(body),
|
|
@@ -47443,7 +47473,7 @@ function makeTransport(fetchImpl, auth, timeoutMs = DEFAULT_TIMEOUT_MS4) {
|
|
|
47443
47473
|
parsed = text4 ? JSON.parse(text4) : null;
|
|
47444
47474
|
} catch {
|
|
47445
47475
|
}
|
|
47446
|
-
if (!res.ok) throw new WixApiError2(res.status, method,
|
|
47476
|
+
if (!res.ok) throw new WixApiError2(res.status, method, path2, parsed);
|
|
47447
47477
|
return parsed;
|
|
47448
47478
|
};
|
|
47449
47479
|
}
|
|
@@ -47453,9 +47483,9 @@ function ownerTransportFrom(fetchImpl, owner) {
|
|
|
47453
47483
|
function visitorTransportFrom(fetchImpl, token, msid) {
|
|
47454
47484
|
return makeTransport(fetchImpl, { token, msid });
|
|
47455
47485
|
}
|
|
47456
|
-
async function probeCall(call, method,
|
|
47486
|
+
async function probeCall(call, method, path2, body) {
|
|
47457
47487
|
try {
|
|
47458
|
-
return { data: await call(method,
|
|
47488
|
+
return { data: await call(method, path2, body), err: null };
|
|
47459
47489
|
} catch (e) {
|
|
47460
47490
|
if (e instanceof WixApiError2) return { data: null, err: e };
|
|
47461
47491
|
throw e;
|
|
@@ -47517,11 +47547,11 @@ var init_rest = __esm({
|
|
|
47517
47547
|
WIX_API3 = "https://www.wixapis.com";
|
|
47518
47548
|
DEFAULT_TIMEOUT_MS4 = 8e3;
|
|
47519
47549
|
WixApiError2 = class extends Error {
|
|
47520
|
-
constructor(status, method,
|
|
47521
|
-
super(`${method} ${
|
|
47550
|
+
constructor(status, method, path2, body) {
|
|
47551
|
+
super(`${method} ${path2} \u2192 ${status}`);
|
|
47522
47552
|
this.status = status;
|
|
47523
47553
|
this.method = method;
|
|
47524
|
-
this.path =
|
|
47554
|
+
this.path = path2;
|
|
47525
47555
|
this.body = body;
|
|
47526
47556
|
this.name = "WixApiError";
|
|
47527
47557
|
}
|
|
@@ -47729,8 +47759,8 @@ function toItems(def, raw) {
|
|
|
47729
47759
|
description: copyOrDrop(def.descriptionOf ? def.descriptionOf(it) : genericDescription(it), 240) || void 0
|
|
47730
47760
|
}));
|
|
47731
47761
|
}
|
|
47732
|
-
async function runDualProbes(owner, visitor) {
|
|
47733
|
-
const rows = await Promise.all(
|
|
47762
|
+
async function runDualProbes(owner, visitor, definitions2 = ALL) {
|
|
47763
|
+
const rows = await Promise.all(definitions2.map(async (def) => {
|
|
47734
47764
|
const [o, vis] = await Promise.all([side(owner, def), side(visitor, def)]);
|
|
47735
47765
|
const imageless = def.imageOf ? o.items.filter((it) => !def.imageOf(it)).length : void 0;
|
|
47736
47766
|
return {
|
|
@@ -47792,7 +47822,7 @@ function sampleTitle(data) {
|
|
|
47792
47822
|
}
|
|
47793
47823
|
return void 0;
|
|
47794
47824
|
}
|
|
47795
|
-
async function readCms(call) {
|
|
47825
|
+
async function readCms(call, opts = {}) {
|
|
47796
47826
|
if (!call) return { collections: [], status: "skipped" };
|
|
47797
47827
|
const { data, err } = await probeCall(call, "GET", "/data/v2/collections");
|
|
47798
47828
|
if (err) {
|
|
@@ -47817,7 +47847,7 @@ async function readCms(call) {
|
|
|
47817
47847
|
...f.encrypted === true ? { encrypted: true } : {}
|
|
47818
47848
|
})).filter((f) => f.key);
|
|
47819
47849
|
const perms = c.permissions && typeof c.permissions === "object" ? c.permissions : void 0;
|
|
47820
|
-
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", {
|
|
47821
47851
|
dataCollectionId: id,
|
|
47822
47852
|
query: { paging: { limit: 5 } }
|
|
47823
47853
|
});
|
|
@@ -47854,8 +47884,8 @@ async function readInstalledApps(call) {
|
|
|
47854
47884
|
"/site-apps/v1/apps",
|
|
47855
47885
|
"/devcenter/v1/apps"
|
|
47856
47886
|
];
|
|
47857
|
-
for (const
|
|
47858
|
-
const { data } = await probeCall(call, "GET",
|
|
47887
|
+
for (const path2 of paths) {
|
|
47888
|
+
const { data } = await probeCall(call, "GET", path2);
|
|
47859
47889
|
if (!data) continue;
|
|
47860
47890
|
const raw = asArr(data.apps ?? data.siteApps ?? data.items);
|
|
47861
47891
|
const apps = raw.map((a) => ({
|
|
@@ -47871,8 +47901,8 @@ async function readMemberRoles(call) {
|
|
|
47871
47901
|
const paths = ["/members/v1/roles", "/members/v2/roles", "/authorization/v1/roles"];
|
|
47872
47902
|
let sawAuthError = false;
|
|
47873
47903
|
let sawEmptyPayload = false;
|
|
47874
|
-
for (const
|
|
47875
|
-
const { data, err } = await probeCall(call, "GET",
|
|
47904
|
+
for (const path2 of paths) {
|
|
47905
|
+
const { data, err } = await probeCall(call, "GET", path2);
|
|
47876
47906
|
if (err) {
|
|
47877
47907
|
if (err.status === 401 || err.status === 403 || err.status >= 500) sawAuthError = true;
|
|
47878
47908
|
continue;
|
|
@@ -48343,15 +48373,15 @@ function pagePathForRole(url) {
|
|
|
48343
48373
|
}
|
|
48344
48374
|
}
|
|
48345
48375
|
function classifyPageRole(url, title, _nav = "") {
|
|
48346
|
-
const { path, isHome } = pagePathForRole(url);
|
|
48376
|
+
const { path: path2, isHome } = pagePathForRole(url);
|
|
48347
48377
|
if (isHome) return "home";
|
|
48348
|
-
const hay = `${
|
|
48378
|
+
const hay = `${path2} ${title}`.toLowerCase();
|
|
48349
48379
|
if (/\b(faq|help|support)\b/.test(hay)) return "faq";
|
|
48350
48380
|
if (/\b(pricing|membership|member-plan|plans?)\b/.test(hay)) return "plans";
|
|
48351
48381
|
if (/\b(drill|library|resource|session-builder|session-generator)\b/.test(hay)) return "library";
|
|
48352
48382
|
if (/\b(members?|account|login|profile)\b/.test(hay) && !/\bmembership\b/.test(hay)) return "members";
|
|
48353
48383
|
if (/\b(shop|store|product|cart)\b/.test(hay)) return "shop";
|
|
48354
|
-
if (/(^|\/)(book|book-online|bookings?)(\/|$)/.test(
|
|
48384
|
+
if (/(^|\/)(book|book-online|bookings?)(\/|$)/.test(path2) || /\b(book-online|bookings?|appoint)\b/.test(hay)) return "book";
|
|
48355
48385
|
if (/\b(menu|dining|restaurant)\b/.test(hay)) return "menu";
|
|
48356
48386
|
if (/\b(blog|journal|news|posts?|ebooks?|insight)\b/.test(hay)) return "blog";
|
|
48357
48387
|
if (/\b(about|story|our-story)\b/.test(hay)) return "about";
|
|
@@ -49005,12 +49035,12 @@ function veloListFilesPath(gridAppId, layout) {
|
|
|
49005
49035
|
async function gridAppIdFromSiteHtml(fetchImpl, siteUrl) {
|
|
49006
49036
|
return (await readPublishedHtml(fetchImpl, siteUrl)).gridAppId;
|
|
49007
49037
|
}
|
|
49008
|
-
function assertSafeVeloPath(
|
|
49009
|
-
if (VELO_INVOKE_RE.test(
|
|
49010
|
-
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}`);
|
|
49011
49041
|
}
|
|
49012
|
-
if (method !== "GET" && VELO_WRITE_RE.test(
|
|
49013
|
-
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}`);
|
|
49014
49044
|
}
|
|
49015
49045
|
}
|
|
49016
49046
|
function parseHttpFunctions(source) {
|
|
@@ -49029,8 +49059,8 @@ function parseHttpFunctions(source) {
|
|
|
49029
49059
|
}
|
|
49030
49060
|
return out;
|
|
49031
49061
|
}
|
|
49032
|
-
function classifyVeloFile(
|
|
49033
|
-
const p =
|
|
49062
|
+
function classifyVeloFile(path2) {
|
|
49063
|
+
const p = path2.replace(/\\/g, "/").toLowerCase();
|
|
49034
49064
|
const base = p.split("/").pop() ?? p;
|
|
49035
49065
|
if (base === "http-functions.js" || base === "http-functions.ts") return "http-functions";
|
|
49036
49066
|
if (base === "data.js" || base === "data.ts") return "data-hooks";
|
|
@@ -49042,8 +49072,8 @@ function classifyVeloFile(path) {
|
|
|
49042
49072
|
if (/(^|\/)public\//.test(p)) return "public";
|
|
49043
49073
|
return "other";
|
|
49044
49074
|
}
|
|
49045
|
-
function isSecretVeloPath(
|
|
49046
|
-
const p =
|
|
49075
|
+
function isSecretVeloPath(path2) {
|
|
49076
|
+
const p = path2.replace(/\\/g, "/").toLowerCase();
|
|
49047
49077
|
return /secrets-backend|\/secrets\/|\.env(?:\.|$)/.test(p);
|
|
49048
49078
|
}
|
|
49049
49079
|
function redactSecrets(source) {
|
|
@@ -49073,7 +49103,7 @@ function str4(x) {
|
|
|
49073
49103
|
function asArr2(x) {
|
|
49074
49104
|
return Array.isArray(x) ? x : [];
|
|
49075
49105
|
}
|
|
49076
|
-
function filesFromOwnerPayload(data) {
|
|
49106
|
+
function filesFromOwnerPayload(data, redact = redactSecrets) {
|
|
49077
49107
|
if (!data || typeof data !== "object") return [];
|
|
49078
49108
|
const root = data;
|
|
49079
49109
|
const raw = [
|
|
@@ -49085,17 +49115,17 @@ function filesFromOwnerPayload(data) {
|
|
|
49085
49115
|
for (const item of raw) {
|
|
49086
49116
|
if (!item || typeof item !== "object") continue;
|
|
49087
49117
|
const f = item;
|
|
49088
|
-
const
|
|
49089
|
-
if (!
|
|
49118
|
+
const path2 = str4(f.path || f.relativePath || f.fileName || f.name);
|
|
49119
|
+
if (!path2 || isSecretVeloPath(path2)) continue;
|
|
49090
49120
|
const content = str4(f.content ?? f.source ?? f.code ?? f.body);
|
|
49091
49121
|
const bytes2 = typeof f.bytes === "number" ? f.bytes : typeof f.size === "number" ? f.size : content.length;
|
|
49092
|
-
const redacted = content ?
|
|
49122
|
+
const redacted = content ? redact(content) : "";
|
|
49093
49123
|
const forDisk = redacted.length > VELO_FILE_CAP ? redacted.slice(0, VELO_FILE_CAP) + "\n/* \u2026truncated */" : redacted;
|
|
49094
49124
|
out.push({
|
|
49095
|
-
path,
|
|
49096
|
-
kind: classifyVeloFile(
|
|
49125
|
+
path: path2,
|
|
49126
|
+
kind: classifyVeloFile(path2),
|
|
49097
49127
|
bytes: bytes2,
|
|
49098
|
-
excerpt: content ? redactExcerpt(
|
|
49128
|
+
excerpt: content ? redactExcerpt(redacted) : void 0,
|
|
49099
49129
|
...forDisk ? { content: forDisk } : {}
|
|
49100
49130
|
});
|
|
49101
49131
|
}
|
|
@@ -49138,8 +49168,8 @@ function veloHintFromEval(evaled, page) {
|
|
|
49138
49168
|
pages: [{ url: page.url, title: page.title, hasCode: wixRendered && hasCode, ...pageId ? { pageId } : {} }]
|
|
49139
49169
|
};
|
|
49140
49170
|
}
|
|
49141
|
-
function pageIdFromVeloPath(
|
|
49142
|
-
const m =
|
|
49171
|
+
function pageIdFromVeloPath(path2) {
|
|
49172
|
+
const m = path2.replace(/\\/g, "/").match(/\/pages\/([A-Za-z0-9_-]+)\.(js|ts|jsx|tsx)$/i);
|
|
49143
49173
|
return m?.[1];
|
|
49144
49174
|
}
|
|
49145
49175
|
function bindVeloFiles(files, pages) {
|
|
@@ -49184,13 +49214,13 @@ function gridAppIdsFromPayload(data) {
|
|
|
49184
49214
|
}
|
|
49185
49215
|
return ids;
|
|
49186
49216
|
}
|
|
49187
|
-
async function listFilesForApp(call, gridAppId) {
|
|
49217
|
+
async function listFilesForApp(call, gridAppId, redact) {
|
|
49188
49218
|
for (const layout of VELO_LAYOUTS) {
|
|
49189
|
-
const
|
|
49190
|
-
assertSafeVeloPath(
|
|
49191
|
-
const { data } = await probeCall(call, "GET",
|
|
49219
|
+
const path2 = veloListFilesPath(gridAppId, layout);
|
|
49220
|
+
assertSafeVeloPath(path2, "GET");
|
|
49221
|
+
const { data } = await probeCall(call, "GET", path2);
|
|
49192
49222
|
if (!data) continue;
|
|
49193
|
-
const files = filesFromOwnerPayload(data);
|
|
49223
|
+
const files = filesFromOwnerPayload(data, redact);
|
|
49194
49224
|
if (files.length) return files;
|
|
49195
49225
|
}
|
|
49196
49226
|
return [];
|
|
@@ -49212,7 +49242,7 @@ async function readOwnerVelo(call, opts) {
|
|
|
49212
49242
|
if (probe.path.includes("git-repo") && (data.repo || data.repository || data.gitRepo || data.url)) git2 = true;
|
|
49213
49243
|
}
|
|
49214
49244
|
for (const id of ids) {
|
|
49215
|
-
const listed = await listFilesForApp(call, id);
|
|
49245
|
+
const listed = await listFilesForApp(call, id, opts?.redact);
|
|
49216
49246
|
for (const f of listed) {
|
|
49217
49247
|
if (!files.some((x) => x.path === f.path)) files.push(f);
|
|
49218
49248
|
}
|
|
@@ -49549,14 +49579,14 @@ function parseAuthorizationConfig(source) {
|
|
|
49549
49579
|
const defaultAnonymousInvoke = invokeFlag(starDefault, "anonymous") ?? true;
|
|
49550
49580
|
const defaultSiteMemberInvoke = invokeFlag(starDefault, "siteMember") ?? true;
|
|
49551
49581
|
const modules = [];
|
|
49552
|
-
for (const [
|
|
49553
|
-
if (
|
|
49582
|
+
for (const [path2, entry] of Object.entries(web)) {
|
|
49583
|
+
if (path2 === "*") continue;
|
|
49554
49584
|
const star = methodStar(entry);
|
|
49555
49585
|
const anonymousInvoke = invokeFlag(star, "anonymous") ?? defaultAnonymousInvoke;
|
|
49556
49586
|
const siteMemberInvoke = invokeFlag(star, "siteMember") ?? defaultSiteMemberInvoke;
|
|
49557
|
-
const jsw = /\.(jsw|web\.js)$/i.test(
|
|
49587
|
+
const jsw = /\.(jsw|web\.js)$/i.test(path2);
|
|
49558
49588
|
modules.push({
|
|
49559
|
-
path,
|
|
49589
|
+
path: path2,
|
|
49560
49590
|
anonymousInvoke,
|
|
49561
49591
|
siteMemberInvoke,
|
|
49562
49592
|
...jsw ? { note: "worker-unreachable" } : {}
|
|
@@ -50695,12 +50725,12 @@ function attachVeloSources(book, sources, put) {
|
|
|
50695
50725
|
}
|
|
50696
50726
|
}
|
|
50697
50727
|
function extOf2(url) {
|
|
50698
|
-
const
|
|
50699
|
-
if (/\.png$/i.test(
|
|
50700
|
-
if (/\.webp$/i.test(
|
|
50701
|
-
if (/\.gif$/i.test(
|
|
50702
|
-
if (/\.svg$/i.test(
|
|
50703
|
-
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";
|
|
50704
50734
|
return "jpg";
|
|
50705
50735
|
}
|
|
50706
50736
|
async function readCapped(res, cap) {
|
|
@@ -51271,8 +51301,8 @@ function unpairedRedirectNote(overlay) {
|
|
|
51271
51301
|
function posix2(p) {
|
|
51272
51302
|
return resolve42(p).replace(/\\/g, "/");
|
|
51273
51303
|
}
|
|
51274
|
-
function committedShellProvisioning(
|
|
51275
|
-
return committedShellFor(posix2(
|
|
51304
|
+
function committedShellProvisioning(path2) {
|
|
51305
|
+
return committedShellFor(posix2(path2));
|
|
51276
51306
|
}
|
|
51277
51307
|
function findRepoRoot(cwd) {
|
|
51278
51308
|
let dir = cwd;
|
|
@@ -51296,14 +51326,14 @@ function deepMerge4(a, b) {
|
|
|
51296
51326
|
}
|
|
51297
51327
|
return out;
|
|
51298
51328
|
}
|
|
51299
|
-
function assertNotCommitted(
|
|
51300
|
-
const committed = committedShellProvisioning(
|
|
51329
|
+
function assertNotCommitted(path2, forbidden) {
|
|
51330
|
+
const committed = committedShellProvisioning(path2);
|
|
51301
51331
|
if (committed) {
|
|
51302
51332
|
throw new Error(
|
|
51303
51333
|
`refusing to overwrite committed ${committedProvisioningPath(committed)} \u2014 use prepare:customer --contract`
|
|
51304
51334
|
);
|
|
51305
51335
|
}
|
|
51306
|
-
if (forbidden && resolve42(
|
|
51336
|
+
if (forbidden && resolve42(path2) === resolve42(forbidden)) {
|
|
51307
51337
|
const named = committedShellProvisioning(forbidden);
|
|
51308
51338
|
throw new Error(
|
|
51309
51339
|
`refusing to overwrite committed ${named ? committedProvisioningPath(named) : forbidden} \u2014 pass a content-package provisioning.json or use prepare:customer --contract`
|
|
@@ -51409,13 +51439,13 @@ function buildMergedContract(options) {
|
|
|
51409
51439
|
merged.branding = branding;
|
|
51410
51440
|
const body = `${JSON.stringify(merged, null, 2)}
|
|
51411
51441
|
`;
|
|
51412
|
-
const
|
|
51413
|
-
writeFileSync23(
|
|
51442
|
+
const path2 = join51(packageDir, "provisioning.contract.json");
|
|
51443
|
+
writeFileSync23(path2, body);
|
|
51414
51444
|
const localPath = join51(appDir2, LOCAL_CONTRACT_REL);
|
|
51415
51445
|
mkdirSync26(dirname30(localPath), { recursive: true });
|
|
51416
51446
|
writeFileSync23(localPath, body);
|
|
51417
51447
|
staged.push(localPath);
|
|
51418
|
-
return { path, staged };
|
|
51448
|
+
return { path: path2, staged };
|
|
51419
51449
|
}
|
|
51420
51450
|
async function applyOverlays(input) {
|
|
51421
51451
|
const cwd = resolve42(input.cwd);
|
|
@@ -52847,18 +52877,18 @@ function cookieCompare(a, b) {
|
|
|
52847
52877
|
cmp = (a.creationIndex || 0) - (b.creationIndex || 0);
|
|
52848
52878
|
return cmp;
|
|
52849
52879
|
}
|
|
52850
|
-
function defaultPath(
|
|
52851
|
-
if (!
|
|
52880
|
+
function defaultPath(path2) {
|
|
52881
|
+
if (!path2 || path2.slice(0, 1) !== "/") {
|
|
52852
52882
|
return "/";
|
|
52853
52883
|
}
|
|
52854
|
-
if (
|
|
52855
|
-
return
|
|
52884
|
+
if (path2 === "/") {
|
|
52885
|
+
return path2;
|
|
52856
52886
|
}
|
|
52857
|
-
const rightSlash =
|
|
52887
|
+
const rightSlash = path2.lastIndexOf("/");
|
|
52858
52888
|
if (rightSlash === 0) {
|
|
52859
52889
|
return "/";
|
|
52860
52890
|
}
|
|
52861
|
-
return
|
|
52891
|
+
return path2.slice(0, rightSlash);
|
|
52862
52892
|
}
|
|
52863
52893
|
function domainMatch(domain, cookieDomain, canonicalize) {
|
|
52864
52894
|
if (domain == null || cookieDomain == null) {
|
|
@@ -53086,18 +53116,18 @@ var init_dist = __esm({
|
|
|
53086
53116
|
/**
|
|
53087
53117
|
* @internal No doc because this is an overload that supports the implementation
|
|
53088
53118
|
*/
|
|
53089
|
-
findCookie(domain,
|
|
53119
|
+
findCookie(domain, path2, key2, callback) {
|
|
53090
53120
|
const promiseCallback = createPromiseCallback(callback);
|
|
53091
|
-
if (domain == null ||
|
|
53121
|
+
if (domain == null || path2 == null || key2 == null) {
|
|
53092
53122
|
return promiseCallback.resolve(void 0);
|
|
53093
53123
|
}
|
|
53094
|
-
const result = this.idx[domain]?.[
|
|
53124
|
+
const result = this.idx[domain]?.[path2]?.[key2];
|
|
53095
53125
|
return promiseCallback.resolve(result);
|
|
53096
53126
|
}
|
|
53097
53127
|
/**
|
|
53098
53128
|
* @internal No doc because this is an overload that supports the implementation
|
|
53099
53129
|
*/
|
|
53100
|
-
findCookies(domain,
|
|
53130
|
+
findCookies(domain, path2, allowSpecialUseDomain = false, callback) {
|
|
53101
53131
|
if (typeof allowSpecialUseDomain === "function") {
|
|
53102
53132
|
callback = allowSpecialUseDomain;
|
|
53103
53133
|
allowSpecialUseDomain = true;
|
|
@@ -53108,7 +53138,7 @@ var init_dist = __esm({
|
|
|
53108
53138
|
return promiseCallback.resolve([]);
|
|
53109
53139
|
}
|
|
53110
53140
|
let pathMatcher;
|
|
53111
|
-
if (!
|
|
53141
|
+
if (!path2) {
|
|
53112
53142
|
pathMatcher = function matchAll(domainIndex) {
|
|
53113
53143
|
for (const curPath in domainIndex) {
|
|
53114
53144
|
const pathIndex = domainIndex[curPath];
|
|
@@ -53123,7 +53153,7 @@ var init_dist = __esm({
|
|
|
53123
53153
|
} else {
|
|
53124
53154
|
pathMatcher = function matchRFC(domainIndex) {
|
|
53125
53155
|
for (const cookiePath in domainIndex) {
|
|
53126
|
-
if (pathMatch(
|
|
53156
|
+
if (pathMatch(path2, cookiePath)) {
|
|
53127
53157
|
const pathIndex = domainIndex[cookiePath];
|
|
53128
53158
|
for (const key2 in pathIndex) {
|
|
53129
53159
|
const value = pathIndex[key2];
|
|
@@ -53151,14 +53181,14 @@ var init_dist = __esm({
|
|
|
53151
53181
|
*/
|
|
53152
53182
|
putCookie(cookie, callback) {
|
|
53153
53183
|
const promiseCallback = createPromiseCallback(callback);
|
|
53154
|
-
const { domain, path, key: key2 } = cookie;
|
|
53155
|
-
if (domain == null ||
|
|
53184
|
+
const { domain, path: path2, key: key2 } = cookie;
|
|
53185
|
+
if (domain == null || path2 == null || key2 == null) {
|
|
53156
53186
|
return promiseCallback.resolve(void 0);
|
|
53157
53187
|
}
|
|
53158
53188
|
const domainEntry = this.idx[domain] ?? /* @__PURE__ */ Object.create(null);
|
|
53159
53189
|
this.idx[domain] = domainEntry;
|
|
53160
|
-
const pathEntry = domainEntry[
|
|
53161
|
-
domainEntry[
|
|
53190
|
+
const pathEntry = domainEntry[path2] ?? /* @__PURE__ */ Object.create(null);
|
|
53191
|
+
domainEntry[path2] = pathEntry;
|
|
53162
53192
|
pathEntry[key2] = cookie;
|
|
53163
53193
|
return promiseCallback.resolve(void 0);
|
|
53164
53194
|
}
|
|
@@ -53172,20 +53202,20 @@ var init_dist = __esm({
|
|
|
53172
53202
|
/**
|
|
53173
53203
|
* @internal No doc because this is an overload that supports the implementation
|
|
53174
53204
|
*/
|
|
53175
|
-
removeCookie(domain,
|
|
53205
|
+
removeCookie(domain, path2, key2, callback) {
|
|
53176
53206
|
const promiseCallback = createPromiseCallback(callback);
|
|
53177
|
-
delete this.idx[domain]?.[
|
|
53207
|
+
delete this.idx[domain]?.[path2]?.[key2];
|
|
53178
53208
|
return promiseCallback.resolve(void 0);
|
|
53179
53209
|
}
|
|
53180
53210
|
/**
|
|
53181
53211
|
* @internal No doc because this is an overload that supports the implementation
|
|
53182
53212
|
*/
|
|
53183
|
-
removeCookies(domain,
|
|
53213
|
+
removeCookies(domain, path2, callback) {
|
|
53184
53214
|
const promiseCallback = createPromiseCallback(callback);
|
|
53185
53215
|
const domainEntry = this.idx[domain];
|
|
53186
53216
|
if (domainEntry) {
|
|
53187
|
-
if (
|
|
53188
|
-
delete domainEntry[
|
|
53217
|
+
if (path2) {
|
|
53218
|
+
delete domainEntry[path2];
|
|
53189
53219
|
} else {
|
|
53190
53220
|
delete this.idx[domain];
|
|
53191
53221
|
}
|
|
@@ -53211,8 +53241,8 @@ var init_dist = __esm({
|
|
|
53211
53241
|
domains.forEach((domain) => {
|
|
53212
53242
|
const domainEntry = idx[domain] ?? {};
|
|
53213
53243
|
const paths = Object.keys(domainEntry);
|
|
53214
|
-
paths.forEach((
|
|
53215
|
-
const pathEntry = domainEntry[
|
|
53244
|
+
paths.forEach((path2) => {
|
|
53245
|
+
const pathEntry = domainEntry[path2] ?? {};
|
|
53216
53246
|
const keys = Object.keys(pathEntry);
|
|
53217
53247
|
keys.forEach((key2) => {
|
|
53218
53248
|
const keyEntry = pathEntry[key2];
|
|
@@ -53980,7 +54010,7 @@ var init_dist = __esm({
|
|
|
53980
54010
|
return promiseCallback.reject(parameterError);
|
|
53981
54011
|
}
|
|
53982
54012
|
const host = canonicalDomain(context.hostname);
|
|
53983
|
-
const
|
|
54013
|
+
const path2 = context.pathname || "/";
|
|
53984
54014
|
const potentiallyTrustworthy = isPotentiallyTrustworthy(
|
|
53985
54015
|
url,
|
|
53986
54016
|
this.allowSecureOnLocal
|
|
@@ -54011,7 +54041,7 @@ var init_dist = __esm({
|
|
|
54011
54041
|
return false;
|
|
54012
54042
|
}
|
|
54013
54043
|
}
|
|
54014
|
-
if (!allPaths && typeof c.path === "string" && !pathMatch(
|
|
54044
|
+
if (!allPaths && typeof c.path === "string" && !pathMatch(path2, c.path)) {
|
|
54015
54045
|
return false;
|
|
54016
54046
|
}
|
|
54017
54047
|
if (c.secure && !potentiallyTrustworthy) {
|
|
@@ -54043,7 +54073,7 @@ var init_dist = __esm({
|
|
|
54043
54073
|
}
|
|
54044
54074
|
store.findCookies(
|
|
54045
54075
|
host,
|
|
54046
|
-
allPaths ? null :
|
|
54076
|
+
allPaths ? null : path2,
|
|
54047
54077
|
this.allowSpecialUseDomain,
|
|
54048
54078
|
(err, cookies) => {
|
|
54049
54079
|
if (err) {
|
|
@@ -55421,9 +55451,9 @@ function filesFromList(data) {
|
|
|
55421
55451
|
if (!Array.isArray(files)) return [];
|
|
55422
55452
|
return files.flatMap((f) => {
|
|
55423
55453
|
if (!f || typeof f !== "object") return [];
|
|
55424
|
-
const
|
|
55454
|
+
const path2 = String(f.path ?? "");
|
|
55425
55455
|
const content = String(f.content ?? "");
|
|
55426
|
-
return
|
|
55456
|
+
return path2 ? [{ path: path2, content }] : [];
|
|
55427
55457
|
});
|
|
55428
55458
|
}
|
|
55429
55459
|
async function resolveGridAppId(fetchImpl, token, msid, siteUrl) {
|
|
@@ -55850,14 +55880,14 @@ function apiKeyAuth(env = process.env) {
|
|
|
55850
55880
|
return key2 && accountId ? { key: key2, accountId } : void 0;
|
|
55851
55881
|
}
|
|
55852
55882
|
function accountTransport(fetchImpl = fetch, timeoutMs = DEFAULT_TIMEOUT_MS5, spawnImpl = spawn4) {
|
|
55853
|
-
return async (method,
|
|
55883
|
+
return async (method, path2, body) => {
|
|
55854
55884
|
const viaKey = apiKeyAuth();
|
|
55855
55885
|
const headers2 = viaKey ? { Authorization: viaKey.key, "wix-account-id": viaKey.accountId, Accept: "application/json" } : { Authorization: await accountToken2(spawnImpl), Accept: "application/json" };
|
|
55856
55886
|
if (body !== void 0) headers2["Content-Type"] = "application/json";
|
|
55857
55887
|
const started = Date.now();
|
|
55858
55888
|
let res;
|
|
55859
55889
|
try {
|
|
55860
|
-
res = await fetchImpl(`${API_BASE2}${
|
|
55890
|
+
res = await fetchImpl(`${API_BASE2}${path2}`, {
|
|
55861
55891
|
method,
|
|
55862
55892
|
headers: headers2,
|
|
55863
55893
|
body: body === void 0 ? void 0 : JSON.stringify(body),
|
|
@@ -55867,10 +55897,10 @@ function accountTransport(fetchImpl = fetch, timeoutMs = DEFAULT_TIMEOUT_MS5, sp
|
|
|
55867
55897
|
const err = e;
|
|
55868
55898
|
if (err?.name === "TimeoutError" || /aborted due to timeout/i.test(err?.message ?? "")) {
|
|
55869
55899
|
throw new Error(
|
|
55870
|
-
`${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.`
|
|
55871
55901
|
);
|
|
55872
55902
|
}
|
|
55873
|
-
throw new Error(`${method} ${
|
|
55903
|
+
throw new Error(`${method} ${path2} failed: ${err?.message ?? String(e)}`);
|
|
55874
55904
|
}
|
|
55875
55905
|
const text4 = await res.text();
|
|
55876
55906
|
let parsed = text4;
|
|
@@ -55878,7 +55908,7 @@ function accountTransport(fetchImpl = fetch, timeoutMs = DEFAULT_TIMEOUT_MS5, sp
|
|
|
55878
55908
|
parsed = text4 ? JSON.parse(text4) : null;
|
|
55879
55909
|
} catch {
|
|
55880
55910
|
}
|
|
55881
|
-
if (!res.ok) throw new WixApiError(res.status, method,
|
|
55911
|
+
if (!res.ok) throw new WixApiError(res.status, method, path2, parsed);
|
|
55882
55912
|
return parsed;
|
|
55883
55913
|
};
|
|
55884
55914
|
}
|
|
@@ -56157,27 +56187,27 @@ async function runSiteCreate(opts) {
|
|
|
56157
56187
|
}
|
|
56158
56188
|
function writeProvisioningBinding(target, binding2, fs = { existsSync: existsSync55, readFileSync: readFileSync66, writeFileSync: writeFileSync24 }) {
|
|
56159
56189
|
const msid = binding2.siteId;
|
|
56160
|
-
const
|
|
56161
|
-
const committed = committedShellProvisioning(
|
|
56190
|
+
const path2 = resolvePath2(target);
|
|
56191
|
+
const committed = committedShellProvisioning(path2);
|
|
56162
56192
|
if (committed) {
|
|
56163
56193
|
throw new Error(
|
|
56164
56194
|
`refusing to overwrite committed ${committedProvisioningPath(committed)} \u2014 pass a content-package provisioning.json, or use \`prepare:customer --contract\``
|
|
56165
56195
|
);
|
|
56166
56196
|
}
|
|
56167
|
-
if (!fs.existsSync(
|
|
56197
|
+
if (!fs.existsSync(path2)) {
|
|
56168
56198
|
throw new Error(
|
|
56169
|
-
`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>.`
|
|
56170
56200
|
);
|
|
56171
56201
|
}
|
|
56172
|
-
const raw = fs.readFileSync(
|
|
56202
|
+
const raw = fs.readFileSync(path2, "utf8");
|
|
56173
56203
|
let manifest;
|
|
56174
56204
|
try {
|
|
56175
56205
|
manifest = JSON.parse(raw);
|
|
56176
56206
|
} catch (e) {
|
|
56177
|
-
throw new Error(`${
|
|
56207
|
+
throw new Error(`${path2} is not valid JSON (${e?.message ?? e}) \u2014 not touching it`);
|
|
56178
56208
|
}
|
|
56179
56209
|
if (manifest === null || typeof manifest !== "object" || Array.isArray(manifest)) {
|
|
56180
|
-
throw new Error(`${
|
|
56210
|
+
throw new Error(`${path2} must contain a JSON object \u2014 not touching it`);
|
|
56181
56211
|
}
|
|
56182
56212
|
if (binding2.siteUrl !== void 0) assertAbsoluteHttpUrl(binding2.siteUrl);
|
|
56183
56213
|
if (binding2.redirectUri !== void 0) assertRedirectUri(binding2.redirectUri);
|
|
@@ -56195,9 +56225,9 @@ function writeProvisioningBinding(target, binding2, fs = { existsSync: existsSyn
|
|
|
56195
56225
|
const indentMatch = /^[ \t]*[{[][\r\n]+([ \t]+)/.exec(raw);
|
|
56196
56226
|
const indent = indentMatch ? indentMatch[1] : " ";
|
|
56197
56227
|
const trailingNewline = /\n$/.test(raw) ? "\n" : "";
|
|
56198
|
-
fs.writeFileSync(
|
|
56228
|
+
fs.writeFileSync(path2, `${JSON.stringify(manifest, null, indent)}${trailingNewline}`, "utf8");
|
|
56199
56229
|
return {
|
|
56200
|
-
path,
|
|
56230
|
+
path: path2,
|
|
56201
56231
|
siteId: msid,
|
|
56202
56232
|
...binding2.clientId ? { clientId: binding2.clientId } : {},
|
|
56203
56233
|
...binding2.siteUrl ? { siteUrl: binding2.siteUrl } : {},
|
|
@@ -56486,6 +56516,347 @@ var init_site_oauth_client = __esm({
|
|
|
56486
56516
|
}
|
|
56487
56517
|
});
|
|
56488
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
|
+
|
|
56489
56860
|
// src/cli.ts
|
|
56490
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";
|
|
56491
56862
|
import { execFileSync as execFileSync7, spawnSync as spawnSync5, spawn as spawn5 } from "node:child_process";
|
|
@@ -56518,11 +56889,11 @@ var ServeCliClient = class {
|
|
|
56518
56889
|
if (!url) throw new Error(`no ${plane} URL configured for this target`);
|
|
56519
56890
|
return url.replace(/\/+$/, "");
|
|
56520
56891
|
}
|
|
56521
|
-
async request(plane, method,
|
|
56892
|
+
async request(plane, method, path2, opts = {}) {
|
|
56522
56893
|
const headers2 = { ...opts.headers };
|
|
56523
56894
|
if (opts.body !== void 0) headers2["content-type"] = "application/json";
|
|
56524
56895
|
const carriesCredential = Object.keys(headers2).some((h2) => CREDENTIAL_HEADERS.has(h2.toLowerCase()));
|
|
56525
|
-
const res = await this.fetchImpl(this.baseFor(plane) +
|
|
56896
|
+
const res = await this.fetchImpl(this.baseFor(plane) + path2, {
|
|
56526
56897
|
method,
|
|
56527
56898
|
headers: headers2,
|
|
56528
56899
|
...carriesCredential ? { redirect: "error" } : {},
|
|
@@ -56735,12 +57106,12 @@ var ServeCliClient = class {
|
|
|
56735
57106
|
if (o.since !== void 0) q.set("since", String(o.since));
|
|
56736
57107
|
if (o.limit) q.set("limit", String(o.limit));
|
|
56737
57108
|
if (o.crashesOnly) q.set("crashesOnly", "1");
|
|
56738
|
-
const
|
|
56739
|
-
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) => {
|
|
56740
57111
|
if (res.status !== 404 || this.target.telemetry.replace(/\/+$/, "") === this.target.serve.replace(/\/+$/, "")) {
|
|
56741
57112
|
return res;
|
|
56742
57113
|
}
|
|
56743
|
-
return this.request("serve", "GET",
|
|
57114
|
+
return this.request("serve", "GET", path2, { headers: this.telHeaders() });
|
|
56744
57115
|
});
|
|
56745
57116
|
}
|
|
56746
57117
|
/** Retained worker console lines (oldest first; `since` = seq cursor for tailing). */
|
|
@@ -56750,12 +57121,12 @@ var ServeCliClient = class {
|
|
|
56750
57121
|
if (o.screenId) q.set("screen", o.screenId);
|
|
56751
57122
|
if (o.since !== void 0) q.set("since", String(o.since));
|
|
56752
57123
|
if (o.limit) q.set("limit", String(o.limit));
|
|
56753
|
-
const
|
|
56754
|
-
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) => {
|
|
56755
57126
|
if (res.status !== 404 || this.target.telemetry.replace(/\/+$/, "") === this.target.serve.replace(/\/+$/, "")) {
|
|
56756
57127
|
return res;
|
|
56757
57128
|
}
|
|
56758
|
-
return this.request("serve", "GET",
|
|
57129
|
+
return this.request("serve", "GET", path2, { headers: this.telHeaders() });
|
|
56759
57130
|
});
|
|
56760
57131
|
}
|
|
56761
57132
|
// ---- serve-control (publish / rollout / kill-switch — the mutable plane) ----
|
|
@@ -56813,8 +57184,8 @@ var ServeCliClient = class {
|
|
|
56813
57184
|
}
|
|
56814
57185
|
/** RFC 0012 release history: list the ledger (GET /v1/releases) or one manifest (…/{releaseId}). */
|
|
56815
57186
|
releases(app, releaseId) {
|
|
56816
|
-
const
|
|
56817
|
-
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() });
|
|
56818
57189
|
}
|
|
56819
57190
|
/** Select a published releaseId for a ring (POST /v1/admin/promote); optional rollout %. */
|
|
56820
57191
|
promote(app, ring, releaseId, percent, force = false) {
|
|
@@ -57171,8 +57542,8 @@ var VALIDATION_METADATA = /* @__PURE__ */ new Set([
|
|
|
57171
57542
|
".claude/.validation-baseline.json",
|
|
57172
57543
|
".claude/.validation-evidence.json"
|
|
57173
57544
|
]);
|
|
57174
|
-
function isValidationMetadata(
|
|
57175
|
-
return VALIDATION_METADATA.has(
|
|
57545
|
+
function isValidationMetadata(path2) {
|
|
57546
|
+
return VALIDATION_METADATA.has(path2) || /(^|[\\/])\.himi([\\/]|$)/.test(path2);
|
|
57176
57547
|
}
|
|
57177
57548
|
function tryGit(args, root) {
|
|
57178
57549
|
try {
|
|
@@ -57188,10 +57559,10 @@ function committedRecords(raw) {
|
|
|
57188
57559
|
const records = [];
|
|
57189
57560
|
for (let i = 0; i < fields.length; i += 2) {
|
|
57190
57561
|
const metadata2 = fields[i];
|
|
57191
|
-
const
|
|
57192
|
-
if (!metadata2.startsWith(":") ||
|
|
57193
|
-
if (isValidationMetadata(
|
|
57194
|
-
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`);
|
|
57195
57566
|
}
|
|
57196
57567
|
return records.sort().join("");
|
|
57197
57568
|
}
|
|
@@ -57251,12 +57622,12 @@ function validationDiffHash(cwd = process.cwd()) {
|
|
|
57251
57622
|
trustFilesystemMode = git(["config", "--bool", "--get", "core.fileMode"], { cwd: root }).trim() !== "false";
|
|
57252
57623
|
} catch {
|
|
57253
57624
|
}
|
|
57254
|
-
const paths = [.../* @__PURE__ */ new Set([...staged, ...unstaged, ...untracked])].filter((
|
|
57255
|
-
const identity = paths.map((
|
|
57256
|
-
const absolute = resolve5(root,
|
|
57257
|
-
const headEntry = headEntries.get(
|
|
57258
|
-
const indexEntry = indexEntries.get(
|
|
57259
|
-
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");
|
|
57260
57631
|
let stat2;
|
|
57261
57632
|
try {
|
|
57262
57633
|
stat2 = lstatSync2(absolute);
|
|
@@ -57270,7 +57641,7 @@ function validationDiffHash(cwd = process.cwd()) {
|
|
|
57270
57641
|
const worktreeEntry = { mode: "120000", oid: blobOid(target, objectAlgorithm) };
|
|
57271
57642
|
const stagedState2 = stagedIdentity(headEntry, indexEntry, worktreeEntry);
|
|
57272
57643
|
return [
|
|
57273
|
-
`${Buffer.byteLength(
|
|
57644
|
+
`${Buffer.byteLength(path2)}:${path2}`,
|
|
57274
57645
|
"symlink",
|
|
57275
57646
|
"120000",
|
|
57276
57647
|
diffHash(target),
|
|
@@ -57281,11 +57652,11 @@ function validationDiffHash(cwd = process.cwd()) {
|
|
|
57281
57652
|
if (stat2.isFile()) {
|
|
57282
57653
|
const filesystemMode = stat2.mode & 73 ? "100755" : "100644";
|
|
57283
57654
|
const worktreeMode = trustFilesystemMode ? filesystemMode : indexEntry?.mode ?? headEntry?.mode ?? "100644";
|
|
57284
|
-
const worktreeOid = git(["hash-object", `--path=${
|
|
57655
|
+
const worktreeOid = git(["hash-object", `--path=${path2}`, "--", path2], { cwd: root }).trim();
|
|
57285
57656
|
const worktreeEntry = { mode: worktreeMode, oid: worktreeOid };
|
|
57286
57657
|
const stagedState2 = stagedIdentity(headEntry, indexEntry, worktreeEntry);
|
|
57287
57658
|
return [
|
|
57288
|
-
`${Buffer.byteLength(
|
|
57659
|
+
`${Buffer.byteLength(path2)}:${path2}`,
|
|
57289
57660
|
"file",
|
|
57290
57661
|
worktreeMode,
|
|
57291
57662
|
diffHash(readFileSync4(absolute)),
|
|
@@ -57304,7 +57675,7 @@ function validationDiffHash(cwd = process.cwd()) {
|
|
|
57304
57675
|
const type = stat2.isDirectory() ? "directory" : "other";
|
|
57305
57676
|
const stagedState = stagedIdentity(headEntry, indexEntry, void 0);
|
|
57306
57677
|
return [
|
|
57307
|
-
`${Buffer.byteLength(
|
|
57678
|
+
`${Buffer.byteLength(path2)}:${path2}`,
|
|
57308
57679
|
type,
|
|
57309
57680
|
stat2.mode.toString(8),
|
|
57310
57681
|
stagedState,
|
|
@@ -57411,7 +57782,7 @@ var SELF_TEST_CASES = [
|
|
|
57411
57782
|
}
|
|
57412
57783
|
];
|
|
57413
57784
|
function runSelfTest() {
|
|
57414
|
-
let
|
|
57785
|
+
let failed2 = 0;
|
|
57415
57786
|
for (const testCase of SELF_TEST_CASES) {
|
|
57416
57787
|
let ok = false;
|
|
57417
57788
|
let thrown = null;
|
|
@@ -57425,20 +57796,20 @@ function runSelfTest() {
|
|
|
57425
57796
|
`);
|
|
57426
57797
|
continue;
|
|
57427
57798
|
}
|
|
57428
|
-
|
|
57799
|
+
failed2++;
|
|
57429
57800
|
process.stderr.write(` \u2717 ${testCase.name}
|
|
57430
57801
|
${thrown ?? testCase.reason}
|
|
57431
57802
|
`);
|
|
57432
57803
|
}
|
|
57433
|
-
return
|
|
57804
|
+
return failed2;
|
|
57434
57805
|
}
|
|
57435
57806
|
if (process.argv[1] && basename(process.argv[1]) === "diff-hash.mjs" && import.meta.url === pathToFileURL(process.argv[1]).href) {
|
|
57436
57807
|
if (process.argv.slice(2).includes("--self-test")) {
|
|
57437
57808
|
process.stdout.write("\u25B8 diff-hash --self-test: proving the identity can change, and can hold\n");
|
|
57438
|
-
const
|
|
57439
|
-
if (
|
|
57809
|
+
const failed2 = runSelfTest();
|
|
57810
|
+
if (failed2) {
|
|
57440
57811
|
process.stderr.write(
|
|
57441
|
-
`\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
|
|
57442
57813
|
`
|
|
57443
57814
|
);
|
|
57444
57815
|
process.exit(1);
|
|
@@ -57531,16 +57902,16 @@ function currentGitUntrackedHash(contentDir2) {
|
|
|
57531
57902
|
maxBuffer: GIT_HASH_MAX_BUFFER
|
|
57532
57903
|
});
|
|
57533
57904
|
const hash = createHash3("sha256");
|
|
57534
|
-
for (const
|
|
57535
|
-
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));
|
|
57536
57907
|
if (local.split(/[\\/]/)[0] === ".himi") continue;
|
|
57537
|
-
const full = join6(root,
|
|
57908
|
+
const full = join6(root, path2);
|
|
57538
57909
|
const stats = lstatSync3(full, { throwIfNoEntry: false });
|
|
57539
57910
|
if (!stats) continue;
|
|
57540
57911
|
const kind = stats.isSymbolicLink() ? "link" : stats.isDirectory() ? "dir" : stats.isFile() ? "file" : null;
|
|
57541
57912
|
if (!kind) continue;
|
|
57542
57913
|
const payload = kind === "link" ? Buffer.from(readlinkSync2(full)) : kind === "file" ? readFileSync5(full) : Buffer.alloc(0);
|
|
57543
|
-
const pathBytes = Buffer.from(
|
|
57914
|
+
const pathBytes = Buffer.from(path2);
|
|
57544
57915
|
hash.update(`${kind} ${pathBytes.length} ${payload.length}
|
|
57545
57916
|
`).update(pathBytes).update(payload);
|
|
57546
57917
|
}
|
|
@@ -57551,11 +57922,11 @@ function sourceTreeHash(root) {
|
|
|
57551
57922
|
const visit = (dir) => {
|
|
57552
57923
|
for (const entry of readdirSync3(dir, { withFileTypes: true }).sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0)) {
|
|
57553
57924
|
if (entry.isDirectory() && [".git", ".himi", "node_modules"].includes(entry.name)) continue;
|
|
57554
|
-
const
|
|
57555
|
-
const local = relative(root,
|
|
57556
|
-
if (entry.isDirectory()) visit(
|
|
57557
|
-
else if (entry.isFile()) hash.update(local).update("\0").update(readFileSync5(
|
|
57558
|
-
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");
|
|
57559
57930
|
}
|
|
57560
57931
|
};
|
|
57561
57932
|
visit(root);
|
|
@@ -57603,9 +57974,9 @@ function readRetainedAttestations(contentDir2) {
|
|
|
57603
57974
|
for (const run2 of parsedRuns) {
|
|
57604
57975
|
if (selfHashFor(run2) !== run2.selfHash) errors.push(`selfHash does not match retained run ${run2.runId}`);
|
|
57605
57976
|
for (const expected of Object.values(run2.screenshots)) {
|
|
57606
|
-
const
|
|
57607
|
-
if (!existsSync3(
|
|
57608
|
-
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)}`);
|
|
57609
57980
|
}
|
|
57610
57981
|
}
|
|
57611
57982
|
const runs = [];
|
|
@@ -57666,8 +58037,8 @@ function writeAttestation(input, opts = {}) {
|
|
|
57666
58037
|
const descriptorHashes = Object.fromEntries(
|
|
57667
58038
|
Object.entries(input.descriptors).sort(([a], [b]) => a.localeCompare(b)).map(([screen, bytes2]) => [screen, sha256(bytes2)])
|
|
57668
58039
|
);
|
|
57669
|
-
const screenshotEntries = Object.entries(input.screenshots ?? {}).sort(([a], [b]) => a.localeCompare(b)).filter(([,
|
|
57670
|
-
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);
|
|
57671
58042
|
return { screen, bytes: bytes2, hash: sha256(bytes2) };
|
|
57672
58043
|
});
|
|
57673
58044
|
const screenshots = Object.fromEntries(screenshotEntries.map(({ screen, hash }) => [screen, hash]));
|
|
@@ -57794,12 +58165,12 @@ function verifyAttestation(attestation, contentDir2, descriptors, expectedApp, r
|
|
|
57794
58165
|
if (sha256(bytes2) !== expected) errors.push(`descriptor hash does not match for ${screen}`);
|
|
57795
58166
|
}
|
|
57796
58167
|
for (const [screen, expected] of Object.entries(attestation.screenshots)) {
|
|
57797
|
-
const
|
|
57798
|
-
if (!existsSync3(
|
|
57799
|
-
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)}`);
|
|
57800
58171
|
continue;
|
|
57801
58172
|
}
|
|
57802
|
-
if (sha256(readFileSync5(
|
|
58173
|
+
if (sha256(readFileSync5(path2)) !== expected) errors.push(`screenshot hash does not match for ${screen}: ${basename2(path2)}`);
|
|
57803
58174
|
}
|
|
57804
58175
|
return { ok: errors.length === 0, errors };
|
|
57805
58176
|
}
|
|
@@ -58126,9 +58497,9 @@ function dpxSessionTokenPath() {
|
|
|
58126
58497
|
return process.env.HIMI_DPX_TOKEN ?? join7(homedir2(), ".dpx", "session", "token");
|
|
58127
58498
|
}
|
|
58128
58499
|
var DPX_SESSION_PORT = 5151;
|
|
58129
|
-
function dpxSessionPresent(
|
|
58500
|
+
function dpxSessionPresent(path2 = dpxSessionTokenPath()) {
|
|
58130
58501
|
try {
|
|
58131
|
-
return existsSync4(
|
|
58502
|
+
return existsSync4(path2) && readFileSync6(path2, "utf8").trim().length > 0;
|
|
58132
58503
|
} catch {
|
|
58133
58504
|
return false;
|
|
58134
58505
|
}
|
|
@@ -58307,10 +58678,10 @@ async function listCollections(call) {
|
|
|
58307
58678
|
let total;
|
|
58308
58679
|
let reachedEnd = false;
|
|
58309
58680
|
for (let page = 0; page < MAX_COLLECTION_PAGES; page++) {
|
|
58310
|
-
const
|
|
58681
|
+
const path2 = offset ? `/data/v2/collections?paging.offset=${offset}` : "/data/v2/collections";
|
|
58311
58682
|
const r = await withRetry(
|
|
58312
58683
|
"list collections",
|
|
58313
|
-
() => call("GET",
|
|
58684
|
+
() => call("GET", path2)
|
|
58314
58685
|
);
|
|
58315
58686
|
const batch = r.collections ?? [];
|
|
58316
58687
|
const t = r.pagingMetadata?.total;
|
|
@@ -59300,9 +59671,9 @@ function storesV1Issues(contentDir2, strict) {
|
|
|
59300
59671
|
const files = [];
|
|
59301
59672
|
const visit = (dir) => {
|
|
59302
59673
|
for (const entry of readdirSync10(dir, { withFileTypes: true })) {
|
|
59303
|
-
const
|
|
59304
|
-
if (entry.isDirectory()) visit(
|
|
59305
|
-
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);
|
|
59306
59677
|
}
|
|
59307
59678
|
};
|
|
59308
59679
|
roots.forEach(visit);
|
|
@@ -59326,12 +59697,12 @@ import { existsSync as existsSync22, readFileSync as readFileSync22, readdirSync
|
|
|
59326
59697
|
import { join as join25, relative as relative4, resolve as resolve16 } from "node:path";
|
|
59327
59698
|
var SOURCE_EXTENSIONS = /* @__PURE__ */ new Set([".ts", ".tsx", ".js", ".jsx", ".json"]);
|
|
59328
59699
|
var IGNORED_DIRECTORIES = /* @__PURE__ */ new Set([".git", "node_modules", "dist", ".himi", "coverage"]);
|
|
59329
|
-
function issue(issues, strict, code, message,
|
|
59330
|
-
issues.push({ code, message, ...
|
|
59700
|
+
function issue(issues, strict, code, message, path2) {
|
|
59701
|
+
issues.push({ code, message, ...path2 ? { path: path2 } : {}, severity: strict ? "error" : "warning" });
|
|
59331
59702
|
}
|
|
59332
|
-
function readText2(
|
|
59703
|
+
function readText2(path2) {
|
|
59333
59704
|
try {
|
|
59334
|
-
return existsSync22(
|
|
59705
|
+
return existsSync22(path2) ? readFileSync22(path2, "utf8") : null;
|
|
59335
59706
|
} catch {
|
|
59336
59707
|
return null;
|
|
59337
59708
|
}
|
|
@@ -59641,6 +60012,7 @@ var BOOLEAN_FLAGS = /* @__PURE__ */ new Set([
|
|
|
59641
60012
|
"json",
|
|
59642
60013
|
"deep",
|
|
59643
60014
|
"quiet",
|
|
60015
|
+
"read-only",
|
|
59644
60016
|
"force",
|
|
59645
60017
|
"replace",
|
|
59646
60018
|
"watch",
|
|
@@ -59768,10 +60140,10 @@ var str5 = (v) => typeof v === "string" ? v : void 0;
|
|
|
59768
60140
|
var num = (v) => typeof v === "string" && v !== "" && Number.isFinite(Number(v)) ? Number(v) : void 0;
|
|
59769
60141
|
function embeddedTemplateCatalog() {
|
|
59770
60142
|
return availableTemplates().map((name) => {
|
|
59771
|
-
const
|
|
59772
|
-
const meta = JSON.parse(readFileSync67(
|
|
60143
|
+
const path2 = join52(templateSourceDir(name), TEMPLATE_META_FILE);
|
|
60144
|
+
const meta = JSON.parse(readFileSync67(path2, "utf8"));
|
|
59773
60145
|
if (!meta || typeof meta.title !== "string" || typeof meta.description !== "string" || !Array.isArray(meta.tags)) {
|
|
59774
|
-
throw new Error(`${
|
|
60146
|
+
throw new Error(`${path2} must be { title: string, description: string, tags: string[], category?: string }`);
|
|
59775
60147
|
}
|
|
59776
60148
|
return { name, ...meta, source: "embedded" };
|
|
59777
60149
|
});
|
|
@@ -60258,6 +60630,7 @@ var USAGE = `himi \u2014 the Himalaya authoring CLI (remote dev loop)
|
|
|
60258
60630
|
also requires a MOBILE applicationType, because ensure
|
|
60259
60631
|
refuses a WEB client \u2014 so a WEB one carrying your
|
|
60260
60632
|
redirect looks right and is not a candidate.
|
|
60633
|
+
himi site analyze --read-only --site <msid> [--client-id <id>] [--json]
|
|
60261
60634
|
himi site analyze --client-id <id> --url <https://\u2026> [--site <msid>] [--out <dir>] [--apply]
|
|
60262
60635
|
[--shell ${SHELL_ENUM}]
|
|
60263
60636
|
collect a Wix business book (APIs + Playwright look) and
|
|
@@ -60371,7 +60744,7 @@ var COMMANDS = [
|
|
|
60371
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>]" },
|
|
60372
60745
|
{ name: "logout", summary: "remove the stored control token for a target", required: "[--target <t>]" },
|
|
60373
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]" },
|
|
60374
|
-
{ 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]" },
|
|
60375
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>]" },
|
|
60376
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]" },
|
|
60377
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)" },
|
|
@@ -60504,9 +60877,9 @@ function ageInDays(publishedAt, now = Date.now()) {
|
|
|
60504
60877
|
if (!Number.isFinite(at)) return void 0;
|
|
60505
60878
|
return Math.max(0, (now - at) / 864e5);
|
|
60506
60879
|
}
|
|
60507
|
-
function packageVersion(
|
|
60880
|
+
function packageVersion(path2) {
|
|
60508
60881
|
try {
|
|
60509
|
-
const version2 = JSON.parse(readFileSync67(
|
|
60882
|
+
const version2 = JSON.parse(readFileSync67(path2, "utf8")).version;
|
|
60510
60883
|
return typeof version2 === "string" && version2 ? version2 : void 0;
|
|
60511
60884
|
} catch {
|
|
60512
60885
|
return void 0;
|
|
@@ -60574,18 +60947,18 @@ var UPDATE_REEXEC_ENV = "HIMI_UPDATED_ONCE";
|
|
|
60574
60947
|
function updateCachePath(env = process.env) {
|
|
60575
60948
|
return env.HIMI_UPDATE_CACHE_FILE ?? join52(homedir7(), ".himalaya", "update-check.json");
|
|
60576
60949
|
}
|
|
60577
|
-
function readUpdateCache(
|
|
60950
|
+
function readUpdateCache(path2) {
|
|
60578
60951
|
try {
|
|
60579
|
-
const parsed = JSON.parse(readFileSync67(
|
|
60952
|
+
const parsed = JSON.parse(readFileSync67(path2, "utf8"));
|
|
60580
60953
|
return parsed && typeof parsed === "object" ? parsed : {};
|
|
60581
60954
|
} catch {
|
|
60582
60955
|
return {};
|
|
60583
60956
|
}
|
|
60584
60957
|
}
|
|
60585
|
-
function writeUpdateCache(
|
|
60958
|
+
function writeUpdateCache(path2, cache) {
|
|
60586
60959
|
try {
|
|
60587
|
-
mkdirSync27(dirname31(
|
|
60588
|
-
writeFileSync25(
|
|
60960
|
+
mkdirSync27(dirname31(path2), { recursive: true, mode: 448 });
|
|
60961
|
+
writeFileSync25(path2, JSON.stringify(cache, null, 2) + "\n", { mode: 384 });
|
|
60589
60962
|
} catch {
|
|
60590
60963
|
}
|
|
60591
60964
|
}
|
|
@@ -60693,10 +61066,10 @@ function isAbandoned(content) {
|
|
|
60693
61066
|
return Number.isFinite(owner) && owner > 0 && host === thisHost() && !processAlive(owner);
|
|
60694
61067
|
}
|
|
60695
61068
|
function staleUpdateLockFile(cachePath, now) {
|
|
60696
|
-
for (const
|
|
61069
|
+
for (const path2 of [`${cachePath}.lock.break`, `${cachePath}.lock`]) {
|
|
60697
61070
|
let content;
|
|
60698
61071
|
try {
|
|
60699
|
-
content = readFileSync67(
|
|
61072
|
+
content = readFileSync67(path2, "utf8");
|
|
60700
61073
|
} catch {
|
|
60701
61074
|
continue;
|
|
60702
61075
|
}
|
|
@@ -60704,12 +61077,12 @@ function staleUpdateLockFile(cachePath, now) {
|
|
|
60704
61077
|
let since = stamped;
|
|
60705
61078
|
if (!Number.isFinite(since)) {
|
|
60706
61079
|
try {
|
|
60707
|
-
since = statSync13(
|
|
61080
|
+
since = statSync13(path2).mtimeMs;
|
|
60708
61081
|
} catch {
|
|
60709
61082
|
continue;
|
|
60710
61083
|
}
|
|
60711
61084
|
}
|
|
60712
|
-
if (now - since >= UPDATE_LOCK_REPORT_AFTER_MS) return
|
|
61085
|
+
if (now - since >= UPDATE_LOCK_REPORT_AFTER_MS) return path2;
|
|
60713
61086
|
}
|
|
60714
61087
|
return void 0;
|
|
60715
61088
|
}
|
|
@@ -60717,24 +61090,24 @@ function acquireUpdateLock(cachePath, now, hooks = {}) {
|
|
|
60717
61090
|
const lockPath = `${cachePath}.lock`;
|
|
60718
61091
|
const breakPath = `${cachePath}.lock.break`;
|
|
60719
61092
|
const mine = lockStamp(now);
|
|
60720
|
-
const readLock = (
|
|
61093
|
+
const readLock = (path2) => {
|
|
60721
61094
|
try {
|
|
60722
|
-
return readFileSync67(
|
|
61095
|
+
return readFileSync67(path2, "utf8");
|
|
60723
61096
|
} catch {
|
|
60724
61097
|
return void 0;
|
|
60725
61098
|
}
|
|
60726
61099
|
};
|
|
60727
|
-
const tryCreate = (
|
|
61100
|
+
const tryCreate = (path2) => {
|
|
60728
61101
|
try {
|
|
60729
|
-
writeFileSync25(
|
|
61102
|
+
writeFileSync25(path2, mine, { flag: "wx", mode: 384 });
|
|
60730
61103
|
return true;
|
|
60731
61104
|
} catch {
|
|
60732
61105
|
return false;
|
|
60733
61106
|
}
|
|
60734
61107
|
};
|
|
60735
|
-
const removeIfMine = (
|
|
61108
|
+
const removeIfMine = (path2) => {
|
|
60736
61109
|
try {
|
|
60737
|
-
if (readLock(
|
|
61110
|
+
if (readLock(path2) === mine) rmSync10(path2, { force: true });
|
|
60738
61111
|
} catch {
|
|
60739
61112
|
}
|
|
60740
61113
|
};
|
|
@@ -60955,9 +61328,9 @@ function helpJson() {
|
|
|
60955
61328
|
}
|
|
60956
61329
|
function previewWebUrl(serveBase, app, release, screenId, surface, previewToken, handover) {
|
|
60957
61330
|
const base = serveBase.replace(/\/$/, "");
|
|
60958
|
-
const
|
|
61331
|
+
const path2 = screenId ? `/preview/a/${app}/screen/${screenId}` : `/preview/a/${app}`;
|
|
60959
61332
|
const query = handover ? `?h=${encodeURIComponent(handover)}` : `?release=${encodeURIComponent(release)}`;
|
|
60960
|
-
return `${base}${
|
|
61333
|
+
return `${base}${path2}${query}${surface ? `&surface=${encodeURIComponent(surface)}` : ""}${!handover && previewToken ? `&pvt=${encodeURIComponent(previewToken)}` : ""}`;
|
|
60961
61334
|
}
|
|
60962
61335
|
function renderDeviceWidths() {
|
|
60963
61336
|
return {
|
|
@@ -61378,10 +61751,10 @@ function readConfigSource(dir) {
|
|
|
61378
61751
|
return null;
|
|
61379
61752
|
}
|
|
61380
61753
|
}
|
|
61381
|
-
function writePngFile(
|
|
61382
|
-
mkdirSync27(dirname31(
|
|
61383
|
-
writeFileSync25(
|
|
61384
|
-
return
|
|
61754
|
+
function writePngFile(path2, base64) {
|
|
61755
|
+
mkdirSync27(dirname31(path2), { recursive: true });
|
|
61756
|
+
writeFileSync25(path2, Buffer.from(base64, "base64"));
|
|
61757
|
+
return path2;
|
|
61385
61758
|
}
|
|
61386
61759
|
async function initFromRemoteTemplate(name, parentDir, template, c) {
|
|
61387
61760
|
const dir = resolve44(parentDir, name);
|
|
@@ -61575,9 +61948,9 @@ async function loadCms(dir) {
|
|
|
61575
61948
|
return data ? { collections: data.collections ?? [], ...data.memberGated ? { memberGated: true } : {} } : void 0;
|
|
61576
61949
|
}
|
|
61577
61950
|
var ConfigLoadError = class extends Error {
|
|
61578
|
-
constructor(
|
|
61579
|
-
super(`could not load ${
|
|
61580
|
-
this.path =
|
|
61951
|
+
constructor(path2, cause) {
|
|
61952
|
+
super(`could not load ${path2}: ${cause.message}`);
|
|
61953
|
+
this.path = path2;
|
|
61581
61954
|
this.cause = cause;
|
|
61582
61955
|
this.name = "ConfigLoadError";
|
|
61583
61956
|
}
|
|
@@ -62551,17 +62924,17 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
62551
62924
|
const dir = contentDir(flags);
|
|
62552
62925
|
const { buildContentBundles: buildContentBundles2 } = await loadAuthoring();
|
|
62553
62926
|
const res = await buildContentBundles2(dir, { resolution: resolutionFlag(flags) });
|
|
62554
|
-
const
|
|
62927
|
+
const failed2 = res.compileErrors;
|
|
62555
62928
|
print({
|
|
62556
|
-
ok:
|
|
62929
|
+
ok: failed2.length === 0,
|
|
62557
62930
|
outDir: res.outDir,
|
|
62558
62931
|
built: res.built,
|
|
62559
|
-
...
|
|
62932
|
+
...failed2.length ? { compileErrors: failed2 } : {},
|
|
62560
62933
|
// #642.1b — a stale @wix/himalaya is advisory on `build` (the bundles may
|
|
62561
62934
|
// still compile); `validate --strict` is where it hard-fails.
|
|
62562
62935
|
...res.sdkVersionIssue ? { warnings: [res.sdkVersionIssue] } : {}
|
|
62563
62936
|
});
|
|
62564
|
-
return
|
|
62937
|
+
return failed2.length ? 1 : 0;
|
|
62565
62938
|
}
|
|
62566
62939
|
case "eject": {
|
|
62567
62940
|
const mod = String(pos[1] ?? "");
|
|
@@ -62642,12 +63015,12 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
62642
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));
|
|
62643
63016
|
const remoteTarget = str5(flags.target);
|
|
62644
63017
|
const boCookie = () => {
|
|
62645
|
-
const
|
|
63018
|
+
const path2 = dpxSessionTokenPath();
|
|
62646
63019
|
let raw;
|
|
62647
63020
|
try {
|
|
62648
|
-
raw = readFileSync67(
|
|
63021
|
+
raw = readFileSync67(path2, "utf8");
|
|
62649
63022
|
} catch {
|
|
62650
|
-
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`);
|
|
62651
63024
|
}
|
|
62652
63025
|
return dpxCookieHeader(raw);
|
|
62653
63026
|
};
|
|
@@ -63117,7 +63490,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
63117
63490
|
bootAndSnapshotState: bootAndSnapshotState2,
|
|
63118
63491
|
renderDescriptorWeb: renderDescriptorWeb2,
|
|
63119
63492
|
renderPngBatch: renderPngBatch2,
|
|
63120
|
-
writePng: (
|
|
63493
|
+
writePng: (path2, base64) => writePngFile(path2, base64),
|
|
63121
63494
|
clearDir: (d) => rmSync10(d, { recursive: true, force: true })
|
|
63122
63495
|
}
|
|
63123
63496
|
});
|
|
@@ -66552,12 +66925,12 @@ ${report2.ok ? "OK \u2014 data + serve plane reachable." : typeof report2.hint =
|
|
|
66552
66925
|
return 1;
|
|
66553
66926
|
}
|
|
66554
66927
|
if (secretTarget.mode === "remote") {
|
|
66555
|
-
const
|
|
66928
|
+
const path2 = dpxSessionTokenPath();
|
|
66556
66929
|
let raw;
|
|
66557
66930
|
try {
|
|
66558
|
-
raw = readFileSync67(
|
|
66931
|
+
raw = readFileSync67(path2, "utf8");
|
|
66559
66932
|
} catch {
|
|
66560
|
-
io.error(JSON.stringify({ error: `no DPX BO session at ${
|
|
66933
|
+
io.error(JSON.stringify({ error: `no DPX BO session at ${path2}` }));
|
|
66561
66934
|
return 1;
|
|
66562
66935
|
}
|
|
66563
66936
|
const { runRemoteSecretsCommand: runRemoteSecretsCommand2 } = await Promise.resolve().then(() => (init_secrets2(), secrets_exports));
|
|
@@ -66827,6 +67200,34 @@ ${report2.ok ? "OK \u2014 data + serve plane reachable." : typeof report2.hint =
|
|
|
66827
67200
|
}
|
|
66828
67201
|
const clientId = str5(flags["client-id"]) ?? process.env.WIX_CLIENT_ID;
|
|
66829
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
|
+
}
|
|
66830
67231
|
if (!clientId || !siteUrl) {
|
|
66831
67232
|
io.error(JSON.stringify({
|
|
66832
67233
|
error: "himi site analyze needs --client-id and --url",
|