@wix/himalaya-cli 0.1051.0 → 0.1053.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/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/dev-server/src/app-module.d.ts +10 -1
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/dev-server/src/wix-member-login.d.ts +5 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/sdui.mjs +8 -0
- package/dist/cli.mjs +310 -220
- package/package.json +2 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AppConfigLike } from "@wix/himalaya/core";
|
|
1
|
+
import type { AppConfig, AppConfigLike, FunctionsAppConfig } from "@wix/himalaya/core";
|
|
2
2
|
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
3
3
|
import type { ActionHandler } from "./actions/types.js";
|
|
4
4
|
import type { ScreenDescriptor } from "./builder.js";
|
|
@@ -121,6 +121,15 @@ export type DataRouteHandler = (req: IncomingMessage, res: ServerResponse, ctx:
|
|
|
121
121
|
store: AppStore;
|
|
122
122
|
serverBaseUrl: string;
|
|
123
123
|
}) => void | Promise<void>;
|
|
124
|
+
/** A functions-only app (`defineApp({ kind: "functions", … })`): no screens, and none of a UI
|
|
125
|
+
* app's config. The same test `defineApp` itself applies. */
|
|
126
|
+
export declare function isFunctionsOnlyConfig(config: AppConfigLike): config is FunctionsAppConfig;
|
|
127
|
+
/** An app's config seen as a UI app's, every field optional. `FunctionsAppConfig` declares none
|
|
128
|
+
* of `AppConfig`'s UI fields, so on a functions-only app each one reads as absent, which is what
|
|
129
|
+
* the `?.` / `??` at every call site already assumes. For code that handles both kinds; code
|
|
130
|
+
* past an `isFunctionsOnlyConfig` return should narrow instead. No app at all reads the same way,
|
|
131
|
+
* as `state.app?.module.config.x` did. */
|
|
132
|
+
export declare function uiConfig(config: AppConfigLike | undefined): Partial<AppConfig>;
|
|
124
133
|
/** The complete contract an app package exports for the dev-server to serve. */
|
|
125
134
|
export interface AppDevModule {
|
|
126
135
|
/** The `defineApp()` result from the app's config.ts — single source of identity. */
|
|
@@ -15,3 +15,8 @@ export declare function webWixCall(method: string, path: string, body: string |
|
|
|
15
15
|
status: number;
|
|
16
16
|
body: string;
|
|
17
17
|
}>;
|
|
18
|
+
/** The signed-in member's Wix id, or null when the profile read fails (the identity route then
|
|
19
|
+
* falls back to the login email). The token belongs in `webWixCall`'s TOKEN slot: the identity
|
|
20
|
+
* route used to pass it third, where it became the GET's ignored body, so the read went out as
|
|
21
|
+
* `Authorization: undefined`, always failed, and every member's id was reported as their email. */
|
|
22
|
+
export declare function readMemberId(memberToken: string): Promise<string | null>;
|
|
@@ -8549,6 +8549,12 @@ function agendaList(props, opts) {
|
|
|
8549
8549
|
}
|
|
8550
8550
|
|
|
8551
8551
|
// ../../core/dev-server/src/app-module.ts
|
|
8552
|
+
function isFunctionsOnlyConfig(config) {
|
|
8553
|
+
return config.kind === "functions";
|
|
8554
|
+
}
|
|
8555
|
+
function uiConfig(config) {
|
|
8556
|
+
return config ?? {};
|
|
8557
|
+
}
|
|
8552
8558
|
function deriveAppMeta(name, m, platforms = {}) {
|
|
8553
8559
|
const config = m.config;
|
|
8554
8560
|
return {
|
|
@@ -8658,6 +8664,7 @@ export {
|
|
|
8658
8664
|
icon,
|
|
8659
8665
|
iconButton,
|
|
8660
8666
|
image,
|
|
8667
|
+
isFunctionsOnlyConfig,
|
|
8661
8668
|
label,
|
|
8662
8669
|
labeledContent,
|
|
8663
8670
|
lazyList,
|
|
@@ -8703,6 +8710,7 @@ export {
|
|
|
8703
8710
|
timeline,
|
|
8704
8711
|
toggle,
|
|
8705
8712
|
tooltip,
|
|
8713
|
+
uiConfig,
|
|
8706
8714
|
video,
|
|
8707
8715
|
voiceNote,
|
|
8708
8716
|
vstack,
|
package/dist/cli.mjs
CHANGED
|
@@ -4274,8 +4274,9 @@ function confinedHost(ts2, contentDir2, options) {
|
|
|
4274
4274
|
host.writeFile = (fileName) => {
|
|
4275
4275
|
throw new Error(`Tier-5 typecheck attempted to write ${fileName} under noEmit \u2014 refusing`);
|
|
4276
4276
|
};
|
|
4277
|
-
|
|
4278
|
-
|
|
4277
|
+
const writable = host;
|
|
4278
|
+
if (writable.createDirectory) {
|
|
4279
|
+
writable.createDirectory = (dir) => {
|
|
4279
4280
|
throw new Error(`Tier-5 typecheck attempted to create ${dir} under noEmit \u2014 refusing`);
|
|
4280
4281
|
};
|
|
4281
4282
|
}
|
|
@@ -11371,6 +11372,177 @@ var init_idiom = __esm({
|
|
|
11371
11372
|
}
|
|
11372
11373
|
});
|
|
11373
11374
|
|
|
11375
|
+
// ../../core/ts/src/brand-color-math.ts
|
|
11376
|
+
function channel2(hex2, offset) {
|
|
11377
|
+
return Number.parseInt(hex2.slice(offset, offset + 2), 16);
|
|
11378
|
+
}
|
|
11379
|
+
function toHex(r, g, b) {
|
|
11380
|
+
return `#${[r, g, b].map((value) => Math.round(value).toString(16).padStart(2, "0")).join("")}`.toUpperCase();
|
|
11381
|
+
}
|
|
11382
|
+
function mix(color, background, colorWeight) {
|
|
11383
|
+
const values = [1, 3, 5].map((offset) => channel2(color, offset) * colorWeight + channel2(background, offset) * (1 - colorWeight));
|
|
11384
|
+
return toHex(values[0], values[1], values[2]);
|
|
11385
|
+
}
|
|
11386
|
+
function relativeLuminance2(color) {
|
|
11387
|
+
const linear = [1, 3, 5].map((offset) => {
|
|
11388
|
+
const value = channel2(color, offset) / 255;
|
|
11389
|
+
return value <= 0.03928 ? value / 12.92 : ((value + 0.055) / 1.055) ** 2.4;
|
|
11390
|
+
});
|
|
11391
|
+
return 0.2126 * linear[0] + 0.7152 * linear[1] + 0.0722 * linear[2];
|
|
11392
|
+
}
|
|
11393
|
+
function contrastRatio2(a, b) {
|
|
11394
|
+
const la = relativeLuminance2(a);
|
|
11395
|
+
const lb = relativeLuminance2(b);
|
|
11396
|
+
return (Math.max(la, lb) + 0.05) / (Math.min(la, lb) + 0.05);
|
|
11397
|
+
}
|
|
11398
|
+
function lstar(color) {
|
|
11399
|
+
const y = relativeLuminance2(color);
|
|
11400
|
+
return y <= 8856e-6 ? y * 903.3 : 116 * Math.cbrt(y) - 16;
|
|
11401
|
+
}
|
|
11402
|
+
function deriveAccentSurface(accent, surface, weight) {
|
|
11403
|
+
const tint = mix(accent, surface, weight);
|
|
11404
|
+
if (contrastRatio2(tint, surface) >= ACCENT_SURFACE_MIN_DELTA) return tint;
|
|
11405
|
+
const away = relativeLuminance2(surface) < 0.5 ? "#FFFFFF" : "#000000";
|
|
11406
|
+
for (let w = 0.02; w <= 0.5; w += 0.02) {
|
|
11407
|
+
const candidate = mix(away, surface, w);
|
|
11408
|
+
if (contrastRatio2(candidate, surface) >= ACCENT_SURFACE_MIN_DELTA) return candidate;
|
|
11409
|
+
}
|
|
11410
|
+
return tint;
|
|
11411
|
+
}
|
|
11412
|
+
function deriveSecondaryAccent(primary) {
|
|
11413
|
+
const shade2 = mix(primary, "#000000", SECONDARY_SHADE_WEIGHT);
|
|
11414
|
+
if (lstar(shade2) >= SECONDARY_MIN_LSTAR) return shade2;
|
|
11415
|
+
return mix(primary, "#FFFFFF", SECONDARY_SHADE_WEIGHT);
|
|
11416
|
+
}
|
|
11417
|
+
function textOn(color) {
|
|
11418
|
+
const luminance2 = relativeLuminance2(color);
|
|
11419
|
+
const whiteContrast = 1.05 / (luminance2 + 0.05);
|
|
11420
|
+
const blackContrast = (luminance2 + 0.05) / 0.05;
|
|
11421
|
+
return whiteContrast >= blackContrast ? "#FFFFFF" : "#000000";
|
|
11422
|
+
}
|
|
11423
|
+
function tuneDarkAccent(brand, darkSurface, lightSurface) {
|
|
11424
|
+
const kitInherentlyDark = lstar(lightSurface) < 50;
|
|
11425
|
+
if (kitInherentlyDark && contrastRatio2(brand, darkSurface) >= DARK_ARM_TARGET_CONTRAST && lstar(brand) <= DARK_ARM_LSTAR_CAP) {
|
|
11426
|
+
return brand;
|
|
11427
|
+
}
|
|
11428
|
+
let lift = DARK_ARM_MIN_LIFT;
|
|
11429
|
+
let candidate = mix(brand, "#FFFFFF", 1 - lift);
|
|
11430
|
+
while (contrastRatio2(candidate, darkSurface) < DARK_ARM_TARGET_CONTRAST && lift < 0.6) {
|
|
11431
|
+
lift += 0.04;
|
|
11432
|
+
candidate = mix(brand, "#FFFFFF", 1 - lift);
|
|
11433
|
+
}
|
|
11434
|
+
while (lstar(candidate) > DARK_ARM_LSTAR_CAP) {
|
|
11435
|
+
const darker = mix(candidate, "#000000", 0.94);
|
|
11436
|
+
if (contrastRatio2(darker, darkSurface) < DARK_ARM_FLOOR_CONTRAST) break;
|
|
11437
|
+
candidate = darker;
|
|
11438
|
+
}
|
|
11439
|
+
return candidate;
|
|
11440
|
+
}
|
|
11441
|
+
function textOnArm(accent) {
|
|
11442
|
+
return contrastRatio2("#FFFFFF", accent) >= 4.5 ? "#FFFFFF" : textOn(accent);
|
|
11443
|
+
}
|
|
11444
|
+
function tuneHighContrastAccent(brand, surface) {
|
|
11445
|
+
const towards = relativeLuminance2(surface) < 0.5 ? "#FFFFFF" : "#000000";
|
|
11446
|
+
let candidate = brand;
|
|
11447
|
+
for (let lift = 0; lift <= 0.9 && contrastRatio2(candidate, surface) < HIGH_CONTRAST_TARGET; lift += 0.04) {
|
|
11448
|
+
candidate = mix(brand, towards, 1 - lift);
|
|
11449
|
+
}
|
|
11450
|
+
return candidate;
|
|
11451
|
+
}
|
|
11452
|
+
function deriveAccentText(accent, surfaces) {
|
|
11453
|
+
const all = (typeof surfaces === "string" ? [surfaces] : [...surfaces]).map((s) => s.slice(0, 7));
|
|
11454
|
+
const page = all[0];
|
|
11455
|
+
const worst = (color) => Math.min(...all.map((s) => contrastRatio2(color, s)));
|
|
11456
|
+
const opaque = accent.length === 9 ? mix(accent.slice(0, 7), page, channel2(accent, 7) / 255) : accent;
|
|
11457
|
+
if (worst(opaque) >= ACCENT_TEXT_MIN_CONTRAST) return opaque;
|
|
11458
|
+
const pole = worst("#FFFFFF") >= worst("#000000") ? "#FFFFFF" : "#000000";
|
|
11459
|
+
for (let step = 1; step <= 100; step++) {
|
|
11460
|
+
const candidate = mix(pole, opaque, step / 100);
|
|
11461
|
+
if (worst(candidate) >= ACCENT_TEXT_MIN_CONTRAST) return candidate;
|
|
11462
|
+
}
|
|
11463
|
+
if (all.length > 1) {
|
|
11464
|
+
const side2 = (hex2) => relativeLuminance2(hex2) > MID_GREY_LUMINANCE;
|
|
11465
|
+
const sameSide = all.filter((s) => side2(s) === side2(page));
|
|
11466
|
+
return deriveAccentText(accent, sameSide.length < all.length ? sameSide : [page]);
|
|
11467
|
+
}
|
|
11468
|
+
return pole;
|
|
11469
|
+
}
|
|
11470
|
+
function textSurfacesOf(colors) {
|
|
11471
|
+
const out = { light: [], dark: [], highContrast: [] };
|
|
11472
|
+
for (const name of TEXT_BACKDROP_TOKENS) {
|
|
11473
|
+
const value = colors[name];
|
|
11474
|
+
for (const arm of ["light", "dark", "highContrast"]) {
|
|
11475
|
+
const hex2 = typeof value === "string" ? value : value && typeof value === "object" && !Array.isArray(value) ? value[arm] ?? value.light : void 0;
|
|
11476
|
+
if (typeof hex2 === "string" && hex2.startsWith("#") && hex2.length >= 7) out[arm].push(hex2);
|
|
11477
|
+
}
|
|
11478
|
+
}
|
|
11479
|
+
return out;
|
|
11480
|
+
}
|
|
11481
|
+
function stripBrandFromIdiom(tokens) {
|
|
11482
|
+
const idiom = tokens.idiom;
|
|
11483
|
+
if (!idiom || typeof idiom !== "object" || Array.isArray(idiom)) return;
|
|
11484
|
+
for (const overlay of Object.values(idiom)) {
|
|
11485
|
+
if (!overlay || typeof overlay !== "object" || Array.isArray(overlay)) continue;
|
|
11486
|
+
const o = overlay;
|
|
11487
|
+
const colors = o.colors;
|
|
11488
|
+
if (colors && typeof colors === "object" && !Array.isArray(colors)) {
|
|
11489
|
+
for (const key2 of BRAND_COLOR_TOKENS) delete colors[key2];
|
|
11490
|
+
if (Object.keys(colors).length === 0) delete o.colors;
|
|
11491
|
+
}
|
|
11492
|
+
const shadows = o.shadows;
|
|
11493
|
+
const glow = shadows && typeof shadows === "object" && !Array.isArray(shadows) ? shadows[BRAND_GLOW_SHADOW] : void 0;
|
|
11494
|
+
if (glow && typeof glow === "object" && !Array.isArray(glow) && "color" in glow) {
|
|
11495
|
+
delete glow.color;
|
|
11496
|
+
if (Object.keys(glow).length === 0) delete shadows[BRAND_GLOW_SHADOW];
|
|
11497
|
+
if (Object.keys(shadows).length === 0) delete o.shadows;
|
|
11498
|
+
}
|
|
11499
|
+
}
|
|
11500
|
+
}
|
|
11501
|
+
function deriveAccentFamily(primary, secondary, surfaces, textSurfaces = {}) {
|
|
11502
|
+
const primaryDark = tuneDarkAccent(primary, surfaces.dark, surfaces.light);
|
|
11503
|
+
const secondaryDark = tuneDarkAccent(secondary, surfaces.dark, surfaces.light);
|
|
11504
|
+
const primaryHigh = tuneHighContrastAccent(primary, surfaces.highContrast);
|
|
11505
|
+
const secondaryHigh = tuneHighContrastAccent(secondary, surfaces.highContrast);
|
|
11506
|
+
return {
|
|
11507
|
+
accentPrimary: { light: primary, dark: primaryDark, highContrast: primaryHigh },
|
|
11508
|
+
accentSecondary: { light: secondary, dark: secondaryDark, highContrast: secondaryHigh },
|
|
11509
|
+
accentSurface: {
|
|
11510
|
+
light: deriveAccentSurface(primary, surfaces.light, ACCENT_SURFACE_LIGHT_WEIGHT),
|
|
11511
|
+
dark: deriveAccentSurface(primaryDark, surfaces.dark, 0.24),
|
|
11512
|
+
highContrast: deriveAccentSurface(primaryHigh, surfaces.highContrast, 0.24)
|
|
11513
|
+
},
|
|
11514
|
+
textOnAccent: {
|
|
11515
|
+
light: textOnArm(primary),
|
|
11516
|
+
dark: textOnArm(primaryDark),
|
|
11517
|
+
highContrast: textOn(primaryHigh)
|
|
11518
|
+
},
|
|
11519
|
+
accentText: {
|
|
11520
|
+
light: deriveAccentText(primary, [surfaces.light, ...textSurfaces.light ?? []]),
|
|
11521
|
+
dark: deriveAccentText(primaryDark, [surfaces.dark, ...textSurfaces.dark ?? []]),
|
|
11522
|
+
highContrast: deriveAccentText(primaryHigh, [surfaces.highContrast, ...textSurfaces.highContrast ?? []])
|
|
11523
|
+
}
|
|
11524
|
+
};
|
|
11525
|
+
}
|
|
11526
|
+
var ACCENT_SURFACE_MIN_DELTA, ACCENT_SURFACE_LIGHT_WEIGHT, SECONDARY_SHADE_WEIGHT, SECONDARY_MIN_LSTAR, DARK_ARM_MIN_LIFT, DARK_ARM_TARGET_CONTRAST, DARK_ARM_FLOOR_CONTRAST, DARK_ARM_LSTAR_CAP, HIGH_CONTRAST_TARGET, ACCENT_TEXT_MIN_CONTRAST, MID_GREY_LUMINANCE, TEXT_BACKDROP_TOKENS, BRAND_COLOR_TOKENS, BRAND_GLOW_SHADOW;
|
|
11527
|
+
var init_brand_color_math = __esm({
|
|
11528
|
+
"../../core/ts/src/brand-color-math.ts"() {
|
|
11529
|
+
ACCENT_SURFACE_MIN_DELTA = 1.08;
|
|
11530
|
+
ACCENT_SURFACE_LIGHT_WEIGHT = 0.12;
|
|
11531
|
+
SECONDARY_SHADE_WEIGHT = 0.72;
|
|
11532
|
+
SECONDARY_MIN_LSTAR = 22;
|
|
11533
|
+
DARK_ARM_MIN_LIFT = 0.08;
|
|
11534
|
+
DARK_ARM_TARGET_CONTRAST = 3.4;
|
|
11535
|
+
DARK_ARM_FLOOR_CONTRAST = 3;
|
|
11536
|
+
DARK_ARM_LSTAR_CAP = 80;
|
|
11537
|
+
HIGH_CONTRAST_TARGET = 8.5;
|
|
11538
|
+
ACCENT_TEXT_MIN_CONTRAST = 4.5;
|
|
11539
|
+
MID_GREY_LUMINANCE = 0.179;
|
|
11540
|
+
TEXT_BACKDROP_TOKENS = ["surfaceSecondary", "surfaceElevated", "surfaceSubtle", "surfaceTertiary"];
|
|
11541
|
+
BRAND_COLOR_TOKENS = ["accentPrimary", "accentSecondary", "accentSurface", "textOnAccent", "accentText"];
|
|
11542
|
+
BRAND_GLOW_SHADOW = "glow";
|
|
11543
|
+
}
|
|
11544
|
+
});
|
|
11545
|
+
|
|
11374
11546
|
// src/token-lint.ts
|
|
11375
11547
|
import { existsSync as existsSync13, readFileSync as readFileSync14 } from "node:fs";
|
|
11376
11548
|
import { join as join16 } from "node:path";
|
|
@@ -11537,13 +11709,71 @@ function contrastFindings(colors) {
|
|
|
11537
11709
|
});
|
|
11538
11710
|
}
|
|
11539
11711
|
}
|
|
11712
|
+
accentOnSurfaces(colors, declared, findings);
|
|
11540
11713
|
return [...findings.values()];
|
|
11541
11714
|
}
|
|
11542
|
-
|
|
11715
|
+
function sameHueClearingAll(fg, bgs, target = AA_TEXT) {
|
|
11716
|
+
const base = fg.slice(0, 7);
|
|
11717
|
+
const poles = onLightSide(bgs[0]) ? ["#000000", "#FFFFFF"] : ["#FFFFFF", "#000000"];
|
|
11718
|
+
for (let step = 0; step <= 100; step++) {
|
|
11719
|
+
for (const pole of poles) {
|
|
11720
|
+
const candidate = mixHex(base, pole, 1 - step / 100);
|
|
11721
|
+
if (bgs.every((bg) => contrastRatio(candidate, bg) >= target)) return candidate;
|
|
11722
|
+
}
|
|
11723
|
+
}
|
|
11724
|
+
return void 0;
|
|
11725
|
+
}
|
|
11726
|
+
function accentOnSurfaces(colors, declared, findings) {
|
|
11727
|
+
const hasAccentText = colors.accentText !== void 0;
|
|
11728
|
+
for (const fgName of hasAccentText ? ["accentText", "accentPrimary"] : ["accentPrimary"]) {
|
|
11729
|
+
if (colors[fgName] === void 0) continue;
|
|
11730
|
+
const role = fgName === "accentText" ? "the colour of accent text" : hasAccentText ? "still the colour of some accent text (the selected Tabs label on web, rich-text links on Android)" : "the colour of accent text (no accentText is declared, so accent text is painted with accentPrimary)";
|
|
11731
|
+
accentOnSurfacesFor(fgName, role, colors, declared, findings);
|
|
11732
|
+
}
|
|
11733
|
+
}
|
|
11734
|
+
function accentOnSurfacesFor(fgName, role, colors, declared, findings) {
|
|
11735
|
+
for (const surface of TEXT_BACKDROP_TOKENS) {
|
|
11736
|
+
if (colors[surface] === void 0) continue;
|
|
11737
|
+
for (const scheme of SCHEMES) {
|
|
11738
|
+
if (!declared.has(scheme)) continue;
|
|
11739
|
+
const fg = schemeValue(colors[fgName], scheme);
|
|
11740
|
+
const bg = schemeValue(colors[surface], scheme);
|
|
11741
|
+
if (!fg || !bg) continue;
|
|
11742
|
+
const painted = paintedOver(fg, bg);
|
|
11743
|
+
if (!painted) continue;
|
|
11744
|
+
const pageRaw = schemeValue(colors.surfacePrimary, scheme);
|
|
11745
|
+
const page = pageRaw && paintedOver(fg, pageRaw) ? pageRaw.slice(0, 7) : void 0;
|
|
11746
|
+
const opaqueBg = bg.slice(0, 7);
|
|
11747
|
+
if (page === opaqueBg) continue;
|
|
11748
|
+
if (page && contrastRatio(paintedOver(fg, pageRaw), page) < AA_TEXT) continue;
|
|
11749
|
+
const ratio = contrastRatio(painted, opaqueBg);
|
|
11750
|
+
if (ratio >= AA_TEXT) continue;
|
|
11751
|
+
const key2 = `${fgName}|${surface}|${fg}|${bg}|${page ?? ""}`;
|
|
11752
|
+
const same2 = findings.get(key2);
|
|
11753
|
+
if (same2) {
|
|
11754
|
+
same2.schemes.push(scheme);
|
|
11755
|
+
continue;
|
|
11756
|
+
}
|
|
11757
|
+
const opposite = page !== void 0 && onLightSide(page) !== onLightSide(opaqueBg);
|
|
11758
|
+
const noSingle = page !== void 0 && opposite && contrastRatio(page, opaqueBg) < AA_TEXT * AA_TEXT;
|
|
11759
|
+
const suggestion = noSingle ? void 0 : sameHueClearingAll(painted, page ? [page, opaqueBg] : [opaqueBg]);
|
|
11760
|
+
const measured = (c) => page ? `${contrastRatio(c, opaqueBg).toFixed(2)}:1 on ${surface}, ${contrastRatio(c, page).toFixed(2)}:1 on surfacePrimary` : `${contrastRatio(c, opaqueBg).toFixed(2)}:1`;
|
|
11761
|
+
const restructure = ` Move ${surface} to the page's side of mid-grey (a ${page && onLightSide(page) ? "light" : "dark"} ${surface} on this page), or scope an explicit accent for that section with \`modifiers.theme\` (e.g. { "colors": { "accentText": "#RRGGBB" } } on the card).`;
|
|
11762
|
+
const fix = noSingle ? ` surfacePrimary (${page}) and ${surface} (${opaqueBg}) sit on opposite sides of mid-grey, so no single accent text colour can clear ${AA_TEXT}:1 on both.${restructure}` : suggestion ? ` A same-hue ${fgName} that clears it${page ? " and the page" : ""} is ${suggestion} (${measured(suggestion)}).` + (opposite ? ` The page and ${surface} sit on opposite sides of mid-grey, so only a narrow mid-tone clears both.${restructure}` : "") : ` No ${fgName} of this hue clears ${AA_TEXT}:1 on ${surface}${page ? " and the page" : ""}.` + (opposite ? restructure : "");
|
|
11763
|
+
findings.set(key2, {
|
|
11764
|
+
key: key2,
|
|
11765
|
+
schemes: [scheme],
|
|
11766
|
+
render: (schemes) => `colors.${fgName} (${fg}) on colors.${surface} (${bg}) is ${ratio.toFixed(2)}:1 in ${schemes.join(" / ")} \u2014 below the WCAG AA ${AA_TEXT}:1 for text. ${fgName} is ${role}, and a transparent label \u2014 a plain or link button, an inline action \u2014 has no background of its own, so inside a card or sheet it is read against ${surface}, not the page.${fix}`
|
|
11767
|
+
});
|
|
11768
|
+
}
|
|
11769
|
+
}
|
|
11770
|
+
}
|
|
11771
|
+
var AA_TEXT, CONTRAST_PAIRS, SCHEMES, channels, toHex2, mixHex, onLightSide;
|
|
11543
11772
|
var init_token_lint = __esm({
|
|
11544
11773
|
"src/token-lint.ts"() {
|
|
11545
11774
|
init_token_colors();
|
|
11546
11775
|
init_idiom();
|
|
11776
|
+
init_brand_color_math();
|
|
11547
11777
|
AA_TEXT = 4.5;
|
|
11548
11778
|
CONTRAST_PAIRS = [
|
|
11549
11779
|
{
|
|
@@ -11559,11 +11789,12 @@ var init_token_lint = __esm({
|
|
|
11559
11789
|
];
|
|
11560
11790
|
SCHEMES = ["light", "dark", "highContrast"];
|
|
11561
11791
|
channels = (hex2) => [1, 3, 5].map((i) => parseInt(hex2.slice(i, i + 2), 16));
|
|
11562
|
-
|
|
11792
|
+
toHex2 = (rgb) => `#${rgb.map((c) => Math.round(Math.min(255, Math.max(0, c))).toString(16).padStart(2, "0")).join("")}`.toUpperCase();
|
|
11563
11793
|
mixHex = (a, b, w) => {
|
|
11564
11794
|
const [ca, cb] = [channels(a), channels(b)];
|
|
11565
|
-
return
|
|
11795
|
+
return toHex2(ca.map((c, i) => c * w + cb[i] * (1 - w)));
|
|
11566
11796
|
};
|
|
11797
|
+
onLightSide = (hex2) => contrastRatio("#000000", hex2) >= contrastRatio("#FFFFFF", hex2);
|
|
11567
11798
|
}
|
|
11568
11799
|
});
|
|
11569
11800
|
|
|
@@ -12332,7 +12563,7 @@ function luminance([r, g, b]) {
|
|
|
12332
12563
|
});
|
|
12333
12564
|
return 0.2126 * lin[0] + 0.7152 * lin[1] + 0.0722 * lin[2];
|
|
12334
12565
|
}
|
|
12335
|
-
function
|
|
12566
|
+
function contrastRatio3(a, b) {
|
|
12336
12567
|
const [hi, lo] = [luminance(a), luminance(b)].sort((x, y) => y - x);
|
|
12337
12568
|
return (hi + 0.05) / (lo + 0.05);
|
|
12338
12569
|
}
|
|
@@ -12341,11 +12572,11 @@ async function contrastingBackdrop(mark, requested) {
|
|
|
12341
12572
|
const { dominant } = await sharp(mark).stats();
|
|
12342
12573
|
const ink = [dominant.r, dominant.g, dominant.b];
|
|
12343
12574
|
const want = hexToRgb(requested);
|
|
12344
|
-
if (!want ||
|
|
12575
|
+
if (!want || contrastRatio3(ink, want) >= MIN_BACKDROP_CONTRAST) return requested;
|
|
12345
12576
|
const towardsWhite = luminance(ink) < 0.5;
|
|
12346
12577
|
for (const amount of [0.35, 0.55, 0.75, 0.9]) {
|
|
12347
|
-
const candidate =
|
|
12348
|
-
if (
|
|
12578
|
+
const candidate = mix2(want, towardsWhite ? [255, 255, 255] : [0, 0, 0], amount);
|
|
12579
|
+
if (contrastRatio3(ink, candidate) >= MIN_BACKDROP_CONTRAST) return rgbToHex(candidate);
|
|
12349
12580
|
}
|
|
12350
12581
|
return towardsWhite ? "#FFFFFF" : "#000000";
|
|
12351
12582
|
}
|
|
@@ -12355,7 +12586,7 @@ function hexToRgb(hex2) {
|
|
|
12355
12586
|
const n = parseInt(m[1], 16);
|
|
12356
12587
|
return [n >> 16 & 255, n >> 8 & 255, n & 255];
|
|
12357
12588
|
}
|
|
12358
|
-
function
|
|
12589
|
+
function mix2(a, b, t) {
|
|
12359
12590
|
return [0, 1, 2].map((i) => Math.round(a[i] + (b[i] - a[i]) * t));
|
|
12360
12591
|
}
|
|
12361
12592
|
function rgbToHex([r, g, b]) {
|
|
@@ -13637,7 +13868,7 @@ function listReport(opts = {}) {
|
|
|
13637
13868
|
for (const [name, sys] of Object.entries(catalog.system)) {
|
|
13638
13869
|
families.push({ family: name, category: sys.category ?? "serif", variable: false, weights: "platform", kb: 0, license: "system" });
|
|
13639
13870
|
}
|
|
13640
|
-
return { ok: true, count: families.length, totalBytes, families };
|
|
13871
|
+
return { ok: true, count: families.length, totalBytes, problems: [], families };
|
|
13641
13872
|
}
|
|
13642
13873
|
async function fontFindings(appDir2, opts = {}) {
|
|
13643
13874
|
const tokensPath = join22(appDir2, configuredTokensPath(appDir2).path ?? "tokens.json");
|
|
@@ -16763,6 +16994,12 @@ var init_agent_context = __esm({
|
|
|
16763
16994
|
});
|
|
16764
16995
|
|
|
16765
16996
|
// ../../core/dev-server/src/app-module.ts
|
|
16997
|
+
function isFunctionsOnlyConfig(config) {
|
|
16998
|
+
return config.kind === "functions";
|
|
16999
|
+
}
|
|
17000
|
+
function uiConfig(config) {
|
|
17001
|
+
return config ?? {};
|
|
17002
|
+
}
|
|
16766
17003
|
function deriveAppMeta(name, m, platforms = {}) {
|
|
16767
17004
|
const config = m.config;
|
|
16768
17005
|
return {
|
|
@@ -17044,7 +17281,10 @@ async function loadContainedDevModule(name, entry, dir) {
|
|
|
17044
17281
|
"the contained dev-module realm is not installed, so the upload's dev/index.ts would have been imported into the host realm (which is not a security boundary)"
|
|
17045
17282
|
);
|
|
17046
17283
|
}
|
|
17047
|
-
const { buildContainedDevModule: buildContainedDevModule2, CONTAINED_DEV_MODULE_SERVICE: CONTAINED_DEV_MODULE_SERVICE2, CONTAINED_DEV_MODULE_ACTION: CONTAINED_DEV_MODULE_ACTION2 } =
|
|
17284
|
+
const { buildContainedDevModule: buildContainedDevModule2, CONTAINED_DEV_MODULE_SERVICE: CONTAINED_DEV_MODULE_SERVICE2, CONTAINED_DEV_MODULE_ACTION: CONTAINED_DEV_MODULE_ACTION2 } = (
|
|
17285
|
+
// @ts-expect-error — .mjs sibling without types; the cast below states what this uses.
|
|
17286
|
+
await Promise.resolve().then(() => (init_build_lib(), build_lib_exports))
|
|
17287
|
+
);
|
|
17048
17288
|
let js;
|
|
17049
17289
|
try {
|
|
17050
17290
|
js = await buildContainedDevModule2(entry, { absWorkingDir: dir, confineTo: dir });
|
|
@@ -17984,6 +18224,7 @@ __export(wix_member_login_exports, {
|
|
|
17984
18224
|
memberDirectLogin: () => memberDirectLogin,
|
|
17985
18225
|
memberDirectRegister: () => memberDirectRegister,
|
|
17986
18226
|
mintVisitor: () => mintVisitor,
|
|
18227
|
+
readMemberId: () => readMemberId,
|
|
17987
18228
|
webWixCall: () => webWixCall
|
|
17988
18229
|
});
|
|
17989
18230
|
import { createHash as createHash10, randomBytes as randomBytes3 } from "node:crypto";
|
|
@@ -18117,6 +18358,16 @@ async function webWixCall(method, path2, body, token, cookie, forwardedHeaders =
|
|
|
18117
18358
|
});
|
|
18118
18359
|
return { status: res.status, body: await res.text() };
|
|
18119
18360
|
}
|
|
18361
|
+
async function readMemberId(memberToken) {
|
|
18362
|
+
try {
|
|
18363
|
+
const identity = await webWixCall("GET", "/members/v1/members/my", void 0, memberToken);
|
|
18364
|
+
if (identity.status < 200 || identity.status >= 300) return null;
|
|
18365
|
+
const parsed = JSON.parse(identity.body);
|
|
18366
|
+
return parsed.member?.id ?? parsed.id ?? null;
|
|
18367
|
+
} catch {
|
|
18368
|
+
return null;
|
|
18369
|
+
}
|
|
18370
|
+
}
|
|
18120
18371
|
var API;
|
|
18121
18372
|
var init_wix_member_login = __esm({
|
|
18122
18373
|
"../../core/dev-server/src/wix-member-login.ts"() {
|
|
@@ -21506,6 +21757,7 @@ function shouldRevealError(args) {
|
|
|
21506
21757
|
var EMAIL_RE, URL_HOST_RE, INTEGER_RE, NUMBER_RE;
|
|
21507
21758
|
var init_validation = __esm({
|
|
21508
21759
|
"../../core/ts/src/validation.ts"() {
|
|
21760
|
+
"use strict";
|
|
21509
21761
|
EMAIL_RE = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*\.[A-Za-z]{2,}$/;
|
|
21510
21762
|
URL_HOST_RE = /^[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*(:[0-9]+)?$/;
|
|
21511
21763
|
INTEGER_RE = /^[+-]?[0-9]+$/;
|
|
@@ -25106,6 +25358,7 @@ function validateWorkerSubtree(raw, slotId, policy, actionCatalog) {
|
|
|
25106
25358
|
var WORKER_SUBTREE_CEILINGS, ID_PART, ACTION_ID;
|
|
25107
25359
|
var init_worker_subtree = __esm({
|
|
25108
25360
|
"../../core/ts/src/worker-subtree.ts"() {
|
|
25361
|
+
"use strict";
|
|
25109
25362
|
init_worker_subtree_safe_types_generated();
|
|
25110
25363
|
WORKER_SUBTREE_CEILINGS = Object.freeze({
|
|
25111
25364
|
maxEncodedBytes: 65536,
|
|
@@ -33722,7 +33975,7 @@ function makeEtag(body) {
|
|
|
33722
33975
|
return `"${createHash16("sha256").update(body).digest("hex").slice(0, 32)}"`;
|
|
33723
33976
|
}
|
|
33724
33977
|
function servedTokensPath(app) {
|
|
33725
|
-
return app.module.designTokensPath ?? resolve31(app.dir, app.module.config.designTokensPath ?? "tokens.json");
|
|
33978
|
+
return app.module.designTokensPath ?? resolve31(app.dir, uiConfig(app.module.config).designTokensPath ?? "tokens.json");
|
|
33726
33979
|
}
|
|
33727
33980
|
function readAppTokens(state) {
|
|
33728
33981
|
if (!state.app) return null;
|
|
@@ -33804,7 +34057,7 @@ function handleL10nRequest(req, res, state) {
|
|
|
33804
34057
|
res.end();
|
|
33805
34058
|
return;
|
|
33806
34059
|
}
|
|
33807
|
-
const sourceLocale = state.app.module.config.locale?.default ?? "en";
|
|
34060
|
+
const sourceLocale = uiConfig(state.app.module.config).locale?.default ?? "en";
|
|
33808
34061
|
let messages;
|
|
33809
34062
|
try {
|
|
33810
34063
|
messages = Object.fromEntries(
|
|
@@ -33842,9 +34095,9 @@ async function runScreenDiagnostics(state, screenId, descriptor) {
|
|
|
33842
34095
|
nativeActions,
|
|
33843
34096
|
appWorkerActions,
|
|
33844
34097
|
strict: false,
|
|
33845
|
-
workerSubtreeScreens: new Set(state.app?.module.config.workerSubtreeScreens ?? []),
|
|
34098
|
+
workerSubtreeScreens: new Set(uiConfig(state.app?.module.config).workerSubtreeScreens ?? []),
|
|
33846
34099
|
// Same a11y rung the build lint applies (RFC 0058 §5) — diagnostics must not disagree.
|
|
33847
|
-
a11y: state.app?.module.config.a11y
|
|
34100
|
+
a11y: uiConfig(state.app?.module.config).a11y
|
|
33848
34101
|
});
|
|
33849
34102
|
const telemetry = state.telemetryEvents.filter((e) => e.screenId === screenId && (/^worker_/.test(e.type) || e.type === "bundle_load_revoked")).slice(-20);
|
|
33850
34103
|
const lastError = [...telemetry].reverse().find((e) => /crash|revoked|error|fail/i.test(e.type)) ?? null;
|
|
@@ -34195,7 +34448,7 @@ async function buildDescriptorForScreenId(state, screenId, query = new URLSearch
|
|
|
34195
34448
|
}
|
|
34196
34449
|
return null;
|
|
34197
34450
|
})();
|
|
34198
|
-
return built ? ensureTransportCapability(applyTopBarDefault(attachAssignments(built, state, evalCtx, cfg?.overrides), state.app.module.config), state.tier5Dir ?? TIER5_ROOT2) : null;
|
|
34451
|
+
return built ? ensureTransportCapability(applyTopBarDefault(attachAssignments(built, state, evalCtx, cfg?.overrides), uiConfig(state.app.module.config)), state.tier5Dir ?? TIER5_ROOT2) : null;
|
|
34199
34452
|
}
|
|
34200
34453
|
return null;
|
|
34201
34454
|
}
|
|
@@ -35033,15 +35286,7 @@ async function handleWebWix(req, res, state) {
|
|
|
35033
35286
|
}
|
|
35034
35287
|
if (path2 === "/v1/__webwix/identity" && (req.method === "GET" || req.method === "POST")) {
|
|
35035
35288
|
if (!session.memberToken) return reply(200, { authenticated: false, userId: null, email: "" });
|
|
35036
|
-
|
|
35037
|
-
try {
|
|
35038
|
-
const identity = await webWixCall("GET", "/members/v1/members/my", session.memberToken);
|
|
35039
|
-
if (identity.status >= 200 && identity.status < 300) {
|
|
35040
|
-
const parsed = JSON.parse(identity.body);
|
|
35041
|
-
userId = parsed.member?.id ?? parsed.id ?? null;
|
|
35042
|
-
}
|
|
35043
|
-
} catch {
|
|
35044
|
-
}
|
|
35289
|
+
const userId = await readMemberId(session.memberToken);
|
|
35045
35290
|
const preferenceIdentity = session.email?.trim().toLowerCase() || userId;
|
|
35046
35291
|
return reply(200, {
|
|
35047
35292
|
authenticated: true,
|
|
@@ -35616,8 +35861,8 @@ async function handleAdminPlayground(req, res, state) {
|
|
|
35616
35861
|
nativeActions,
|
|
35617
35862
|
appWorkerActions,
|
|
35618
35863
|
strict,
|
|
35619
|
-
workerSubtreeScreens: new Set(state.app?.module.config.workerSubtreeScreens ?? []),
|
|
35620
|
-
a11y: state.app?.module.config.a11y
|
|
35864
|
+
workerSubtreeScreens: new Set(uiConfig(state.app?.module.config).workerSubtreeScreens ?? []),
|
|
35865
|
+
a11y: uiConfig(state.app?.module.config).a11y
|
|
35621
35866
|
});
|
|
35622
35867
|
return sendJson(res, report2.ok ? 200 : 422, report2);
|
|
35623
35868
|
}
|
|
@@ -39964,7 +40209,7 @@ async function buildReleaseFromContent(contentDir2, dest, opts = {}) {
|
|
|
39964
40209
|
}
|
|
39965
40210
|
function readTokensForLint(preloaded) {
|
|
39966
40211
|
try {
|
|
39967
|
-
const tokenPath = preloaded.module.designTokensPath ?? resolve32(preloaded.dir, preloaded.module.config.designTokensPath ?? "tokens.json");
|
|
40212
|
+
const tokenPath = preloaded.module.designTokensPath ?? resolve32(preloaded.dir, uiConfig(preloaded.module.config).designTokensPath ?? "tokens.json");
|
|
39968
40213
|
const parsed = JSON.parse(readFileSync42(tokenPath, "utf8"));
|
|
39969
40214
|
delete parsed._meta;
|
|
39970
40215
|
return parsed;
|
|
@@ -39976,7 +40221,8 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
39976
40221
|
const app = preloaded.name;
|
|
39977
40222
|
const tier5Dir = opts.tier5Dir ?? TIER5_DIR;
|
|
39978
40223
|
const collect2 = opts.collect;
|
|
39979
|
-
|
|
40224
|
+
const config = preloaded.module.config;
|
|
40225
|
+
if (isFunctionsOnlyConfig(config)) {
|
|
39980
40226
|
return buildFunctionsOnlyRelease(preloaded, dest);
|
|
39981
40227
|
}
|
|
39982
40228
|
const store = typeof dest === "string" ? new FileReleaseStore(dest) : dest;
|
|
@@ -40002,14 +40248,14 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
40002
40248
|
};
|
|
40003
40249
|
const LIVE_LOAD_BUDGET_MS = 3e4;
|
|
40004
40250
|
const appLocalDbSchema = (() => {
|
|
40005
|
-
const entities =
|
|
40251
|
+
const entities = config.dataSchema?.entities ?? [];
|
|
40006
40252
|
const names = entities.map((e) => e?.name).filter((n) => typeof n === "string" && n.length > 0);
|
|
40007
40253
|
return names.length ? names.map((name) => ({ name })) : null;
|
|
40008
40254
|
})();
|
|
40009
40255
|
let liveWixCall = null;
|
|
40010
40256
|
const ensureLiveWixCall = async () => {
|
|
40011
40257
|
if (liveWixCall) return liveWixCall;
|
|
40012
|
-
const auth =
|
|
40258
|
+
const auth = config.auth;
|
|
40013
40259
|
const clientId = auth?.config?.clientId;
|
|
40014
40260
|
if (auth?.providerId !== "wix-consumer" || typeof clientId !== "string" || !clientId) {
|
|
40015
40261
|
throw new Error(
|
|
@@ -40094,7 +40340,7 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
40094
40340
|
};
|
|
40095
40341
|
let handlers;
|
|
40096
40342
|
let minBinaryVersion = null;
|
|
40097
|
-
const requiredCapabilities = new Set(
|
|
40343
|
+
const requiredCapabilities = new Set(config.capabilities ?? []);
|
|
40098
40344
|
const requiredNativeComponents = /* @__PURE__ */ new Set();
|
|
40099
40345
|
const tierScreens = [];
|
|
40100
40346
|
const tierBundles = /* @__PURE__ */ new Map();
|
|
@@ -40340,11 +40586,11 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
40340
40586
|
nativeActions,
|
|
40341
40587
|
appWorkerActions,
|
|
40342
40588
|
strict: collect2.strict,
|
|
40343
|
-
workerSubtreeScreens: new Set(
|
|
40344
|
-
l10n: l10nLintOptions(
|
|
40589
|
+
workerSubtreeScreens: new Set(config.workerSubtreeScreens ?? []),
|
|
40590
|
+
l10n: l10nLintOptions(config.locale, preloaded.dir),
|
|
40345
40591
|
// RFC 0058 §5 — the app's own rung of the a11y ladder. Omitted ⇒ the validator's
|
|
40346
40592
|
// default, "error"; an in-repo app with ratcheted debt declares "warn".
|
|
40347
|
-
a11y:
|
|
40593
|
+
a11y: config.a11y
|
|
40348
40594
|
});
|
|
40349
40595
|
lint.push({ screenId, ok: report2.ok, issues: report2.issues });
|
|
40350
40596
|
}
|
|
@@ -40372,8 +40618,8 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
40372
40618
|
nativeActions,
|
|
40373
40619
|
appWorkerActions,
|
|
40374
40620
|
strict: collect2.strict,
|
|
40375
|
-
workerSubtreeScreens: new Set(
|
|
40376
|
-
a11y:
|
|
40621
|
+
workerSubtreeScreens: new Set(config.workerSubtreeScreens ?? []),
|
|
40622
|
+
a11y: config.a11y
|
|
40377
40623
|
});
|
|
40378
40624
|
lint.push({ screenId: wantedRender, ok: report2.ok, issues: report2.issues });
|
|
40379
40625
|
}
|
|
@@ -40407,6 +40653,10 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
40407
40653
|
store: preloaded.module.createStore(app),
|
|
40408
40654
|
toggles: {},
|
|
40409
40655
|
query: new URLSearchParams(),
|
|
40656
|
+
// A bake has no requesting member: the anonymous caller the dev-server also defaults to.
|
|
40657
|
+
// `ScreenBuildContext.caller` is documented never-absent, so a `seedIds` may read
|
|
40658
|
+
// `ctx.caller.entitled` unguarded, and would have thrown here without it.
|
|
40659
|
+
caller: { entitled: false },
|
|
40410
40660
|
serverBaseUrl: base,
|
|
40411
40661
|
bundleIntegrity: () => null,
|
|
40412
40662
|
// Resolve for real: a baked templated route whose descriptor references an asset must
|
|
@@ -40516,7 +40766,7 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
40516
40766
|
}
|
|
40517
40767
|
Object.assign(catalogs, await bakeCatalogs(
|
|
40518
40768
|
app,
|
|
40519
|
-
|
|
40769
|
+
config.locale,
|
|
40520
40770
|
async (tag) => {
|
|
40521
40771
|
const res = await devFetch(
|
|
40522
40772
|
`${base}/v1/l10n?app=${encodeURIComponent(app)}&tag=${encodeURIComponent(tag)}`,
|
|
@@ -40531,7 +40781,7 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
40531
40781
|
const served = await cfgRes.text();
|
|
40532
40782
|
const prodText = withProdServeAppConfig(
|
|
40533
40783
|
opts.keepDevOnlyAppConfig ? served : withoutDevOnlyAppConfig(served),
|
|
40534
|
-
|
|
40784
|
+
config.environments?.prod
|
|
40535
40785
|
);
|
|
40536
40786
|
const streamPolicyErrors = validateReleaseStreamPolicyConfig(prodText);
|
|
40537
40787
|
if (streamPolicyErrors.length) {
|
|
@@ -40603,7 +40853,7 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
40603
40853
|
playerRequirements: {
|
|
40604
40854
|
capabilities: [...requiredCapabilities].sort(),
|
|
40605
40855
|
nativeComponents: [...requiredNativeComponents].sort(),
|
|
40606
|
-
authProviders: [
|
|
40856
|
+
authProviders: [config.auth.providerId].filter(Boolean).sort()
|
|
40607
40857
|
},
|
|
40608
40858
|
iconHash,
|
|
40609
40859
|
...brandFonts.length ? { brandFonts } : {},
|
|
@@ -40659,7 +40909,7 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
40659
40909
|
// core identifies an oversized bundle by SRI, which is unactionable on its own, so the
|
|
40660
40910
|
// name is resolved back in here (most-specific match: `integrity` is a full SRI, but a
|
|
40661
40911
|
// descriptor carrying none would fall back to a bare name, and names nest).
|
|
40662
|
-
tierCapViolations: checkTierCaps(
|
|
40912
|
+
tierCapViolations: checkTierCaps(config, tierScreens, [...tierBundles.values()]).map((v) => {
|
|
40663
40913
|
const named = [...tierBundles.values()].filter((b) => v.message.includes(b.integrity)).sort((a, b) => b.integrity.length - a.integrity.length)[0];
|
|
40664
40914
|
return named ? { ...v, message: `${v.message} \u2014 bundle "${named.name}"` } : v;
|
|
40665
40915
|
}),
|
|
@@ -40672,7 +40922,7 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
40672
40922
|
...renderTokens !== void 0 ? { tokens: renderTokens } : {},
|
|
40673
40923
|
...preloaded.meta.surfaces ? { surfaceNav: preloaded.meta.surfaces } : {},
|
|
40674
40924
|
auth: (() => {
|
|
40675
|
-
const a =
|
|
40925
|
+
const a = config.auth;
|
|
40676
40926
|
const cid = a?.config?.clientId;
|
|
40677
40927
|
return { ...a?.providerId ? { providerId: a.providerId } : {}, ...typeof cid === "string" && cid ? { clientId: cid } : {} };
|
|
40678
40928
|
})()
|
|
@@ -40716,7 +40966,7 @@ async function buildFunctionsOnlyRelease(preloaded, dest) {
|
|
|
40716
40966
|
const sha = gitSha();
|
|
40717
40967
|
const manifest = { releaseId: contentReleaseId(content), gitSha: sha, ...content };
|
|
40718
40968
|
await store.putManifest(app, manifest);
|
|
40719
|
-
return { manifest, failedToBuild: [], missingBundles: [], auth: {} };
|
|
40969
|
+
return { manifest, failedToBuild: [], missingBundles: [], auth: {}, tierCapViolations: [] };
|
|
40720
40970
|
}
|
|
40721
40971
|
function listBuildableApps() {
|
|
40722
40972
|
const appsDir = join37(REPO_ROOT7, "apps");
|
|
@@ -40729,6 +40979,7 @@ var init_build3 = __esm({
|
|
|
40729
40979
|
init_contained_dev_module();
|
|
40730
40980
|
init_tier5_dir();
|
|
40731
40981
|
init_build_sha();
|
|
40982
|
+
init_app_module();
|
|
40732
40983
|
init_app_icon();
|
|
40733
40984
|
init_app_assets();
|
|
40734
40985
|
init_plan_fonts();
|
|
@@ -48118,6 +48369,14 @@ function memoryStore(manifest, built) {
|
|
|
48118
48369
|
},
|
|
48119
48370
|
async getAppConfig() {
|
|
48120
48371
|
return null;
|
|
48372
|
+
},
|
|
48373
|
+
// The two members the cast used to paper over. Serve-relative, as FileReleaseStore's is; and
|
|
48374
|
+
// nothing to prune, since this store only ever holds the one release it was built with.
|
|
48375
|
+
bundleUrl(_app, sha2565) {
|
|
48376
|
+
return `/v1/bundles/${sha2565}.bundle.js`;
|
|
48377
|
+
},
|
|
48378
|
+
async prune() {
|
|
48379
|
+
return 0;
|
|
48121
48380
|
}
|
|
48122
48381
|
};
|
|
48123
48382
|
}
|
|
@@ -54671,177 +54930,6 @@ var init_tokens3 = __esm({
|
|
|
54671
54930
|
}
|
|
54672
54931
|
});
|
|
54673
54932
|
|
|
54674
|
-
// ../../core/ts/src/brand-color-math.ts
|
|
54675
|
-
function channel2(hex2, offset) {
|
|
54676
|
-
return Number.parseInt(hex2.slice(offset, offset + 2), 16);
|
|
54677
|
-
}
|
|
54678
|
-
function toHex2(r, g, b) {
|
|
54679
|
-
return `#${[r, g, b].map((value) => Math.round(value).toString(16).padStart(2, "0")).join("")}`.toUpperCase();
|
|
54680
|
-
}
|
|
54681
|
-
function mix2(color, background, colorWeight) {
|
|
54682
|
-
const values = [1, 3, 5].map((offset) => channel2(color, offset) * colorWeight + channel2(background, offset) * (1 - colorWeight));
|
|
54683
|
-
return toHex2(values[0], values[1], values[2]);
|
|
54684
|
-
}
|
|
54685
|
-
function relativeLuminance2(color) {
|
|
54686
|
-
const linear = [1, 3, 5].map((offset) => {
|
|
54687
|
-
const value = channel2(color, offset) / 255;
|
|
54688
|
-
return value <= 0.03928 ? value / 12.92 : ((value + 0.055) / 1.055) ** 2.4;
|
|
54689
|
-
});
|
|
54690
|
-
return 0.2126 * linear[0] + 0.7152 * linear[1] + 0.0722 * linear[2];
|
|
54691
|
-
}
|
|
54692
|
-
function contrastRatio3(a, b) {
|
|
54693
|
-
const la = relativeLuminance2(a);
|
|
54694
|
-
const lb = relativeLuminance2(b);
|
|
54695
|
-
return (Math.max(la, lb) + 0.05) / (Math.min(la, lb) + 0.05);
|
|
54696
|
-
}
|
|
54697
|
-
function lstar(color) {
|
|
54698
|
-
const y = relativeLuminance2(color);
|
|
54699
|
-
return y <= 8856e-6 ? y * 903.3 : 116 * Math.cbrt(y) - 16;
|
|
54700
|
-
}
|
|
54701
|
-
function deriveAccentSurface(accent, surface, weight) {
|
|
54702
|
-
const tint = mix2(accent, surface, weight);
|
|
54703
|
-
if (contrastRatio3(tint, surface) >= ACCENT_SURFACE_MIN_DELTA) return tint;
|
|
54704
|
-
const away = relativeLuminance2(surface) < 0.5 ? "#FFFFFF" : "#000000";
|
|
54705
|
-
for (let w = 0.02; w <= 0.5; w += 0.02) {
|
|
54706
|
-
const candidate = mix2(away, surface, w);
|
|
54707
|
-
if (contrastRatio3(candidate, surface) >= ACCENT_SURFACE_MIN_DELTA) return candidate;
|
|
54708
|
-
}
|
|
54709
|
-
return tint;
|
|
54710
|
-
}
|
|
54711
|
-
function deriveSecondaryAccent(primary) {
|
|
54712
|
-
const shade2 = mix2(primary, "#000000", SECONDARY_SHADE_WEIGHT);
|
|
54713
|
-
if (lstar(shade2) >= SECONDARY_MIN_LSTAR) return shade2;
|
|
54714
|
-
return mix2(primary, "#FFFFFF", SECONDARY_SHADE_WEIGHT);
|
|
54715
|
-
}
|
|
54716
|
-
function textOn(color) {
|
|
54717
|
-
const luminance2 = relativeLuminance2(color);
|
|
54718
|
-
const whiteContrast = 1.05 / (luminance2 + 0.05);
|
|
54719
|
-
const blackContrast = (luminance2 + 0.05) / 0.05;
|
|
54720
|
-
return whiteContrast >= blackContrast ? "#FFFFFF" : "#000000";
|
|
54721
|
-
}
|
|
54722
|
-
function tuneDarkAccent(brand, darkSurface, lightSurface) {
|
|
54723
|
-
const kitInherentlyDark = lstar(lightSurface) < 50;
|
|
54724
|
-
if (kitInherentlyDark && contrastRatio3(brand, darkSurface) >= DARK_ARM_TARGET_CONTRAST && lstar(brand) <= DARK_ARM_LSTAR_CAP) {
|
|
54725
|
-
return brand;
|
|
54726
|
-
}
|
|
54727
|
-
let lift = DARK_ARM_MIN_LIFT;
|
|
54728
|
-
let candidate = mix2(brand, "#FFFFFF", 1 - lift);
|
|
54729
|
-
while (contrastRatio3(candidate, darkSurface) < DARK_ARM_TARGET_CONTRAST && lift < 0.6) {
|
|
54730
|
-
lift += 0.04;
|
|
54731
|
-
candidate = mix2(brand, "#FFFFFF", 1 - lift);
|
|
54732
|
-
}
|
|
54733
|
-
while (lstar(candidate) > DARK_ARM_LSTAR_CAP) {
|
|
54734
|
-
const darker = mix2(candidate, "#000000", 0.94);
|
|
54735
|
-
if (contrastRatio3(darker, darkSurface) < DARK_ARM_FLOOR_CONTRAST) break;
|
|
54736
|
-
candidate = darker;
|
|
54737
|
-
}
|
|
54738
|
-
return candidate;
|
|
54739
|
-
}
|
|
54740
|
-
function textOnArm(accent) {
|
|
54741
|
-
return contrastRatio3("#FFFFFF", accent) >= 4.5 ? "#FFFFFF" : textOn(accent);
|
|
54742
|
-
}
|
|
54743
|
-
function tuneHighContrastAccent(brand, surface) {
|
|
54744
|
-
const towards = relativeLuminance2(surface) < 0.5 ? "#FFFFFF" : "#000000";
|
|
54745
|
-
let candidate = brand;
|
|
54746
|
-
for (let lift = 0; lift <= 0.9 && contrastRatio3(candidate, surface) < HIGH_CONTRAST_TARGET; lift += 0.04) {
|
|
54747
|
-
candidate = mix2(brand, towards, 1 - lift);
|
|
54748
|
-
}
|
|
54749
|
-
return candidate;
|
|
54750
|
-
}
|
|
54751
|
-
function deriveAccentText(accent, surfaces) {
|
|
54752
|
-
const all = (typeof surfaces === "string" ? [surfaces] : [...surfaces]).map((s) => s.slice(0, 7));
|
|
54753
|
-
const page = all[0];
|
|
54754
|
-
const worst = (color) => Math.min(...all.map((s) => contrastRatio3(color, s)));
|
|
54755
|
-
const opaque = accent.length === 9 ? mix2(accent.slice(0, 7), page, channel2(accent, 7) / 255) : accent;
|
|
54756
|
-
if (worst(opaque) >= ACCENT_TEXT_MIN_CONTRAST) return opaque;
|
|
54757
|
-
const pole = worst("#FFFFFF") >= worst("#000000") ? "#FFFFFF" : "#000000";
|
|
54758
|
-
for (let step = 1; step <= 100; step++) {
|
|
54759
|
-
const candidate = mix2(pole, opaque, step / 100);
|
|
54760
|
-
if (worst(candidate) >= ACCENT_TEXT_MIN_CONTRAST) return candidate;
|
|
54761
|
-
}
|
|
54762
|
-
if (all.length > 1) {
|
|
54763
|
-
const side2 = (hex2) => relativeLuminance2(hex2) > MID_GREY_LUMINANCE;
|
|
54764
|
-
const sameSide = all.filter((s) => side2(s) === side2(page));
|
|
54765
|
-
return deriveAccentText(accent, sameSide.length < all.length ? sameSide : [page]);
|
|
54766
|
-
}
|
|
54767
|
-
return pole;
|
|
54768
|
-
}
|
|
54769
|
-
function textSurfacesOf(colors) {
|
|
54770
|
-
const out = { light: [], dark: [], highContrast: [] };
|
|
54771
|
-
for (const name of TEXT_BACKDROP_TOKENS) {
|
|
54772
|
-
const value = colors[name];
|
|
54773
|
-
for (const arm of ["light", "dark", "highContrast"]) {
|
|
54774
|
-
const hex2 = typeof value === "string" ? value : value && typeof value === "object" && !Array.isArray(value) ? value[arm] ?? value.light : void 0;
|
|
54775
|
-
if (typeof hex2 === "string" && hex2.startsWith("#") && hex2.length >= 7) out[arm].push(hex2);
|
|
54776
|
-
}
|
|
54777
|
-
}
|
|
54778
|
-
return out;
|
|
54779
|
-
}
|
|
54780
|
-
function stripBrandFromIdiom(tokens) {
|
|
54781
|
-
const idiom = tokens.idiom;
|
|
54782
|
-
if (!idiom || typeof idiom !== "object" || Array.isArray(idiom)) return;
|
|
54783
|
-
for (const overlay of Object.values(idiom)) {
|
|
54784
|
-
if (!overlay || typeof overlay !== "object" || Array.isArray(overlay)) continue;
|
|
54785
|
-
const o = overlay;
|
|
54786
|
-
const colors = o.colors;
|
|
54787
|
-
if (colors && typeof colors === "object" && !Array.isArray(colors)) {
|
|
54788
|
-
for (const key2 of BRAND_COLOR_TOKENS) delete colors[key2];
|
|
54789
|
-
if (Object.keys(colors).length === 0) delete o.colors;
|
|
54790
|
-
}
|
|
54791
|
-
const shadows = o.shadows;
|
|
54792
|
-
const glow = shadows && typeof shadows === "object" && !Array.isArray(shadows) ? shadows[BRAND_GLOW_SHADOW] : void 0;
|
|
54793
|
-
if (glow && typeof glow === "object" && !Array.isArray(glow) && "color" in glow) {
|
|
54794
|
-
delete glow.color;
|
|
54795
|
-
if (Object.keys(glow).length === 0) delete shadows[BRAND_GLOW_SHADOW];
|
|
54796
|
-
if (Object.keys(shadows).length === 0) delete o.shadows;
|
|
54797
|
-
}
|
|
54798
|
-
}
|
|
54799
|
-
}
|
|
54800
|
-
function deriveAccentFamily(primary, secondary, surfaces, textSurfaces = {}) {
|
|
54801
|
-
const primaryDark = tuneDarkAccent(primary, surfaces.dark, surfaces.light);
|
|
54802
|
-
const secondaryDark = tuneDarkAccent(secondary, surfaces.dark, surfaces.light);
|
|
54803
|
-
const primaryHigh = tuneHighContrastAccent(primary, surfaces.highContrast);
|
|
54804
|
-
const secondaryHigh = tuneHighContrastAccent(secondary, surfaces.highContrast);
|
|
54805
|
-
return {
|
|
54806
|
-
accentPrimary: { light: primary, dark: primaryDark, highContrast: primaryHigh },
|
|
54807
|
-
accentSecondary: { light: secondary, dark: secondaryDark, highContrast: secondaryHigh },
|
|
54808
|
-
accentSurface: {
|
|
54809
|
-
light: deriveAccentSurface(primary, surfaces.light, ACCENT_SURFACE_LIGHT_WEIGHT),
|
|
54810
|
-
dark: deriveAccentSurface(primaryDark, surfaces.dark, 0.24),
|
|
54811
|
-
highContrast: deriveAccentSurface(primaryHigh, surfaces.highContrast, 0.24)
|
|
54812
|
-
},
|
|
54813
|
-
textOnAccent: {
|
|
54814
|
-
light: textOnArm(primary),
|
|
54815
|
-
dark: textOnArm(primaryDark),
|
|
54816
|
-
highContrast: textOn(primaryHigh)
|
|
54817
|
-
},
|
|
54818
|
-
accentText: {
|
|
54819
|
-
light: deriveAccentText(primary, [surfaces.light, ...textSurfaces.light ?? []]),
|
|
54820
|
-
dark: deriveAccentText(primaryDark, [surfaces.dark, ...textSurfaces.dark ?? []]),
|
|
54821
|
-
highContrast: deriveAccentText(primaryHigh, [surfaces.highContrast, ...textSurfaces.highContrast ?? []])
|
|
54822
|
-
}
|
|
54823
|
-
};
|
|
54824
|
-
}
|
|
54825
|
-
var ACCENT_SURFACE_MIN_DELTA, ACCENT_SURFACE_LIGHT_WEIGHT, SECONDARY_SHADE_WEIGHT, SECONDARY_MIN_LSTAR, DARK_ARM_MIN_LIFT, DARK_ARM_TARGET_CONTRAST, DARK_ARM_FLOOR_CONTRAST, DARK_ARM_LSTAR_CAP, HIGH_CONTRAST_TARGET, ACCENT_TEXT_MIN_CONTRAST, MID_GREY_LUMINANCE, TEXT_BACKDROP_TOKENS, BRAND_COLOR_TOKENS, BRAND_GLOW_SHADOW;
|
|
54826
|
-
var init_brand_color_math = __esm({
|
|
54827
|
-
"../../core/ts/src/brand-color-math.ts"() {
|
|
54828
|
-
ACCENT_SURFACE_MIN_DELTA = 1.08;
|
|
54829
|
-
ACCENT_SURFACE_LIGHT_WEIGHT = 0.12;
|
|
54830
|
-
SECONDARY_SHADE_WEIGHT = 0.72;
|
|
54831
|
-
SECONDARY_MIN_LSTAR = 22;
|
|
54832
|
-
DARK_ARM_MIN_LIFT = 0.08;
|
|
54833
|
-
DARK_ARM_TARGET_CONTRAST = 3.4;
|
|
54834
|
-
DARK_ARM_FLOOR_CONTRAST = 3;
|
|
54835
|
-
DARK_ARM_LSTAR_CAP = 80;
|
|
54836
|
-
HIGH_CONTRAST_TARGET = 8.5;
|
|
54837
|
-
ACCENT_TEXT_MIN_CONTRAST = 4.5;
|
|
54838
|
-
MID_GREY_LUMINANCE = 0.179;
|
|
54839
|
-
TEXT_BACKDROP_TOKENS = ["surfaceSecondary", "surfaceElevated", "surfaceSubtle", "surfaceTertiary"];
|
|
54840
|
-
BRAND_COLOR_TOKENS = ["accentPrimary", "accentSecondary", "accentSurface", "textOnAccent", "accentText"];
|
|
54841
|
-
BRAND_GLOW_SHADOW = "glow";
|
|
54842
|
-
}
|
|
54843
|
-
});
|
|
54844
|
-
|
|
54845
54933
|
// src/site-analyze/branding-derive.ts
|
|
54846
54934
|
function secondBrandColour(wst) {
|
|
54847
54935
|
for (const name of ["--wst-color-fill-accent-2", "--wst-color-fill-accent-3"]) {
|
|
@@ -69669,7 +69757,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
69669
69757
|
const { detectAndroidNativeDecode: detectAndroidNativeDecode2, detectNativeDecode: detectNativeDecode2, nativeDecodePlatforms: nativeDecodePlatforms2 } = await Promise.resolve().then(() => (init_native_decode(), native_decode_exports));
|
|
69670
69758
|
let platforms;
|
|
69671
69759
|
try {
|
|
69672
|
-
platforms = nativeDecodePlatforms2(flags.native === true ? true : str6(flags.native));
|
|
69760
|
+
platforms = nativeDecodePlatforms2(flags.native === true ? true : str6(flags.native) ?? String(flags.native));
|
|
69673
69761
|
} catch (error) {
|
|
69674
69762
|
io.error(JSON.stringify({ error: error.message }));
|
|
69675
69763
|
return 2;
|
|
@@ -71669,10 +71757,11 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
71669
71757
|
// right below says how (or whether) the narrowing was measured.
|
|
71670
71758
|
enabled: (() => {
|
|
71671
71759
|
const envelope = resolveSurfaceEnvelope(platforms).enabled;
|
|
71672
|
-
|
|
71760
|
+
const families = produced.families;
|
|
71761
|
+
if (!families) return envelope;
|
|
71673
71762
|
return envelope.filter((id) => {
|
|
71674
71763
|
const surface = surfaceById(id);
|
|
71675
|
-
return !surface || !isWidgetFamilySurface(surface) ||
|
|
71764
|
+
return !surface || !isWidgetFamilySurface(surface) || families.has(surfaceFrozenFamily(surface));
|
|
71676
71765
|
});
|
|
71677
71766
|
})(),
|
|
71678
71767
|
// Says which question the `produced` column answered, and — when it could not
|
|
@@ -73541,7 +73630,8 @@ ${report2.ok ? "OK \u2014 data + serve plane reachable." : typeof report2.hint =
|
|
|
73541
73630
|
return 2;
|
|
73542
73631
|
}
|
|
73543
73632
|
const environment2 = str6(flags.environment) ?? "preview";
|
|
73544
|
-
|
|
73633
|
+
const isResourceEnvironment = (v) => v === "preview" || v === "production";
|
|
73634
|
+
if (!isResourceEnvironment(environment2)) {
|
|
73545
73635
|
io.error(JSON.stringify({ error: "--environment must be preview or production" }));
|
|
73546
73636
|
return 2;
|
|
73547
73637
|
}
|
|
@@ -73824,7 +73914,7 @@ ${report2.ok ? "OK \u2014 data + serve plane reachable." : typeof report2.hint =
|
|
|
73824
73914
|
redirectUri: redirectFlag,
|
|
73825
73915
|
cwd: str6(flags.content) ?? process.cwd()
|
|
73826
73916
|
});
|
|
73827
|
-
print(
|
|
73917
|
+
print(r);
|
|
73828
73918
|
return 0;
|
|
73829
73919
|
} catch (e) {
|
|
73830
73920
|
io.error(JSON.stringify({ error: e.message }));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wix/himalaya-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1053.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "himi — the Himalaya authoring CLI. Build a Tier-5 content package on your own machine, push it to the production serve as a draft, preview it on web + Himi Player, and read worker logs back — the remote dev loop. Wraps @himalaya/serve-cli for transport.",
|
|
6
6
|
"keywords": [
|
|
@@ -65,5 +65,5 @@
|
|
|
65
65
|
"artifactId": "himalaya-cli"
|
|
66
66
|
}
|
|
67
67
|
},
|
|
68
|
-
"falconPackageHash": "
|
|
68
|
+
"falconPackageHash": "09a8cfb09738de91c22097314d5bb642195d40f284ccec170bb75968"
|
|
69
69
|
}
|