@wix/himalaya-cli 0.1044.0 → 0.1046.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/sdk/wix-platform/src/index.d.ts +2 -2
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-platform.mjs +6 -67
- package/dist/cli.mjs +308 -172
- package/dist/preview-assets.generated.bin +0 -0
- package/guides/designing-himi-screens.md +5 -1
- package/guides/sdk-reference.json +4 -4
- package/guides/wix-platform-usage.md +1 -1
- package/package.json +2 -2
- package/stdlib/design-kits/README.md +8 -0
- package/templates/beauty-salon/tokens.json +5 -0
- package/templates/beauty-salon-owner/tokens.json +5 -0
- package/templates/community-club/tokens.json +5 -0
- package/templates/community-club-owner/tokens.json +5 -0
- package/templates/events-meetups/tokens.json +5 -0
- package/templates/events-meetups-owner/tokens.json +5 -0
- package/templates/gym-fitness/tokens.json +5 -0
- package/templates/gym-fitness-owner/tokens.json +5 -0
- package/templates/nonprofit-cause/tokens.json +5 -0
- package/templates/nonprofit-cause-owner/tokens.json +5 -0
- package/templates/podcast-creator/tokens.json +5 -0
- package/templates/podcast-creator-owner/tokens.json +5 -0
- package/templates/portfolio-creative/tokens.json +5 -0
- package/templates/portfolio-creative-owner/tokens.json +5 -0
- package/templates/restaurant/tokens.json +5 -0
- package/templates/restaurant-owner/tokens.json +5 -0
- package/templates/retail-store/tokens.json +5 -0
- package/templates/retail-store-owner/tokens.json +5 -0
- package/templates/yoga-studio/tokens.json +5 -0
- package/templates/yoga-studio-owner/tokens.json +5 -0
|
@@ -19,7 +19,7 @@ export interface ExperimentResult {
|
|
|
19
19
|
variant: string;
|
|
20
20
|
}
|
|
21
21
|
export declare const experiments: {
|
|
22
|
-
/**
|
|
22
|
+
/** The app's served variant for `spec` (`himi flags`), or `fallback` when none is assigned. */
|
|
23
23
|
conduct(spec: string, fallback?: string): Promise<ExperimentResult>;
|
|
24
24
|
/** Boolean convenience — true when the variant is exactly "true". */
|
|
25
25
|
isEnabled(spec: string): Promise<boolean>;
|
|
@@ -32,7 +32,7 @@ export declare const experiments: {
|
|
|
32
32
|
}>;
|
|
33
33
|
};
|
|
34
34
|
export declare const flags: {
|
|
35
|
-
/** Whether
|
|
35
|
+
/** Whether the app's served flag `spec` is ON (variant `on`/`true`/`new`), else `fallback`. */
|
|
36
36
|
isEnabled(spec: string, fallback?: boolean): Promise<boolean>;
|
|
37
37
|
/** A toggle's raw value (variant string) for non-boolean specs. */
|
|
38
38
|
value(spec: string, fallback?: string): Promise<string>;
|
|
@@ -62,40 +62,15 @@ function flights() {
|
|
|
62
62
|
function dropConductFlights() {
|
|
63
63
|
flights()?.inflight.clear();
|
|
64
64
|
}
|
|
65
|
-
var conductedReal = (value) => ({ value, cacheable: true });
|
|
66
|
-
var conductedSeam = (value) => ({ value, cacheable: false });
|
|
67
|
-
async function l2Get(ns, spec) {
|
|
68
|
-
try {
|
|
69
|
-
const r = await call("conductedGet", { door: ns, spec });
|
|
70
|
-
return {
|
|
71
|
-
value: r?.hit && typeof r.value === "string" && r.value.length > 0 ? r.value : null,
|
|
72
|
-
scope: typeof r?.scope === "string" && r.scope.length > 0 ? r.scope : null
|
|
73
|
-
};
|
|
74
|
-
} catch {
|
|
75
|
-
return { value: null, scope: null };
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
async function l2Put(ns, spec, value, scope) {
|
|
79
|
-
try {
|
|
80
|
-
await call("conductedPut", { door: ns, spec, value, scope });
|
|
81
|
-
} catch {
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
65
|
async function conductCached(ns, spec, fallback, resolve) {
|
|
85
66
|
const f = flights();
|
|
86
|
-
if (!f) return
|
|
67
|
+
if (!f) return resolve();
|
|
87
68
|
const flightKey = JSON.stringify([ns, spec, fallback]);
|
|
88
69
|
const pending = f.inflight.get(flightKey);
|
|
89
70
|
if (pending) return pending;
|
|
90
71
|
const task = (async () => {
|
|
91
72
|
try {
|
|
92
|
-
|
|
93
|
-
if (cached !== null) return cached;
|
|
94
|
-
const { value, cacheable } = await resolve();
|
|
95
|
-
if (cacheable && value !== null && value.length > 0 && scope !== null) {
|
|
96
|
-
await l2Put(ns, spec, value, scope);
|
|
97
|
-
}
|
|
98
|
-
return value;
|
|
73
|
+
return await resolve();
|
|
99
74
|
} finally {
|
|
100
75
|
f.inflight.delete(flightKey);
|
|
101
76
|
}
|
|
@@ -103,31 +78,16 @@ async function conductCached(ns, spec, fallback, resolve) {
|
|
|
103
78
|
f.inflight.set(flightKey, task);
|
|
104
79
|
return task;
|
|
105
80
|
}
|
|
106
|
-
var PETRI_CONDUCT = "/_api/wix-petri-webapp/v1/conductExperiment";
|
|
107
81
|
async function resolveExperiment(spec, fallback) {
|
|
108
|
-
if (isMemberReal("experiments")) {
|
|
109
|
-
try {
|
|
110
|
-
const r2 = await realWix("POST", PETRI_CONDUCT, { key: spec, fallbackValue: fallback });
|
|
111
|
-
if (typeof r2?.value === "string") return conductedReal(r2.value);
|
|
112
|
-
} catch {
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
82
|
const r = await call("experimentsConduct", { spec, fallback });
|
|
116
|
-
return
|
|
83
|
+
return typeof r?.variant === "string" ? r.variant : null;
|
|
117
84
|
}
|
|
118
85
|
async function resolveFlag(spec, fallback) {
|
|
119
|
-
if (isMemberReal("flags")) {
|
|
120
|
-
try {
|
|
121
|
-
const r2 = await realWix("POST", PETRI_CONDUCT, { key: spec, fallbackValue: String(fallback) });
|
|
122
|
-
if (typeof r2?.value === "string") return conductedReal(r2.value);
|
|
123
|
-
} catch {
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
86
|
const r = await call("flagsIsEnabled", { spec, fallback });
|
|
127
|
-
return
|
|
87
|
+
return typeof r?.enabled === "boolean" ? String(r.enabled) : null;
|
|
128
88
|
}
|
|
129
89
|
var experiments = {
|
|
130
|
-
/**
|
|
90
|
+
/** The app's served variant for `spec` (`himi flags`), or `fallback` when none is assigned. */
|
|
131
91
|
async conduct(spec, fallback = "false") {
|
|
132
92
|
const resolved = await conductCached("experiments", spec, fallback, () => resolveExperiment(spec, fallback));
|
|
133
93
|
return { spec, variant: resolved ?? fallback };
|
|
@@ -146,7 +106,7 @@ var experiments = {
|
|
|
146
106
|
}
|
|
147
107
|
};
|
|
148
108
|
var flags = {
|
|
149
|
-
/** Whether
|
|
109
|
+
/** Whether the app's served flag `spec` is ON (variant `on`/`true`/`new`), else `fallback`. */
|
|
150
110
|
async isEnabled(spec, fallback = false) {
|
|
151
111
|
const resolved = await conductCached("flags", spec, String(fallback), () => resolveFlag(spec, fallback));
|
|
152
112
|
if (resolved === null) return fallback;
|
|
@@ -186,25 +146,11 @@ var i18n = {
|
|
|
186
146
|
var ping = {
|
|
187
147
|
/** Register the device's push token with Wix Ping. */
|
|
188
148
|
async register() {
|
|
189
|
-
if (isMemberReal("ping")) {
|
|
190
|
-
try {
|
|
191
|
-
const r2 = await realWix("POST", "/_api/ping-webapp/v1/registrations", {});
|
|
192
|
-
if (r2 && typeof r2.registered === "boolean") return { registered: r2.registered, token: r2.token ?? "" };
|
|
193
|
-
} catch {
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
149
|
const r = await call("pingRegister");
|
|
197
150
|
return { registered: r?.registered ?? false, token: r?.token ?? "" };
|
|
198
151
|
},
|
|
199
152
|
/** Current Ping registration status (no network). */
|
|
200
153
|
async status() {
|
|
201
|
-
if (isMemberReal("ping")) {
|
|
202
|
-
try {
|
|
203
|
-
const r2 = await realWix("GET", "/_api/ping-webapp/v1/registrations");
|
|
204
|
-
if (r2 && typeof r2.registered === "boolean") return { registered: r2.registered, token: r2.token ?? "" };
|
|
205
|
-
} catch {
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
154
|
const r = await call("pingStatus");
|
|
209
155
|
return { registered: r?.registered ?? false, token: r?.token ?? "" };
|
|
210
156
|
}
|
|
@@ -212,13 +158,6 @@ var ping = {
|
|
|
212
158
|
var deeplink = {
|
|
213
159
|
/** Resolve a deferred (post-install) deep link via Wix Jot. Null when none. */
|
|
214
160
|
async resolveDeferred() {
|
|
215
|
-
if (isMemberReal("deeplink")) {
|
|
216
|
-
try {
|
|
217
|
-
const r2 = await realWix("GET", "/_api/app-link-server/v1/deferred-deep-link");
|
|
218
|
-
if (r2) return { link: r2.link && r2.link.length > 0 ? r2.link : null };
|
|
219
|
-
} catch {
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
161
|
const r = await call("deeplinkResolveDeferred");
|
|
223
162
|
return { link: r?.link && r.link.length > 0 ? r.link : null };
|
|
224
163
|
}
|
package/dist/cli.mjs
CHANGED
|
@@ -13197,8 +13197,17 @@ function hexToRgb2(hex2) {
|
|
|
13197
13197
|
return [int >> 16 & 255, int >> 8 & 255, int & 255];
|
|
13198
13198
|
}
|
|
13199
13199
|
function rgba(color, alpha2) {
|
|
13200
|
-
|
|
13201
|
-
|
|
13200
|
+
let h = color.trim().replace(/^#/, "");
|
|
13201
|
+
let own3 = 1;
|
|
13202
|
+
if (/^[\da-f]{4}$/i.test(h) || /^[\da-f]{8}$/i.test(h)) {
|
|
13203
|
+
const a = h.length === 4 ? h[3] + h[3] : h.slice(6, 8);
|
|
13204
|
+
own3 = parseInt(a, 16) / 255;
|
|
13205
|
+
h = h.length === 4 ? h.slice(0, 3) : h.slice(0, 6);
|
|
13206
|
+
}
|
|
13207
|
+
const rgb = hexToRgb2(`#${h}`);
|
|
13208
|
+
if (!rgb) return color;
|
|
13209
|
+
const composed = own3 === 1 ? clamp(alpha2) : Math.round(clamp(alpha2) * own3 * 1e3) / 1e3;
|
|
13210
|
+
return `rgba(${rgb[0]}, ${rgb[1]}, ${rgb[2]}, ${composed})`;
|
|
13202
13211
|
}
|
|
13203
13212
|
function normalizeSpring(spring, durationMs) {
|
|
13204
13213
|
return {
|
|
@@ -18821,6 +18830,204 @@ ${cookieHeader}`);
|
|
|
18821
18830
|
}
|
|
18822
18831
|
});
|
|
18823
18832
|
|
|
18833
|
+
// ../../core/ts/src/flags-engine.ts
|
|
18834
|
+
function bucket(key2) {
|
|
18835
|
+
const digest2 = sha1(key2);
|
|
18836
|
+
const n = (digest2[0] << 24 | digest2[1] << 16 | digest2[2] << 8 | digest2[3]) >>> 0;
|
|
18837
|
+
return n % 1e4;
|
|
18838
|
+
}
|
|
18839
|
+
function attrValue(ctx, attribute) {
|
|
18840
|
+
switch (attribute) {
|
|
18841
|
+
case "platform":
|
|
18842
|
+
return ctx.platform;
|
|
18843
|
+
case "appVersion":
|
|
18844
|
+
return ctx.appVersion;
|
|
18845
|
+
case "locale":
|
|
18846
|
+
return ctx.locale;
|
|
18847
|
+
case "appId":
|
|
18848
|
+
return ctx.appId;
|
|
18849
|
+
case "userId":
|
|
18850
|
+
return ctx.userId;
|
|
18851
|
+
default:
|
|
18852
|
+
return ctx.custom?.[attribute];
|
|
18853
|
+
}
|
|
18854
|
+
}
|
|
18855
|
+
function clauseMatches(ctx, c) {
|
|
18856
|
+
const v = attrValue(ctx, c.attribute);
|
|
18857
|
+
switch (c.op) {
|
|
18858
|
+
case "eq":
|
|
18859
|
+
return v !== void 0 && c.values.includes(v);
|
|
18860
|
+
case "neq":
|
|
18861
|
+
return v === void 0 || !c.values.includes(v);
|
|
18862
|
+
case "in":
|
|
18863
|
+
return v !== void 0 && c.values.includes(v);
|
|
18864
|
+
case "contains":
|
|
18865
|
+
return v !== void 0 && c.values.some((needle) => v.includes(needle));
|
|
18866
|
+
default:
|
|
18867
|
+
return false;
|
|
18868
|
+
}
|
|
18869
|
+
}
|
|
18870
|
+
function ruleMatches(ctx, rule) {
|
|
18871
|
+
return rule.clauses.length > 0 && rule.clauses.every((c) => clauseMatches(ctx, c));
|
|
18872
|
+
}
|
|
18873
|
+
function variantForBucket(def, b) {
|
|
18874
|
+
const total = def.variants.reduce((s, v) => s + Math.max(0, v.weight), 0);
|
|
18875
|
+
if (total <= 0) return def.defaultVariant;
|
|
18876
|
+
const target = b / 1e4 * total;
|
|
18877
|
+
let acc = 0;
|
|
18878
|
+
for (const v of def.variants) {
|
|
18879
|
+
acc += Math.max(0, v.weight);
|
|
18880
|
+
if (target < acc) return v.key;
|
|
18881
|
+
}
|
|
18882
|
+
return def.variants[def.variants.length - 1].key;
|
|
18883
|
+
}
|
|
18884
|
+
function evaluate(def, ctx, override) {
|
|
18885
|
+
const base = { key: def.key, experimentId: def.experiment?.id };
|
|
18886
|
+
if (override) return { ...base, variant: override, reason: "override" };
|
|
18887
|
+
if (!def.enabled) return { ...base, variant: def.defaultVariant, reason: "disabled" };
|
|
18888
|
+
for (const rule of def.targeting ?? []) {
|
|
18889
|
+
if (ruleMatches(ctx, rule)) return { ...base, variant: rule.variant, reason: "targeting" };
|
|
18890
|
+
}
|
|
18891
|
+
const id = ctx.userId ?? ctx.sessionId;
|
|
18892
|
+
const seed2 = def.seed ?? def.key;
|
|
18893
|
+
const rollout = def.rolloutPercentage ?? 100;
|
|
18894
|
+
if (rollout < 100) {
|
|
18895
|
+
const gate = bucket(`${id}:${seed2}:rollout`);
|
|
18896
|
+
if (gate >= rollout * 100) return { ...base, variant: def.defaultVariant, reason: "default" };
|
|
18897
|
+
}
|
|
18898
|
+
const variant = variantForBucket(def, bucket(`${id}:${seed2}`));
|
|
18899
|
+
return { ...base, variant, reason: "rollout" };
|
|
18900
|
+
}
|
|
18901
|
+
function evaluateAll(defs, ctx, overrides) {
|
|
18902
|
+
const out = {};
|
|
18903
|
+
for (const def of defs) out[def.key] = evaluate(def, ctx, overrides?.[def.key]);
|
|
18904
|
+
return out;
|
|
18905
|
+
}
|
|
18906
|
+
function utf8(input) {
|
|
18907
|
+
return new TextEncoder().encode(input);
|
|
18908
|
+
}
|
|
18909
|
+
function sha1(input) {
|
|
18910
|
+
const bytes2 = typeof input === "string" ? utf8(input) : input;
|
|
18911
|
+
const bitLen = bytes2.length * 8;
|
|
18912
|
+
const padded = new Uint8Array(((bytes2.length + 9 + 63) / 64 | 0) * 64);
|
|
18913
|
+
padded.set(bytes2);
|
|
18914
|
+
padded[bytes2.length] = 128;
|
|
18915
|
+
const view = new DataView(padded.buffer);
|
|
18916
|
+
view.setUint32(padded.length - 8, Math.floor(bitLen / 4294967296));
|
|
18917
|
+
view.setUint32(padded.length - 4, bitLen >>> 0);
|
|
18918
|
+
let h0 = 1732584193, h1 = 4023233417, h2 = 2562383102, h3 = 271733878, h4 = 3285377520;
|
|
18919
|
+
const w = new Uint32Array(80);
|
|
18920
|
+
for (let off = 0; off < padded.length; off += 64) {
|
|
18921
|
+
for (let i = 0; i < 16; i++) w[i] = view.getUint32(off + i * 4);
|
|
18922
|
+
for (let i = 16; i < 80; i++) {
|
|
18923
|
+
const v = w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16];
|
|
18924
|
+
w[i] = (v << 1 | v >>> 31) >>> 0;
|
|
18925
|
+
}
|
|
18926
|
+
let a = h0, b = h1, c = h2, d = h3, e = h4;
|
|
18927
|
+
for (let i = 0; i < 80; i++) {
|
|
18928
|
+
let f;
|
|
18929
|
+
let k;
|
|
18930
|
+
if (i < 20) {
|
|
18931
|
+
f = b & c | ~b & d;
|
|
18932
|
+
k = 1518500249;
|
|
18933
|
+
} else if (i < 40) {
|
|
18934
|
+
f = b ^ c ^ d;
|
|
18935
|
+
k = 1859775393;
|
|
18936
|
+
} else if (i < 60) {
|
|
18937
|
+
f = b & c | b & d | c & d;
|
|
18938
|
+
k = 2400959708;
|
|
18939
|
+
} else {
|
|
18940
|
+
f = b ^ c ^ d;
|
|
18941
|
+
k = 3395469782;
|
|
18942
|
+
}
|
|
18943
|
+
const t = ((a << 5 | a >>> 27) >>> 0) + (f >>> 0) + e + k + w[i] >>> 0;
|
|
18944
|
+
e = d;
|
|
18945
|
+
d = c;
|
|
18946
|
+
c = (b << 30 | b >>> 2) >>> 0;
|
|
18947
|
+
b = a;
|
|
18948
|
+
a = t;
|
|
18949
|
+
}
|
|
18950
|
+
h0 = h0 + a >>> 0;
|
|
18951
|
+
h1 = h1 + b >>> 0;
|
|
18952
|
+
h2 = h2 + c >>> 0;
|
|
18953
|
+
h3 = h3 + d >>> 0;
|
|
18954
|
+
h4 = h4 + e >>> 0;
|
|
18955
|
+
}
|
|
18956
|
+
const out = new Uint8Array(20);
|
|
18957
|
+
const outView = new DataView(out.buffer);
|
|
18958
|
+
outView.setUint32(0, h0);
|
|
18959
|
+
outView.setUint32(4, h1);
|
|
18960
|
+
outView.setUint32(8, h2);
|
|
18961
|
+
outView.setUint32(12, h3);
|
|
18962
|
+
outView.setUint32(16, h4);
|
|
18963
|
+
return out;
|
|
18964
|
+
}
|
|
18965
|
+
var init_flags_engine = __esm({
|
|
18966
|
+
"../../core/ts/src/flags-engine.ts"() {
|
|
18967
|
+
}
|
|
18968
|
+
});
|
|
18969
|
+
|
|
18970
|
+
// ../../core/serve-runtime/src/flag-assignments.ts
|
|
18971
|
+
function bad(error) {
|
|
18972
|
+
return new Response(JSON.stringify({ error }), { status: 400, headers: { "content-type": JSON_CT, "cache-control": "no-store" } });
|
|
18973
|
+
}
|
|
18974
|
+
function flagAssignmentsBody(app, defs, ctx, overrides, ttlSeconds = FLAG_ASSIGNMENTS_TTL_SECONDS) {
|
|
18975
|
+
const evalCtx = {
|
|
18976
|
+
sessionId: ctx.id,
|
|
18977
|
+
appId: app,
|
|
18978
|
+
...ctx.platform ? { platform: ctx.platform } : {},
|
|
18979
|
+
...ctx.appVersion ? { appVersion: ctx.appVersion } : {},
|
|
18980
|
+
...ctx.locale ? { locale: ctx.locale } : {}
|
|
18981
|
+
};
|
|
18982
|
+
const byKey = new Map(defs.map((d) => [d.key, d]));
|
|
18983
|
+
const assignments = {};
|
|
18984
|
+
for (const [key2, a] of Object.entries(evaluateAll(defs, evalCtx, overrides))) {
|
|
18985
|
+
const value = byKey.get(key2)?.variants.find((v) => v.key === a.variant)?.value;
|
|
18986
|
+
assignments[key2] = {
|
|
18987
|
+
variant: a.variant,
|
|
18988
|
+
reason: a.reason,
|
|
18989
|
+
...a.experimentId ? { experimentId: a.experimentId } : {},
|
|
18990
|
+
...value !== void 0 ? { value } : {}
|
|
18991
|
+
};
|
|
18992
|
+
}
|
|
18993
|
+
return { app, id: ctx.id, assignments, ttlSeconds };
|
|
18994
|
+
}
|
|
18995
|
+
function flagAssignmentsResponse(request, app, defs, overrides, ttlSeconds = FLAG_ASSIGNMENTS_TTL_SECONDS) {
|
|
18996
|
+
if (request.method !== "GET" && request.method !== "HEAD") {
|
|
18997
|
+
return new Response(JSON.stringify({ error: "method_not_allowed" }), { status: 405, headers: { "content-type": JSON_CT } });
|
|
18998
|
+
}
|
|
18999
|
+
const url = new URL(request.url);
|
|
19000
|
+
const id = url.searchParams.get("id") ?? "";
|
|
19001
|
+
if (!id) return bad("missing_id");
|
|
19002
|
+
if (id.length > MAX_ID_LENGTH) return bad("id_too_long");
|
|
19003
|
+
const q = (k) => url.searchParams.get(k) || void 0;
|
|
19004
|
+
const body = JSON.stringify(flagAssignmentsBody(app, defs.filter(isEvaluable), {
|
|
19005
|
+
id,
|
|
19006
|
+
platform: q("platform"),
|
|
19007
|
+
appVersion: q("appVersion"),
|
|
19008
|
+
locale: q("locale")
|
|
19009
|
+
}, overrides, ttlSeconds));
|
|
19010
|
+
const etag = strongEtag(body);
|
|
19011
|
+
const headers2 = { "content-type": JSON_CT, etag, "cache-control": `private, max-age=${Math.min(ttlSeconds, 60)}` };
|
|
19012
|
+
if (request.headers.get("if-none-match") === etag) return new Response(null, { status: 304, headers: headers2 });
|
|
19013
|
+
return new Response(request.method === "HEAD" ? null : body, { status: 200, headers: headers2 });
|
|
19014
|
+
}
|
|
19015
|
+
function isEvaluable(d) {
|
|
19016
|
+
const x = d;
|
|
19017
|
+
return !!x && typeof x.key === "string" && Array.isArray(x.variants) && typeof x.defaultVariant === "string";
|
|
19018
|
+
}
|
|
19019
|
+
var FLAG_ASSIGNMENTS_PATH, FLAG_ASSIGNMENTS_TTL_SECONDS, MAX_ID_LENGTH, JSON_CT;
|
|
19020
|
+
var init_flag_assignments = __esm({
|
|
19021
|
+
"../../core/serve-runtime/src/flag-assignments.ts"() {
|
|
19022
|
+
init_flags_engine();
|
|
19023
|
+
init_contract();
|
|
19024
|
+
FLAG_ASSIGNMENTS_PATH = /^\/v1\/flags\/([^/]+)\/assignments$/;
|
|
19025
|
+
FLAG_ASSIGNMENTS_TTL_SECONDS = 300;
|
|
19026
|
+
MAX_ID_LENGTH = 256;
|
|
19027
|
+
JSON_CT = "application/json; charset=utf-8";
|
|
19028
|
+
}
|
|
19029
|
+
});
|
|
19030
|
+
|
|
18824
19031
|
// ../../core/dev-server/src/images.ts
|
|
18825
19032
|
import { createHash as createHash11 } from "node:crypto";
|
|
18826
19033
|
function svgFor(productId, title, sku) {
|
|
@@ -24966,6 +25173,7 @@ function withTheme(ctx, theme) {
|
|
|
24966
25173
|
const base = ctx.tokens;
|
|
24967
25174
|
const colors = { ...base.colors ?? {} };
|
|
24968
25175
|
if (theme.colors) for (const [k, v] of Object.entries(theme.colors)) colors[k] = v;
|
|
25176
|
+
if (theme.colors && "accentPrimary" in theme.colors && !("accentText" in theme.colors)) delete colors.accentText;
|
|
24969
25177
|
const typography = { ...base.typography ?? {} };
|
|
24970
25178
|
if (theme.typography) for (const [k, v] of Object.entries(theme.typography)) typography[k] = v;
|
|
24971
25179
|
const kit = { ...base.kit ?? {} };
|
|
@@ -26143,6 +26351,9 @@ function actionClick(ctx, action) {
|
|
|
26143
26351
|
ctx.onAction(resolveItemDeep2(action, ctx));
|
|
26144
26352
|
};
|
|
26145
26353
|
}
|
|
26354
|
+
function accentTextColor(ctx) {
|
|
26355
|
+
return ctx.color("accentText", ctx.color("accentPrimary", "#116DFF"));
|
|
26356
|
+
}
|
|
26146
26357
|
function actionTextButton(ctx, action, label2, color, extra) {
|
|
26147
26358
|
if (action == null) return null;
|
|
26148
26359
|
const onClick = actionClick(ctx, action);
|
|
@@ -29033,7 +29244,7 @@ var init_renderNode = __esm({
|
|
|
29033
29244
|
e?.stopPropagation?.();
|
|
29034
29245
|
ctx.onAction(resolveItemDeep2(props.action, ctx));
|
|
29035
29246
|
} : void 0;
|
|
29036
|
-
const fg = primary ? C("textOnAccent", "#fff") :
|
|
29247
|
+
const fg = primary ? C("textOnAccent", "#fff") : accentTextColor(ctx);
|
|
29037
29248
|
const pillRadius = props.cornerRadius != null ? props.cornerRadius : ctx.radius("pill", 24);
|
|
29038
29249
|
const vPad = props.iconOnly ? 11 : props.size === "sm" ? 8 : props.size === "lg" ? 16 : 13;
|
|
29039
29250
|
const hPadBase = props.iconOnly ? 11 : props.size === "sm" ? 13 : props.size === "lg" ? 22 : 16;
|
|
@@ -29102,14 +29313,14 @@ var init_renderNode = __esm({
|
|
|
29102
29313
|
fontSize: f.remSize,
|
|
29103
29314
|
background: primary ? accent : "transparent",
|
|
29104
29315
|
color: fg,
|
|
29105
|
-
border: outlined ? `1px solid ${
|
|
29316
|
+
border: outlined ? `1px solid ${fg}` : "none",
|
|
29106
29317
|
cursor: disabled ? "default" : "pointer",
|
|
29107
29318
|
opacity: disabled ? 0.55 : 1,
|
|
29108
29319
|
boxSizing: "border-box",
|
|
29109
29320
|
...wrap
|
|
29110
29321
|
}, rowStretch, "fit-content"),
|
|
29111
29322
|
children: [
|
|
29112
|
-
props.loading && /* @__PURE__ */ jsx6("span", { style: { width: glyph, height: glyph, borderRadius: "50%", border: `2px solid ${primary ?
|
|
29323
|
+
props.loading && /* @__PURE__ */ jsx6("span", { style: { width: glyph, height: glyph, borderRadius: "50%", border: `2px solid ${rgba(fg, primary ? 0.4 : 0.35)}`, borderTopColor: fg, animation: ctx.empty ? void 0 : "himalaya-spin .7s linear infinite" } }),
|
|
29113
29324
|
!props.loading && resolvedLeadingIcon && ic(String(resolvedLeadingIcon)),
|
|
29114
29325
|
!props.iconOnly && (resolvedTitle != null && resolvedTitle !== "" ? String(resolvedTitle) : txt(props.title, ctx) || "Button"),
|
|
29115
29326
|
!props.loading && !props.iconOnly && resolvedTrailingIcon && ic(String(resolvedTrailingIcon))
|
|
@@ -32018,143 +32229,6 @@ var init_flags = __esm({
|
|
|
32018
32229
|
}
|
|
32019
32230
|
});
|
|
32020
32231
|
|
|
32021
|
-
// ../../core/ts/src/flags-engine.ts
|
|
32022
|
-
function bucket(key2) {
|
|
32023
|
-
const digest2 = sha1(key2);
|
|
32024
|
-
const n = (digest2[0] << 24 | digest2[1] << 16 | digest2[2] << 8 | digest2[3]) >>> 0;
|
|
32025
|
-
return n % 1e4;
|
|
32026
|
-
}
|
|
32027
|
-
function attrValue(ctx, attribute) {
|
|
32028
|
-
switch (attribute) {
|
|
32029
|
-
case "platform":
|
|
32030
|
-
return ctx.platform;
|
|
32031
|
-
case "appVersion":
|
|
32032
|
-
return ctx.appVersion;
|
|
32033
|
-
case "locale":
|
|
32034
|
-
return ctx.locale;
|
|
32035
|
-
case "appId":
|
|
32036
|
-
return ctx.appId;
|
|
32037
|
-
case "userId":
|
|
32038
|
-
return ctx.userId;
|
|
32039
|
-
default:
|
|
32040
|
-
return ctx.custom?.[attribute];
|
|
32041
|
-
}
|
|
32042
|
-
}
|
|
32043
|
-
function clauseMatches(ctx, c) {
|
|
32044
|
-
const v = attrValue(ctx, c.attribute);
|
|
32045
|
-
switch (c.op) {
|
|
32046
|
-
case "eq":
|
|
32047
|
-
return v !== void 0 && c.values.includes(v);
|
|
32048
|
-
case "neq":
|
|
32049
|
-
return v === void 0 || !c.values.includes(v);
|
|
32050
|
-
case "in":
|
|
32051
|
-
return v !== void 0 && c.values.includes(v);
|
|
32052
|
-
case "contains":
|
|
32053
|
-
return v !== void 0 && c.values.some((needle) => v.includes(needle));
|
|
32054
|
-
default:
|
|
32055
|
-
return false;
|
|
32056
|
-
}
|
|
32057
|
-
}
|
|
32058
|
-
function ruleMatches(ctx, rule) {
|
|
32059
|
-
return rule.clauses.length > 0 && rule.clauses.every((c) => clauseMatches(ctx, c));
|
|
32060
|
-
}
|
|
32061
|
-
function variantForBucket(def, b) {
|
|
32062
|
-
const total = def.variants.reduce((s, v) => s + Math.max(0, v.weight), 0);
|
|
32063
|
-
if (total <= 0) return def.defaultVariant;
|
|
32064
|
-
const target = b / 1e4 * total;
|
|
32065
|
-
let acc = 0;
|
|
32066
|
-
for (const v of def.variants) {
|
|
32067
|
-
acc += Math.max(0, v.weight);
|
|
32068
|
-
if (target < acc) return v.key;
|
|
32069
|
-
}
|
|
32070
|
-
return def.variants[def.variants.length - 1].key;
|
|
32071
|
-
}
|
|
32072
|
-
function evaluate(def, ctx, override) {
|
|
32073
|
-
const base = { key: def.key, experimentId: def.experiment?.id };
|
|
32074
|
-
if (override) return { ...base, variant: override, reason: "override" };
|
|
32075
|
-
if (!def.enabled) return { ...base, variant: def.defaultVariant, reason: "disabled" };
|
|
32076
|
-
for (const rule of def.targeting ?? []) {
|
|
32077
|
-
if (ruleMatches(ctx, rule)) return { ...base, variant: rule.variant, reason: "targeting" };
|
|
32078
|
-
}
|
|
32079
|
-
const id = ctx.userId ?? ctx.sessionId;
|
|
32080
|
-
const seed2 = def.seed ?? def.key;
|
|
32081
|
-
const rollout = def.rolloutPercentage ?? 100;
|
|
32082
|
-
if (rollout < 100) {
|
|
32083
|
-
const gate = bucket(`${id}:${seed2}:rollout`);
|
|
32084
|
-
if (gate >= rollout * 100) return { ...base, variant: def.defaultVariant, reason: "default" };
|
|
32085
|
-
}
|
|
32086
|
-
const variant = variantForBucket(def, bucket(`${id}:${seed2}`));
|
|
32087
|
-
return { ...base, variant, reason: "rollout" };
|
|
32088
|
-
}
|
|
32089
|
-
function evaluateAll(defs, ctx, overrides) {
|
|
32090
|
-
const out = {};
|
|
32091
|
-
for (const def of defs) out[def.key] = evaluate(def, ctx, overrides?.[def.key]);
|
|
32092
|
-
return out;
|
|
32093
|
-
}
|
|
32094
|
-
function utf8(input) {
|
|
32095
|
-
return new TextEncoder().encode(input);
|
|
32096
|
-
}
|
|
32097
|
-
function sha1(input) {
|
|
32098
|
-
const bytes2 = typeof input === "string" ? utf8(input) : input;
|
|
32099
|
-
const bitLen = bytes2.length * 8;
|
|
32100
|
-
const padded = new Uint8Array(((bytes2.length + 9 + 63) / 64 | 0) * 64);
|
|
32101
|
-
padded.set(bytes2);
|
|
32102
|
-
padded[bytes2.length] = 128;
|
|
32103
|
-
const view = new DataView(padded.buffer);
|
|
32104
|
-
view.setUint32(padded.length - 8, Math.floor(bitLen / 4294967296));
|
|
32105
|
-
view.setUint32(padded.length - 4, bitLen >>> 0);
|
|
32106
|
-
let h0 = 1732584193, h1 = 4023233417, h2 = 2562383102, h3 = 271733878, h4 = 3285377520;
|
|
32107
|
-
const w = new Uint32Array(80);
|
|
32108
|
-
for (let off = 0; off < padded.length; off += 64) {
|
|
32109
|
-
for (let i = 0; i < 16; i++) w[i] = view.getUint32(off + i * 4);
|
|
32110
|
-
for (let i = 16; i < 80; i++) {
|
|
32111
|
-
const v = w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16];
|
|
32112
|
-
w[i] = (v << 1 | v >>> 31) >>> 0;
|
|
32113
|
-
}
|
|
32114
|
-
let a = h0, b = h1, c = h2, d = h3, e = h4;
|
|
32115
|
-
for (let i = 0; i < 80; i++) {
|
|
32116
|
-
let f;
|
|
32117
|
-
let k;
|
|
32118
|
-
if (i < 20) {
|
|
32119
|
-
f = b & c | ~b & d;
|
|
32120
|
-
k = 1518500249;
|
|
32121
|
-
} else if (i < 40) {
|
|
32122
|
-
f = b ^ c ^ d;
|
|
32123
|
-
k = 1859775393;
|
|
32124
|
-
} else if (i < 60) {
|
|
32125
|
-
f = b & c | b & d | c & d;
|
|
32126
|
-
k = 2400959708;
|
|
32127
|
-
} else {
|
|
32128
|
-
f = b ^ c ^ d;
|
|
32129
|
-
k = 3395469782;
|
|
32130
|
-
}
|
|
32131
|
-
const t = ((a << 5 | a >>> 27) >>> 0) + (f >>> 0) + e + k + w[i] >>> 0;
|
|
32132
|
-
e = d;
|
|
32133
|
-
d = c;
|
|
32134
|
-
c = (b << 30 | b >>> 2) >>> 0;
|
|
32135
|
-
b = a;
|
|
32136
|
-
a = t;
|
|
32137
|
-
}
|
|
32138
|
-
h0 = h0 + a >>> 0;
|
|
32139
|
-
h1 = h1 + b >>> 0;
|
|
32140
|
-
h2 = h2 + c >>> 0;
|
|
32141
|
-
h3 = h3 + d >>> 0;
|
|
32142
|
-
h4 = h4 + e >>> 0;
|
|
32143
|
-
}
|
|
32144
|
-
const out = new Uint8Array(20);
|
|
32145
|
-
const outView = new DataView(out.buffer);
|
|
32146
|
-
outView.setUint32(0, h0);
|
|
32147
|
-
outView.setUint32(4, h1);
|
|
32148
|
-
outView.setUint32(8, h2);
|
|
32149
|
-
outView.setUint32(12, h3);
|
|
32150
|
-
outView.setUint32(16, h4);
|
|
32151
|
-
return out;
|
|
32152
|
-
}
|
|
32153
|
-
var init_flags_engine = __esm({
|
|
32154
|
-
"../../core/ts/src/flags-engine.ts"() {
|
|
32155
|
-
}
|
|
32156
|
-
});
|
|
32157
|
-
|
|
32158
32232
|
// ../../core/ts/src/launch-manifest.ts
|
|
32159
32233
|
import Ajv2 from "ajv";
|
|
32160
32234
|
var directiveObject, LAUNCH_MANIFEST_SCHEMA;
|
|
@@ -36220,6 +36294,23 @@ function createDevServer(opts = {}) {
|
|
|
36220
36294
|
const k = readKit(kitM[1]);
|
|
36221
36295
|
return k ? sendJson(res, 200, k, { "access-control-allow-origin": "*" }) : sendJson(res, 404, { error: "unknown_kit", id: kitM[1] }, { "access-control-allow-origin": "*" });
|
|
36222
36296
|
}
|
|
36297
|
+
const flagAssignM = /^\/v1\/flags\/([^/?]+)\/assignments(?:\?|$)/.exec(url);
|
|
36298
|
+
if (flagAssignM && (req.method === "GET" || req.method === "HEAD")) {
|
|
36299
|
+
await state.flagSync.refresh(state.app?.dir, state.flagStore, Date.now());
|
|
36300
|
+
const ours = flagAssignM[1] === state.appName;
|
|
36301
|
+
const answer = flagAssignmentsResponse(
|
|
36302
|
+
new Request(`http://dev-server${url}`, {
|
|
36303
|
+
method: req.method,
|
|
36304
|
+
headers: typeof req.headers["if-none-match"] === "string" ? { "if-none-match": req.headers["if-none-match"] } : {}
|
|
36305
|
+
}),
|
|
36306
|
+
flagAssignM[1],
|
|
36307
|
+
ours ? state.flagStore.list() : [],
|
|
36308
|
+
ours ? currentFlagConfig(state)?.overrides : void 0
|
|
36309
|
+
);
|
|
36310
|
+
res.writeHead(answer.status, { ...Object.fromEntries(answer.headers), "access-control-allow-origin": "*" });
|
|
36311
|
+
res.end(answer.status === 200 && req.method === "GET" ? await answer.text() : void 0);
|
|
36312
|
+
return;
|
|
36313
|
+
}
|
|
36223
36314
|
if (url.startsWith("/v1/revocations") && req.method === "GET") {
|
|
36224
36315
|
let revoked = [];
|
|
36225
36316
|
if (state.app) {
|
|
@@ -36442,6 +36533,7 @@ var init_src6 = __esm({
|
|
|
36442
36533
|
init_wix_gateway();
|
|
36443
36534
|
init_wix_member_login();
|
|
36444
36535
|
init_wix_bridge();
|
|
36536
|
+
init_flag_assignments();
|
|
36445
36537
|
init_images();
|
|
36446
36538
|
init_l10n();
|
|
36447
36539
|
init_l10n_catalog();
|
|
@@ -49454,7 +49546,7 @@ var init_wix_member_auth = __esm({
|
|
|
49454
49546
|
|
|
49455
49547
|
// ../../core/serve/src/server.ts
|
|
49456
49548
|
function json3(status, body, headers2 = {}) {
|
|
49457
|
-
return new Response(JSON.stringify(body), { status, headers: { "content-type":
|
|
49549
|
+
return new Response(JSON.stringify(body), { status, headers: { "content-type": JSON_CT2, ...headers2 } });
|
|
49458
49550
|
}
|
|
49459
49551
|
function isCookieAuthorizedPath(path2) {
|
|
49460
49552
|
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;
|
|
@@ -49614,7 +49706,7 @@ ${releaseId}`;
|
|
|
49614
49706
|
if (request.headers.get("if-none-match") === etag) {
|
|
49615
49707
|
return new Response(null, { status: 304, headers: { etag, "cache-control": cache, ...vary } });
|
|
49616
49708
|
}
|
|
49617
|
-
return new Response(body, { status: 200, headers: { "content-type":
|
|
49709
|
+
return new Response(body, { status: 200, headers: { "content-type": JSON_CT2, etag, "cache-control": cache, ...vary } });
|
|
49618
49710
|
}
|
|
49619
49711
|
async function authorizePinnedRead(request, url, app, releaseId, screenId) {
|
|
49620
49712
|
const denied = await checkPinnedRead({
|
|
@@ -49809,7 +49901,7 @@ ${releaseId}`;
|
|
|
49809
49901
|
});
|
|
49810
49902
|
}
|
|
49811
49903
|
if ((request.method === "GET" || request.method === "HEAD") && path2 === "/v1/__webwix/identity") {
|
|
49812
|
-
const headers2 = { "content-type":
|
|
49904
|
+
const headers2 = { "content-type": JSON_CT2, "cache-control": "no-store" };
|
|
49813
49905
|
if (request.method === "HEAD") return new Response(null, { status: 200, headers: headers2 });
|
|
49814
49906
|
const webwixDirect = opts.webwixDirect ? await opts.webwixDirect() === true : opts.webwixBridge !== false;
|
|
49815
49907
|
if (memberAuthOn()) {
|
|
@@ -50037,7 +50129,7 @@ ${releaseId}`;
|
|
|
50037
50129
|
}
|
|
50038
50130
|
return new Response(listBody, {
|
|
50039
50131
|
status: 200,
|
|
50040
|
-
headers: { "content-type":
|
|
50132
|
+
headers: { "content-type": JSON_CT2, ...listHeaders }
|
|
50041
50133
|
});
|
|
50042
50134
|
}
|
|
50043
50135
|
if (path2 === "/v1/templates") {
|
|
@@ -50094,7 +50186,7 @@ ${releaseId}`;
|
|
|
50094
50186
|
}
|
|
50095
50187
|
return new Response(bytes2, {
|
|
50096
50188
|
status: 200,
|
|
50097
|
-
headers: { "content-type":
|
|
50189
|
+
headers: { "content-type": JSON_CT2, etag, ...cache, "x-himalaya-app": app }
|
|
50098
50190
|
});
|
|
50099
50191
|
}
|
|
50100
50192
|
if (path2 === "/v1/authoring-docs" || /^\/v1\/authoring-docs\/(spec|mobile-ux)$/.test(path2)) {
|
|
@@ -50359,7 +50451,7 @@ ${releaseId}`;
|
|
|
50359
50451
|
if (request.headers.get("if-none-match") === etag2) return new Response(null, { status: 304, headers: headers2 });
|
|
50360
50452
|
const body2 = await pinnedBody(app, meta2.descriptorHash, () => store.getScreen(app, screenId));
|
|
50361
50453
|
if (!body2) return json3(404, { error: "screen_not_found", screenId });
|
|
50362
|
-
return new Response(body2, { status: 200, headers: { "content-type":
|
|
50454
|
+
return new Response(body2, { status: 200, headers: { "content-type": JSON_CT2, ...headers2, "x-himalaya-app": app } });
|
|
50363
50455
|
}
|
|
50364
50456
|
const m = await manifest(app);
|
|
50365
50457
|
const meta = m?.screens[screenId];
|
|
@@ -50372,7 +50464,7 @@ ${releaseId}`;
|
|
|
50372
50464
|
if (!body) return json3(404, { error: "screen_not_found", screenId });
|
|
50373
50465
|
return new Response(body, {
|
|
50374
50466
|
status: 200,
|
|
50375
|
-
headers: { "content-type":
|
|
50467
|
+
headers: { "content-type": JSON_CT2, etag, "cache-control": DOC_CACHE_CONTROL, "x-himalaya-app": app }
|
|
50376
50468
|
});
|
|
50377
50469
|
}
|
|
50378
50470
|
if (path2 === "/v1/widgets") {
|
|
@@ -50400,7 +50492,7 @@ ${releaseId}`;
|
|
|
50400
50492
|
if (!body) return json3(404, { error: "widget_not_found", widgetId });
|
|
50401
50493
|
return new Response(body, {
|
|
50402
50494
|
status: 200,
|
|
50403
|
-
headers: { "content-type":
|
|
50495
|
+
headers: { "content-type": JSON_CT2, etag, "cache-control": cache, ...vary, "x-himalaya-app": app }
|
|
50404
50496
|
});
|
|
50405
50497
|
}
|
|
50406
50498
|
return json3(404, { error: "not_found" });
|
|
@@ -50427,7 +50519,7 @@ ${releaseId}`;
|
|
|
50427
50519
|
return withCors(request, response);
|
|
50428
50520
|
};
|
|
50429
50521
|
}
|
|
50430
|
-
var
|
|
50522
|
+
var JSON_CT2;
|
|
50431
50523
|
var init_server = __esm({
|
|
50432
50524
|
"../../core/serve/src/server.ts"() {
|
|
50433
50525
|
init_sha256();
|
|
@@ -50438,7 +50530,7 @@ var init_server = __esm({
|
|
|
50438
50530
|
init_package_share();
|
|
50439
50531
|
init_wix_bridge();
|
|
50440
50532
|
init_wix_member_auth();
|
|
50441
|
-
|
|
50533
|
+
JSON_CT2 = "application/json; charset=utf-8";
|
|
50442
50534
|
}
|
|
50443
50535
|
});
|
|
50444
50536
|
|
|
@@ -50619,6 +50711,8 @@ function makeRunHandler(opts) {
|
|
|
50619
50711
|
{ "cache-control": "max-age=30" }
|
|
50620
50712
|
);
|
|
50621
50713
|
}
|
|
50714
|
+
const flagAssign = FLAG_ASSIGNMENTS_PATH.exec(path2);
|
|
50715
|
+
if (flagAssign) return flagAssignmentsResponse(request, flagAssign[1], []);
|
|
50622
50716
|
if (path2.startsWith("/v1/flags/")) {
|
|
50623
50717
|
return json4(200, { app: opts.app, definitions: {} }, { "cache-control": "no-store" });
|
|
50624
50718
|
}
|
|
@@ -50690,6 +50784,7 @@ var json4;
|
|
|
50690
50784
|
var init_run_handler = __esm({
|
|
50691
50785
|
"../../core/serve/src/run-handler.ts"() {
|
|
50692
50786
|
init_server();
|
|
50787
|
+
init_flag_assignments();
|
|
50693
50788
|
init_preview2();
|
|
50694
50789
|
init_himi_package();
|
|
50695
50790
|
json4 = (status, body, headers2 = {}) => new Response(JSON.stringify(body), {
|
|
@@ -50828,21 +50923,21 @@ var init_preview_assets_generated = __esm({
|
|
|
50828
50923
|
"../../packages/serve/src/preview-assets.generated.ts"() {
|
|
50829
50924
|
init_preview_assets_format();
|
|
50830
50925
|
PREVIEW_ASSET_MANIFEST = [
|
|
50831
|
-
{ key: "assets/index-
|
|
50832
|
-
{ key: "fonts/Roboto-LICENSE.txt", contentType: "application/octet-stream", offset:
|
|
50833
|
-
{ key: "fonts/Roboto-Variable.ttf", contentType: "font/ttf", offset:
|
|
50834
|
-
{ key: "fonts/WixMadeforDisplay-Bold.ttf", contentType: "font/ttf", offset:
|
|
50835
|
-
{ key: "fonts/WixMadeforDisplay-ExtraBold.ttf", contentType: "font/ttf", offset:
|
|
50836
|
-
{ key: "fonts/WixMadeforDisplay-Medium.ttf", contentType: "font/ttf", offset:
|
|
50837
|
-
{ key: "fonts/WixMadeforDisplay-Regular.ttf", contentType: "font/ttf", offset:
|
|
50838
|
-
{ key: "fonts/WixMadeforDisplay-SemiBold.ttf", contentType: "font/ttf", offset:
|
|
50839
|
-
{ key: "fonts/WixMadeforText-Bold.ttf", contentType: "font/ttf", offset:
|
|
50840
|
-
{ key: "fonts/WixMadeforText-ExtraBold.ttf", contentType: "font/ttf", offset:
|
|
50841
|
-
{ key: "fonts/WixMadeforText-Medium.ttf", contentType: "font/ttf", offset:
|
|
50842
|
-
{ key: "fonts/WixMadeforText-Regular.ttf", contentType: "font/ttf", offset:
|
|
50843
|
-
{ key: "fonts/WixMadeforText-SemiBold.ttf", contentType: "font/ttf", offset:
|
|
50844
|
-
{ key: "index.html", contentType: "text/html; charset=utf-8", offset:
|
|
50845
|
-
{ key: "t5-frame.html", contentType: "text/html; charset=utf-8", offset:
|
|
50926
|
+
{ key: "assets/index-DT6bRpY_.js", contentType: "application/javascript; charset=utf-8", offset: 8, length: 1055972, sha256: "3a52c8395a6509cfe2cae8036024b987cd3361095ff5450bfd7a9efa0123850b" },
|
|
50927
|
+
{ key: "fonts/Roboto-LICENSE.txt", contentType: "application/octet-stream", offset: 1055980, length: 4610, sha256: "994062dd7af4186a739de55dd9e151c63b6301f8e2cbafc608d35c2e87da0cd2" },
|
|
50928
|
+
{ key: "fonts/Roboto-Variable.ttf", contentType: "font/ttf", offset: 1060590, length: 488584, sha256: "d7598e12c5dbef095ff8272cfc55da0250bd07fbdecbac8a530b9b277872a134" },
|
|
50929
|
+
{ key: "fonts/WixMadeforDisplay-Bold.ttf", contentType: "font/ttf", offset: 1549174, length: 90924, sha256: "ec4c7d63772d980d6e147b2df6215fd2737e4b04cebe0cf7e11dc695fb63cdcf" },
|
|
50930
|
+
{ key: "fonts/WixMadeforDisplay-ExtraBold.ttf", contentType: "font/ttf", offset: 1640098, length: 90984, sha256: "bf4c16a2774edd38a921edf3099469866cd74c094fd596f3fa4e81f54a04dfaa" },
|
|
50931
|
+
{ key: "fonts/WixMadeforDisplay-Medium.ttf", contentType: "font/ttf", offset: 1731082, length: 90980, sha256: "368faca44fb9f7207e4af784e94750b1ee59c1098b8689e0f4a918926f244fb5" },
|
|
50932
|
+
{ key: "fonts/WixMadeforDisplay-Regular.ttf", contentType: "font/ttf", offset: 1822062, length: 90872, sha256: "97ed8f1a6772abe26e3d8af5cecfc4b02faa94497d585b0398b5053b739a70c1" },
|
|
50933
|
+
{ key: "fonts/WixMadeforDisplay-SemiBold.ttf", contentType: "font/ttf", offset: 1912934, length: 90980, sha256: "642feab8a48ddf6c7a89d7c2a7c0edfa0e6e773f671287e460e222703563191e" },
|
|
50934
|
+
{ key: "fonts/WixMadeforText-Bold.ttf", contentType: "font/ttf", offset: 2003914, length: 108636, sha256: "37c179b4fefb63ea9637322b84583a2df53aa226c150294eea1675c14b1b8e29" },
|
|
50935
|
+
{ key: "fonts/WixMadeforText-ExtraBold.ttf", contentType: "font/ttf", offset: 2112550, length: 109084, sha256: "62e2fe4718129f36ecdb0ae4de385bd6b81ecc876146447167c6c140fad699a9" },
|
|
50936
|
+
{ key: "fonts/WixMadeforText-Medium.ttf", contentType: "font/ttf", offset: 2221634, length: 109048, sha256: "4ecf270136af928612c76fe4ebade91d8156975e5ea4c0cf9225501dd1788e02" },
|
|
50937
|
+
{ key: "fonts/WixMadeforText-Regular.ttf", contentType: "font/ttf", offset: 2330682, length: 107700, sha256: "dee56f09fd3efc127c1ea95557edc74110c1460a46287da36e0af25efd341ef5" },
|
|
50938
|
+
{ key: "fonts/WixMadeforText-SemiBold.ttf", contentType: "font/ttf", offset: 2438382, length: 88108, sha256: "dced97a77624bc5f8b1ae65850360908297f4588e09feb6f22792d29dc7e765b" },
|
|
50939
|
+
{ key: "index.html", contentType: "text/html; charset=utf-8", offset: 2526490, length: 4947, sha256: "a9dcd2ec33b7ea5cee46b0a1f37f926678dd6939b442e3d50bff0101f0fe63ba" },
|
|
50940
|
+
{ key: "t5-frame.html", contentType: "text/html; charset=utf-8", offset: 2531437, length: 17209, sha256: "dffc9718e2faa63ae2cc919e0a842f585ed565aaaa7c53778e90379442c731b6" }
|
|
50846
50941
|
];
|
|
50847
50942
|
}
|
|
50848
50943
|
});
|
|
@@ -54487,6 +54582,35 @@ function tuneHighContrastAccent(brand, surface) {
|
|
|
54487
54582
|
}
|
|
54488
54583
|
return candidate;
|
|
54489
54584
|
}
|
|
54585
|
+
function deriveAccentText(accent, surfaces) {
|
|
54586
|
+
const all = (typeof surfaces === "string" ? [surfaces] : [...surfaces]).map((s) => s.slice(0, 7));
|
|
54587
|
+
const page = all[0];
|
|
54588
|
+
const worst = (color) => Math.min(...all.map((s) => contrastRatio3(color, s)));
|
|
54589
|
+
const opaque = accent.length === 9 ? mix2(accent.slice(0, 7), page, channel2(accent, 7) / 255) : accent;
|
|
54590
|
+
if (worst(opaque) >= ACCENT_TEXT_MIN_CONTRAST) return opaque;
|
|
54591
|
+
const pole = worst("#FFFFFF") >= worst("#000000") ? "#FFFFFF" : "#000000";
|
|
54592
|
+
for (let step = 1; step <= 100; step++) {
|
|
54593
|
+
const candidate = mix2(pole, opaque, step / 100);
|
|
54594
|
+
if (worst(candidate) >= ACCENT_TEXT_MIN_CONTRAST) return candidate;
|
|
54595
|
+
}
|
|
54596
|
+
if (all.length > 1) {
|
|
54597
|
+
const side2 = (hex2) => relativeLuminance2(hex2) > MID_GREY_LUMINANCE;
|
|
54598
|
+
const sameSide = all.filter((s) => side2(s) === side2(page));
|
|
54599
|
+
return deriveAccentText(accent, sameSide.length < all.length ? sameSide : [page]);
|
|
54600
|
+
}
|
|
54601
|
+
return pole;
|
|
54602
|
+
}
|
|
54603
|
+
function textSurfacesOf(colors) {
|
|
54604
|
+
const out = { light: [], dark: [], highContrast: [] };
|
|
54605
|
+
for (const name of TEXT_BACKDROP_TOKENS) {
|
|
54606
|
+
const value = colors[name];
|
|
54607
|
+
for (const arm of ["light", "dark", "highContrast"]) {
|
|
54608
|
+
const hex2 = typeof value === "string" ? value : value && typeof value === "object" && !Array.isArray(value) ? value[arm] ?? value.light : void 0;
|
|
54609
|
+
if (typeof hex2 === "string" && hex2.startsWith("#") && hex2.length >= 7) out[arm].push(hex2);
|
|
54610
|
+
}
|
|
54611
|
+
}
|
|
54612
|
+
return out;
|
|
54613
|
+
}
|
|
54490
54614
|
function stripBrandFromIdiom(tokens) {
|
|
54491
54615
|
const idiom = tokens.idiom;
|
|
54492
54616
|
if (!idiom || typeof idiom !== "object" || Array.isArray(idiom)) return;
|
|
@@ -54507,7 +54631,7 @@ function stripBrandFromIdiom(tokens) {
|
|
|
54507
54631
|
}
|
|
54508
54632
|
}
|
|
54509
54633
|
}
|
|
54510
|
-
function deriveAccentFamily(primary, secondary, surfaces) {
|
|
54634
|
+
function deriveAccentFamily(primary, secondary, surfaces, textSurfaces = {}) {
|
|
54511
54635
|
const primaryDark = tuneDarkAccent(primary, surfaces.dark, surfaces.light);
|
|
54512
54636
|
const secondaryDark = tuneDarkAccent(secondary, surfaces.dark, surfaces.light);
|
|
54513
54637
|
const primaryHigh = tuneHighContrastAccent(primary, surfaces.highContrast);
|
|
@@ -54524,10 +54648,15 @@ function deriveAccentFamily(primary, secondary, surfaces) {
|
|
|
54524
54648
|
light: textOnArm(primary),
|
|
54525
54649
|
dark: textOnArm(primaryDark),
|
|
54526
54650
|
highContrast: textOn(primaryHigh)
|
|
54651
|
+
},
|
|
54652
|
+
accentText: {
|
|
54653
|
+
light: deriveAccentText(primary, [surfaces.light, ...textSurfaces.light ?? []]),
|
|
54654
|
+
dark: deriveAccentText(primaryDark, [surfaces.dark, ...textSurfaces.dark ?? []]),
|
|
54655
|
+
highContrast: deriveAccentText(primaryHigh, [surfaces.highContrast, ...textSurfaces.highContrast ?? []])
|
|
54527
54656
|
}
|
|
54528
54657
|
};
|
|
54529
54658
|
}
|
|
54530
|
-
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, BRAND_COLOR_TOKENS, BRAND_GLOW_SHADOW;
|
|
54659
|
+
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;
|
|
54531
54660
|
var init_brand_color_math = __esm({
|
|
54532
54661
|
"../../core/ts/src/brand-color-math.ts"() {
|
|
54533
54662
|
ACCENT_SURFACE_MIN_DELTA = 1.08;
|
|
@@ -54539,7 +54668,10 @@ var init_brand_color_math = __esm({
|
|
|
54539
54668
|
DARK_ARM_FLOOR_CONTRAST = 3;
|
|
54540
54669
|
DARK_ARM_LSTAR_CAP = 80;
|
|
54541
54670
|
HIGH_CONTRAST_TARGET = 8.5;
|
|
54542
|
-
|
|
54671
|
+
ACCENT_TEXT_MIN_CONTRAST = 4.5;
|
|
54672
|
+
MID_GREY_LUMINANCE = 0.179;
|
|
54673
|
+
TEXT_BACKDROP_TOKENS = ["surfaceSecondary", "surfaceElevated", "surfaceSubtle", "surfaceTertiary"];
|
|
54674
|
+
BRAND_COLOR_TOKENS = ["accentPrimary", "accentSecondary", "accentSurface", "textOnAccent", "accentText"];
|
|
54543
54675
|
BRAND_GLOW_SHADOW = "glow";
|
|
54544
54676
|
}
|
|
54545
54677
|
});
|
|
@@ -54575,7 +54707,9 @@ function withDerivedAccents(tokensOverlay, wst) {
|
|
|
54575
54707
|
light: lightArm2(surfacePrimary) ?? "#FFFFFF",
|
|
54576
54708
|
dark: armOf(surfacePrimary, "dark") ?? "#0D1117",
|
|
54577
54709
|
highContrast: armOf(surfacePrimary, "highContrast") ?? "#000000"
|
|
54578
|
-
|
|
54710
|
+
// #3275 — the crawl knows only the site's LIGHT surfaces; a light card judged against a dark
|
|
54711
|
+
// arm would fight that arm's page, and `--apply` re-derives every arm after the merge anyway.
|
|
54712
|
+
}, { light: textSurfacesOf(tokensOverlay.colors ?? {}).light });
|
|
54579
54713
|
const keepCrawledLight = (derived, existing) => {
|
|
54580
54714
|
const crawled = lightArm2(existing);
|
|
54581
54715
|
return crawled ? { ...derived, light: crawled } : derived;
|
|
@@ -54584,6 +54718,7 @@ function withDerivedAccents(tokensOverlay, wst) {
|
|
|
54584
54718
|
colors.accentSecondary = keepCrawledLight(family.accentSecondary, tokensOverlay.colors?.accentSecondary);
|
|
54585
54719
|
colors.accentSurface = keepCrawledLight(family.accentSurface, tokensOverlay.colors?.accentSurface);
|
|
54586
54720
|
colors.textOnAccent = keepCrawledLight(family.textOnAccent, tokensOverlay.colors?.textOnAccent);
|
|
54721
|
+
colors.accentText = keepCrawledLight(family.accentText, tokensOverlay.colors?.accentText);
|
|
54587
54722
|
return { ...tokensOverlay, colors };
|
|
54588
54723
|
}
|
|
54589
54724
|
function mergedArm(colors, name, arm, fallback) {
|
|
@@ -54606,11 +54741,12 @@ function alignAccentsToSurfaces(mergedColors, overlayColors) {
|
|
|
54606
54741
|
light: mergedArm(colors, "surfacePrimary", "light", "#FFFFFF"),
|
|
54607
54742
|
dark: mergedArm(colors, "surfacePrimary", "dark", "#0D1117"),
|
|
54608
54743
|
highContrast: mergedArm(colors, "surfacePrimary", "highContrast", "#000000")
|
|
54609
|
-
});
|
|
54744
|
+
}, textSurfacesOf(colors));
|
|
54610
54745
|
colors.accentPrimary = family.accentPrimary;
|
|
54611
54746
|
colors.accentSecondary = family.accentSecondary;
|
|
54612
54747
|
colors.accentSurface = family.accentSurface;
|
|
54613
54748
|
colors.textOnAccent = family.textOnAccent;
|
|
54749
|
+
colors.accentText = family.accentText;
|
|
54614
54750
|
return colors;
|
|
54615
54751
|
}
|
|
54616
54752
|
function deriveBranding(input) {
|
|
Binary file
|
|
@@ -83,7 +83,11 @@ family whose faces could not be fetched, which would otherwise ship as its fallb
|
|
|
83
83
|
### Token discipline — every value is a `TokenRef`, never a literal
|
|
84
84
|
Colors, gradients, shadows, materials, motions are named tokens (`{ token: "accentPrimary" }`), never
|
|
85
85
|
hex. `himi validate` rejects unknown names; a literal hex is a design smell even when it "works." Use the **semantic** roles for meaning:
|
|
86
|
-
`success` / `warning` / `danger` for status, `textOnAccent` for text sitting on an accent surface
|
|
86
|
+
`success` / `warning` / `danger` for status, `textOnAccent` for text sitting on an accent surface,
|
|
87
|
+
and `accentText` for accent-COLOURED text on the page (links, "See all"). `accentPrimary` is the
|
|
88
|
+
accent FILL; many brand accents fail 4.5:1 as text, so brand derivation writes a same-hue
|
|
89
|
+
`accentText` that passes, and secondary/tertiary/link/plain Button labels already use it. It is
|
|
90
|
+
optional: every renderer falls back to `accentPrimary` when a tokens.json has none.
|
|
87
91
|
|
|
88
92
|
### Copy is configuration — never hardcoded in the descriptor
|
|
89
93
|
User-facing text is white-labelable **configuration**, exactly like a color token — a template/app
|
|
@@ -3463,13 +3463,13 @@
|
|
|
3463
3463
|
"name": "experiments",
|
|
3464
3464
|
"kind": "const",
|
|
3465
3465
|
"jsdoc": "",
|
|
3466
|
-
"decl": "export const experiments = {\n /**
|
|
3466
|
+
"decl": "export const experiments = {\n /** The app's served variant for `spec` (`himi flags`), or `fallback` when none is assigned. */\n async conduct(spec: string, fallback = \"false\"): Promise<ExperimentResult> {\n const resolved = await conductCached(\"experiments\", spec, fallback, () => resolveExperiment(spec, fallback));\n return { spec, variant: resolved ?? fallback };\n },\n /** Boolean convenience — true when the variant is exactly \"true\". */\n async isEnabled(spec: string): Promise<boolean> {\n return (await experiments.conduct(spec, \"false\")).variant === \"true\";\n },\n /** Report A/B exposure for `spec`/`variant` — emits the platform's\n * `experiment_exposed` telemetry so outcome events attribute to the variant.\n * (Symphony relies on server-side conduction; this is the generalized app-side\n * exposure hook.) */\n async exposure(spec: string, variant: string): Promise<{ ok: boolean }> {\n const r = await call<{ ok?: boolean }>(\"experimentsExposure\", { spec, variant });\n return { ok: r?.ok ?? false };\n },\n};"
|
|
3467
3467
|
},
|
|
3468
3468
|
{
|
|
3469
3469
|
"name": "flags",
|
|
3470
3470
|
"kind": "const",
|
|
3471
3471
|
"jsdoc": "",
|
|
3472
|
-
"decl": "export const flags = {\n /** Whether
|
|
3472
|
+
"decl": "export const flags = {\n /** Whether the app's served flag `spec` is ON (variant `on`/`true`/`new`), else `fallback`. */\n async isEnabled(spec: string, fallback = false): Promise<boolean> {\n const resolved = await conductCached(\"flags\", spec, String(fallback), () => resolveFlag(spec, fallback));\n if (resolved === null) return fallback;\n return resolved === \"true\" || resolved === \"new\";\n },\n /** A toggle's raw value (variant string) for non-boolean specs. */\n async value(spec: string, fallback = \"\"): Promise<string> {\n const r = await call<{ value?: string }>(\"flagsValue\", { spec, fallback });\n return r?.value ?? fallback;\n },\n /** All known toggle states (dev/diagnostic). */\n async all(): Promise<Record<string, string>> {\n const r = await call<{ flags?: Record<string, string> }>(\"flagsAll\");\n return r?.flags && typeof r.flags === \"object\" ? r.flags : {};\n },\n};"
|
|
3473
3473
|
},
|
|
3474
3474
|
{
|
|
3475
3475
|
"name": "i18n",
|
|
@@ -3487,13 +3487,13 @@
|
|
|
3487
3487
|
"name": "ping",
|
|
3488
3488
|
"kind": "const",
|
|
3489
3489
|
"jsdoc": "",
|
|
3490
|
-
"decl": "export const ping = {\n /** Register the device's push token with Wix Ping. */\n async register(): Promise<PingRegistration> {\n
|
|
3490
|
+
"decl": "export const ping = {\n /** Register the device's push token with Wix Ping. */\n async register(): Promise<PingRegistration> {\n const r = await call<{ registered?: boolean; token?: string }>(\"pingRegister\");\n return { registered: r?.registered ?? false, token: r?.token ?? \"\" };\n },\n /** Current Ping registration status (no network). */\n async status(): Promise<PingRegistration> {\n const r = await call<{ registered?: boolean; token?: string }>(\"pingStatus\");\n return { registered: r?.registered ?? false, token: r?.token ?? \"\" };\n },\n};"
|
|
3491
3491
|
},
|
|
3492
3492
|
{
|
|
3493
3493
|
"name": "deeplink",
|
|
3494
3494
|
"kind": "const",
|
|
3495
3495
|
"jsdoc": "",
|
|
3496
|
-
"decl": "export const deeplink = {\n /** Resolve a deferred (post-install) deep link via Wix Jot. Null when none. */\n async resolveDeferred(): Promise<{ link: string | null }> {\n
|
|
3496
|
+
"decl": "export const deeplink = {\n /** Resolve a deferred (post-install) deep link via Wix Jot. Null when none. */\n async resolveDeferred(): Promise<{ link: string | null }> {\n const r = await call<{ link?: string }>(\"deeplinkResolveDeferred\");\n return { link: r?.link && r.link.length > 0 ? r.link : null };\n },\n};"
|
|
3497
3497
|
},
|
|
3498
3498
|
{
|
|
3499
3499
|
"name": "SignedInstanceStatus",
|
|
@@ -26,7 +26,7 @@ import { bi, experiments, flags, i18n, auth, monitoring } from "@himalaya/wix-pl
|
|
|
26
26
|
await bi.pageView("home");
|
|
27
27
|
await bi.click("cta_start", "home");
|
|
28
28
|
|
|
29
|
-
// experiments (
|
|
29
|
+
// experiments / flags — the app's served flags (`himi flags`), never Wix Petri
|
|
30
30
|
const variant = await experiments.conduct("specs.ai", "false"); // → { spec, variant }
|
|
31
31
|
if (await flags.isEnabled("specs.newCheckout")) { /* … */ }
|
|
32
32
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wix/himalaya-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1046.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": "920a07437cf238c0bf1e34b799a4fe38573b57c6da92541fc2836079"
|
|
69
69
|
}
|
|
@@ -126,6 +126,14 @@ elevation subtle (≤ 2:1 vs the page, dark arms stepping *lighter* as elevation
|
|
|
126
126
|
rises); accents ≥ 3:1 on the page with textOnAccent ≥ 4.5:1; semantic colors
|
|
127
127
|
≥ 3:1 on the page and on their own surfaces.
|
|
128
128
|
|
|
129
|
+
`accentText` (#3275) is deliberately NOT in the ladder. It is the accent's text
|
|
130
|
+
arm, which non-filled button labels paint and which falls back to `accentPrimary`
|
|
131
|
+
when absent. Brand application derives it per arm: the brand itself when it already
|
|
132
|
+
clears 4.5:1 on `surfacePrimary`, else the smallest same-hue step that does
|
|
133
|
+
(`deriveAccentText` in `core/ts/src/brand-color-math.ts`). A kit never has to ship
|
|
134
|
+
it, and `core/ts/tests/brand-tokens.test.ts` checks that every kit × brand result
|
|
135
|
+
clears 4.5:1.
|
|
136
|
+
|
|
129
137
|
Deliberate judgment calls (the 2026-07 color reconsideration):
|
|
130
138
|
|
|
131
139
|
- **playful** — the hot-pink `textPrimary` failed 7:1 everywhere; legibility
|