@wix/himalaya-cli 0.1454.0 → 0.1455.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.mjs +565 -471
- package/guides/designing-himi-screens.md +7 -1
- package/guides/hhp.md +16 -0
- package/guides/recipe-search.md +125 -0
- package/package.json +2 -2
package/dist/cli.mjs
CHANGED
|
@@ -4346,8 +4346,8 @@ function committedProvisioningPath(name) {
|
|
|
4346
4346
|
function committedShellFor(path2) {
|
|
4347
4347
|
const normalized = path2.replace(/\\/g, "/");
|
|
4348
4348
|
return SHELL_NAMES2.find((name) => {
|
|
4349
|
-
const
|
|
4350
|
-
return normalized ===
|
|
4349
|
+
const relative18 = committedProvisioningPath(name);
|
|
4350
|
+
return normalized === relative18 || normalized.endsWith(`/${relative18}`);
|
|
4351
4351
|
});
|
|
4352
4352
|
}
|
|
4353
4353
|
function isBrandable(repoRoot2, name) {
|
|
@@ -7070,9 +7070,9 @@ function compileV2(html, profile, options) {
|
|
|
7070
7070
|
if (!row) error(el2, "HHP-BINDING-SCOPE", "Item bindings require a keyed list template.");
|
|
7071
7071
|
return raw;
|
|
7072
7072
|
}
|
|
7073
|
-
const
|
|
7074
|
-
if (!info4?.paths.has(
|
|
7075
|
-
return `$service:${serviceName}.${
|
|
7073
|
+
const relative18 = statePath(raw);
|
|
7074
|
+
if (!info4?.paths.has(relative18)) error(el2, "HHP-BINDING-PATH", `Unknown controller state path ${relative18}.`);
|
|
7075
|
+
return `$service:${serviceName}.${relative18}`;
|
|
7076
7076
|
}
|
|
7077
7077
|
const read = (value, dotted) => dotted.split(".").reduce((current, key3) => current && typeof current === "object" && Object.hasOwn(current, key3) ? current[key3] : void 0, value);
|
|
7078
7078
|
function rowValues(row, raw) {
|
|
@@ -8115,7 +8115,6 @@ function resolveTranslation(value, catalog3, sourceCatalog) {
|
|
|
8115
8115
|
var BINDING_SIGILS, BINDING_SIGIL_RE, TRANSLATION_PREFIX, TRANSLATION_KEY_RE;
|
|
8116
8116
|
var init_bindings = __esm({
|
|
8117
8117
|
"../../core/ts/src/bindings.ts"() {
|
|
8118
|
-
"use strict";
|
|
8119
8118
|
BINDING_SIGILS = ["service", "flag", "item", "t"];
|
|
8120
8119
|
BINDING_SIGIL_RE = new RegExp(
|
|
8121
8120
|
`^\\$(?:${BINDING_SIGILS.filter((s2) => s2 !== "t").join("|")})\\b|^\\$t:`
|
|
@@ -14624,6 +14623,277 @@ var init_loader = __esm({
|
|
|
14624
14623
|
}
|
|
14625
14624
|
});
|
|
14626
14625
|
|
|
14626
|
+
// ../app-icons/pixels.ts
|
|
14627
|
+
var pixels_exports = {};
|
|
14628
|
+
__export(pixels_exports, {
|
|
14629
|
+
LETTERBOX_ERROR_FRACTION: () => LETTERBOX_ERROR_FRACTION,
|
|
14630
|
+
LETTERBOX_WARN_FRACTION: () => LETTERBOX_WARN_FRACTION,
|
|
14631
|
+
NORMALIZE_FIT_FRACTION: () => NORMALIZE_FIT_FRACTION,
|
|
14632
|
+
PIXEL_TOOLCHAIN_HINT: () => PIXEL_TOOLCHAIN_HINT,
|
|
14633
|
+
PixelToolchainUnavailable: () => PixelToolchainUnavailable,
|
|
14634
|
+
SVG_RASTER_MAX_EDGE: () => SVG_RASTER_MAX_EDGE,
|
|
14635
|
+
appStoreIconPixelFindings: () => appStoreIconPixelFindings,
|
|
14636
|
+
derivePlayListingIcon: () => derivePlayListingIcon,
|
|
14637
|
+
inspectIconPixels: () => inspectIconPixels,
|
|
14638
|
+
normalizeSourceIcon: () => normalizeSourceIcon,
|
|
14639
|
+
pixelToolchainAvailable: () => pixelToolchainAvailable,
|
|
14640
|
+
pixelToolchainProblem: () => pixelToolchainProblem,
|
|
14641
|
+
rasterizeSvg: () => rasterizeSvg,
|
|
14642
|
+
renderGlyphTile: () => renderGlyphTile
|
|
14643
|
+
});
|
|
14644
|
+
function isNotInstalled(e2) {
|
|
14645
|
+
const code = e2?.code;
|
|
14646
|
+
return code === "MODULE_NOT_FOUND" || code === "ERR_MODULE_NOT_FOUND";
|
|
14647
|
+
}
|
|
14648
|
+
function messageOf(e2) {
|
|
14649
|
+
return e2 instanceof Error ? e2.message : String(e2);
|
|
14650
|
+
}
|
|
14651
|
+
async function loadSharp() {
|
|
14652
|
+
if (cachedSharp) return cachedSharp;
|
|
14653
|
+
const failures = [];
|
|
14654
|
+
let presentButBroken = false;
|
|
14655
|
+
try {
|
|
14656
|
+
const { createRequire: createRequire4 } = await import("node:module");
|
|
14657
|
+
cachedSharp = createRequire4(import.meta.url)("sharp");
|
|
14658
|
+
lastProblem = null;
|
|
14659
|
+
return cachedSharp;
|
|
14660
|
+
} catch (e2) {
|
|
14661
|
+
presentButBroken ||= !isNotInstalled(e2);
|
|
14662
|
+
failures.push(`require: ${messageOf(e2)}`);
|
|
14663
|
+
}
|
|
14664
|
+
try {
|
|
14665
|
+
cachedSharp = (await import("sharp")).default;
|
|
14666
|
+
lastProblem = null;
|
|
14667
|
+
return cachedSharp;
|
|
14668
|
+
} catch (e2) {
|
|
14669
|
+
presentButBroken ||= !isNotInstalled(e2);
|
|
14670
|
+
failures.push(`import: ${messageOf(e2)}`);
|
|
14671
|
+
}
|
|
14672
|
+
lastProblem = presentButBroken ? `the image toolchain (sharp) is installed but could not be loaded \u2014 ${failures.join("; ")}` : PIXEL_TOOLCHAIN_HINT;
|
|
14673
|
+
return null;
|
|
14674
|
+
}
|
|
14675
|
+
async function pixelToolchainAvailable() {
|
|
14676
|
+
return await loadSharp() !== null;
|
|
14677
|
+
}
|
|
14678
|
+
async function pixelToolchainProblem() {
|
|
14679
|
+
return await loadSharp() === null ? lastProblem ?? PIXEL_TOOLCHAIN_HINT : null;
|
|
14680
|
+
}
|
|
14681
|
+
async function sharpOrThrow() {
|
|
14682
|
+
const s2 = await loadSharp();
|
|
14683
|
+
if (!s2) throw new PixelToolchainUnavailable(lastProblem ?? PIXEL_TOOLCHAIN_HINT);
|
|
14684
|
+
return s2;
|
|
14685
|
+
}
|
|
14686
|
+
async function inspectIconPixels(png) {
|
|
14687
|
+
const sharp = await sharpOrThrow();
|
|
14688
|
+
const { data, info: info4 } = await sharp(png).ensureAlpha().raw().toBuffer({ resolveWithObject: true });
|
|
14689
|
+
const { width, height, channels: channels3 } = info4;
|
|
14690
|
+
if (channels3 !== 4) throw new Error(`app-icons: expected RGBA after ensureAlpha, got ${channels3} channels`);
|
|
14691
|
+
let minAlpha = 255;
|
|
14692
|
+
let transparent = 0;
|
|
14693
|
+
for (let i2 = 3; i2 < data.length; i2 += 4) {
|
|
14694
|
+
const a2 = data[i2];
|
|
14695
|
+
if (a2 < minAlpha) minAlpha = a2;
|
|
14696
|
+
if (a2 <= ALPHA_OPAQUE) transparent++;
|
|
14697
|
+
}
|
|
14698
|
+
const probe = Math.max(1, Math.round(Math.min(width, height) * CORNER_PROBE));
|
|
14699
|
+
let minCornerAlpha = 255;
|
|
14700
|
+
for (const [x0, y0] of [
|
|
14701
|
+
[0, 0],
|
|
14702
|
+
[width - probe, 0],
|
|
14703
|
+
[0, height - probe],
|
|
14704
|
+
[width - probe, height - probe]
|
|
14705
|
+
]) {
|
|
14706
|
+
for (let y2 = y0; y2 < y0 + probe; y2++) {
|
|
14707
|
+
for (let x2 = x0; x2 < x0 + probe; x2++) {
|
|
14708
|
+
const a2 = data[(y2 * width + x2) * 4 + 3];
|
|
14709
|
+
if (a2 < minCornerAlpha) minCornerAlpha = a2;
|
|
14710
|
+
}
|
|
14711
|
+
}
|
|
14712
|
+
}
|
|
14713
|
+
const inset = Math.round(Math.min(width, height) * INTERIOR_INSET);
|
|
14714
|
+
let interiorMinAlpha = 255;
|
|
14715
|
+
for (let y2 = inset; y2 < height - inset; y2++) {
|
|
14716
|
+
for (let x2 = inset; x2 < width - inset; x2++) {
|
|
14717
|
+
const a2 = data[(y2 * width + x2) * 4 + 3];
|
|
14718
|
+
if (a2 < interiorMinAlpha) interiorMinAlpha = a2;
|
|
14719
|
+
}
|
|
14720
|
+
}
|
|
14721
|
+
return {
|
|
14722
|
+
width,
|
|
14723
|
+
height,
|
|
14724
|
+
minAlpha,
|
|
14725
|
+
transparentFraction: transparent / (width * height),
|
|
14726
|
+
minCornerAlpha,
|
|
14727
|
+
interiorMinAlpha,
|
|
14728
|
+
// `minAlpha <= ALPHA_OPAQUE` IS "has transparency", and the caller has just computed
|
|
14729
|
+
// it — contentBox used to re-derive it with a full extra sweep of the raster.
|
|
14730
|
+
contentBox: contentBox(data, width, height, minAlpha <= ALPHA_OPAQUE)
|
|
14731
|
+
};
|
|
14732
|
+
}
|
|
14733
|
+
function contentBox(data, width, height, hasTransparency) {
|
|
14734
|
+
const at2 = (x2, y2) => (y2 * width + x2) * 4;
|
|
14735
|
+
const bg = [data[at2(0, 0)], data[at2(0, 0) + 1], data[at2(0, 0) + 2]];
|
|
14736
|
+
const isInk = (x2, y2) => {
|
|
14737
|
+
const i2 = at2(x2, y2);
|
|
14738
|
+
if (hasTransparency) return data[i2 + 3] > ALPHA_OPAQUE;
|
|
14739
|
+
return Math.abs(data[i2] - bg[0]) > INK_TOLERANCE || Math.abs(data[i2 + 1] - bg[1]) > INK_TOLERANCE || Math.abs(data[i2 + 2] - bg[2]) > INK_TOLERANCE;
|
|
14740
|
+
};
|
|
14741
|
+
let minX = width, minY = height, maxX = -1, maxY = -1;
|
|
14742
|
+
for (let y2 = 0; y2 < height; y2++) {
|
|
14743
|
+
for (let x2 = 0; x2 < width; x2++) {
|
|
14744
|
+
if (!isInk(x2, y2)) continue;
|
|
14745
|
+
if (x2 < minX) minX = x2;
|
|
14746
|
+
if (x2 > maxX) maxX = x2;
|
|
14747
|
+
if (y2 < minY) minY = y2;
|
|
14748
|
+
if (y2 > maxY) maxY = y2;
|
|
14749
|
+
}
|
|
14750
|
+
}
|
|
14751
|
+
if (maxX < 0) return null;
|
|
14752
|
+
return {
|
|
14753
|
+
widthFraction: (maxX - minX + 1) / width,
|
|
14754
|
+
heightFraction: (maxY - minY + 1) / height
|
|
14755
|
+
};
|
|
14756
|
+
}
|
|
14757
|
+
function appStoreIconPixelFindings(f2) {
|
|
14758
|
+
const out2 = [];
|
|
14759
|
+
const preMasked = f2.interiorMinAlpha > ALPHA_OPAQUE && f2.minCornerAlpha <= ALPHA_OPAQUE && f2.transparentFraction <= PRE_MASK_MAX_TRANSPARENT_FRACTION;
|
|
14760
|
+
if (preMasked) {
|
|
14761
|
+
out2.push({
|
|
14762
|
+
level: "error",
|
|
14763
|
+
message: "App icon looks pre-masked: its corners are transparent while the middle is opaque. iOS and Play both apply their own corner mask, so rounded artwork is rounded twice and looks visibly wrong on device \u2014 and the transparency itself is an App Store rejection (ITMS-90717 / ITMS-90647). Ship a full-bleed square with 90-degree corners and no inset."
|
|
14764
|
+
});
|
|
14765
|
+
} else if (f2.minAlpha <= ALPHA_OPAQUE) {
|
|
14766
|
+
out2.push({
|
|
14767
|
+
level: "error",
|
|
14768
|
+
message: `App icon has transparent pixels (${(f2.transparentFraction * 100).toFixed(1)}% of the canvas, lowest alpha ${f2.minAlpha}). An App Store icon may carry an alpha channel but no transparent regions \u2014 Apple rejects this as ITMS-90717 / ITMS-90647. Flatten it onto an opaque background (\`himi icon set <file>\` does this for you).`
|
|
14769
|
+
});
|
|
14770
|
+
}
|
|
14771
|
+
if (f2.contentBox === null) {
|
|
14772
|
+
out2.push({
|
|
14773
|
+
level: "error",
|
|
14774
|
+
message: "App icon is a single flat colour with no distinguishable artwork \u2014 the mark is not visible in it. Supply art that contrasts with the background, or use `himi icon generate` for a glyph tile."
|
|
14775
|
+
});
|
|
14776
|
+
return out2;
|
|
14777
|
+
}
|
|
14778
|
+
const shorter = Math.min(f2.contentBox.widthFraction, f2.contentBox.heightFraction);
|
|
14779
|
+
if (shorter < LETTERBOX_ERROR_FRACTION) {
|
|
14780
|
+
out2.push({
|
|
14781
|
+
level: "error",
|
|
14782
|
+
message: `App icon artwork fills only ${(shorter * 100).toFixed(0)}% of the canvas on its shorter side, so it reads as a speck on a home screen. This is what a wide wordmark centred in a square looks like \u2014 crop to the mark, or use a monogram/glyph instead of the wordmark.`
|
|
14783
|
+
});
|
|
14784
|
+
} else if (shorter < LETTERBOX_WARN_FRACTION) {
|
|
14785
|
+
out2.push({
|
|
14786
|
+
level: "warn",
|
|
14787
|
+
message: `App icon artwork fills ${(shorter * 100).toFixed(0)}% of the canvas on its shorter side \u2014 it will read as a thin strip at home-screen size. Consider cropping to the mark.`
|
|
14788
|
+
});
|
|
14789
|
+
}
|
|
14790
|
+
return out2;
|
|
14791
|
+
}
|
|
14792
|
+
function luminance([r2, g2, b2]) {
|
|
14793
|
+
const lin = [r2, g2, b2].map((v2) => {
|
|
14794
|
+
const c2 = v2 / 255;
|
|
14795
|
+
return c2 <= 0.04045 ? c2 / 12.92 : ((c2 + 0.055) / 1.055) ** 2.4;
|
|
14796
|
+
});
|
|
14797
|
+
return 0.2126 * lin[0] + 0.7152 * lin[1] + 0.0722 * lin[2];
|
|
14798
|
+
}
|
|
14799
|
+
function contrastRatio(a2, b2) {
|
|
14800
|
+
const [hi2, lo2] = [luminance(a2), luminance(b2)].sort((x2, y2) => y2 - x2);
|
|
14801
|
+
return (hi2 + 0.05) / (lo2 + 0.05);
|
|
14802
|
+
}
|
|
14803
|
+
async function contrastingBackdrop(mark, requested) {
|
|
14804
|
+
const sharp = await sharpOrThrow();
|
|
14805
|
+
const { dominant } = await sharp(mark).stats();
|
|
14806
|
+
const ink = [dominant.r, dominant.g, dominant.b];
|
|
14807
|
+
const want = hexToRgb(requested);
|
|
14808
|
+
if (!want || contrastRatio(ink, want) >= MIN_BACKDROP_CONTRAST) return requested;
|
|
14809
|
+
const towardsWhite = luminance(ink) < 0.5;
|
|
14810
|
+
for (const amount of [0.35, 0.55, 0.75, 0.9]) {
|
|
14811
|
+
const candidate = mix(want, towardsWhite ? [255, 255, 255] : [0, 0, 0], amount);
|
|
14812
|
+
if (contrastRatio(ink, candidate) >= MIN_BACKDROP_CONTRAST) return rgbToHex(candidate);
|
|
14813
|
+
}
|
|
14814
|
+
return towardsWhite ? "#FFFFFF" : "#000000";
|
|
14815
|
+
}
|
|
14816
|
+
function hexToRgb(hex2) {
|
|
14817
|
+
const m2 = /^#([0-9a-fA-F]{6})$/.exec(hex2);
|
|
14818
|
+
if (!m2) return null;
|
|
14819
|
+
const n2 = parseInt(m2[1], 16);
|
|
14820
|
+
return [n2 >> 16 & 255, n2 >> 8 & 255, n2 & 255];
|
|
14821
|
+
}
|
|
14822
|
+
function mix(a2, b2, t2) {
|
|
14823
|
+
return [0, 1, 2].map((i2) => Math.round(a2[i2] + (b2[i2] - a2[i2]) * t2));
|
|
14824
|
+
}
|
|
14825
|
+
function rgbToHex([r2, g2, b2]) {
|
|
14826
|
+
return `#${[r2, g2, b2].map((v2) => v2.toString(16).padStart(2, "0")).join("")}`.toUpperCase();
|
|
14827
|
+
}
|
|
14828
|
+
async function normalizeSourceIcon(input, opts) {
|
|
14829
|
+
const sharp = await sharpOrThrow();
|
|
14830
|
+
const size = opts.size ?? 1024;
|
|
14831
|
+
const fit2 = opts.fit ?? NORMALIZE_FIT_FRACTION;
|
|
14832
|
+
const inner = Math.max(1, Math.round(size * fit2));
|
|
14833
|
+
const pad3 = Math.round((size - inner) / 2);
|
|
14834
|
+
let trimmed;
|
|
14835
|
+
try {
|
|
14836
|
+
trimmed = await sharp(input).ensureAlpha().trim().png().toBuffer();
|
|
14837
|
+
} catch {
|
|
14838
|
+
trimmed = await sharp(input).ensureAlpha().png().toBuffer();
|
|
14839
|
+
}
|
|
14840
|
+
const mark = await sharp(trimmed).resize(inner, inner, { fit: "contain", background: { r: 0, g: 0, b: 0, alpha: 0 } }).png().toBuffer();
|
|
14841
|
+
const background = await contrastingBackdrop(mark, opts.background);
|
|
14842
|
+
return sharp({
|
|
14843
|
+
create: {
|
|
14844
|
+
width: size,
|
|
14845
|
+
height: size,
|
|
14846
|
+
channels: 4,
|
|
14847
|
+
background: { r: 0, g: 0, b: 0, alpha: 0 }
|
|
14848
|
+
}
|
|
14849
|
+
}).composite([{ input: mark, top: pad3, left: pad3 }]).flatten({ background }).removeAlpha().png({ palette: false }).toBuffer();
|
|
14850
|
+
}
|
|
14851
|
+
async function derivePlayListingIcon(master, size = 512) {
|
|
14852
|
+
const sharp = await sharpOrThrow();
|
|
14853
|
+
return sharp(master).resize(size, size).ensureAlpha().png({ palette: false }).toBuffer();
|
|
14854
|
+
}
|
|
14855
|
+
async function renderGlyphTile(svg, background, size = 1024) {
|
|
14856
|
+
const sharp = await sharpOrThrow();
|
|
14857
|
+
return sharp(Buffer.from(svg)).resize(size, size).flatten({ background }).removeAlpha().png({ palette: false }).toBuffer();
|
|
14858
|
+
}
|
|
14859
|
+
async function rasterizeSvg(svg, scale = 3) {
|
|
14860
|
+
const sharp = await loadSharp();
|
|
14861
|
+
if (!sharp) return null;
|
|
14862
|
+
const { width = 0, height = 0 } = await sharp(svg, { limitInputPixels: false }).metadata();
|
|
14863
|
+
const edge = Math.max(width, height);
|
|
14864
|
+
const density = edge > 0 ? Math.max(1, Math.min(72 * scale, 72 * SVG_RASTER_MAX_EDGE / edge)) : 72 * scale;
|
|
14865
|
+
const decoded = width * density / 72 * (height * density / 72);
|
|
14866
|
+
if (decoded > SHARP_INPUT_PIXEL_LIMIT) {
|
|
14867
|
+
throw new Error(`SVG is too large to rasterize: ${width}x${height} intrinsic size; give it a width/height (or viewBox) under ${Math.floor(72 * Math.sqrt(SHARP_INPUT_PIXEL_LIMIT))}px per side`);
|
|
14868
|
+
}
|
|
14869
|
+
return sharp(svg, { density }).resize({ width: SVG_RASTER_MAX_EDGE, height: SVG_RASTER_MAX_EDGE, fit: "inside", withoutEnlargement: true }).png().toBuffer();
|
|
14870
|
+
}
|
|
14871
|
+
var cachedSharp, lastProblem, PIXEL_TOOLCHAIN_HINT, PixelToolchainUnavailable, ALPHA_OPAQUE, CORNER_PROBE, INTERIOR_INSET, INK_TOLERANCE, PRE_MASK_MAX_TRANSPARENT_FRACTION, LETTERBOX_WARN_FRACTION, LETTERBOX_ERROR_FRACTION, NORMALIZE_FIT_FRACTION, MIN_BACKDROP_CONTRAST, SVG_RASTER_MAX_EDGE, SHARP_INPUT_PIXEL_LIMIT;
|
|
14872
|
+
var init_pixels = __esm({
|
|
14873
|
+
"../app-icons/pixels.ts"() {
|
|
14874
|
+
cachedSharp = null;
|
|
14875
|
+
lastProblem = null;
|
|
14876
|
+
PIXEL_TOOLCHAIN_HINT = "the image toolchain (sharp) is not installed \u2014 run `npm i -g sharp` to enable transparency, pre-masked-corner and letterbox checks";
|
|
14877
|
+
PixelToolchainUnavailable = class extends Error {
|
|
14878
|
+
constructor(reason = PIXEL_TOOLCHAIN_HINT) {
|
|
14879
|
+
super(`app-icons: ${reason}`);
|
|
14880
|
+
this.name = "PixelToolchainUnavailable";
|
|
14881
|
+
}
|
|
14882
|
+
};
|
|
14883
|
+
ALPHA_OPAQUE = 250;
|
|
14884
|
+
CORNER_PROBE = 0.06;
|
|
14885
|
+
INTERIOR_INSET = 0.2;
|
|
14886
|
+
INK_TOLERANCE = 24;
|
|
14887
|
+
PRE_MASK_MAX_TRANSPARENT_FRACTION = 0.1;
|
|
14888
|
+
LETTERBOX_WARN_FRACTION = 0.35;
|
|
14889
|
+
LETTERBOX_ERROR_FRACTION = 0.2;
|
|
14890
|
+
NORMALIZE_FIT_FRACTION = 0.82;
|
|
14891
|
+
MIN_BACKDROP_CONTRAST = 1.5;
|
|
14892
|
+
SVG_RASTER_MAX_EDGE = 2048;
|
|
14893
|
+
SHARP_INPUT_PIXEL_LIMIT = 16383 * 16383;
|
|
14894
|
+
}
|
|
14895
|
+
});
|
|
14896
|
+
|
|
14627
14897
|
// ../../apps/himi-player/player-host-manifest.ts
|
|
14628
14898
|
var PLAYER_HOST_MANIFEST;
|
|
14629
14899
|
var init_player_host_manifest = __esm({
|
|
@@ -15011,8 +15281,8 @@ var init_hhp_command = __esm({
|
|
|
15011
15281
|
|
|
15012
15282
|
// src/hhp.ts
|
|
15013
15283
|
import { existsSync as existsSync15, readFileSync as readFileSync16, writeFileSync as writeFileSync7, mkdirSync as mkdirSync7, renameSync, rmSync as rmSync4, lstatSync as lstatSync5, readdirSync as readdirSync12 } from "node:fs";
|
|
15014
|
-
import { dirname as dirname11, resolve as resolve17, relative as relative3, sep as sep6, join as join15 } from "node:path";
|
|
15015
|
-
import { randomUUID } from "node:crypto";
|
|
15284
|
+
import { basename as basename7, dirname as dirname11, resolve as resolve17, relative as relative3, sep as sep6, join as join15 } from "node:path";
|
|
15285
|
+
import { createHash as createHash8, randomUUID } from "node:crypto";
|
|
15016
15286
|
import ts3 from "typescript";
|
|
15017
15287
|
function localPath(root, path2, from = join15(root, "hhp.json")) {
|
|
15018
15288
|
if (/^[a-z]+:|^\/\//i.test(path2)) throw new Error("HHP source dependencies must be local files.");
|
|
@@ -15082,7 +15352,7 @@ export function withHhpScreens<T extends { screens: { exact: Record<string, any>
|
|
|
15082
15352
|
for (const id of Object.keys(descriptors)) if (Object.hasOwn(app.screens.exact, id)) throw new Error("HHP screen conflicts with authored screen: " + id);
|
|
15083
15353
|
const exact = Object.fromEntries(Object.entries(descriptors).map(([id, descriptor]) => [id, (ctx: { serverBaseUrl: string; bundleIntegrity(name: string): string | null; asset(name: string): {url:string} | null }) => {
|
|
15084
15354
|
const result = structuredClone(descriptor);
|
|
15085
|
-
const resolveAssets = (value: any, field = ""): any => { if (["url", "imageUrl", "src"].includes(field) && typeof value === "string" && value.startsWith("asset:")) { const asset = ctx.asset(value.slice(6)); if (!asset) throw new Error("Missing HHP asset " + value); return asset.url; } if (Array.isArray(value)) return value.map((child) => resolveAssets(child, field)); if (value && typeof value === "object") return Object.fromEntries(Object.entries(value).map(([key, child]) => [key, resolveAssets(child, key)])); return value; }; result.payload = resolveAssets(result.payload);
|
|
15355
|
+
const resolveAssets = (value: any, field = ""): any => { if (["url", "imageUrl", "src"].includes(field) && typeof value === "string" && value.startsWith("asset:")) { const asset = ctx.asset(value.slice(6)); if (!asset) throw new Error("Missing HHP asset " + value); return asset.url.replace(/^[a-z][a-z0-9+.-]*:\\/\\/[^/?#]*/i, ""); } if (Array.isArray(value)) return value.map((child) => resolveAssets(child, field)); if (value && typeof value === "object") return Object.fromEntries(Object.entries(value).map(([key, child]) => [key, resolveAssets(child, key)])); return value; }; result.payload = resolveAssets(result.payload);
|
|
15086
15356
|
if (result.logicBundle) { const name = result.logicBundle.url.split("/").pop()!; const sri = ctx.bundleIntegrity(name); if (!sri) return null; result.logicBundle.url = ctx.serverBaseUrl + result.logicBundle.url; result.logicBundle.integrity = sri; }
|
|
15087
15357
|
return result;
|
|
15088
15358
|
}]));
|
|
@@ -15097,9 +15367,18 @@ async function compileContentHhp(root, opts = {}) {
|
|
|
15097
15367
|
const diagnostics = [], results = [];
|
|
15098
15368
|
const outputs = /* @__PURE__ */ new Map();
|
|
15099
15369
|
const assets = collectAssets(root);
|
|
15370
|
+
const svgRefs = /* @__PURE__ */ new Map();
|
|
15371
|
+
const directRasters = /* @__PURE__ */ new Set();
|
|
15100
15372
|
const assetName = (path2, from) => {
|
|
15101
15373
|
const hit = path2.startsWith("asset:") ? assets.find((asset) => asset.name === path2.slice(6)) : assets.find((asset) => asset.path === localPath(root, path2, from));
|
|
15102
15374
|
if (!hit) throw new Error(`Local resource ${path2} must exist in the app's declared assets directory.`);
|
|
15375
|
+
if (/\.svg$/i.test(hit.name) && !hit.name.startsWith(`${RASTER_DIR}/`)) {
|
|
15376
|
+
const ref = svgRefs.get(hit.path) ?? { name: hit.name, raster: rasterName(hit.name, readFileSync16(hit.path)), files: /* @__PURE__ */ new Set() };
|
|
15377
|
+
ref.files.add(from);
|
|
15378
|
+
svgRefs.set(hit.path, ref);
|
|
15379
|
+
return ref.raster;
|
|
15380
|
+
}
|
|
15381
|
+
if (hit.name.startsWith(`${RASTER_DIR}/`)) directRasters.add(hit.path);
|
|
15103
15382
|
return hit.name;
|
|
15104
15383
|
};
|
|
15105
15384
|
const indexPath = localPath(root, "dev/index.ts"), originalIndex = readFileSync16(indexPath, "utf8"), wiredIndex = managedRegistry(originalIndex);
|
|
@@ -15146,6 +15425,28 @@ async function compileContentHhp(root, opts = {}) {
|
|
|
15146
15425
|
const existing = (await loadContent(root, { fresh: true })).module.screens.exact;
|
|
15147
15426
|
for (const id of Object.keys(manifest.screens)) if (Object.hasOwn(existing, id)) diagnostics.push({ code: "HHP-REGISTRY-CONFLICT", severity: "error", file: indexPath, line: 1, column: 1, message: `HHP screen ${id} conflicts with an authored screen.` });
|
|
15148
15427
|
}
|
|
15428
|
+
const rasters = /* @__PURE__ */ new Map();
|
|
15429
|
+
for (const path2 of directRasters) rasters.set(path2, null);
|
|
15430
|
+
const assetsDir = findAssetsDir(root);
|
|
15431
|
+
for (const [path2, ref] of [...svgRefs].sort(([a2], [b2]) => a2.localeCompare(b2))) {
|
|
15432
|
+
let png;
|
|
15433
|
+
try {
|
|
15434
|
+
png = await (opts.rasterizeSvg ?? rasterizeSvg)(readFileSync16(path2));
|
|
15435
|
+
} catch (e2) {
|
|
15436
|
+
for (const file2 of ref.files) diagnostics.push({ code: "HHP-ASSET-SVG", severity: "error", file: file2, line: 1, column: 1, message: `Could not rasterize ${ref.name} (${e2.message.split("\n")[0]}). Fix the SVG, or export it as PNG or WebP.` });
|
|
15437
|
+
continue;
|
|
15438
|
+
}
|
|
15439
|
+
const target2 = assetsDir && join15(assetsDir, ref.raster);
|
|
15440
|
+
if (!png && target2 && existsExact(target2)) {
|
|
15441
|
+
rasters.set(target2, null);
|
|
15442
|
+
continue;
|
|
15443
|
+
}
|
|
15444
|
+
if (!png || !target2) {
|
|
15445
|
+
for (const file2 of ref.files) diagnostics.push({ code: "HHP-ASSET-SVG", severity: "error", file: file2, line: 1, column: 1, message: `${ref.name} is an SVG image, which iOS and Android cannot decode, and the image toolchain (sharp) that converts it to PNG is unavailable. Export it as PNG or WebP, or install sharp (\`npm i -g sharp\`).` });
|
|
15446
|
+
continue;
|
|
15447
|
+
}
|
|
15448
|
+
rasters.set(target2, png);
|
|
15449
|
+
}
|
|
15149
15450
|
const ok2 = !diagnostics.some((d2) => d2.severity === "error");
|
|
15150
15451
|
if (!ok2) return { ok: ok2, diagnostics, screens: Object.keys(manifest.screens), outputs: [] };
|
|
15151
15452
|
outputs.set("dev/hhp/index.ts", registry(results));
|
|
@@ -15167,6 +15468,14 @@ async function compileContentHhp(root, opts = {}) {
|
|
|
15167
15468
|
const path2 = localPath(root, rel);
|
|
15168
15469
|
if (existsSync15(path2) && rel.endsWith(".ts") && !readFileSync16(path2, "utf8").startsWith(GENERATED.trim()) && !readFileSync16(path2, "utf8").startsWith("// GENERATED HHP v2 worker.")) throw new Error(`HHP output conflicts with authored file ${rel}.`);
|
|
15169
15470
|
}
|
|
15471
|
+
for (const [path2, png] of rasters) {
|
|
15472
|
+
if (!png) continue;
|
|
15473
|
+
if (existsExact(path2) && readFileSync16(path2).equals(png)) continue;
|
|
15474
|
+
mkdirSync7(dirname11(path2), { recursive: true });
|
|
15475
|
+
writeFileSync7(`${path2}.tmp`, png);
|
|
15476
|
+
rmSync4(path2, { force: true });
|
|
15477
|
+
renameSync(`${path2}.tmp`, path2);
|
|
15478
|
+
}
|
|
15170
15479
|
const target = localPath(root, "dev/hhp"), stage = localPath(root, `dev/.hhp-${randomUUID()}`), backup = `${stage}-old`;
|
|
15171
15480
|
mkdirSync7(stage, { recursive: true });
|
|
15172
15481
|
try {
|
|
@@ -15211,8 +15520,26 @@ async function compileContentHhp(root, opts = {}) {
|
|
|
15211
15520
|
} finally {
|
|
15212
15521
|
rmSync4(stage, { recursive: true, force: true });
|
|
15213
15522
|
}
|
|
15523
|
+
pruneRasters(root, rasters);
|
|
15214
15524
|
return result;
|
|
15215
15525
|
}
|
|
15526
|
+
function pruneRasters(root, rasters) {
|
|
15527
|
+
const keep = new Set(rasters.keys());
|
|
15528
|
+
const assetsDir = findAssetsDir(root);
|
|
15529
|
+
const dir = assetsDir && join15(assetsDir, RASTER_DIR);
|
|
15530
|
+
if (!dir || !existsSync15(dir)) return;
|
|
15531
|
+
const walk2 = (abs) => {
|
|
15532
|
+
for (const entry of readdirSync12(abs, { withFileTypes: true })) {
|
|
15533
|
+
const child = join15(abs, entry.name);
|
|
15534
|
+
if (entry.isDirectory()) {
|
|
15535
|
+
walk2(child);
|
|
15536
|
+
if (!readdirSync12(child).length) rmSync4(child, { recursive: true });
|
|
15537
|
+
} else if (entry.isFile() && RASTER_FILE.test(entry.name) && !keep.has(child)) rmSync4(child);
|
|
15538
|
+
}
|
|
15539
|
+
};
|
|
15540
|
+
walk2(dir);
|
|
15541
|
+
if (!readdirSync12(dir).length) rmSync4(dir, { recursive: true });
|
|
15542
|
+
}
|
|
15216
15543
|
async function initHhpScreen(root, id) {
|
|
15217
15544
|
if (!/^[a-z][a-z0-9_]*$/.test(id)) throw new Error("Use a lowercase screen name with underscores.");
|
|
15218
15545
|
const manifest = readHhpManifest(root) ?? { version: "hhp/2", screens: {} };
|
|
@@ -15270,7 +15597,7 @@ function hhpEditorSettings(source) {
|
|
|
15270
15597
|
}
|
|
15271
15598
|
return JSON.stringify(settings, null, 2) + "\n";
|
|
15272
15599
|
}
|
|
15273
|
-
var GENERATED, BEGIN, END;
|
|
15600
|
+
var GENERATED, BEGIN, END, RASTER_DIR, existsExact, rasterName, RASTER_FILE;
|
|
15274
15601
|
var init_hhp = __esm({
|
|
15275
15602
|
"src/hhp.ts"() {
|
|
15276
15603
|
init_catalog();
|
|
@@ -15279,9 +15606,14 @@ var init_hhp = __esm({
|
|
|
15279
15606
|
init_loader();
|
|
15280
15607
|
init_preview_surfaces();
|
|
15281
15608
|
init_app_assets();
|
|
15609
|
+
init_pixels();
|
|
15282
15610
|
GENERATED = "// GENERATED HHP v2 \u2014 edit screens/, then run himi build.\n";
|
|
15283
15611
|
BEGIN = "// himi:hhp:begin";
|
|
15284
15612
|
END = "// himi:hhp:end";
|
|
15613
|
+
RASTER_DIR = "hhp-raster";
|
|
15614
|
+
existsExact = (path2) => existsSync15(path2) && readdirSync12(dirname11(path2)).includes(basename7(path2));
|
|
15615
|
+
rasterName = (svgName, svg) => `${RASTER_DIR}/${svgName.split("/").join("__")}.${createHash8("sha256").update(svg).digest("hex").slice(0, 12)}.png`;
|
|
15616
|
+
RASTER_FILE = /\.svg\.[0-9a-f]{12}\.png$/i;
|
|
15285
15617
|
}
|
|
15286
15618
|
});
|
|
15287
15619
|
|
|
@@ -17842,7 +18174,7 @@ function relativeLuminance(hex2) {
|
|
|
17842
18174
|
const lin = [1, 3, 5].map((i2) => parseInt(hex2.slice(i2, i2 + 2), 16) / 255).map((v2) => v2 <= 0.03928 ? v2 / 12.92 : ((v2 + 0.055) / 1.055) ** 2.4);
|
|
17843
18175
|
return 0.2126 * lin[0] + 0.7152 * lin[1] + 0.0722 * lin[2];
|
|
17844
18176
|
}
|
|
17845
|
-
function
|
|
18177
|
+
function contrastRatio2(a2, b2) {
|
|
17846
18178
|
const la2 = relativeLuminance(a2);
|
|
17847
18179
|
const lb = relativeLuminance(b2);
|
|
17848
18180
|
return (Math.max(la2, lb) + 0.05) / (Math.min(la2, lb) + 0.05);
|
|
@@ -17930,7 +18262,7 @@ function channel2(hex2, offset) {
|
|
|
17930
18262
|
function toHex(r2, g2, b2) {
|
|
17931
18263
|
return `#${[r2, g2, b2].map((value) => Math.round(value).toString(16).padStart(2, "0")).join("")}`.toUpperCase();
|
|
17932
18264
|
}
|
|
17933
|
-
function
|
|
18265
|
+
function mix2(color, background, colorWeight) {
|
|
17934
18266
|
const values = [1, 3, 5].map((offset) => channel2(color, offset) * colorWeight + channel2(background, offset) * (1 - colorWeight));
|
|
17935
18267
|
return toHex(values[0], values[1], values[2]);
|
|
17936
18268
|
}
|
|
@@ -17941,7 +18273,7 @@ function relativeLuminance2(color) {
|
|
|
17941
18273
|
});
|
|
17942
18274
|
return 0.2126 * linear[0] + 0.7152 * linear[1] + 0.0722 * linear[2];
|
|
17943
18275
|
}
|
|
17944
|
-
function
|
|
18276
|
+
function contrastRatio3(a2, b2) {
|
|
17945
18277
|
const la2 = relativeLuminance2(a2);
|
|
17946
18278
|
const lb = relativeLuminance2(b2);
|
|
17947
18279
|
return (Math.max(la2, lb) + 0.05) / (Math.min(la2, lb) + 0.05);
|
|
@@ -17951,19 +18283,19 @@ function lstar(color) {
|
|
|
17951
18283
|
return y2 <= 8856e-6 ? y2 * 903.3 : 116 * Math.cbrt(y2) - 16;
|
|
17952
18284
|
}
|
|
17953
18285
|
function deriveAccentSurface(accent, surface, weight) {
|
|
17954
|
-
const tint =
|
|
17955
|
-
if (
|
|
18286
|
+
const tint = mix2(accent, surface, weight);
|
|
18287
|
+
if (contrastRatio3(tint, surface) >= ACCENT_SURFACE_MIN_DELTA) return tint;
|
|
17956
18288
|
const away = relativeLuminance2(surface) < 0.5 ? "#FFFFFF" : "#000000";
|
|
17957
18289
|
for (let w2 = 0.02; w2 <= 0.5; w2 += 0.02) {
|
|
17958
|
-
const candidate =
|
|
17959
|
-
if (
|
|
18290
|
+
const candidate = mix2(away, surface, w2);
|
|
18291
|
+
if (contrastRatio3(candidate, surface) >= ACCENT_SURFACE_MIN_DELTA) return candidate;
|
|
17960
18292
|
}
|
|
17961
18293
|
return tint;
|
|
17962
18294
|
}
|
|
17963
18295
|
function deriveSecondaryAccent(primary) {
|
|
17964
|
-
const shade2 =
|
|
18296
|
+
const shade2 = mix2(primary, "#000000", SECONDARY_SHADE_WEIGHT);
|
|
17965
18297
|
if (lstar(shade2) >= SECONDARY_MIN_LSTAR) return shade2;
|
|
17966
|
-
return
|
|
18298
|
+
return mix2(primary, "#FFFFFF", SECONDARY_SHADE_WEIGHT);
|
|
17967
18299
|
}
|
|
17968
18300
|
function textOn(color) {
|
|
17969
18301
|
const luminance2 = relativeLuminance2(color);
|
|
@@ -17973,42 +18305,42 @@ function textOn(color) {
|
|
|
17973
18305
|
}
|
|
17974
18306
|
function tuneDarkAccent(brand, darkSurface, lightSurface) {
|
|
17975
18307
|
const kitInherentlyDark = lstar(lightSurface) < 50;
|
|
17976
|
-
if (kitInherentlyDark &&
|
|
18308
|
+
if (kitInherentlyDark && contrastRatio3(brand, darkSurface) >= DARK_ARM_TARGET_CONTRAST && lstar(brand) <= DARK_ARM_LSTAR_CAP) {
|
|
17977
18309
|
return brand;
|
|
17978
18310
|
}
|
|
17979
18311
|
let lift = DARK_ARM_MIN_LIFT;
|
|
17980
|
-
let candidate =
|
|
17981
|
-
while (
|
|
18312
|
+
let candidate = mix2(brand, "#FFFFFF", 1 - lift);
|
|
18313
|
+
while (contrastRatio3(candidate, darkSurface) < DARK_ARM_TARGET_CONTRAST && lift < 0.6) {
|
|
17982
18314
|
lift += 0.04;
|
|
17983
|
-
candidate =
|
|
18315
|
+
candidate = mix2(brand, "#FFFFFF", 1 - lift);
|
|
17984
18316
|
}
|
|
17985
18317
|
while (lstar(candidate) > DARK_ARM_LSTAR_CAP) {
|
|
17986
|
-
const darker =
|
|
17987
|
-
if (
|
|
18318
|
+
const darker = mix2(candidate, "#000000", 0.94);
|
|
18319
|
+
if (contrastRatio3(darker, darkSurface) < DARK_ARM_FLOOR_CONTRAST) break;
|
|
17988
18320
|
candidate = darker;
|
|
17989
18321
|
}
|
|
17990
18322
|
return candidate;
|
|
17991
18323
|
}
|
|
17992
18324
|
function textOnArm(accent) {
|
|
17993
|
-
return
|
|
18325
|
+
return contrastRatio3("#FFFFFF", accent) >= 4.5 ? "#FFFFFF" : textOn(accent);
|
|
17994
18326
|
}
|
|
17995
18327
|
function tuneHighContrastAccent(brand, surface) {
|
|
17996
18328
|
const towards = relativeLuminance2(surface) < 0.5 ? "#FFFFFF" : "#000000";
|
|
17997
18329
|
let candidate = brand;
|
|
17998
|
-
for (let lift = 0; lift <= 0.9 &&
|
|
17999
|
-
candidate =
|
|
18330
|
+
for (let lift = 0; lift <= 0.9 && contrastRatio3(candidate, surface) < HIGH_CONTRAST_TARGET; lift += 0.04) {
|
|
18331
|
+
candidate = mix2(brand, towards, 1 - lift);
|
|
18000
18332
|
}
|
|
18001
18333
|
return candidate;
|
|
18002
18334
|
}
|
|
18003
18335
|
function deriveAccentText(accent, surfaces) {
|
|
18004
18336
|
const all = (typeof surfaces === "string" ? [surfaces] : [...surfaces]).map((s2) => s2.slice(0, 7));
|
|
18005
18337
|
const page = all[0];
|
|
18006
|
-
const worst = (color) => Math.min(...all.map((s2) =>
|
|
18007
|
-
const opaque = accent.length === 9 ?
|
|
18338
|
+
const worst = (color) => Math.min(...all.map((s2) => contrastRatio3(color, s2)));
|
|
18339
|
+
const opaque = accent.length === 9 ? mix2(accent.slice(0, 7), page, channel2(accent, 7) / 255) : accent;
|
|
18008
18340
|
if (worst(opaque) >= ACCENT_TEXT_MIN_CONTRAST) return opaque;
|
|
18009
18341
|
const pole = worst("#FFFFFF") >= worst("#000000") ? "#FFFFFF" : "#000000";
|
|
18010
18342
|
for (let step = 1; step <= 100; step++) {
|
|
18011
|
-
const candidate =
|
|
18343
|
+
const candidate = mix2(pole, opaque, step / 100);
|
|
18012
18344
|
if (worst(candidate) >= ACCENT_TEXT_MIN_CONTRAST) return candidate;
|
|
18013
18345
|
}
|
|
18014
18346
|
if (all.length > 1) {
|
|
@@ -18352,10 +18684,10 @@ function paintedOver(fg, bg) {
|
|
|
18352
18684
|
function sameHueForContrast(fg, bg, target = AA_TEXT) {
|
|
18353
18685
|
const base = fg.slice(0, 7);
|
|
18354
18686
|
const opaqueBg = bg.slice(0, 7);
|
|
18355
|
-
const pole =
|
|
18687
|
+
const pole = contrastRatio2("#000000", opaqueBg) >= contrastRatio2("#FFFFFF", opaqueBg) ? "#000000" : "#FFFFFF";
|
|
18356
18688
|
for (let step = 0; step <= 100; step++) {
|
|
18357
18689
|
const candidate = mixHex(base, pole, 1 - step / 100);
|
|
18358
|
-
if (
|
|
18690
|
+
if (contrastRatio2(candidate, opaqueBg) >= target) return candidate;
|
|
18359
18691
|
}
|
|
18360
18692
|
return void 0;
|
|
18361
18693
|
}
|
|
@@ -18377,7 +18709,7 @@ function contrastFindings(colors) {
|
|
|
18377
18709
|
const painted2 = paintedOver(fg, bg);
|
|
18378
18710
|
if (!painted2) continue;
|
|
18379
18711
|
const opaqueBg = bg.slice(0, 7);
|
|
18380
|
-
const ratio =
|
|
18712
|
+
const ratio = contrastRatio2(painted2, opaqueBg);
|
|
18381
18713
|
if (ratio >= AA_TEXT) continue;
|
|
18382
18714
|
const key3 = `${fgName}|${pair.bg}|${fg}|${bg}`;
|
|
18383
18715
|
const same3 = findings.get(key3);
|
|
@@ -18385,10 +18717,10 @@ function contrastFindings(colors) {
|
|
|
18385
18717
|
same3.schemes.push(scheme);
|
|
18386
18718
|
continue;
|
|
18387
18719
|
}
|
|
18388
|
-
const darker =
|
|
18720
|
+
const darker = contrastRatio2("#000000", opaqueBg) >= contrastRatio2("#FFFFFF", opaqueBg);
|
|
18389
18721
|
const ink = darker ? "#000000" : "#FFFFFF";
|
|
18390
|
-
const suggestion = pair.suggest === "same-hue" ? sameHueForContrast(painted2, opaqueBg) : pair.suggest === "ink" &&
|
|
18391
|
-
const fix = !suggestion ? ` Pick a ${fgName} that clears ${AA_TEXT}:1 against ${pair.bg}.` : pair.suggest === "same-hue" ? ` A ${darker ? "darker" : "lighter"} ${fgName} of the same hue that clears it is ${suggestion} (${
|
|
18722
|
+
const suggestion = pair.suggest === "same-hue" ? sameHueForContrast(painted2, opaqueBg) : pair.suggest === "ink" && contrastRatio2(ink, opaqueBg) >= AA_TEXT ? ink : void 0;
|
|
18723
|
+
const fix = !suggestion ? ` Pick a ${fgName} that clears ${AA_TEXT}:1 against ${pair.bg}.` : pair.suggest === "same-hue" ? ` A ${darker ? "darker" : "lighter"} ${fgName} of the same hue that clears it is ${suggestion} (${contrastRatio2(suggestion, opaqueBg).toFixed(2)}:1).` : ` ${suggestion} clears it (${contrastRatio2(suggestion, opaqueBg).toFixed(2)}:1).`;
|
|
18392
18724
|
findings.set(key3, {
|
|
18393
18725
|
key: key3,
|
|
18394
18726
|
schemes: [scheme],
|
|
@@ -18405,7 +18737,7 @@ function sameHueClearingAll(fg, bgs, target = AA_TEXT) {
|
|
|
18405
18737
|
for (let step = 0; step <= 100; step++) {
|
|
18406
18738
|
for (const pole of poles) {
|
|
18407
18739
|
const candidate = mixHex(base, pole, 1 - step / 100);
|
|
18408
|
-
if (bgs.every((bg) =>
|
|
18740
|
+
if (bgs.every((bg) => contrastRatio2(candidate, bg) >= target)) return candidate;
|
|
18409
18741
|
}
|
|
18410
18742
|
}
|
|
18411
18743
|
return void 0;
|
|
@@ -18432,8 +18764,8 @@ function accentOnSurfacesFor(fgName, role, colors, declared, findings) {
|
|
|
18432
18764
|
const page = pageRaw && paintedOver(fg, pageRaw) ? pageRaw.slice(0, 7) : void 0;
|
|
18433
18765
|
const opaqueBg = bg.slice(0, 7);
|
|
18434
18766
|
if (page === opaqueBg) continue;
|
|
18435
|
-
if (page &&
|
|
18436
|
-
const ratio =
|
|
18767
|
+
if (page && contrastRatio2(paintedOver(fg, pageRaw), page) < AA_TEXT) continue;
|
|
18768
|
+
const ratio = contrastRatio2(painted2, opaqueBg);
|
|
18437
18769
|
if (ratio >= AA_TEXT) continue;
|
|
18438
18770
|
const key3 = `${fgName}|${surface}|${fg}|${bg}|${page ?? ""}`;
|
|
18439
18771
|
const same3 = findings.get(key3);
|
|
@@ -18442,9 +18774,9 @@ function accentOnSurfacesFor(fgName, role, colors, declared, findings) {
|
|
|
18442
18774
|
continue;
|
|
18443
18775
|
}
|
|
18444
18776
|
const opposite = page !== void 0 && onLightSide(page) !== onLightSide(opaqueBg);
|
|
18445
|
-
const noSingle = page !== void 0 && opposite &&
|
|
18777
|
+
const noSingle = page !== void 0 && opposite && contrastRatio2(page, opaqueBg) < AA_TEXT * AA_TEXT;
|
|
18446
18778
|
const suggestion = noSingle ? void 0 : sameHueClearingAll(painted2, page ? [page, opaqueBg] : [opaqueBg]);
|
|
18447
|
-
const measured = (c2) => page ? `${
|
|
18779
|
+
const measured = (c2) => page ? `${contrastRatio2(c2, opaqueBg).toFixed(2)}:1 on ${surface}, ${contrastRatio2(c2, page).toFixed(2)}:1 on surfacePrimary` : `${contrastRatio2(c2, opaqueBg).toFixed(2)}:1`;
|
|
18448
18780
|
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).`;
|
|
18449
18781
|
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 : "");
|
|
18450
18782
|
findings.set(key3, {
|
|
@@ -18487,7 +18819,7 @@ var init_token_lint = __esm({
|
|
|
18487
18819
|
const [ca2, cb] = [channels(a2), channels(b2)];
|
|
18488
18820
|
return toHex2(ca2.map((c2, i2) => c2 * w2 + cb[i2] * (1 - w2)));
|
|
18489
18821
|
};
|
|
18490
|
-
onLightSide = (hex2) =>
|
|
18822
|
+
onLightSide = (hex2) => contrastRatio2("#000000", hex2) >= contrastRatio2("#FFFFFF", hex2);
|
|
18491
18823
|
}
|
|
18492
18824
|
});
|
|
18493
18825
|
|
|
@@ -19085,261 +19417,6 @@ var init_app_icon = __esm({
|
|
|
19085
19417
|
}
|
|
19086
19418
|
});
|
|
19087
19419
|
|
|
19088
|
-
// ../app-icons/pixels.ts
|
|
19089
|
-
var pixels_exports = {};
|
|
19090
|
-
__export(pixels_exports, {
|
|
19091
|
-
LETTERBOX_ERROR_FRACTION: () => LETTERBOX_ERROR_FRACTION,
|
|
19092
|
-
LETTERBOX_WARN_FRACTION: () => LETTERBOX_WARN_FRACTION,
|
|
19093
|
-
NORMALIZE_FIT_FRACTION: () => NORMALIZE_FIT_FRACTION,
|
|
19094
|
-
PIXEL_TOOLCHAIN_HINT: () => PIXEL_TOOLCHAIN_HINT,
|
|
19095
|
-
PixelToolchainUnavailable: () => PixelToolchainUnavailable,
|
|
19096
|
-
appStoreIconPixelFindings: () => appStoreIconPixelFindings,
|
|
19097
|
-
derivePlayListingIcon: () => derivePlayListingIcon,
|
|
19098
|
-
inspectIconPixels: () => inspectIconPixels,
|
|
19099
|
-
normalizeSourceIcon: () => normalizeSourceIcon,
|
|
19100
|
-
pixelToolchainAvailable: () => pixelToolchainAvailable,
|
|
19101
|
-
pixelToolchainProblem: () => pixelToolchainProblem,
|
|
19102
|
-
renderGlyphTile: () => renderGlyphTile
|
|
19103
|
-
});
|
|
19104
|
-
function isNotInstalled(e2) {
|
|
19105
|
-
const code = e2?.code;
|
|
19106
|
-
return code === "MODULE_NOT_FOUND" || code === "ERR_MODULE_NOT_FOUND";
|
|
19107
|
-
}
|
|
19108
|
-
function messageOf(e2) {
|
|
19109
|
-
return e2 instanceof Error ? e2.message : String(e2);
|
|
19110
|
-
}
|
|
19111
|
-
async function loadSharp() {
|
|
19112
|
-
if (cachedSharp) return cachedSharp;
|
|
19113
|
-
const failures = [];
|
|
19114
|
-
let presentButBroken = false;
|
|
19115
|
-
try {
|
|
19116
|
-
const { createRequire: createRequire4 } = await import("node:module");
|
|
19117
|
-
cachedSharp = createRequire4(import.meta.url)("sharp");
|
|
19118
|
-
lastProblem = null;
|
|
19119
|
-
return cachedSharp;
|
|
19120
|
-
} catch (e2) {
|
|
19121
|
-
presentButBroken ||= !isNotInstalled(e2);
|
|
19122
|
-
failures.push(`require: ${messageOf(e2)}`);
|
|
19123
|
-
}
|
|
19124
|
-
try {
|
|
19125
|
-
cachedSharp = (await import("sharp")).default;
|
|
19126
|
-
lastProblem = null;
|
|
19127
|
-
return cachedSharp;
|
|
19128
|
-
} catch (e2) {
|
|
19129
|
-
presentButBroken ||= !isNotInstalled(e2);
|
|
19130
|
-
failures.push(`import: ${messageOf(e2)}`);
|
|
19131
|
-
}
|
|
19132
|
-
lastProblem = presentButBroken ? `the image toolchain (sharp) is installed but could not be loaded \u2014 ${failures.join("; ")}` : PIXEL_TOOLCHAIN_HINT;
|
|
19133
|
-
return null;
|
|
19134
|
-
}
|
|
19135
|
-
async function pixelToolchainAvailable() {
|
|
19136
|
-
return await loadSharp() !== null;
|
|
19137
|
-
}
|
|
19138
|
-
async function pixelToolchainProblem() {
|
|
19139
|
-
return await loadSharp() === null ? lastProblem ?? PIXEL_TOOLCHAIN_HINT : null;
|
|
19140
|
-
}
|
|
19141
|
-
async function sharpOrThrow() {
|
|
19142
|
-
const s2 = await loadSharp();
|
|
19143
|
-
if (!s2) throw new PixelToolchainUnavailable(lastProblem ?? PIXEL_TOOLCHAIN_HINT);
|
|
19144
|
-
return s2;
|
|
19145
|
-
}
|
|
19146
|
-
async function inspectIconPixels(png) {
|
|
19147
|
-
const sharp = await sharpOrThrow();
|
|
19148
|
-
const { data, info: info4 } = await sharp(png).ensureAlpha().raw().toBuffer({ resolveWithObject: true });
|
|
19149
|
-
const { width, height, channels: channels3 } = info4;
|
|
19150
|
-
if (channels3 !== 4) throw new Error(`app-icons: expected RGBA after ensureAlpha, got ${channels3} channels`);
|
|
19151
|
-
let minAlpha = 255;
|
|
19152
|
-
let transparent = 0;
|
|
19153
|
-
for (let i2 = 3; i2 < data.length; i2 += 4) {
|
|
19154
|
-
const a2 = data[i2];
|
|
19155
|
-
if (a2 < minAlpha) minAlpha = a2;
|
|
19156
|
-
if (a2 <= ALPHA_OPAQUE) transparent++;
|
|
19157
|
-
}
|
|
19158
|
-
const probe = Math.max(1, Math.round(Math.min(width, height) * CORNER_PROBE));
|
|
19159
|
-
let minCornerAlpha = 255;
|
|
19160
|
-
for (const [x0, y0] of [
|
|
19161
|
-
[0, 0],
|
|
19162
|
-
[width - probe, 0],
|
|
19163
|
-
[0, height - probe],
|
|
19164
|
-
[width - probe, height - probe]
|
|
19165
|
-
]) {
|
|
19166
|
-
for (let y2 = y0; y2 < y0 + probe; y2++) {
|
|
19167
|
-
for (let x2 = x0; x2 < x0 + probe; x2++) {
|
|
19168
|
-
const a2 = data[(y2 * width + x2) * 4 + 3];
|
|
19169
|
-
if (a2 < minCornerAlpha) minCornerAlpha = a2;
|
|
19170
|
-
}
|
|
19171
|
-
}
|
|
19172
|
-
}
|
|
19173
|
-
const inset = Math.round(Math.min(width, height) * INTERIOR_INSET);
|
|
19174
|
-
let interiorMinAlpha = 255;
|
|
19175
|
-
for (let y2 = inset; y2 < height - inset; y2++) {
|
|
19176
|
-
for (let x2 = inset; x2 < width - inset; x2++) {
|
|
19177
|
-
const a2 = data[(y2 * width + x2) * 4 + 3];
|
|
19178
|
-
if (a2 < interiorMinAlpha) interiorMinAlpha = a2;
|
|
19179
|
-
}
|
|
19180
|
-
}
|
|
19181
|
-
return {
|
|
19182
|
-
width,
|
|
19183
|
-
height,
|
|
19184
|
-
minAlpha,
|
|
19185
|
-
transparentFraction: transparent / (width * height),
|
|
19186
|
-
minCornerAlpha,
|
|
19187
|
-
interiorMinAlpha,
|
|
19188
|
-
// `minAlpha <= ALPHA_OPAQUE` IS "has transparency", and the caller has just computed
|
|
19189
|
-
// it — contentBox used to re-derive it with a full extra sweep of the raster.
|
|
19190
|
-
contentBox: contentBox(data, width, height, minAlpha <= ALPHA_OPAQUE)
|
|
19191
|
-
};
|
|
19192
|
-
}
|
|
19193
|
-
function contentBox(data, width, height, hasTransparency) {
|
|
19194
|
-
const at2 = (x2, y2) => (y2 * width + x2) * 4;
|
|
19195
|
-
const bg = [data[at2(0, 0)], data[at2(0, 0) + 1], data[at2(0, 0) + 2]];
|
|
19196
|
-
const isInk = (x2, y2) => {
|
|
19197
|
-
const i2 = at2(x2, y2);
|
|
19198
|
-
if (hasTransparency) return data[i2 + 3] > ALPHA_OPAQUE;
|
|
19199
|
-
return Math.abs(data[i2] - bg[0]) > INK_TOLERANCE || Math.abs(data[i2 + 1] - bg[1]) > INK_TOLERANCE || Math.abs(data[i2 + 2] - bg[2]) > INK_TOLERANCE;
|
|
19200
|
-
};
|
|
19201
|
-
let minX = width, minY = height, maxX = -1, maxY = -1;
|
|
19202
|
-
for (let y2 = 0; y2 < height; y2++) {
|
|
19203
|
-
for (let x2 = 0; x2 < width; x2++) {
|
|
19204
|
-
if (!isInk(x2, y2)) continue;
|
|
19205
|
-
if (x2 < minX) minX = x2;
|
|
19206
|
-
if (x2 > maxX) maxX = x2;
|
|
19207
|
-
if (y2 < minY) minY = y2;
|
|
19208
|
-
if (y2 > maxY) maxY = y2;
|
|
19209
|
-
}
|
|
19210
|
-
}
|
|
19211
|
-
if (maxX < 0) return null;
|
|
19212
|
-
return {
|
|
19213
|
-
widthFraction: (maxX - minX + 1) / width,
|
|
19214
|
-
heightFraction: (maxY - minY + 1) / height
|
|
19215
|
-
};
|
|
19216
|
-
}
|
|
19217
|
-
function appStoreIconPixelFindings(f2) {
|
|
19218
|
-
const out2 = [];
|
|
19219
|
-
const preMasked = f2.interiorMinAlpha > ALPHA_OPAQUE && f2.minCornerAlpha <= ALPHA_OPAQUE && f2.transparentFraction <= PRE_MASK_MAX_TRANSPARENT_FRACTION;
|
|
19220
|
-
if (preMasked) {
|
|
19221
|
-
out2.push({
|
|
19222
|
-
level: "error",
|
|
19223
|
-
message: "App icon looks pre-masked: its corners are transparent while the middle is opaque. iOS and Play both apply their own corner mask, so rounded artwork is rounded twice and looks visibly wrong on device \u2014 and the transparency itself is an App Store rejection (ITMS-90717 / ITMS-90647). Ship a full-bleed square with 90-degree corners and no inset."
|
|
19224
|
-
});
|
|
19225
|
-
} else if (f2.minAlpha <= ALPHA_OPAQUE) {
|
|
19226
|
-
out2.push({
|
|
19227
|
-
level: "error",
|
|
19228
|
-
message: `App icon has transparent pixels (${(f2.transparentFraction * 100).toFixed(1)}% of the canvas, lowest alpha ${f2.minAlpha}). An App Store icon may carry an alpha channel but no transparent regions \u2014 Apple rejects this as ITMS-90717 / ITMS-90647. Flatten it onto an opaque background (\`himi icon set <file>\` does this for you).`
|
|
19229
|
-
});
|
|
19230
|
-
}
|
|
19231
|
-
if (f2.contentBox === null) {
|
|
19232
|
-
out2.push({
|
|
19233
|
-
level: "error",
|
|
19234
|
-
message: "App icon is a single flat colour with no distinguishable artwork \u2014 the mark is not visible in it. Supply art that contrasts with the background, or use `himi icon generate` for a glyph tile."
|
|
19235
|
-
});
|
|
19236
|
-
return out2;
|
|
19237
|
-
}
|
|
19238
|
-
const shorter = Math.min(f2.contentBox.widthFraction, f2.contentBox.heightFraction);
|
|
19239
|
-
if (shorter < LETTERBOX_ERROR_FRACTION) {
|
|
19240
|
-
out2.push({
|
|
19241
|
-
level: "error",
|
|
19242
|
-
message: `App icon artwork fills only ${(shorter * 100).toFixed(0)}% of the canvas on its shorter side, so it reads as a speck on a home screen. This is what a wide wordmark centred in a square looks like \u2014 crop to the mark, or use a monogram/glyph instead of the wordmark.`
|
|
19243
|
-
});
|
|
19244
|
-
} else if (shorter < LETTERBOX_WARN_FRACTION) {
|
|
19245
|
-
out2.push({
|
|
19246
|
-
level: "warn",
|
|
19247
|
-
message: `App icon artwork fills ${(shorter * 100).toFixed(0)}% of the canvas on its shorter side \u2014 it will read as a thin strip at home-screen size. Consider cropping to the mark.`
|
|
19248
|
-
});
|
|
19249
|
-
}
|
|
19250
|
-
return out2;
|
|
19251
|
-
}
|
|
19252
|
-
function luminance([r2, g2, b2]) {
|
|
19253
|
-
const lin = [r2, g2, b2].map((v2) => {
|
|
19254
|
-
const c2 = v2 / 255;
|
|
19255
|
-
return c2 <= 0.04045 ? c2 / 12.92 : ((c2 + 0.055) / 1.055) ** 2.4;
|
|
19256
|
-
});
|
|
19257
|
-
return 0.2126 * lin[0] + 0.7152 * lin[1] + 0.0722 * lin[2];
|
|
19258
|
-
}
|
|
19259
|
-
function contrastRatio3(a2, b2) {
|
|
19260
|
-
const [hi2, lo2] = [luminance(a2), luminance(b2)].sort((x2, y2) => y2 - x2);
|
|
19261
|
-
return (hi2 + 0.05) / (lo2 + 0.05);
|
|
19262
|
-
}
|
|
19263
|
-
async function contrastingBackdrop(mark, requested) {
|
|
19264
|
-
const sharp = await sharpOrThrow();
|
|
19265
|
-
const { dominant } = await sharp(mark).stats();
|
|
19266
|
-
const ink = [dominant.r, dominant.g, dominant.b];
|
|
19267
|
-
const want = hexToRgb(requested);
|
|
19268
|
-
if (!want || contrastRatio3(ink, want) >= MIN_BACKDROP_CONTRAST) return requested;
|
|
19269
|
-
const towardsWhite = luminance(ink) < 0.5;
|
|
19270
|
-
for (const amount of [0.35, 0.55, 0.75, 0.9]) {
|
|
19271
|
-
const candidate = mix2(want, towardsWhite ? [255, 255, 255] : [0, 0, 0], amount);
|
|
19272
|
-
if (contrastRatio3(ink, candidate) >= MIN_BACKDROP_CONTRAST) return rgbToHex(candidate);
|
|
19273
|
-
}
|
|
19274
|
-
return towardsWhite ? "#FFFFFF" : "#000000";
|
|
19275
|
-
}
|
|
19276
|
-
function hexToRgb(hex2) {
|
|
19277
|
-
const m2 = /^#([0-9a-fA-F]{6})$/.exec(hex2);
|
|
19278
|
-
if (!m2) return null;
|
|
19279
|
-
const n2 = parseInt(m2[1], 16);
|
|
19280
|
-
return [n2 >> 16 & 255, n2 >> 8 & 255, n2 & 255];
|
|
19281
|
-
}
|
|
19282
|
-
function mix2(a2, b2, t2) {
|
|
19283
|
-
return [0, 1, 2].map((i2) => Math.round(a2[i2] + (b2[i2] - a2[i2]) * t2));
|
|
19284
|
-
}
|
|
19285
|
-
function rgbToHex([r2, g2, b2]) {
|
|
19286
|
-
return `#${[r2, g2, b2].map((v2) => v2.toString(16).padStart(2, "0")).join("")}`.toUpperCase();
|
|
19287
|
-
}
|
|
19288
|
-
async function normalizeSourceIcon(input, opts) {
|
|
19289
|
-
const sharp = await sharpOrThrow();
|
|
19290
|
-
const size = opts.size ?? 1024;
|
|
19291
|
-
const fit2 = opts.fit ?? NORMALIZE_FIT_FRACTION;
|
|
19292
|
-
const inner = Math.max(1, Math.round(size * fit2));
|
|
19293
|
-
const pad3 = Math.round((size - inner) / 2);
|
|
19294
|
-
let trimmed;
|
|
19295
|
-
try {
|
|
19296
|
-
trimmed = await sharp(input).ensureAlpha().trim().png().toBuffer();
|
|
19297
|
-
} catch {
|
|
19298
|
-
trimmed = await sharp(input).ensureAlpha().png().toBuffer();
|
|
19299
|
-
}
|
|
19300
|
-
const mark = await sharp(trimmed).resize(inner, inner, { fit: "contain", background: { r: 0, g: 0, b: 0, alpha: 0 } }).png().toBuffer();
|
|
19301
|
-
const background = await contrastingBackdrop(mark, opts.background);
|
|
19302
|
-
return sharp({
|
|
19303
|
-
create: {
|
|
19304
|
-
width: size,
|
|
19305
|
-
height: size,
|
|
19306
|
-
channels: 4,
|
|
19307
|
-
background: { r: 0, g: 0, b: 0, alpha: 0 }
|
|
19308
|
-
}
|
|
19309
|
-
}).composite([{ input: mark, top: pad3, left: pad3 }]).flatten({ background }).removeAlpha().png({ palette: false }).toBuffer();
|
|
19310
|
-
}
|
|
19311
|
-
async function derivePlayListingIcon(master, size = 512) {
|
|
19312
|
-
const sharp = await sharpOrThrow();
|
|
19313
|
-
return sharp(master).resize(size, size).ensureAlpha().png({ palette: false }).toBuffer();
|
|
19314
|
-
}
|
|
19315
|
-
async function renderGlyphTile(svg, background, size = 1024) {
|
|
19316
|
-
const sharp = await sharpOrThrow();
|
|
19317
|
-
return sharp(Buffer.from(svg)).resize(size, size).flatten({ background }).removeAlpha().png({ palette: false }).toBuffer();
|
|
19318
|
-
}
|
|
19319
|
-
var cachedSharp, lastProblem, PIXEL_TOOLCHAIN_HINT, PixelToolchainUnavailable, ALPHA_OPAQUE, CORNER_PROBE, INTERIOR_INSET, INK_TOLERANCE, PRE_MASK_MAX_TRANSPARENT_FRACTION, LETTERBOX_WARN_FRACTION, LETTERBOX_ERROR_FRACTION, NORMALIZE_FIT_FRACTION, MIN_BACKDROP_CONTRAST;
|
|
19320
|
-
var init_pixels = __esm({
|
|
19321
|
-
"../app-icons/pixels.ts"() {
|
|
19322
|
-
cachedSharp = null;
|
|
19323
|
-
lastProblem = null;
|
|
19324
|
-
PIXEL_TOOLCHAIN_HINT = "the image toolchain (sharp) is not installed \u2014 run `npm i -g sharp` to enable transparency, pre-masked-corner and letterbox checks";
|
|
19325
|
-
PixelToolchainUnavailable = class extends Error {
|
|
19326
|
-
constructor(reason = PIXEL_TOOLCHAIN_HINT) {
|
|
19327
|
-
super(`app-icons: ${reason}`);
|
|
19328
|
-
this.name = "PixelToolchainUnavailable";
|
|
19329
|
-
}
|
|
19330
|
-
};
|
|
19331
|
-
ALPHA_OPAQUE = 250;
|
|
19332
|
-
CORNER_PROBE = 0.06;
|
|
19333
|
-
INTERIOR_INSET = 0.2;
|
|
19334
|
-
INK_TOLERANCE = 24;
|
|
19335
|
-
PRE_MASK_MAX_TRANSPARENT_FRACTION = 0.1;
|
|
19336
|
-
LETTERBOX_WARN_FRACTION = 0.35;
|
|
19337
|
-
LETTERBOX_ERROR_FRACTION = 0.2;
|
|
19338
|
-
NORMALIZE_FIT_FRACTION = 0.82;
|
|
19339
|
-
MIN_BACKDROP_CONTRAST = 1.5;
|
|
19340
|
-
}
|
|
19341
|
-
});
|
|
19342
|
-
|
|
19343
19420
|
// src/icon.ts
|
|
19344
19421
|
var icon_exports = {};
|
|
19345
19422
|
__export(icon_exports, {
|
|
@@ -19360,9 +19437,9 @@ __export(icon_exports, {
|
|
|
19360
19437
|
siteLogoAbsence: () => siteLogoAbsence,
|
|
19361
19438
|
summarize: () => summarize
|
|
19362
19439
|
});
|
|
19363
|
-
import { createHash as
|
|
19440
|
+
import { createHash as createHash9 } from "node:crypto";
|
|
19364
19441
|
import { existsSync as existsSync21, mkdirSync as mkdirSync10, readFileSync as readFileSync21, statSync as statSync5, writeFileSync as writeFileSync8 } from "node:fs";
|
|
19365
|
-
import { basename as
|
|
19442
|
+
import { basename as basename8, dirname as dirname15, join as join21, resolve as resolve21, sep as sep7 } from "node:path";
|
|
19366
19443
|
function readManifest(dir) {
|
|
19367
19444
|
try {
|
|
19368
19445
|
return JSON.parse(readFileSync21(join21(dir, MANIFEST), "utf8"));
|
|
@@ -19449,7 +19526,7 @@ async function iconStatus(dir) {
|
|
|
19449
19526
|
...base,
|
|
19450
19527
|
templateIcon: templateIconMatch(png),
|
|
19451
19528
|
bytes: png.length,
|
|
19452
|
-
sha256:
|
|
19529
|
+
sha256: createHash9("sha256").update(png).digest("hex"),
|
|
19453
19530
|
header: pngHeader(png),
|
|
19454
19531
|
byteIssues
|
|
19455
19532
|
};
|
|
@@ -19537,7 +19614,7 @@ async function installIcon(dir, sourcePath, opts = {}) {
|
|
|
19537
19614
|
const issues = appStoreIconIssues(input);
|
|
19538
19615
|
if (issues.length) {
|
|
19539
19616
|
throw new Error(
|
|
19540
|
-
`himi icon: ${
|
|
19617
|
+
`himi icon: ${basename8(src)} ${issues.join("; ")}. Normalizing it needs the image toolchain \u2014 ${await pixelToolchainProblem() ?? PIXEL_TOOLCHAIN_HINT} \u2014 or supply an opaque 1024x1024 PNG. The existing icon was left alone.`
|
|
19541
19618
|
);
|
|
19542
19619
|
}
|
|
19543
19620
|
}
|
|
@@ -19843,17 +19920,17 @@ var init_plan_fonts = __esm({
|
|
|
19843
19920
|
});
|
|
19844
19921
|
|
|
19845
19922
|
// ../font-bake/face-source.ts
|
|
19846
|
-
import { createHash as
|
|
19923
|
+
import { createHash as createHash10 } from "node:crypto";
|
|
19847
19924
|
import { existsSync as existsSync24, mkdirSync as mkdirSync11, readFileSync as readFileSync23, renameSync as renameSync2, rmSync as rmSync5, writeFileSync as writeFileSync9 } from "node:fs";
|
|
19848
19925
|
import { homedir as homedir3 } from "node:os";
|
|
19849
|
-
import { basename as
|
|
19926
|
+
import { basename as basename9, join as join24 } from "node:path";
|
|
19850
19927
|
import { fileURLToPath as fileURLToPath11 } from "node:url";
|
|
19851
19928
|
function hasVendoredFloor() {
|
|
19852
19929
|
return existsSync24(VENDORED_DIR);
|
|
19853
19930
|
}
|
|
19854
19931
|
function faceSource(file2, sha2567) {
|
|
19855
|
-
const vendored = join24(VENDORED_DIR,
|
|
19856
|
-
if (existsSync24(vendored) &&
|
|
19932
|
+
const vendored = join24(VENDORED_DIR, basename9(file2));
|
|
19933
|
+
if (existsSync24(vendored) && createHash10("sha256").update(readFileSync23(vendored)).digest("hex") === sha2567) {
|
|
19857
19934
|
return vendored;
|
|
19858
19935
|
}
|
|
19859
19936
|
const cached3 = join24(CACHE_DIR, sha2567);
|
|
@@ -19987,7 +20064,7 @@ var init_face_source = __esm({
|
|
|
19987
20064
|
REPO_ROOT5 = fileURLToPath11(new URL("../..", import.meta.url));
|
|
19988
20065
|
VENDORED_DIR = process.env.HIMI_FONTS_VENDORED_DIR || join24(REPO_ROOT5, "stdlib", "fonts", "vendored", "wix-madefor");
|
|
19989
20066
|
CACHE_DIR = join24(process.env.XDG_CACHE_HOME || join24(homedir3(), ".cache"), "himi", "fonts");
|
|
19990
|
-
sha256Hex3 = (bytes2) =>
|
|
20067
|
+
sha256Hex3 = (bytes2) => createHash10("sha256").update(bytes2).digest("hex");
|
|
19991
20068
|
RAW = ["https://", "raw.", "githubuser", "content.com"].join("");
|
|
19992
20069
|
UPSTREAM_DIR = /^(ofl|apache|ufl)\/[a-z0-9_-]+$/;
|
|
19993
20070
|
FETCH_TIMEOUT_MS = 2e4;
|
|
@@ -21193,7 +21270,7 @@ __export(catalog_cache_exports, {
|
|
|
21193
21270
|
catalogCompatible: () => catalogCompatible,
|
|
21194
21271
|
catalogManifestDigest: () => catalogManifestDigest
|
|
21195
21272
|
});
|
|
21196
|
-
import { createHash as
|
|
21273
|
+
import { createHash as createHash11, randomUUID as randomUUID2 } from "node:crypto";
|
|
21197
21274
|
import {
|
|
21198
21275
|
existsSync as existsSync29,
|
|
21199
21276
|
mkdirSync as mkdirSync13,
|
|
@@ -21289,7 +21366,7 @@ var init_catalog_cache = __esm({
|
|
|
21289
21366
|
this.name = "CatalogError";
|
|
21290
21367
|
}
|
|
21291
21368
|
};
|
|
21292
|
-
hash = (b2) => `sha256-${
|
|
21369
|
+
hash = (b2) => `sha256-${createHash11("sha256").update(b2).digest("hex")}`;
|
|
21293
21370
|
CatalogCache = class {
|
|
21294
21371
|
root;
|
|
21295
21372
|
baseUrl;
|
|
@@ -21307,7 +21384,7 @@ var init_catalog_cache = __esm({
|
|
|
21307
21384
|
homedir4(),
|
|
21308
21385
|
".himi",
|
|
21309
21386
|
"authoring-cache",
|
|
21310
|
-
|
|
21387
|
+
createHash11("sha256").update(this.baseUrl).digest("hex").slice(0, 16)
|
|
21311
21388
|
)
|
|
21312
21389
|
);
|
|
21313
21390
|
this.cliVersion = opts.cliVersion;
|
|
@@ -23547,7 +23624,7 @@ var init_src2 = __esm({
|
|
|
23547
23624
|
|
|
23548
23625
|
// ../app-icons/plan.ts
|
|
23549
23626
|
import { existsSync as existsSync31, readFileSync as readFileSync31, readdirSync as readdirSync18 } from "node:fs";
|
|
23550
|
-
import { createHash as
|
|
23627
|
+
import { createHash as createHash12 } from "node:crypto";
|
|
23551
23628
|
import { dirname as dirname19, join as join32, resolve as resolve26 } from "node:path";
|
|
23552
23629
|
function stripComments(src) {
|
|
23553
23630
|
let out2 = "";
|
|
@@ -23634,7 +23711,7 @@ function parseIconConfig(configTs) {
|
|
|
23634
23711
|
return out2;
|
|
23635
23712
|
}
|
|
23636
23713
|
function idHash(id) {
|
|
23637
|
-
return
|
|
23714
|
+
return createHash12("sha1").update(id).digest();
|
|
23638
23715
|
}
|
|
23639
23716
|
function deriveGlyph(id) {
|
|
23640
23717
|
const h2 = idHash(id);
|
|
@@ -23812,7 +23889,7 @@ function placeholderHashes() {
|
|
|
23812
23889
|
}
|
|
23813
23890
|
function fileSha256(path2) {
|
|
23814
23891
|
try {
|
|
23815
|
-
return
|
|
23892
|
+
return createHash12("sha256").update(readFileSync31(path2)).digest("hex");
|
|
23816
23893
|
} catch {
|
|
23817
23894
|
return null;
|
|
23818
23895
|
}
|
|
@@ -25518,7 +25595,7 @@ __export(progress_exports, {
|
|
|
25518
25595
|
writeFileAtomic: () => writeFileAtomic
|
|
25519
25596
|
});
|
|
25520
25597
|
import { spawn as spawn3 } from "node:child_process";
|
|
25521
|
-
import { createHash as
|
|
25598
|
+
import { createHash as createHash13 } from "node:crypto";
|
|
25522
25599
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
25523
25600
|
import { appendFileSync, closeSync, existsSync as existsSync35, lstatSync as lstatSync8, mkdirSync as mkdirSync16, openSync, readdirSync as readdirSync21, readFileSync as readFileSync35, readSync, renameSync as renameSync5, rmSync as rmSync8, statSync as statSync8, writeFileSync as writeFileSync14 } from "node:fs";
|
|
25524
25601
|
import { isAbsolute as isAbsolute3, join as join36, relative as relative6, resolve as resolve28, sep as sep8 } from "node:path";
|
|
@@ -25604,7 +25681,7 @@ function isSymlink(file2) {
|
|
|
25604
25681
|
function archiveBytes(dir, bytes2) {
|
|
25605
25682
|
const ext = imageExtension(bytes2);
|
|
25606
25683
|
if (!ext) return null;
|
|
25607
|
-
const sha2567 =
|
|
25684
|
+
const sha2567 = createHash13("sha256").update(bytes2).digest("hex");
|
|
25608
25685
|
const rel = join36(HISTORY_DIR, `${sha2567}.${ext}`);
|
|
25609
25686
|
const dest = join36(dir, rel);
|
|
25610
25687
|
if (!realDirIn(dir, HISTORY_DIR)) throw new UnsafeHimiDirError(HISTORY_DIR);
|
|
@@ -25689,7 +25766,7 @@ function journalMilestone(dir, input) {
|
|
|
25689
25766
|
const now = input.now ?? /* @__PURE__ */ new Date();
|
|
25690
25767
|
const step = MILESTONE_STEP[input.milestone];
|
|
25691
25768
|
const abs = input.image ? locateImage(dir, input.image) : null;
|
|
25692
|
-
const images = abs ? [{ sha256:
|
|
25769
|
+
const images = abs ? [{ sha256: createHash13("sha256").update(readFileSync35(abs)).digest("hex") }] : [];
|
|
25693
25770
|
let message = input.message;
|
|
25694
25771
|
if (input.unlessUnchanged) {
|
|
25695
25772
|
const latest = [...entries].reverse().find((e2) => isCliEntry(e2) && e2.milestone === input.milestone);
|
|
@@ -26608,7 +26685,7 @@ var init_claude_plugin = __esm({
|
|
|
26608
26685
|
});
|
|
26609
26686
|
|
|
26610
26687
|
// src/run-identity.ts
|
|
26611
|
-
import { createHash as
|
|
26688
|
+
import { createHash as createHash14 } from "node:crypto";
|
|
26612
26689
|
import { realpathSync as realpathSync5 } from "node:fs";
|
|
26613
26690
|
import { resolve as resolve29 } from "node:path";
|
|
26614
26691
|
function runRootId(dir) {
|
|
@@ -26618,7 +26695,7 @@ function runRootId(dir) {
|
|
|
26618
26695
|
} catch {
|
|
26619
26696
|
real = resolve29(dir);
|
|
26620
26697
|
}
|
|
26621
|
-
return
|
|
26698
|
+
return createHash14("sha256").update(real).digest("hex");
|
|
26622
26699
|
}
|
|
26623
26700
|
function runIdentity(dir) {
|
|
26624
26701
|
return { pid: process.pid, root: runRootId(dir) };
|
|
@@ -26634,7 +26711,7 @@ var init_run_identity = __esm({
|
|
|
26634
26711
|
import { spawn as nodeSpawn } from "node:child_process";
|
|
26635
26712
|
import { closeSync as closeSync2, constants as fsc, existsSync as existsSync36, lstatSync as lstatSync9, mkdirSync as mkdirSync17, openSync as openSync2, readFileSync as readFileSync36, rmSync as rmSync9 } from "node:fs";
|
|
26636
26713
|
import { createServer as createServer2 } from "node:net";
|
|
26637
|
-
import { basename as
|
|
26714
|
+
import { basename as basename10, join as join37 } from "node:path";
|
|
26638
26715
|
function previewPortFor(appName2) {
|
|
26639
26716
|
let h2 = 2166136261;
|
|
26640
26717
|
for (let i2 = 0; i2 < appName2.length; i2++) {
|
|
@@ -26649,7 +26726,7 @@ function previewKey(manifestText, dir) {
|
|
|
26649
26726
|
if (typeof name === "string" && name) return name;
|
|
26650
26727
|
} catch {
|
|
26651
26728
|
}
|
|
26652
|
-
return
|
|
26729
|
+
return basename10(dir);
|
|
26653
26730
|
}
|
|
26654
26731
|
function previewPortForDir(dir) {
|
|
26655
26732
|
const p2 = join37(dir, "himalaya.content.json");
|
|
@@ -30799,7 +30876,7 @@ var init_wix_push_links = __esm({
|
|
|
30799
30876
|
});
|
|
30800
30877
|
|
|
30801
30878
|
// ../../core/dev-server/src/app-config.ts
|
|
30802
|
-
import { createHash as
|
|
30879
|
+
import { createHash as createHash15 } from "node:crypto";
|
|
30803
30880
|
function deriveTelemetryConfig(app) {
|
|
30804
30881
|
const cfg = { enabled: true, samplingRate: 1 };
|
|
30805
30882
|
const prodTelemetry = app.environments?.prod?.telemetry;
|
|
@@ -30996,7 +31073,7 @@ function buildAppConfigDocument(req, meta, override, bundleCtx, devNetMocks) {
|
|
|
30996
31073
|
const locale = pickLocale(typeof acceptLanguage === "string" ? acceptLanguage : null);
|
|
30997
31074
|
const config = locale ? translate(JSON.parse(JSON.stringify(baseline)), locale) : baseline;
|
|
30998
31075
|
const body = JSON.stringify(config);
|
|
30999
|
-
const etag = `"${
|
|
31076
|
+
const etag = `"${createHash15("sha1").update(`${locale ?? "en"}:${body}`).digest("hex")}"`;
|
|
31000
31077
|
return { config, body, etag, locale };
|
|
31001
31078
|
}
|
|
31002
31079
|
function handleAppConfigRequest(req, res, meta, override, bundleCtx, devNetMocks) {
|
|
@@ -35540,7 +35617,7 @@ __export(wix_member_login_exports, {
|
|
|
35540
35617
|
webWixCall: () => webWixCall,
|
|
35541
35618
|
webWixStream: () => webWixStream
|
|
35542
35619
|
});
|
|
35543
|
-
import { createHash as
|
|
35620
|
+
import { createHash as createHash16, randomBytes as randomBytes3 } from "node:crypto";
|
|
35544
35621
|
function b64url(buf) {
|
|
35545
35622
|
return buf.toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
35546
35623
|
}
|
|
@@ -35579,7 +35656,7 @@ function authCodeFrom(url) {
|
|
|
35579
35656
|
}
|
|
35580
35657
|
async function exchangeSessionToken(clientId, redirectUri, visitorToken, sessionToken) {
|
|
35581
35658
|
const verifier = b64url(randomBytes3(32));
|
|
35582
|
-
const challenge = b64url(
|
|
35659
|
+
const challenge = b64url(createHash16("sha256").update(verifier).digest());
|
|
35583
35660
|
const state = b64url(randomBytes3(8));
|
|
35584
35661
|
const rs2 = await postJson(
|
|
35585
35662
|
"/_api/redirects-api/v1/redirect-session",
|
|
@@ -36430,7 +36507,7 @@ var init_person_session_auth = __esm({
|
|
|
36430
36507
|
import { readFileSync as readFileSync45 } from "node:fs";
|
|
36431
36508
|
import { homedir as homedir6 } from "node:os";
|
|
36432
36509
|
import { join as pathJoin2 } from "node:path";
|
|
36433
|
-
import { createHash as
|
|
36510
|
+
import { createHash as createHash17 } from "node:crypto";
|
|
36434
36511
|
function captureAccountSession(req, opts = {}) {
|
|
36435
36512
|
const env = opts.env ?? process.env;
|
|
36436
36513
|
const now = opts.now ?? Date.now();
|
|
@@ -36469,7 +36546,7 @@ async function accountPrincipal(cookie, fetchImpl = fetch) {
|
|
|
36469
36546
|
const identity = await resolveWixAccounts(cookie, fetchImpl);
|
|
36470
36547
|
if (!identity.ok) return { ok: false, reason: identity.reason };
|
|
36471
36548
|
const ids = identity.accounts.map((a2) => a2.accountId).sort().join("\n");
|
|
36472
|
-
return { ok: true, principal: `acct_${
|
|
36549
|
+
return { ok: true, principal: `acct_${createHash17("sha256").update(ids).digest("hex").slice(0, 32)}` };
|
|
36473
36550
|
}
|
|
36474
36551
|
function safeAccountReturn(raw, requestHost, requestProto = "http") {
|
|
36475
36552
|
if (typeof raw !== "string" || !raw) return "/";
|
|
@@ -36579,9 +36656,9 @@ var init_flag_assignments = __esm({
|
|
|
36579
36656
|
});
|
|
36580
36657
|
|
|
36581
36658
|
// ../../core/dev-server/src/images.ts
|
|
36582
|
-
import { createHash as
|
|
36659
|
+
import { createHash as createHash18 } from "node:crypto";
|
|
36583
36660
|
function svgFor(productId, title, sku) {
|
|
36584
|
-
const seedHex =
|
|
36661
|
+
const seedHex = createHash18("sha1").update(productId + ":" + title).digest("hex");
|
|
36585
36662
|
const h2 = (n2) => parseInt(seedHex.slice(n2, n2 + 2), 16);
|
|
36586
36663
|
const hue1 = h2(0) % 360;
|
|
36587
36664
|
const hue2 = (hue1 + 30 + h2(2) % 60) % 360;
|
|
@@ -36613,7 +36690,7 @@ function escapeXml(s2) {
|
|
|
36613
36690
|
return s2.replace(/[<>&"']/g, (c2) => ({ "<": "<", ">": ">", "&": "&", '"': """, "'": "'" })[c2] ?? c2);
|
|
36614
36691
|
}
|
|
36615
36692
|
function wixPhotoSvg(category, seed2) {
|
|
36616
|
-
const seedHex =
|
|
36693
|
+
const seedHex = createHash18("sha1").update(category + ":" + seed2).digest("hex");
|
|
36617
36694
|
const h2 = (n2) => parseInt(seedHex.slice(n2, n2 + 2), 16);
|
|
36618
36695
|
const palette2 = paletteForCategory(category, h2);
|
|
36619
36696
|
const glyph = glyphForCategory(category);
|
|
@@ -36738,7 +36815,7 @@ var init_stable_ids = __esm({
|
|
|
36738
36815
|
|
|
36739
36816
|
// ../../core/dev-server/src/preview.ts
|
|
36740
36817
|
import { spawn as spawn4 } from "node:child_process";
|
|
36741
|
-
import { createHash as
|
|
36818
|
+
import { createHash as createHash19 } from "node:crypto";
|
|
36742
36819
|
import { existsSync as existsSync44, createReadStream, statSync as statSync11, readFileSync as readFileSync46, renameSync as renameSync9, unlinkSync as unlinkSync3 } from "node:fs";
|
|
36743
36820
|
import { homedir as homedir7, tmpdir as tmpdir2 } from "node:os";
|
|
36744
36821
|
import { resolve as resolvePath, dirname as dirname27 } from "node:path";
|
|
@@ -36754,7 +36831,7 @@ function macosWinlistBin() {
|
|
|
36754
36831
|
}
|
|
36755
36832
|
function macosWinlistSourceHash() {
|
|
36756
36833
|
try {
|
|
36757
|
-
return
|
|
36834
|
+
return createHash19("sha1").update(readFileSync46(MACOS_WINLIST)).digest("hex").slice(0, 12);
|
|
36758
36835
|
} catch {
|
|
36759
36836
|
return "missing";
|
|
36760
36837
|
}
|
|
@@ -37610,9 +37687,9 @@ var init_preview2 = __esm({
|
|
|
37610
37687
|
});
|
|
37611
37688
|
|
|
37612
37689
|
// ../../core/dev-server/src/tier4-integrity.ts
|
|
37613
|
-
import { createHash as
|
|
37690
|
+
import { createHash as createHash20 } from "node:crypto";
|
|
37614
37691
|
function computeSri(bytes2) {
|
|
37615
|
-
const digest2 =
|
|
37692
|
+
const digest2 = createHash20("sha384").update(bytes2).digest("base64");
|
|
37616
37693
|
return `sha384-${digest2}`;
|
|
37617
37694
|
}
|
|
37618
37695
|
function parseManifestIntegrity(manifest) {
|
|
@@ -131370,7 +131447,8 @@ function renderDescriptorToHtml(payload, tokens2, scheme = "light", provider = n
|
|
|
131370
131447
|
...typeof width === "number" && Number.isFinite(width) && width > 0 ? { sizeClass: sizeClassFromWidth(width), containerWidth: width } : {},
|
|
131371
131448
|
...rtl ? { isRTL: true } : {},
|
|
131372
131449
|
...opts?.idiomContext ? { idiomContext: opts.idiomContext } : {},
|
|
131373
|
-
...opts?.debugUnknownComponents ? { debugUnknownComponents: true } : {}
|
|
131450
|
+
...opts?.debugUnknownComponents ? { debugUnknownComponents: true } : {},
|
|
131451
|
+
...opts?.assetBaseUrl ? { assetBaseUrl: opts.assetBaseUrl } : {}
|
|
131374
131452
|
});
|
|
131375
131453
|
const FOCUS_STYLE_MARKUP = `<style data-himalaya-focus-ring>${FOCUS_RING_CSS}</style>`;
|
|
131376
131454
|
const withFocusRing = (markup) => markup ? FOCUS_STYLE_MARKUP + markup : markup;
|
|
@@ -131791,7 +131869,7 @@ function composeStickyTree(payload, header, footer) {
|
|
|
131791
131869
|
if (footer) children.push(footer);
|
|
131792
131870
|
return { id: "screen", type: "ScreenChrome", children };
|
|
131793
131871
|
}
|
|
131794
|
-
async function renderDescriptorWeb(descriptor, tokens2, scheme, wantPng, services = null, width, isRTL, idiomContext) {
|
|
131872
|
+
async function renderDescriptorWeb(descriptor, tokens2, scheme, wantPng, services = null, width, isRTL, idiomContext, assetBaseUrl) {
|
|
131795
131873
|
const desc = descriptor;
|
|
131796
131874
|
const tooDeep = rawJsonDepthFinding(descriptor);
|
|
131797
131875
|
if (tooDeep) return { renderable: false, reason: `depth_budget_exceeded: ${tooDeep.message}` };
|
|
@@ -131832,7 +131910,7 @@ async function renderDescriptorWeb(descriptor, tokens2, scheme, wantPng, service
|
|
|
131832
131910
|
stickyHeader || stickyFooter ? { stickyHeader, stickyFooter } : void 0,
|
|
131833
131911
|
// #4497 — the agent fast loop is a dev tool: an unknown component type keeps its
|
|
131834
131912
|
// developer label here (a shipped web app renders nothing for it).
|
|
131835
|
-
{ ...isRTL ? { isRTL: true } : {}, ...idiomContext ? { idiomContext } : {}, debugUnknownComponents: true }
|
|
131913
|
+
{ ...isRTL ? { isRTL: true } : {}, ...idiomContext ? { idiomContext } : {}, ...assetBaseUrl ? { assetBaseUrl } : {}, debugUnknownComponents: true }
|
|
131836
131914
|
);
|
|
131837
131915
|
} catch (err) {
|
|
131838
131916
|
return {
|
|
@@ -132594,7 +132672,7 @@ __export(widgets_exports, {
|
|
|
132594
132672
|
viewWidgetId: () => viewWidgetId,
|
|
132595
132673
|
widgetRealm: () => widgetRealm
|
|
132596
132674
|
});
|
|
132597
|
-
import { createHash as
|
|
132675
|
+
import { createHash as createHash21 } from "node:crypto";
|
|
132598
132676
|
import { inspect } from "node:util";
|
|
132599
132677
|
async function widgetRealm() {
|
|
132600
132678
|
if (!realmPromise) {
|
|
@@ -132650,7 +132728,7 @@ function dropEntry(cache, key3) {
|
|
|
132650
132728
|
cache.bytes -= entry.bytes;
|
|
132651
132729
|
}
|
|
132652
132730
|
function produceCacheKey(bundleJs, timeoutMs, clock) {
|
|
132653
|
-
const digest2 =
|
|
132731
|
+
const digest2 = createHash21("sha256").update(bundleJs).digest("base64");
|
|
132654
132732
|
return `${timeoutMs}|${clock === void 0 ? "live" : Math.trunc(clock)}|${digest2}`;
|
|
132655
132733
|
}
|
|
132656
132734
|
function cachedProduce(evaluator, key3) {
|
|
@@ -133040,7 +133118,7 @@ function contentEtag(snapshot2) {
|
|
|
133040
133118
|
// Lever A — a timeline change must bump the etag (frame values/times are content).
|
|
133041
133119
|
frames: snapshot2.frames ?? null
|
|
133042
133120
|
});
|
|
133043
|
-
return "sha256-" +
|
|
133121
|
+
return "sha256-" + createHash21("sha256").update(canonical6).digest("base64");
|
|
133044
133122
|
}
|
|
133045
133123
|
async function buildWidgetSnapshot(bundleJs, widgetId, opts = {}) {
|
|
133046
133124
|
const { widgets } = await extractWidgets(bundleJs, opts);
|
|
@@ -133543,8 +133621,8 @@ var init_config2 = __esm({
|
|
|
133543
133621
|
import { createServer as createServer3 } from "node:http";
|
|
133544
133622
|
import { readFile, stat } from "node:fs/promises";
|
|
133545
133623
|
import { readFileSync as readFileSync53, existsSync as existsSync47, watch, mkdirSync as mkdirSync23, rmSync as rmSync11 } from "node:fs";
|
|
133546
|
-
import { basename as
|
|
133547
|
-
import { createHash as
|
|
133624
|
+
import { basename as basename11, dirname as dirname30, extname as extname2, join as join47, relative as relative8, resolve as resolve38, normalize as normalize3, sep as sep10 } from "node:path";
|
|
133625
|
+
import { createHash as createHash22, randomUUID as randomUUID5 } from "node:crypto";
|
|
133548
133626
|
import { fileURLToPath as fileURLToPath23, pathToFileURL as pathToFileURL6 } from "node:url";
|
|
133549
133627
|
function readLogicBundle(read, tier5Dir, name) {
|
|
133550
133628
|
return read(tier5Dir ?? TIER5_ROOT2, name) ?? (tier5Dir && tier5Dir !== TIER5_ROOT2 ? read(TIER5_ROOT2, name) : void 0);
|
|
@@ -133590,7 +133668,7 @@ async function readBody2(req) {
|
|
|
133590
133668
|
return Buffer.concat(chunks).toString("utf-8");
|
|
133591
133669
|
}
|
|
133592
133670
|
function makeEtag(body) {
|
|
133593
|
-
return `"${
|
|
133671
|
+
return `"${createHash22("sha256").update(body).digest("hex").slice(0, 32)}"`;
|
|
133594
133672
|
}
|
|
133595
133673
|
function servedTokensPath(app) {
|
|
133596
133674
|
return app.module.designTokensPath ?? resolve38(app.dir, uiConfig(app.module.config).designTokensPath ?? "tokens.json");
|
|
@@ -134121,7 +134199,7 @@ function bundleIntegritySync(name, dir) {
|
|
|
134121
134199
|
for (const root of dir ? [dir, TIER5_ROOT2] : [TIER5_ROOT2]) {
|
|
134122
134200
|
try {
|
|
134123
134201
|
const bytes2 = readFileSync53(resolve38(root, `${name}.bundle.js`));
|
|
134124
|
-
return "sha256-" +
|
|
134202
|
+
return "sha256-" + createHash22("sha256").update(bytes2).digest("base64");
|
|
134125
134203
|
} catch {
|
|
134126
134204
|
}
|
|
134127
134205
|
}
|
|
@@ -134542,7 +134620,7 @@ function tokensAreDerived(state) {
|
|
|
134542
134620
|
}
|
|
134543
134621
|
function servedTokensHash(app) {
|
|
134544
134622
|
try {
|
|
134545
|
-
return
|
|
134623
|
+
return createHash22("sha256").update(readFileSync53(servedTokensPath(app))).digest("hex");
|
|
134546
134624
|
} catch {
|
|
134547
134625
|
return "";
|
|
134548
134626
|
}
|
|
@@ -134570,7 +134648,7 @@ function syncAppDependencyWatchers(state, inputs) {
|
|
|
134570
134648
|
for (const file2 of appDependencyFiles(inputs, state.app.dir)) {
|
|
134571
134649
|
const dir = dirname30(file2);
|
|
134572
134650
|
if (!byDir.has(dir)) byDir.set(dir, /* @__PURE__ */ new Set());
|
|
134573
|
-
byDir.get(dir).add(
|
|
134651
|
+
byDir.get(dir).add(basename11(file2));
|
|
134574
134652
|
}
|
|
134575
134653
|
let timer;
|
|
134576
134654
|
const changed = /* @__PURE__ */ new Set();
|
|
@@ -135292,7 +135370,7 @@ async function handleWebWix(req, res, state) {
|
|
|
135292
135370
|
userId: userId ?? session.email ?? null,
|
|
135293
135371
|
email: session.email ?? "",
|
|
135294
135372
|
preferenceContext: preferenceIdentity ? {
|
|
135295
|
-
accountId: `m_${
|
|
135373
|
+
accountId: `m_${createHash22("sha256").update(preferenceIdentity).digest("hex")}`,
|
|
135296
135374
|
// Headless client IDs are site-bound and come from the server's app
|
|
135297
135375
|
// configuration, never the URL's user-supplied business parameter.
|
|
135298
135376
|
businessId: auth.clientId
|
|
@@ -135392,7 +135470,10 @@ async function handleDev(req, res, state) {
|
|
|
135392
135470
|
body.services ?? null,
|
|
135393
135471
|
width,
|
|
135394
135472
|
body.rtl === true,
|
|
135395
|
-
idiomContext
|
|
135473
|
+
idiomContext,
|
|
135474
|
+
// #4595 — HHP package images arrive host-less (`/v1/asset/<sha>?app=`); a PNG page loads at
|
|
135475
|
+
// about:blank, so resolve them against this server, as a device resolves them against its origin.
|
|
135476
|
+
state.serverBaseUrl
|
|
135396
135477
|
);
|
|
135397
135478
|
const legacy = { screenId, scheme, ...render, diagnostics };
|
|
135398
135479
|
const report3 = foldLegacyReport(legacy, {
|
|
@@ -136032,7 +136113,7 @@ async function readBundleFile(name, dir) {
|
|
|
136032
136113
|
if (!roots.some((root) => path2.startsWith(root))) continue;
|
|
136033
136114
|
try {
|
|
136034
136115
|
const bytes2 = await readFile(path2);
|
|
136035
|
-
const integrity2 = "sha256-" +
|
|
136116
|
+
const integrity2 = "sha256-" + createHash22("sha256").update(bytes2).digest("base64");
|
|
136036
136117
|
return { bytes: bytes2, integrity: integrity2 };
|
|
136037
136118
|
} catch {
|
|
136038
136119
|
}
|
|
@@ -136202,7 +136283,7 @@ function readActionHandlerManifest(app) {
|
|
|
136202
136283
|
} catch {
|
|
136203
136284
|
return { handlers: [] };
|
|
136204
136285
|
}
|
|
136205
|
-
const integrity2 = "sha256-" +
|
|
136286
|
+
const integrity2 = "sha256-" + createHash22("sha256").update(bytes2).digest("base64");
|
|
136206
136287
|
const bundleUrl = `/v1/action-handler-bundles/${app}`;
|
|
136207
136288
|
return { handlers: decls.map((d2) => ({ id: d2.id, policy: d2.policy, description: d2.description, bundleUrl, integrity: integrity2 })) };
|
|
136208
136289
|
}
|
|
@@ -136215,7 +136296,7 @@ async function handleActionHandlerBundleGet(res, app) {
|
|
|
136215
136296
|
if (!path2.startsWith(ACTION_HANDLERS_ROOT)) return sendJson(res, 404, { error: "not_found" });
|
|
136216
136297
|
try {
|
|
136217
136298
|
const bytes2 = await readFile(path2);
|
|
136218
|
-
const integrity2 = "sha256-" +
|
|
136299
|
+
const integrity2 = "sha256-" + createHash22("sha256").update(bytes2).digest("base64");
|
|
136219
136300
|
res.setHeader("content-type", "application/javascript; charset=utf-8");
|
|
136220
136301
|
res.setHeader("cache-control", "max-age=300");
|
|
136221
136302
|
res.setHeader("x-himalaya-bundle-integrity", integrity2);
|
|
@@ -136228,8 +136309,8 @@ async function handleActionHandlerBundleGet(res, app) {
|
|
|
136228
136309
|
}
|
|
136229
136310
|
async function serveStatic(req, res, root, prefix) {
|
|
136230
136311
|
const requested = decodeURIComponent((req.url ?? "").split("?")[0]);
|
|
136231
|
-
const
|
|
136232
|
-
const safe = normalize3(
|
|
136312
|
+
const relative18 = requested.replace(prefix, "").replace(/^\//, "");
|
|
136313
|
+
const safe = normalize3(relative18).replace(/^(\.\.[\/\\])+/, "");
|
|
136233
136314
|
const fullPath = resolve38(root, safe);
|
|
136234
136315
|
if (!fullPath.startsWith(root)) {
|
|
136235
136316
|
return send(res, 403, "forbidden");
|
|
@@ -137010,9 +137091,9 @@ var init_src6 = __esm({
|
|
|
137010
137091
|
});
|
|
137011
137092
|
|
|
137012
137093
|
// ../../core/serve-storage/src/release-patch.ts
|
|
137013
|
-
import { createHash as
|
|
137094
|
+
import { createHash as createHash23 } from "node:crypto";
|
|
137014
137095
|
function sha256hex(b2) {
|
|
137015
|
-
return
|
|
137096
|
+
return createHash23("sha256").update(b2).digest("hex");
|
|
137016
137097
|
}
|
|
137017
137098
|
function stableStringify(value) {
|
|
137018
137099
|
if (value === null || typeof value !== "object") return JSON.stringify(value);
|
|
@@ -140045,11 +140126,11 @@ var init_dependencies = __esm({
|
|
|
140045
140126
|
});
|
|
140046
140127
|
|
|
140047
140128
|
// ../../core/functions-build/src/sbom.ts
|
|
140048
|
-
import { createHash as
|
|
140129
|
+
import { createHash as createHash24 } from "node:crypto";
|
|
140049
140130
|
function createFunctionSbom(packages) {
|
|
140050
140131
|
const components2 = [...packages].sort((a2, b2) => a2.name.localeCompare(b2.name)).map(({ name, version: version4, integrity: integrity2, license }) => ({ name, version: version4, integrity: integrity2, license }));
|
|
140051
140132
|
const body = JSON.stringify({ format: "himalaya-sbom-v1", components: components2 });
|
|
140052
|
-
return { format: "himalaya-sbom-v1", components: components2, hash:
|
|
140133
|
+
return { format: "himalaya-sbom-v1", components: components2, hash: createHash24("sha256").update(body).digest("hex") };
|
|
140053
140134
|
}
|
|
140054
140135
|
var init_sbom = __esm({
|
|
140055
140136
|
"../../core/functions-build/src/sbom.ts"() {
|
|
@@ -140057,12 +140138,12 @@ var init_sbom = __esm({
|
|
|
140057
140138
|
});
|
|
140058
140139
|
|
|
140059
140140
|
// ../../core/functions-build/src/build.ts
|
|
140060
|
-
import { createHash as
|
|
140141
|
+
import { createHash as createHash25 } from "node:crypto";
|
|
140061
140142
|
function sha2563(value) {
|
|
140062
|
-
return
|
|
140143
|
+
return createHash25("sha256").update(value).digest("hex");
|
|
140063
140144
|
}
|
|
140064
140145
|
function sri(value) {
|
|
140065
|
-
return `sha256-${
|
|
140146
|
+
return `sha256-${createHash25("sha256").update(value).digest("base64")}`;
|
|
140066
140147
|
}
|
|
140067
140148
|
function schemaHash(schema) {
|
|
140068
140149
|
if (!schema) return "";
|
|
@@ -140257,7 +140338,7 @@ __export(build_exports2, {
|
|
|
140257
140338
|
withStoreNavBundle: () => withStoreNavBundle,
|
|
140258
140339
|
withoutDevOnlyAppConfig: () => withoutDevOnlyAppConfig
|
|
140259
140340
|
});
|
|
140260
|
-
import { createHash as
|
|
140341
|
+
import { createHash as createHash26 } from "node:crypto";
|
|
140261
140342
|
import { readFileSync as readFileSync54, readdirSync as readdirSync25, existsSync as existsSync48 } from "node:fs";
|
|
140262
140343
|
import { dirname as dirname31, join as join48, resolve as resolve39 } from "node:path";
|
|
140263
140344
|
import { fileURLToPath as fileURLToPath24 } from "node:url";
|
|
@@ -140340,10 +140421,10 @@ function servesMessages(text9) {
|
|
|
140340
140421
|
}
|
|
140341
140422
|
}
|
|
140342
140423
|
function sha2564(buf) {
|
|
140343
|
-
return
|
|
140424
|
+
return createHash26("sha256").update(buf).digest("hex");
|
|
140344
140425
|
}
|
|
140345
140426
|
function sri2(buf) {
|
|
140346
|
-
return "sha256-" +
|
|
140427
|
+
return "sha256-" + createHash26("sha256").update(buf).digest("base64");
|
|
140347
140428
|
}
|
|
140348
140429
|
async function widgetFailureDetail(res) {
|
|
140349
140430
|
try {
|
|
@@ -140771,7 +140852,7 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
140771
140852
|
const compareScheme = collect2?.render?.compareScheme;
|
|
140772
140853
|
const renderCompare = async (descriptor, services) => {
|
|
140773
140854
|
if (!compareScheme || compareScheme === renderScheme) return {};
|
|
140774
|
-
const rr2 = await renderDescriptorWeb(descriptor, renderTokens, compareScheme, false, services, collect2?.render?.width, collect2?.render?.rtl === true);
|
|
140855
|
+
const rr2 = await renderDescriptorWeb(descriptor, renderTokens, compareScheme, false, services, collect2?.render?.width, collect2?.render?.rtl === true, void 0, base);
|
|
140775
140856
|
return { compare: { scheme: compareScheme, renderable: rr2.renderable, ...rr2.html ? { html: rr2.html } : {}, ...rr2.reason ? { reason: rr2.reason } : {} } };
|
|
140776
140857
|
};
|
|
140777
140858
|
const LIVE_LOAD_BUDGET_MS = 3e4;
|
|
@@ -141213,7 +141294,7 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
141213
141294
|
}
|
|
141214
141295
|
if (collect2?.render && (!collect2.render.screenId || collect2.render.screenId === screenId)) {
|
|
141215
141296
|
const { services, liveCalls, liveReturned, liveErrors, mockCalls, mockUnserved, mockBootFailed, liveFailed } = await renderServicesFor(bundleName, descriptor, screenId);
|
|
141216
|
-
const rr2 = await renderDescriptorWeb(descriptor, renderTokens, renderScheme, collect2.render.png === true, services, collect2.render.width, collect2.render.rtl === true);
|
|
141297
|
+
const rr2 = await renderDescriptorWeb(descriptor, renderTokens, renderScheme, collect2.render.png === true, services, collect2.render.width, collect2.render.rtl === true, void 0, base);
|
|
141217
141298
|
renders.push({ screenId, scheme: renderScheme, ...rr2, ...await renderCompare(descriptor, services), ...collect2.render.dumpState && services ? { serviceState: services } : {}, ...liveCalls ? { liveCalls } : {}, ...liveReturned !== void 0 ? { liveReturned } : {}, ...liveFailed ? { liveFailed } : {}, ...liveErrors ? { liveErrors } : {}, ...mockCalls ? { mockCalls, mockUnserved } : {}, ...mockBootFailed ? { mockBootFailed } : {} });
|
|
141218
141299
|
}
|
|
141219
141300
|
}
|
|
@@ -141241,7 +141322,7 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
141241
141322
|
lint.push({ screenId: wantedRender, ok: report3.ok, issues: report3.issues });
|
|
141242
141323
|
}
|
|
141243
141324
|
const { services, liveCalls, liveReturned, liveErrors, mockCalls, mockUnserved, mockBootFailed, liveFailed } = await renderServicesFor(bundleName, descriptor, wantedRender);
|
|
141244
|
-
const rr2 = await renderDescriptorWeb(descriptor, renderTokens, renderScheme, collect2.render.png === true, services, collect2.render.width, collect2.render.rtl === true);
|
|
141325
|
+
const rr2 = await renderDescriptorWeb(descriptor, renderTokens, renderScheme, collect2.render.png === true, services, collect2.render.width, collect2.render.rtl === true, void 0, base);
|
|
141245
141326
|
renders.push({ screenId: wantedRender, scheme: renderScheme, ...rr2, ...await renderCompare(descriptor, services), ...collect2.render.dumpState && services ? { serviceState: services } : {}, ...liveCalls ? { liveCalls } : {}, ...liveReturned !== void 0 ? { liveReturned } : {}, ...liveFailed ? { liveFailed } : {}, ...liveErrors ? { liveErrors } : {}, ...mockCalls ? { mockCalls, mockUnserved } : {}, ...mockBootFailed ? { mockBootFailed } : {} });
|
|
141246
141327
|
} else if (res.status === 422) {
|
|
141247
141328
|
const finding = await depthRefusalOf(res);
|
|
@@ -142555,9 +142636,9 @@ __export(studio_exports, {
|
|
|
142555
142636
|
renderStudioHtml: () => renderStudioHtml,
|
|
142556
142637
|
writeStudioRecord: () => writeStudioRecord
|
|
142557
142638
|
});
|
|
142558
|
-
import { createHash as
|
|
142639
|
+
import { createHash as createHash27 } from "node:crypto";
|
|
142559
142640
|
import { existsSync as existsSync51, readdirSync as readdirSync27, readFileSync as readFileSync57, realpathSync as realpathSync8, statSync as statSync12 } from "node:fs";
|
|
142560
|
-
import { basename as
|
|
142641
|
+
import { basename as basename12, extname as extname3, join as join51, relative as relative9, resolve as resolve40, sep as sep11 } from "node:path";
|
|
142561
142642
|
import { pathToFileURL as pathToFileURL7 } from "node:url";
|
|
142562
142643
|
function realInside(dir, abs) {
|
|
142563
142644
|
try {
|
|
@@ -142605,7 +142686,7 @@ function observeShots(dir, memory, now) {
|
|
|
142605
142686
|
const seen = /* @__PURE__ */ new Set();
|
|
142606
142687
|
const files = existsSync51(shotsDir) ? readdirSync27(shotsDir).filter((f2) => /\.(png|jpe?g)$/i.test(f2)).sort() : [];
|
|
142607
142688
|
for (const f2 of files) {
|
|
142608
|
-
const id =
|
|
142689
|
+
const id = basename12(f2, extname3(f2));
|
|
142609
142690
|
const archived = archiveFile(dir, memory, join51(shotsDir, f2));
|
|
142610
142691
|
if (!archived) continue;
|
|
142611
142692
|
seen.add(id);
|
|
@@ -142639,7 +142720,7 @@ function palette(dir) {
|
|
|
142639
142720
|
}
|
|
142640
142721
|
function appIdentity(dir) {
|
|
142641
142722
|
const manifest = obj(readJson4(join51(dir, "himalaya.content.json")));
|
|
142642
|
-
const name = text(manifest?.name) ??
|
|
142723
|
+
const name = text(manifest?.name) ?? basename12(resolve40(dir));
|
|
142643
142724
|
const icon = text(manifest?.icon)?.trim();
|
|
142644
142725
|
const iconPath = icon ? resolve40(dir, icon) : null;
|
|
142645
142726
|
const real = iconPath ? realInside(dir, iconPath) : null;
|
|
@@ -142818,7 +142899,7 @@ function buildView(dir, memory, now) {
|
|
|
142818
142899
|
message: e2.message,
|
|
142819
142900
|
step: isCliEntry(e2) ? null : e2.step ?? null,
|
|
142820
142901
|
stepNumber: isCliEntry(e2) ? null : e2.stepNumber ?? null,
|
|
142821
|
-
images: (e2.images ?? []).map((i2) => historyUrl(
|
|
142902
|
+
images: (e2.images ?? []).map((i2) => historyUrl(basename12(i2.file))),
|
|
142822
142903
|
by: isCliEntry(e2) ? CLI_AUTHOR : null
|
|
142823
142904
|
})),
|
|
142824
142905
|
screens,
|
|
@@ -142837,7 +142918,7 @@ function buildView(dir, memory, now) {
|
|
|
142837
142918
|
reveal: memory.reveal ?? null
|
|
142838
142919
|
};
|
|
142839
142920
|
const { generatedAt: _ignored, timelineFrames: _count, ...stable } = view;
|
|
142840
|
-
const v2 =
|
|
142921
|
+
const v2 = createHash27("sha256").update(JSON.stringify(stable)).digest("hex").slice(0, 16);
|
|
142841
142922
|
return { v: v2, ...view };
|
|
142842
142923
|
}
|
|
142843
142924
|
function writeAtomic(file2, content) {
|
|
@@ -149687,7 +149768,7 @@ var init_fxp = __esm({
|
|
|
149687
149768
|
});
|
|
149688
149769
|
|
|
149689
149770
|
// ../../packages/serve/src/pkcs12.ts
|
|
149690
|
-
import { X509Certificate, createHash as
|
|
149771
|
+
import { X509Certificate, createHash as createHash28, createPrivateKey as createPrivateKey2, createPublicKey, pbkdf2Sync, createDecipheriv } from "node:crypto";
|
|
149691
149772
|
function decodePkcs12(der, password) {
|
|
149692
149773
|
try {
|
|
149693
149774
|
const pfx = readSequence(der, 0);
|
|
@@ -149961,7 +150042,7 @@ function expand(src, v2) {
|
|
|
149961
150042
|
return out2;
|
|
149962
150043
|
}
|
|
149963
150044
|
function sha12(data) {
|
|
149964
|
-
return
|
|
150045
|
+
return createHash28("sha1").update(data).digest();
|
|
149965
150046
|
}
|
|
149966
150047
|
function readAt(buf, i2) {
|
|
149967
150048
|
if (i2 >= buf.length) return void 0;
|
|
@@ -150050,7 +150131,7 @@ var init_pkcs12 = __esm({
|
|
|
150050
150131
|
});
|
|
150051
150132
|
|
|
150052
150133
|
// ../../packages/serve/src/customer-signing-assets.ts
|
|
150053
|
-
import { createHash as
|
|
150134
|
+
import { createHash as createHash29 } from "node:crypto";
|
|
150054
150135
|
function readValue(node) {
|
|
150055
150136
|
const [tag, children] = Object.entries(node)[0] ?? [];
|
|
150056
150137
|
if (!tag || !Array.isArray(children)) return refuse3("customer_profile_invalid");
|
|
@@ -150128,7 +150209,7 @@ function toBundle(assets, expected, decoded, profileType, apns, deviceCount) {
|
|
|
150128
150209
|
provisioningProfile: Buffer.from(assets.provisioningProfile).toString("base64"),
|
|
150129
150210
|
profileSha256: sha2565(assets.provisioningProfile),
|
|
150130
150211
|
certificateSha256: sha2565(decoded.cert.raw),
|
|
150131
|
-
certificateSha1:
|
|
150212
|
+
certificateSha1: createHash29("sha1").update(decoded.cert.raw).digest("hex").toUpperCase(),
|
|
150132
150213
|
expiresAt: new Date(Math.min(decoded.expiration, Date.parse(decoded.cert.validTo))).toISOString(),
|
|
150133
150214
|
...apns ? { apnsEnvironment: apns } : {},
|
|
150134
150215
|
deviceCount
|
|
@@ -150179,7 +150260,7 @@ var init_customer_signing_assets = __esm({
|
|
|
150179
150260
|
init_fxp();
|
|
150180
150261
|
init_pkcs12();
|
|
150181
150262
|
init_customer_dist_signing();
|
|
150182
|
-
sha2565 = (bytes2) =>
|
|
150263
|
+
sha2565 = (bytes2) => createHash29("sha256").update(bytes2).digest("hex");
|
|
150183
150264
|
refuse3 = (code) => {
|
|
150184
150265
|
throw new CustomerSigningError(code);
|
|
150185
150266
|
};
|
|
@@ -150347,7 +150428,7 @@ var init_customer_signing_inspect = __esm({
|
|
|
150347
150428
|
|
|
150348
150429
|
// src/push-onboarding.ts
|
|
150349
150430
|
import { existsSync as existsSync53, mkdirSync as mkdirSync24, readFileSync as readFileSync60, statSync as statSync13, writeFileSync as writeFileSync20, chmodSync as chmodSync2 } from "node:fs";
|
|
150350
|
-
import { basename as
|
|
150431
|
+
import { basename as basename13, dirname as dirname32, join as join52, resolve as resolve43 } from "node:path";
|
|
150351
150432
|
function readJson5(path2) {
|
|
150352
150433
|
try {
|
|
150353
150434
|
const parsed = JSON.parse(readFileSync60(path2, "utf8"));
|
|
@@ -150368,7 +150449,7 @@ function pushInputsFromContent(dir) {
|
|
|
150368
150449
|
// autoClaimSlug's docblock describes as the project-declared slug. Without the fallback a
|
|
150369
150450
|
// package with no `name` sent a body missing `app` and earned `400 invalid_app_id` with both
|
|
150370
150451
|
// private keys already on the wire.
|
|
150371
|
-
app: text3(content.name) ??
|
|
150452
|
+
app: text3(content.name) ?? basename13(root),
|
|
150372
150453
|
...text3(provisioning.siteId) ? { site: text3(provisioning.siteId) } : {},
|
|
150373
150454
|
...text3(native.iosBundleId) ? { bundleId: text3(native.iosBundleId) } : {},
|
|
150374
150455
|
...text3(native.androidApplicationId) ? { androidApplicationId: text3(native.androidApplicationId) } : {}
|
|
@@ -150978,7 +151059,7 @@ __export(config_push_edit_exports, {
|
|
|
150978
151059
|
previewPushConfigEdit: () => previewPushConfigEdit
|
|
150979
151060
|
});
|
|
150980
151061
|
import { readFileSync as readFileSync62 } from "node:fs";
|
|
150981
|
-
import { basename as
|
|
151062
|
+
import { basename as basename14 } from "node:path";
|
|
150982
151063
|
import ts6 from "typescript";
|
|
150983
151064
|
function enablePushInConfig(source, options) {
|
|
150984
151065
|
const pingAppName = DEFAULT_PING_APP_NAME;
|
|
@@ -151097,13 +151178,13 @@ function noLiteralInstruction(pingAppName) {
|
|
|
151097
151178
|
function previewPushConfigEdit(dir, options) {
|
|
151098
151179
|
const path2 = configEntry(dir);
|
|
151099
151180
|
if (!path2) return void 0;
|
|
151100
|
-
const { applied, instructions } = enablePushInConfig(readFileSync62(path2, "utf8"), { ...options, fileName:
|
|
151181
|
+
const { applied, instructions } = enablePushInConfig(readFileSync62(path2, "utf8"), { ...options, fileName: basename14(path2) });
|
|
151101
151182
|
return { wouldApply: applied, instructions };
|
|
151102
151183
|
}
|
|
151103
151184
|
async function applyPushConfigEdit(dir, options, validate5) {
|
|
151104
151185
|
const path2 = configEntry(dir);
|
|
151105
151186
|
if (!path2) return void 0;
|
|
151106
|
-
const fileName =
|
|
151187
|
+
const fileName = basename14(path2);
|
|
151107
151188
|
const refuse7 = (why) => ({ changed: false, pushOn: false, applied: [], instructions: [why] });
|
|
151108
151189
|
if (isSymlink2(path2)) return refuse7(`${fileName} is a symlink, so it was not edited: turn push on in the file it points to.`);
|
|
151109
151190
|
const original = readFileSync62(path2, "utf8");
|
|
@@ -151424,7 +151505,7 @@ __export(pack_exports, {
|
|
|
151424
151505
|
unpackTo: () => unpackTo,
|
|
151425
151506
|
writeZip: () => writeZip
|
|
151426
151507
|
});
|
|
151427
|
-
import { createHash as
|
|
151508
|
+
import { createHash as createHash30 } from "node:crypto";
|
|
151428
151509
|
import { deflateRawSync, inflateRawSync } from "node:zlib";
|
|
151429
151510
|
import { existsSync as existsSync55, mkdirSync as mkdirSync25, readFileSync as readFileSync63, readdirSync as readdirSync28, rmSync as rmSync12, statSync as statSync15, writeFileSync as writeFileSync21 } from "node:fs";
|
|
151430
151511
|
import { dirname as dirname33, join as join54, resolve as resolve46 } from "node:path";
|
|
@@ -151574,11 +151655,11 @@ function gatherReleaseEntries(appDir3) {
|
|
|
151574
151655
|
return { entries, manifest, skipped };
|
|
151575
151656
|
}
|
|
151576
151657
|
function sha256Hex4(bytes2) {
|
|
151577
|
-
return
|
|
151658
|
+
return createHash30("sha256").update(bytes2).digest("hex");
|
|
151578
151659
|
}
|
|
151579
151660
|
function computeContentHash(entries) {
|
|
151580
151661
|
const input = packageHashInput(entries.map((e2) => ({ path: e2.path, hash: sha256Hex4(e2.bytes) })));
|
|
151581
|
-
return "sha256-" +
|
|
151662
|
+
return "sha256-" + createHash30("sha256").update(input).digest("base64");
|
|
151582
151663
|
}
|
|
151583
151664
|
function buildEntries(appDir3, app, opts) {
|
|
151584
151665
|
const { entries: released, manifest, skipped } = gatherReleaseEntries(appDir3);
|
|
@@ -151769,7 +151850,7 @@ __export(app_source_exports, {
|
|
|
151769
151850
|
writeConflicts: () => writeConflicts,
|
|
151770
151851
|
zipAppSource: () => zipAppSource
|
|
151771
151852
|
});
|
|
151772
|
-
import { createHash as
|
|
151853
|
+
import { createHash as createHash31 } from "node:crypto";
|
|
151773
151854
|
import { readdirSync as readdirSync29, lstatSync as lstatSync15, readFileSync as readFileSync64, mkdirSync as mkdirSync26, writeFileSync as writeFileSync22, existsSync as existsSync56, rmSync as rmSync13, rmdirSync as rmdirSync2, unlinkSync as unlinkSync4 } from "node:fs";
|
|
151774
151855
|
import { join as join55, resolve as resolve47, sep as sep13 } from "node:path";
|
|
151775
151856
|
import { createRequire as createRequire3 } from "node:module";
|
|
@@ -151885,13 +151966,13 @@ function sourceFingerprint(dir) {
|
|
|
151885
151966
|
dir,
|
|
151886
151967
|
(archivePath, hostRel) => {
|
|
151887
151968
|
if (/\.md$/i.test(archivePath)) return;
|
|
151888
|
-
files.push(`${archivePath}\0${
|
|
151969
|
+
files.push(`${archivePath}\0${createHash31("sha256").update(readFileSync64(join55(dir, hostRel))).digest("hex")}`);
|
|
151889
151970
|
},
|
|
151890
151971
|
() => {
|
|
151891
151972
|
}
|
|
151892
151973
|
);
|
|
151893
151974
|
files.sort();
|
|
151894
|
-
return
|
|
151975
|
+
return createHash31("sha256").update(files.join("\n")).digest("hex");
|
|
151895
151976
|
}
|
|
151896
151977
|
function largestEntries(entries, limit = 5) {
|
|
151897
151978
|
return entries.map((e2) => ({
|
|
@@ -152085,6 +152166,7 @@ __export(run_watch_exports, {
|
|
|
152085
152166
|
ReloadBus: () => ReloadBus,
|
|
152086
152167
|
boardFile: () => boardFile,
|
|
152087
152168
|
diffReleases: () => diffReleases,
|
|
152169
|
+
hhpRasterDir: () => hhpRasterDir,
|
|
152088
152170
|
himiDir: () => himiDir,
|
|
152089
152171
|
ignoredChange: () => ignoredChange,
|
|
152090
152172
|
isEmptyDiff: () => isEmptyDiff,
|
|
@@ -152100,7 +152182,7 @@ __export(run_watch_exports, {
|
|
|
152100
152182
|
});
|
|
152101
152183
|
import { closeSync as closeSync4, constants as constants2, existsSync as existsSync57, fstatSync, lstatSync as lstatSync16, statSync as statSync16, readdirSync as readdirSync30, mkdirSync as mkdirSync27, openSync as openSync4, readFileSync as readFileSync65, realpathSync as realpathSync9, renameSync as renameSync10, rmSync as rmSync14, writeFileSync as writeFileSync23, watch as fsWatch } from "node:fs";
|
|
152102
152184
|
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
152103
|
-
import { extname as extname4, join as join56, resolve as resolve48, sep as sep14 } from "node:path";
|
|
152185
|
+
import { extname as extname4, join as join56, relative as relative11, resolve as resolve48, sep as sep14 } from "node:path";
|
|
152104
152186
|
function diffReleases(prev, next) {
|
|
152105
152187
|
const bundles = Object.keys(next.bundles).filter((b2) => prev.bundles[b2]?.sha256 !== next.bundles[b2].sha256).sort();
|
|
152106
152188
|
const changedBundles = new Set(bundles);
|
|
@@ -152125,10 +152207,20 @@ function reloadEvents(d2) {
|
|
|
152125
152207
|
if (d2.config) out2.push(["config.invalidated", {}]);
|
|
152126
152208
|
return out2;
|
|
152127
152209
|
}
|
|
152128
|
-
function
|
|
152210
|
+
function hhpRasterDir(dir) {
|
|
152211
|
+
const assets = findAssetsDir(dir);
|
|
152212
|
+
if (!assets) return null;
|
|
152213
|
+
const rel = relative11(dir, assets).split(sep14).join("/");
|
|
152214
|
+
return rel ? `${rel}/hhp-raster` : "hhp-raster";
|
|
152215
|
+
}
|
|
152216
|
+
function ignoredChange(relPath, isDirectory = () => false, rasterDir = "assets/hhp-raster") {
|
|
152129
152217
|
const parts = relPath.split(/[\\/]/).filter(Boolean);
|
|
152130
152218
|
if (parts[0] === "dev" && (parts[1] === "hhp" || parts[1]?.startsWith(".hhp-"))) return true;
|
|
152131
152219
|
if (parts[0] === "tier5-src" && parts[1]?.startsWith("hhp-")) return true;
|
|
152220
|
+
if (rasterDir) {
|
|
152221
|
+
const rel = parts.join("/");
|
|
152222
|
+
if (rel === rasterDir || rel.startsWith(`${rasterDir}/`)) return true;
|
|
152223
|
+
}
|
|
152132
152224
|
if (!parts.length) return true;
|
|
152133
152225
|
const [top] = parts;
|
|
152134
152226
|
if ([".himi", "dist", "node_modules", ".git", ".build", ...AGENT_TOOLING_DIRS].includes(top)) return true;
|
|
@@ -152139,11 +152231,12 @@ function ignoredChange(relPath, isDirectory = () => false) {
|
|
|
152139
152231
|
}
|
|
152140
152232
|
function watchContent(dir, onChange, opts = {}) {
|
|
152141
152233
|
const debounceMs = opts.debounceMs ?? 200;
|
|
152234
|
+
const rasterDir = hhpRasterDir(dir);
|
|
152142
152235
|
const watch2 = opts.watch ?? ((p2, o2, l2) => fsWatch(p2, o2, (event, file2) => l2(event, file2 === null ? null : String(file2))));
|
|
152143
152236
|
let timer = null;
|
|
152144
152237
|
const pending = /* @__PURE__ */ new Set();
|
|
152145
152238
|
const changed = (_event, file2) => {
|
|
152146
|
-
if (!file2 || ignoredChange(file2, (rel) => isDir(join56(dir, rel)))) return;
|
|
152239
|
+
if (!file2 || ignoredChange(file2, (rel) => isDir(join56(dir, rel)), rasterDir)) return;
|
|
152147
152240
|
pending.add(file2);
|
|
152148
152241
|
if (timer) clearTimeout(timer);
|
|
152149
152242
|
timer = setTimeout(() => {
|
|
@@ -152167,7 +152260,7 @@ function watchContent(dir, onChange, opts = {}) {
|
|
|
152167
152260
|
const path2 = join56(directory, String(name)), rel = prefix ? `${prefix}/${name}` : String(name);
|
|
152168
152261
|
try {
|
|
152169
152262
|
const stat2 = lstatSync16(path2);
|
|
152170
|
-
if (stat2.isSymbolicLink() || ignoredChange(rel, () => stat2.isDirectory())) continue;
|
|
152263
|
+
if (stat2.isSymbolicLink() || ignoredChange(rel, () => stat2.isDirectory(), rasterDir)) continue;
|
|
152171
152264
|
if (stat2.isDirectory()) visit(path2, rel);
|
|
152172
152265
|
else if (stat2.isFile()) files.set(rel, `${stat2.mtimeMs}:${stat2.ctimeMs}:${stat2.size}`);
|
|
152173
152266
|
} catch {
|
|
@@ -152369,6 +152462,7 @@ var init_run_watch = __esm({
|
|
|
152369
152462
|
"src/run-watch.ts"() {
|
|
152370
152463
|
init_source_deny();
|
|
152371
152464
|
init_run_identity();
|
|
152465
|
+
init_app_assets();
|
|
152372
152466
|
isEmptyDiff = (d2) => !d2.screens.length && !d2.bundles.length && !d2.tokens && !d2.config;
|
|
152373
152467
|
ReloadBus = class {
|
|
152374
152468
|
subscribers = /* @__PURE__ */ new Set();
|
|
@@ -152413,7 +152507,7 @@ __export(screen_state_exports, {
|
|
|
152413
152507
|
shotStateFor: () => shotStateFor,
|
|
152414
152508
|
withHomeCaveat: () => withHomeCaveat
|
|
152415
152509
|
});
|
|
152416
|
-
import { createHash as
|
|
152510
|
+
import { createHash as createHash32 } from "node:crypto";
|
|
152417
152511
|
import { lstatSync as lstatSync17, readFileSync as readFileSync66 } from "node:fs";
|
|
152418
152512
|
import { join as join57 } from "node:path";
|
|
152419
152513
|
function quotableLine(text9) {
|
|
@@ -152533,7 +152627,7 @@ var init_screen_state = __esm({
|
|
|
152533
152627
|
KEEP = 40;
|
|
152534
152628
|
LINE_MAX = 120;
|
|
152535
152629
|
str3 = (v2) => typeof v2 === "string" && v2.trim() ? v2 : void 0;
|
|
152536
|
-
sha256Of = (file2) =>
|
|
152630
|
+
sha256Of = (file2) => createHash32("sha256").update(readFileSync66(file2)).digest("hex");
|
|
152537
152631
|
}
|
|
152538
152632
|
});
|
|
152539
152633
|
|
|
@@ -152548,9 +152642,9 @@ __export(studio_reel_exports, {
|
|
|
152548
152642
|
thin: () => thin,
|
|
152549
152643
|
utcDay: () => utcDay
|
|
152550
152644
|
});
|
|
152551
|
-
import { createHash as
|
|
152645
|
+
import { createHash as createHash33 } from "node:crypto";
|
|
152552
152646
|
import { lstatSync as lstatSync18, readFileSync as readFileSync67 } from "node:fs";
|
|
152553
|
-
import { basename as
|
|
152647
|
+
import { basename as basename15, join as join58 } from "node:path";
|
|
152554
152648
|
function loadMemory2(dir) {
|
|
152555
152649
|
const m2 = readJson6(join58(dir, ".himi", "studio", "memory.json"));
|
|
152556
152650
|
if (!isObj3(m2) || m2.version !== 1 || !isObj3(m2.shots) || !Array.isArray(m2.timeline)) return null;
|
|
@@ -152606,13 +152700,13 @@ function planReel(dir) {
|
|
|
152606
152700
|
message: e2.message,
|
|
152607
152701
|
step: isCliEntry(e2) ? null : str4(e2.step),
|
|
152608
152702
|
by: isCliEntry(e2) ? CLI_AUTHOR : null,
|
|
152609
|
-
files: (Array.isArray(e2.images) ? e2.images : []).map((i2) => isObj3(i2) && typeof i2.file === "string" ?
|
|
152703
|
+
files: (Array.isArray(e2.images) ? e2.images : []).map((i2) => isObj3(i2) && typeof i2.file === "string" ? basename15(i2.file) : "").filter((f2) => HISTORY_NAME.test(f2))
|
|
152610
152704
|
}));
|
|
152611
152705
|
const times = [summary2.startedAt, ...timeline.map((t2) => t2.ts), memory?.createdAt].filter((x2) => !!x2).sort();
|
|
152612
152706
|
const startedAt = times[0] ?? null;
|
|
152613
152707
|
const endedAt = [summary2.lastAt, ...timeline.map((t2) => t2.ts)].filter((x2) => !!x2).sort().pop() ?? null;
|
|
152614
152708
|
return {
|
|
152615
|
-
app: typeof manifest?.name === "string" && manifest.name ? manifest.name :
|
|
152709
|
+
app: typeof manifest?.name === "string" && manifest.name ? manifest.name : basename15(dir),
|
|
152616
152710
|
accent,
|
|
152617
152711
|
startedAt,
|
|
152618
152712
|
endedAt,
|
|
@@ -152637,7 +152731,7 @@ function inlineImages(dir, plan, budget = REEL_BUDGET_BYTES) {
|
|
|
152637
152731
|
const st2 = lstatSync18(path2);
|
|
152638
152732
|
if (!st2.isFile() || st2.nlink !== 1) return null;
|
|
152639
152733
|
const bytes2 = readFileSync67(path2);
|
|
152640
|
-
return
|
|
152734
|
+
return createHash33("sha256").update(bytes2).digest("hex") === f2.slice(0, 64) && imageExtension(bytes2) === f2.slice(65) ? bytes2 : null;
|
|
152641
152735
|
} catch {
|
|
152642
152736
|
return null;
|
|
152643
152737
|
}
|
|
@@ -152858,11 +152952,11 @@ __export(milestones_exports, {
|
|
|
152858
152952
|
watchUrlFor: () => watchUrlFor,
|
|
152859
152953
|
writeHandoverReel: () => writeHandoverReel
|
|
152860
152954
|
});
|
|
152861
|
-
import { createHash as
|
|
152955
|
+
import { createHash as createHash34, randomUUID as randomUUID7 } from "node:crypto";
|
|
152862
152956
|
import { spawn as spawn5 } from "node:child_process";
|
|
152863
152957
|
import { closeSync as closeSync5, existsSync as existsSync58, lstatSync as lstatSync19, readFileSync as readFileSync69, statSync as statSync17 } from "node:fs";
|
|
152864
152958
|
import { createServer as createServer4 } from "node:net";
|
|
152865
|
-
import { basename as
|
|
152959
|
+
import { basename as basename16, dirname as dirname34, isAbsolute as isAbsolute6, join as join60, relative as relative12, resolve as resolve49, sep as sep15 } from "node:path";
|
|
152866
152960
|
function homeShotPath(dir, home) {
|
|
152867
152961
|
const root = resolve49(dir);
|
|
152868
152962
|
const base = resolve49(root, ".himi", "shots");
|
|
@@ -152877,7 +152971,7 @@ function homeShotPath(dir, home) {
|
|
|
152877
152971
|
return shot;
|
|
152878
152972
|
}
|
|
152879
152973
|
function displayPath(p2, cwd = process.cwd()) {
|
|
152880
|
-
const rel =
|
|
152974
|
+
const rel = relative12(cwd, p2);
|
|
152881
152975
|
return rel && !rel.startsWith("..") && !isAbsolute6(rel) ? rel : p2;
|
|
152882
152976
|
}
|
|
152883
152977
|
function progressCommand(opts) {
|
|
@@ -153018,7 +153112,7 @@ async function openBoardForSession(dir, cwd = process.cwd()) {
|
|
|
153018
153112
|
try {
|
|
153019
153113
|
const { openStudio: openStudio2 } = await Promise.resolve().then(() => (init_studio(), studio_exports));
|
|
153020
153114
|
const { page, url } = openStudio2(dir);
|
|
153021
|
-
const rel =
|
|
153115
|
+
const rel = relative12(cwd, page);
|
|
153022
153116
|
return { page: rel && !rel.startsWith("..") && !isAbsolute6(rel) ? rel : page, url, opened: false };
|
|
153023
153117
|
} catch (e2) {
|
|
153024
153118
|
return { opened: false, error: `the build board was not created: ${e2.message} \u2014 \`himi studio --no-open\` in the app retries it` };
|
|
@@ -153502,7 +153596,7 @@ function writeHandoverReel(dir) {
|
|
|
153502
153596
|
const { html } = buildReel(dir);
|
|
153503
153597
|
const file2 = join60(dir, ".himi", "making-of.html");
|
|
153504
153598
|
writeFileAtomic(file2, html);
|
|
153505
|
-
return { file: file2, hint: `hand ${
|
|
153599
|
+
return { file: file2, hint: `hand ${basename16(file2)} to the owner at the handover \u2014 one self-contained page of their app taking shape; send it beside the preview link, never instead of it` };
|
|
153506
153600
|
} catch (e2) {
|
|
153507
153601
|
return { skipped: `the making-of was not written: ${e2.message.split("\n")[0]} \u2014 \`himi studio reel\` retries it` };
|
|
153508
153602
|
}
|
|
@@ -153516,7 +153610,7 @@ function afterHandoverPostcard(dir, opts = {}) {
|
|
|
153516
153610
|
} catch {
|
|
153517
153611
|
fresh = false;
|
|
153518
153612
|
}
|
|
153519
|
-
const makingOf = fresh ? { file: file2, hint: `hand ${
|
|
153613
|
+
const makingOf = fresh ? { file: file2, hint: `hand ${basename16(file2)} to the owner at the handover \u2014 one self-contained page of their app taking shape; send it beside the preview link, never instead of it` } : writeHandoverReel(dir);
|
|
153520
153614
|
const next = "file" in makingOf ? [`hand the owner the making-of, ${shellQuote(displayPath(makingOf.file))}, beside the preview link \u2014 in your final message and report, never instead of the link`] : [`\`himi studio reel${contentArg(opts.content)}\` writes the making-of to hand the owner beside the preview link (${makingOf.skipped})`];
|
|
153521
153615
|
return { makingOf, next };
|
|
153522
153616
|
}
|
|
@@ -153539,7 +153633,7 @@ var init_milestones = __esm({
|
|
|
153539
153633
|
FIRST_LOOK_BUDGET_MS = 9e4;
|
|
153540
153634
|
VALIDATE_PICTURE_BUDGET_MS = 3e4;
|
|
153541
153635
|
plural2 = (n2, one, many = `${one}s`) => `${n2} ${n2 === 1 ? one : many}`;
|
|
153542
|
-
appName = (dir) => appLabel(dir) ??
|
|
153636
|
+
appName = (dir) => appLabel(dir) ?? basename16(dir);
|
|
153543
153637
|
STILL_BUILDING_AFTER_MS = 10 * 60 * 1e3;
|
|
153544
153638
|
STILL_BUILDING_MESSAGE = "Still building: here's the home screen now.";
|
|
153545
153639
|
yourFirstLookMessage = (dir) => `First look at your app: ${appName(dir)}'s home screen, with your changes.`;
|
|
@@ -153548,7 +153642,7 @@ var init_milestones = __esm({
|
|
|
153548
153642
|
INIT_SOURCE_FILE = join60(".himi", "init-source.json");
|
|
153549
153643
|
STARTING_POINT_REF = "starting-point";
|
|
153550
153644
|
TEMPLATE_NAME = /^[A-Za-z0-9._-]{1,64}$/;
|
|
153551
|
-
sha256Of2 = (file2) =>
|
|
153645
|
+
sha256Of2 = (file2) => createHash34("sha256").update(readFileSync69(file2)).digest("hex");
|
|
153552
153646
|
WATCH_REMINDER_EVERY_MS = 10 * 60 * 1e3;
|
|
153553
153647
|
REMINDERS_FILE = join60(".himi", "reminders.json");
|
|
153554
153648
|
pidAlive = (pid) => {
|
|
@@ -154598,7 +154692,7 @@ __export(eject_exports, {
|
|
|
154598
154692
|
ejectModule: () => ejectModule
|
|
154599
154693
|
});
|
|
154600
154694
|
import { existsSync as existsSync61, mkdirSync as mkdirSync29, readFileSync as readFileSync73, writeFileSync as writeFileSync26 } from "node:fs";
|
|
154601
|
-
import { dirname as dirname36, join as join64, relative as
|
|
154695
|
+
import { dirname as dirname36, join as join64, relative as relative13, resolve as resolve50, sep as sep16 } from "node:path";
|
|
154602
154696
|
function locate(repoRootOrCwd, mod) {
|
|
154603
154697
|
const inRepo = resolve50(repoRootOrCwd, `stdlib/flows/${mod}/src/index.ts`);
|
|
154604
154698
|
if (existsSync61(inRepo)) return { path: inRepo, form: "source" };
|
|
@@ -154651,7 +154745,7 @@ function ejectModule(opts) {
|
|
|
154651
154745
|
if (!existsSync61(f2)) continue;
|
|
154652
154746
|
const before = readFileSync73(f2, "utf8");
|
|
154653
154747
|
let after = before;
|
|
154654
|
-
let rel =
|
|
154748
|
+
let rel = relative13(dirname36(f2), target).split(sep16).join("/").replace(/\.tsx?$/, ".js");
|
|
154655
154749
|
if (!rel.startsWith(".")) rel = `./${rel}`;
|
|
154656
154750
|
for (const spec of specifiersFor(mod)) {
|
|
154657
154751
|
const q2 = spec.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -156613,10 +156707,10 @@ var init_calls = __esm({
|
|
|
156613
156707
|
});
|
|
156614
156708
|
|
|
156615
156709
|
// ../../core/functions-runtime/src/queue.ts
|
|
156616
|
-
import { createHash as
|
|
156710
|
+
import { createHash as createHash35 } from "node:crypto";
|
|
156617
156711
|
function inputSchemaHash(definition) {
|
|
156618
156712
|
const schema = definition.input;
|
|
156619
|
-
return schema ?
|
|
156713
|
+
return schema ? createHash35("sha256").update(JSON.stringify(schema.descriptor ?? { kind: schema.kind, optional: schema.optional === true })).digest("hex") : "";
|
|
156620
156714
|
}
|
|
156621
156715
|
function createFunctionEnqueueCapability(options) {
|
|
156622
156716
|
return {
|
|
@@ -156682,14 +156776,14 @@ var init_queue = __esm({
|
|
|
156682
156776
|
});
|
|
156683
156777
|
|
|
156684
156778
|
// ../../core/data-resources/src/plan.ts
|
|
156685
|
-
import { createHash as
|
|
156779
|
+
import { createHash as createHash36 } from "node:crypto";
|
|
156686
156780
|
function canonical3(value) {
|
|
156687
156781
|
if (Array.isArray(value)) return `[${value.map(canonical3).join(",")}]`;
|
|
156688
156782
|
if (value && typeof value === "object") return `{${Object.entries(value).sort(([a2], [b2]) => a2.localeCompare(b2)).map(([key3, item]) => `${JSON.stringify(key3)}:${canonical3(item)}`).join(",")}}`;
|
|
156689
156783
|
return JSON.stringify(value);
|
|
156690
156784
|
}
|
|
156691
156785
|
function hashResourcePlan(plan) {
|
|
156692
|
-
return
|
|
156786
|
+
return createHash36("sha256").update(canonical3(plan)).digest("hex");
|
|
156693
156787
|
}
|
|
156694
156788
|
function finalize(input) {
|
|
156695
156789
|
return { ...input, hash: hashResourcePlan(input) };
|
|
@@ -157656,7 +157750,7 @@ var init_cli_bridge = __esm({
|
|
|
157656
157750
|
// src/mcp/file-tools.ts
|
|
157657
157751
|
import { closeSync as closeSync6, constants as constants3, lstatSync as lstatSync20, mkdirSync as mkdirSync31, openSync as openSync5, readdirSync as readdirSync31, readFileSync as readFileSync78, realpathSync as realpathSync10, renameSync as renameSync11, rmSync as rmSync15, statSync as statSync18, writeSync, existsSync as existsSync66 } from "node:fs";
|
|
157658
157752
|
import { randomBytes as randomBytes4 } from "node:crypto";
|
|
157659
|
-
import { dirname as dirname37, isAbsolute as isAbsolute7, join as join69, relative as
|
|
157753
|
+
import { dirname as dirname37, isAbsolute as isAbsolute7, join as join69, relative as relative14, resolve as resolve53, sep as sep17 } from "node:path";
|
|
157660
157754
|
import * as z2 from "zod";
|
|
157661
157755
|
function within(root, p2) {
|
|
157662
157756
|
return p2 === root || p2.startsWith(root.endsWith(sep17) ? root : root + sep17);
|
|
@@ -157674,10 +157768,10 @@ function realish(p2) {
|
|
|
157674
157768
|
}
|
|
157675
157769
|
function symlinkComponent(base, abs) {
|
|
157676
157770
|
let cur = base;
|
|
157677
|
-
for (const part3 of
|
|
157771
|
+
for (const part3 of relative14(base, abs).split(sep17).filter(Boolean)) {
|
|
157678
157772
|
cur = join69(cur, part3);
|
|
157679
157773
|
try {
|
|
157680
|
-
if (lstatSync20(cur).isSymbolicLink()) return
|
|
157774
|
+
if (lstatSync20(cur).isSymbolicLink()) return relative14(base, cur);
|
|
157681
157775
|
} catch {
|
|
157682
157776
|
return void 0;
|
|
157683
157777
|
}
|
|
@@ -157700,7 +157794,7 @@ async function confinedAppDir(args, deps) {
|
|
|
157700
157794
|
if (!within(root, dir) || !within(realpathSync10(root), realish(dir))) return refuse5("outside_workspace", `"${String(args.dir)}" is outside the workspace folder`);
|
|
157701
157795
|
const link = symlinkComponent(root, dir);
|
|
157702
157796
|
if (link) return refuse5("outside_workspace", `"${link}" is a symlink \u2014 the app folder must be a real folder in the workspace`);
|
|
157703
|
-
const rel =
|
|
157797
|
+
const rel = relative14(root, dir);
|
|
157704
157798
|
if (rel && (isDeniedSourcePath(`${rel}/x`) || isDeniedSourcePath(`${rel.toLowerCase()}/x`))) return refuse5("denied", `"${rel}" is a folder this tool does not touch`);
|
|
157705
157799
|
if (!existsSync66(join69(dir, CONTENT_MARKER))) {
|
|
157706
157800
|
return refuse5("not_an_app", `"${rel || "."}" is not an app folder (no ${CONTENT_MARKER}) \u2014 see himi_list_apps, or create one with himi_init`);
|
|
@@ -157719,10 +157813,10 @@ function onDiskSpelling(abs) {
|
|
|
157719
157813
|
return join69(realpathSync10.native(cur), ...tail);
|
|
157720
157814
|
}
|
|
157721
157815
|
function denied(appDir3, abs) {
|
|
157722
|
-
const rel =
|
|
157816
|
+
const rel = relative14(appDir3, abs);
|
|
157723
157817
|
if (isDeniedSourcePath(rel) || isDeniedSourcePath(rel.toLowerCase())) return true;
|
|
157724
157818
|
try {
|
|
157725
|
-
return isDeniedSourcePath(
|
|
157819
|
+
return isDeniedSourcePath(relative14(realpathSync10.native(appDir3), onDiskSpelling(abs)));
|
|
157726
157820
|
} catch {
|
|
157727
157821
|
return true;
|
|
157728
157822
|
}
|
|
@@ -157755,14 +157849,14 @@ function writeNoFollow2(appDir3, abs, content) {
|
|
|
157755
157849
|
const link = symlinkComponent(appDir3, abs);
|
|
157756
157850
|
if (link || !within(realpathSync10(appDir3), realpathSync10(dirname37(abs)))) {
|
|
157757
157851
|
rmSync15(tmp, { force: true });
|
|
157758
|
-
throw new Error(`"${link ??
|
|
157852
|
+
throw new Error(`"${link ?? relative14(appDir3, dirname37(abs))}" changed into a link while writing`);
|
|
157759
157853
|
}
|
|
157760
157854
|
renameSync11(tmp, abs);
|
|
157761
157855
|
}
|
|
157762
157856
|
function listFiles(appDir3) {
|
|
157763
157857
|
const files = [];
|
|
157764
157858
|
const walk2 = (d2) => {
|
|
157765
|
-
const parentRel =
|
|
157859
|
+
const parentRel = relative14(appDir3, d2);
|
|
157766
157860
|
for (const e2 of readdirSync31(d2, { withFileTypes: true }).sort((a2, b2) => a2.name.localeCompare(b2.name))) {
|
|
157767
157861
|
if (e2.isSymbolicLink()) continue;
|
|
157768
157862
|
const p2 = join69(d2, e2.name);
|
|
@@ -157770,7 +157864,7 @@ function listFiles(appDir3) {
|
|
|
157770
157864
|
if (isDeniedSourceDir(e2.name, parentRel) || isDeniedSourceDir(e2.name.toLowerCase(), parentRel)) continue;
|
|
157771
157865
|
if (!walk2(p2)) return false;
|
|
157772
157866
|
} else if (e2.isFile()) {
|
|
157773
|
-
const rel =
|
|
157867
|
+
const rel = relative14(appDir3, p2);
|
|
157774
157868
|
if (isDeniedSourcePath(rel) || isDeniedSourcePath(rel.toLowerCase())) continue;
|
|
157775
157869
|
if (files.length >= MAX_LISTED) return false;
|
|
157776
157870
|
files.push({ path: rel.split(sep17).join("/"), bytes: statSync18(p2).size });
|
|
@@ -158866,9 +158960,9 @@ __export(browser_authoring_exports, {
|
|
|
158866
158960
|
sdkSubpathReader: () => sdkSubpathReader
|
|
158867
158961
|
});
|
|
158868
158962
|
import { createServer as createServer5 } from "node:http";
|
|
158869
|
-
import { createHash as
|
|
158963
|
+
import { createHash as createHash37, randomBytes as randomBytes5 } from "node:crypto";
|
|
158870
158964
|
import { existsSync as existsSync68, readdirSync as readdirSync32, readFileSync as readFileSync81, realpathSync as realpathSync11, statSync as statSync19 } from "node:fs";
|
|
158871
|
-
import { join as join71, posix as posix3, relative as
|
|
158965
|
+
import { join as join71, posix as posix3, relative as relative15, sep as sep18 } from "node:path";
|
|
158872
158966
|
function humanMs(ms2) {
|
|
158873
158967
|
return ms2 < 1e3 ? `${ms2}ms` : `${Math.round(ms2 / 1e3)}s`;
|
|
158874
158968
|
}
|
|
@@ -158918,7 +159012,7 @@ function collectRelativeSiblings(files, tier5SrcDir) {
|
|
|
158918
159012
|
];
|
|
158919
159013
|
for (const abs of candidates) {
|
|
158920
159014
|
if (!existsSync68(abs) || statSync19(abs).isDirectory()) continue;
|
|
158921
|
-
const key3 = `/tier5-src/${
|
|
159015
|
+
const key3 = `/tier5-src/${relative15(tier5SrcDir, abs).split(sep18).join(posix3.sep)}`;
|
|
158922
159016
|
if (key3 in files) break;
|
|
158923
159017
|
files[key3] = readFileSync81(abs, "utf8");
|
|
158924
159018
|
queue.push(key3);
|
|
@@ -158965,7 +159059,7 @@ function encodeJob(job) {
|
|
|
158965
159059
|
return Buffer.from(JSON.stringify(job), "utf8").toString("base64");
|
|
158966
159060
|
}
|
|
158967
159061
|
function mintToken2(payload, nonce = randomBytes5(16).toString("hex")) {
|
|
158968
|
-
const digest2 =
|
|
159062
|
+
const digest2 = createHash37("sha256").update(payload, "utf8").digest("base64url");
|
|
158969
159063
|
return `${nonce}.${digest2}`;
|
|
158970
159064
|
}
|
|
158971
159065
|
function defaultOpenBrowser2(url) {
|
|
@@ -159417,7 +159511,7 @@ __export(design_kits_exports, {
|
|
|
159417
159511
|
listKits: () => listKits2
|
|
159418
159512
|
});
|
|
159419
159513
|
import { existsSync as existsSync70, readFileSync as readFileSync83, readdirSync as readdirSync33 } from "node:fs";
|
|
159420
|
-
import { join as join73, basename as
|
|
159514
|
+
import { join as join73, basename as basename17 } from "node:path";
|
|
159421
159515
|
import { fileURLToPath as fileURLToPath27 } from "node:url";
|
|
159422
159516
|
function kitsDir() {
|
|
159423
159517
|
return KIT_DIR_CANDIDATES.find((p2) => existsSync70(p2));
|
|
@@ -159425,7 +159519,7 @@ function kitsDir() {
|
|
|
159425
159519
|
function listKits2() {
|
|
159426
159520
|
const dir = kitsDir();
|
|
159427
159521
|
if (!dir) return [];
|
|
159428
|
-
return readdirSync33(dir).filter((f2) => f2.endsWith(".json")).map((f2) =>
|
|
159522
|
+
return readdirSync33(dir).filter((f2) => f2.endsWith(".json")).map((f2) => basename17(f2, ".json")).sort();
|
|
159429
159523
|
}
|
|
159430
159524
|
function kitReport(name) {
|
|
159431
159525
|
const dir = kitsDir();
|
|
@@ -159485,7 +159579,7 @@ __export(assets_exports, {
|
|
|
159485
159579
|
verifyReport: () => verifyReport
|
|
159486
159580
|
});
|
|
159487
159581
|
import { readFileSync as readFileSync84 } from "node:fs";
|
|
159488
|
-
import { basename as
|
|
159582
|
+
import { basename as basename18 } from "node:path";
|
|
159489
159583
|
function declaredAssets(dir) {
|
|
159490
159584
|
return collectAssets(dir).map((a2) => {
|
|
159491
159585
|
const bytes2 = readFileSync84(a2.path);
|
|
@@ -159566,7 +159660,7 @@ function verifyReport(dir, app, manifest) {
|
|
|
159566
159660
|
}
|
|
159567
159661
|
function addAssetPayload(manifest, filePath, opts) {
|
|
159568
159662
|
const bytes2 = readFileSync84(filePath);
|
|
159569
|
-
const name = opts.name ??
|
|
159663
|
+
const name = opts.name ?? basename18(filePath);
|
|
159570
159664
|
const sha2567 = assetSha256(bytes2);
|
|
159571
159665
|
const record2 = {
|
|
159572
159666
|
sha256: sha2567,
|
|
@@ -162691,7 +162785,7 @@ var init_iap_api = __esm({
|
|
|
162691
162785
|
});
|
|
162692
162786
|
|
|
162693
162787
|
// ../store-release/iap-manifest.ts
|
|
162694
|
-
import { createHash as
|
|
162788
|
+
import { createHash as createHash38 } from "node:crypto";
|
|
162695
162789
|
function readTarget(reader, value) {
|
|
162696
162790
|
const obj4 = reader.object(value, "target", TARGET_KEYS);
|
|
162697
162791
|
return {
|
|
@@ -162837,7 +162931,7 @@ function canonicalJson(value) {
|
|
|
162837
162931
|
return JSON.stringify(sortKeys(value));
|
|
162838
162932
|
}
|
|
162839
162933
|
function sha256Digest(value) {
|
|
162840
|
-
return `sha256:${
|
|
162934
|
+
return `sha256:${createHash38("sha256").update(canonicalJson(value)).digest("hex")}`;
|
|
162841
162935
|
}
|
|
162842
162936
|
function manifestDigest(manifest) {
|
|
162843
162937
|
return sha256Digest(manifest);
|
|
@@ -163028,7 +163122,7 @@ var init_iap_pricing = __esm({
|
|
|
163028
163122
|
});
|
|
163029
163123
|
|
|
163030
163124
|
// ../store-release/iap-result.ts
|
|
163031
|
-
import { basename as
|
|
163125
|
+
import { basename as basename19 } from "node:path";
|
|
163032
163126
|
function missingMetadataRequirement(screenshotState, itemNamesFile) {
|
|
163033
163127
|
if (screenshotState === void 0) return MISSING_SCREENSHOT;
|
|
163034
163128
|
const leftover = LEFTOVER_STATES[screenshotState];
|
|
@@ -163060,7 +163154,7 @@ function metadataVersion(observed) {
|
|
|
163060
163154
|
}
|
|
163061
163155
|
function screenshotReport(path2, observed) {
|
|
163062
163156
|
const held = observed?.reviewScreenshot;
|
|
163063
|
-
return { requested:
|
|
163157
|
+
return { requested: basename19(path2), ...held ? { observed: { fileName: held.fileName, state: held.state } } : {} };
|
|
163064
163158
|
}
|
|
163065
163159
|
function itemResult(input) {
|
|
163066
163160
|
const { target, item, observed } = input;
|
|
@@ -163192,8 +163286,8 @@ var init_screenshot_display_types = __esm({
|
|
|
163192
163286
|
});
|
|
163193
163287
|
|
|
163194
163288
|
// ../store-release/iap-review-screenshot.ts
|
|
163195
|
-
import { createHash as
|
|
163196
|
-
import { basename as
|
|
163289
|
+
import { createHash as createHash39 } from "node:crypto";
|
|
163290
|
+
import { basename as basename20, resolve as resolve56 } from "node:path";
|
|
163197
163291
|
function pngSize(bytes2) {
|
|
163198
163292
|
const signed = PNG_SIGNATURE.every((b2, i2) => bytes2[i2] === b2);
|
|
163199
163293
|
if (!signed || bytes2.length < 24 || bytes2.toString("ascii", 12, 16) !== "IHDR") return void 0;
|
|
@@ -163211,7 +163305,7 @@ function readImageSize(bytes2) {
|
|
|
163211
163305
|
return pngSize(buffer) ?? jpegSize(buffer);
|
|
163212
163306
|
}
|
|
163213
163307
|
function md5Hex(bytes2) {
|
|
163214
|
-
return
|
|
163308
|
+
return createHash39("md5").update(bytes2).digest("hex");
|
|
163215
163309
|
}
|
|
163216
163310
|
function isAppStoreScreenshotSize(file2) {
|
|
163217
163311
|
return displayTypeForSize(file2.width, file2.height) !== null;
|
|
@@ -163233,7 +163327,7 @@ function readReviewScreenshot(path2, source) {
|
|
|
163233
163327
|
}
|
|
163234
163328
|
const size = readImageSize(bytes2);
|
|
163235
163329
|
if (!size) throw new Error(`${absolute} is not a PNG or JPEG image`);
|
|
163236
|
-
return { ...size, path: absolute, fileName:
|
|
163330
|
+
return { ...size, path: absolute, fileName: basename20(absolute), bytes: bytes2, checksum: md5Hex(bytes2) };
|
|
163237
163331
|
}
|
|
163238
163332
|
function loadReviewScreenshots(manifest, source, indices = manifest.items.map((_2, i2) => i2)) {
|
|
163239
163333
|
const files = /* @__PURE__ */ new Map();
|
|
@@ -164144,11 +164238,11 @@ var init_credential_profile = __esm({
|
|
|
164144
164238
|
});
|
|
164145
164239
|
|
|
164146
164240
|
// ../store-release/iap-credentials.ts
|
|
164147
|
-
import { createHash as
|
|
164241
|
+
import { createHash as createHash40 } from "node:crypto";
|
|
164148
164242
|
import { existsSync as existsSync75, readFileSync as readFileSync90, realpathSync as realpathSync12 } from "node:fs";
|
|
164149
164243
|
import { homedir as homedir11 } from "node:os";
|
|
164150
164244
|
function accountFingerprint(keyId, issuerId) {
|
|
164151
|
-
return `sha256:${
|
|
164245
|
+
return `sha256:${createHash40("sha256").update(`${issuerId}:${keyId}`).digest("hex").slice(0, 16)}`;
|
|
164152
164246
|
}
|
|
164153
164247
|
function requireExplicitProfile(profileFlag, target) {
|
|
164154
164248
|
const profile = profileFlag?.trim();
|
|
@@ -164235,7 +164329,7 @@ var init_wix_payments_contract = __esm({
|
|
|
164235
164329
|
});
|
|
164236
164330
|
|
|
164237
164331
|
// ../store-release/iap-draft.ts
|
|
164238
|
-
import { createHash as
|
|
164332
|
+
import { createHash as createHash41 } from "node:crypto";
|
|
164239
164333
|
function fit(text9, max) {
|
|
164240
164334
|
const chars = [...text9];
|
|
164241
164335
|
return chars.length <= max ? text9 : `${chars.slice(0, max - 1).join("").trimEnd()}${ELLIPSIS}`;
|
|
@@ -164385,7 +164479,7 @@ var init_iap_draft = __esm({
|
|
|
164385
164479
|
TIER_DESCRIPTION = "Unlocks one item in the app";
|
|
164386
164480
|
ELLIPSIS = "\u2026";
|
|
164387
164481
|
entityKey = (entityType, entityId) => `${entityType}:${entityId}`;
|
|
164388
|
-
sha = (text9) =>
|
|
164482
|
+
sha = (text9) => createHash41("sha256").update(text9).digest("hex");
|
|
164389
164483
|
ENTITIES = { "&": "&", " ": " ", "<": "<", ">": ">", """: '"', "'": "'" };
|
|
164390
164484
|
MAX_SUFFIX = 24;
|
|
164391
164485
|
ReferenceNames = class {
|
|
@@ -164711,7 +164805,7 @@ var init_store_spec = __esm({
|
|
|
164711
164805
|
|
|
164712
164806
|
// src/iap-config-edit.ts
|
|
164713
164807
|
import { existsSync as existsSync76, readFileSync as readFileSync92 } from "node:fs";
|
|
164714
|
-
import { basename as
|
|
164808
|
+
import { basename as basename21, join as join77 } from "node:path";
|
|
164715
164809
|
import ts8 from "typescript";
|
|
164716
164810
|
function bindPurchasesAppInConfig(source, options) {
|
|
164717
164811
|
const fileName = options.fileName ?? "config.ts";
|
|
@@ -164798,14 +164892,14 @@ function withStoreBundle(dir, options) {
|
|
|
164798
164892
|
function previewIapConfigEdit(dir, options) {
|
|
164799
164893
|
const path2 = configEntry(dir);
|
|
164800
164894
|
if (!path2) return void 0;
|
|
164801
|
-
if (isSymlink2(path2)) return { path: path2, changed: false, applied: [], conflicts: [], instructions: [`${
|
|
164802
|
-
const { changed, applied, conflicts, instructions } = bindPurchasesAppInConfig(readFileSync92(path2, "utf8"), { ...withStoreBundle(dir, options), fileName:
|
|
164895
|
+
if (isSymlink2(path2)) return { path: path2, changed: false, applied: [], conflicts: [], instructions: [`${basename21(path2)} is a symlink, so it would not be edited: add the purchases app in the file it points to.`] };
|
|
164896
|
+
const { changed, applied, conflicts, instructions } = bindPurchasesAppInConfig(readFileSync92(path2, "utf8"), { ...withStoreBundle(dir, options), fileName: basename21(path2) });
|
|
164803
164897
|
return { path: path2, changed, applied, conflicts, instructions };
|
|
164804
164898
|
}
|
|
164805
164899
|
async function applyIapConfigEdit(dir, options, validate5) {
|
|
164806
164900
|
const path2 = configEntry(dir);
|
|
164807
164901
|
if (!path2) return void 0;
|
|
164808
|
-
const fileName =
|
|
164902
|
+
const fileName = basename21(path2);
|
|
164809
164903
|
const refuse7 = (why) => ({ path: path2, changed: false, applied: [], conflicts: [], instructions: [why] });
|
|
164810
164904
|
if (isSymlink2(path2)) return refuse7(`${fileName} is a symlink, so it was not edited: add the purchases app in the file it points to.`);
|
|
164811
164905
|
const original = readFileSync92(path2, "utf8");
|
|
@@ -165265,7 +165359,7 @@ var init_store_iap_connect = __esm({
|
|
|
165265
165359
|
});
|
|
165266
165360
|
|
|
165267
165361
|
// src/store-iap-screenshots.ts
|
|
165268
|
-
import { dirname as dirname41, join as join78, relative as
|
|
165362
|
+
import { dirname as dirname41, join as join78, relative as relative16 } from "node:path";
|
|
165269
165363
|
function purchaseScreensFor(item) {
|
|
165270
165364
|
const screen = item.wix && PURCHASE_SCREENS[item.wix.entityType];
|
|
165271
165365
|
if (!screen || !item.wix) return [];
|
|
@@ -165393,7 +165487,7 @@ async function shoot(selected, run2, outDir) {
|
|
|
165393
165487
|
} catch (e2) {
|
|
165394
165488
|
return { ...report3, skipped: `could not save the screenshot: ${e2.message}` };
|
|
165395
165489
|
}
|
|
165396
|
-
return { ...report3, screenshot:
|
|
165490
|
+
return { ...report3, screenshot: relative16(dirname41(run2.manifestPath), path2) };
|
|
165397
165491
|
}
|
|
165398
165492
|
function visibleText2(html) {
|
|
165399
165493
|
return html.replace(/ | | /gi, "\xA0").replace(/&/g, "&");
|
|
@@ -166669,7 +166763,7 @@ __export(preflight_app_exports, {
|
|
|
166669
166763
|
readXcconfigVars: () => readXcconfigVars
|
|
166670
166764
|
});
|
|
166671
166765
|
import { readFileSync as readFileSync95, existsSync as existsSync78, readdirSync as readdirSync34, statSync as statSync21 } from "node:fs";
|
|
166672
|
-
import { createHash as
|
|
166766
|
+
import { createHash as createHash42 } from "node:crypto";
|
|
166673
166767
|
import { dirname as dirname43, join as join81 } from "node:path";
|
|
166674
166768
|
function analyze(projectYml, storeConfig, icon, account) {
|
|
166675
166769
|
const f2 = [];
|
|
@@ -167050,7 +167144,7 @@ function placeholderHashes2() {
|
|
|
167050
167144
|
const p2 = join81(templateIos, target, "Assets.xcassets", "AppIcon.appiconset", "icon_1024.png");
|
|
167051
167145
|
try {
|
|
167052
167146
|
if (!statSync21(p2).isFile()) continue;
|
|
167053
|
-
return [LEGACY_PLACEHOLDER_SHA2562,
|
|
167147
|
+
return [LEGACY_PLACEHOLDER_SHA2562, createHash42("sha256").update(readFileSync95(p2)).digest("hex")];
|
|
167054
167148
|
} catch {
|
|
167055
167149
|
}
|
|
167056
167150
|
}
|
|
@@ -167087,7 +167181,7 @@ async function appIconState(iosDir) {
|
|
|
167087
167181
|
try {
|
|
167088
167182
|
if (!statSync21(p2).isFile()) continue;
|
|
167089
167183
|
const bytes2 = readFileSync95(p2);
|
|
167090
|
-
const hash2 =
|
|
167184
|
+
const hash2 = createHash42("sha256").update(bytes2).digest("hex");
|
|
167091
167185
|
const pixels = await pixelIssues(bytes2);
|
|
167092
167186
|
return {
|
|
167093
167187
|
exists: true,
|
|
@@ -167690,7 +167784,7 @@ var init_site_member = __esm({
|
|
|
167690
167784
|
});
|
|
167691
167785
|
|
|
167692
167786
|
// src/notify-ping-all.ts
|
|
167693
|
-
import { createHash as
|
|
167787
|
+
import { createHash as createHash43 } from "node:crypto";
|
|
167694
167788
|
async function listApprovedMembers(input) {
|
|
167695
167789
|
const first = await scanMembers(input);
|
|
167696
167790
|
const second = await scanMembers(input);
|
|
@@ -167744,7 +167838,7 @@ async function scanMembers(input) {
|
|
|
167744
167838
|
}
|
|
167745
167839
|
}
|
|
167746
167840
|
function campaignRequestId(campaignId, memberId) {
|
|
167747
|
-
const bytes2 =
|
|
167841
|
+
const bytes2 = createHash43("sha256").update(JSON.stringify(["himi-push-campaign", campaignId, memberId])).digest().subarray(0, 16);
|
|
167748
167842
|
bytes2[6] = bytes2[6] & 15 | 80;
|
|
167749
167843
|
bytes2[8] = bytes2[8] & 63 | 128;
|
|
167750
167844
|
const hex2 = bytes2.toString("hex");
|
|
@@ -168728,7 +168822,7 @@ __export(generate_exports, {
|
|
|
168728
168822
|
withHeader: () => withHeader,
|
|
168729
168823
|
writeGenerated: () => writeGenerated
|
|
168730
168824
|
});
|
|
168731
|
-
import { createHash as
|
|
168825
|
+
import { createHash as createHash44 } from "node:crypto";
|
|
168732
168826
|
import { existsSync as existsSync80, mkdirSync as mkdirSync38, readdirSync as readdirSync35, readFileSync as readFileSync100, writeFileSync as writeFileSync34 } from "node:fs";
|
|
168733
168827
|
import { dirname as dirname46, join as join84 } from "node:path";
|
|
168734
168828
|
function withHeader(body) {
|
|
@@ -168894,7 +168988,7 @@ var init_generate = __esm({
|
|
|
168894
168988
|
GENERATED_HEADER = "// @generated by himi base44 screens \u2014 sha256:";
|
|
168895
168989
|
HEADER_RE = /^\/\/ @generated by himi base44 screens — sha256:([0-9a-f]{64})\n/;
|
|
168896
168990
|
ENGINE_FILES = ["tier5-src/_shared/entity-list.ts", "tier5-src/_shared/entity-detail.ts", "tier5-src/_shared/entity-plan.ts", "dev/entity-screens.ts"];
|
|
168897
|
-
sha2566 = (s2) =>
|
|
168991
|
+
sha2566 = (s2) => createHash44("sha256").update(s2).digest("hex");
|
|
168898
168992
|
planFile = (p2) => `${p2.ids.bundleDetail}-plan`;
|
|
168899
168993
|
ident = (p2) => `plan_${p2.ids.detail.replace(/^b44_/, "")}`;
|
|
168900
168994
|
json7 = (v2) => JSON.stringify(v2, null, 2);
|
|
@@ -172272,9 +172366,9 @@ function tokensFromWst(wst) {
|
|
|
172272
172366
|
if (surface2) colors.surfaceSecondary = { light: surface2 };
|
|
172273
172367
|
const opaque = (c2) => c2 && c2.length === 7 ? c2 : void 0;
|
|
172274
172368
|
const surface = opaque(usableCssColor(wst["--wst-color-fill-base-1"]));
|
|
172275
|
-
const ramp = !surface ? [] : ["--wst-color-fill-base-shade-1", "--wst-color-fill-base-shade-2", "--wst-color-fill-base-shade-3"].map((v2) => opaque(usableCssColor(wst[v2]))).filter((c2) => !!c2).map((c2) => ({ c: c2, ratio:
|
|
172369
|
+
const ramp = !surface ? [] : ["--wst-color-fill-base-shade-1", "--wst-color-fill-base-shade-2", "--wst-color-fill-base-shade-3"].map((v2) => opaque(usableCssColor(wst[v2]))).filter((c2) => !!c2).map((c2) => ({ c: c2, ratio: contrastRatio2(c2, surface) }));
|
|
172276
172370
|
const primary = surface ? opaque(usableCssColor(wst["--wst-color-text-primary"])) : void 0;
|
|
172277
|
-
const primaryRatio = primary && surface ?
|
|
172371
|
+
const primaryRatio = primary && surface ? contrastRatio2(primary, surface) : void 0;
|
|
172278
172372
|
const tertiary = primaryRatio === void 0 ? void 0 : ramp.filter((x2) => x2.ratio >= 4.5 && x2.ratio < primaryRatio).sort((a2, b2) => a2.ratio - b2.ratio)[0];
|
|
172279
172373
|
if (tertiary) colors.textTertiary = { light: tertiary.c };
|
|
172280
172374
|
const border = ramp.filter((x2) => x2.ratio >= 1.3 && x2.ratio <= 3).sort((a2, b2) => a2.ratio - b2.ratio)[0];
|
|
@@ -177074,7 +177168,7 @@ var init_errors2 = __esm({
|
|
|
177074
177168
|
});
|
|
177075
177169
|
|
|
177076
177170
|
// src/one-app/collect.ts
|
|
177077
|
-
import { createHash as
|
|
177171
|
+
import { createHash as createHash45 } from "node:crypto";
|
|
177078
177172
|
function isObject2(value) {
|
|
177079
177173
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
177080
177174
|
}
|
|
@@ -177146,7 +177240,7 @@ function semanticFingerprint(structure) {
|
|
|
177146
177240
|
}
|
|
177147
177241
|
return JSON.stringify(value);
|
|
177148
177242
|
};
|
|
177149
|
-
return
|
|
177243
|
+
return createHash45("sha256").update(canonical6(structure, true)).digest("hex");
|
|
177150
177244
|
}
|
|
177151
177245
|
async function collectOneApp(input, deps = {}) {
|
|
177152
177246
|
if (typeof input.metaSiteId !== "string" || !UUID.test(input.metaSiteId)) {
|
|
@@ -177358,7 +177452,7 @@ var init_collect = __esm({
|
|
|
177358
177452
|
});
|
|
177359
177453
|
|
|
177360
177454
|
// src/one-app/validate-topbar.ts
|
|
177361
|
-
import { createHash as
|
|
177455
|
+
import { createHash as createHash46 } from "node:crypto";
|
|
177362
177456
|
import { readFileSync as readFileSync105, statSync as statSync22 } from "node:fs";
|
|
177363
177457
|
import { resolve as resolve62, join as join92 } from "node:path";
|
|
177364
177458
|
import ts9 from "typescript";
|
|
@@ -177516,7 +177610,7 @@ function validate4(evidenceDir, contentDir2) {
|
|
|
177516
177610
|
if (typeof expectedHash !== "string" || !/^[a-f0-9]{64}$/i.test(expectedHash)) {
|
|
177517
177611
|
throw new Error("manifest.json is missing a valid raw-structure.json hash.");
|
|
177518
177612
|
}
|
|
177519
|
-
if (
|
|
177613
|
+
if (createHash46("sha256").update(rawBytes).digest("hex") !== expectedHash) {
|
|
177520
177614
|
throw new Error("raw-structure.json does not match the hash recorded in manifest.json.");
|
|
177521
177615
|
}
|
|
177522
177616
|
source = authoredControls(JSON.parse(rawBytes.toString("utf8")));
|
|
@@ -177993,7 +178087,7 @@ __export(cli_exports2, {
|
|
|
177993
178087
|
runOneAppCommand: () => runOneAppCommand
|
|
177994
178088
|
});
|
|
177995
178089
|
import { closeSync as closeSync7, constants as constants4, lstatSync as lstatSync22, mkdirSync as mkdirSync43, openSync as openSync6, readFileSync as readFileSync106, realpathSync as realpathSync14, writeFileSync as writeFileSync41 } from "node:fs";
|
|
177996
|
-
import { createHash as
|
|
178090
|
+
import { createHash as createHash47 } from "node:crypto";
|
|
177997
178091
|
import { dirname as dirname49, join as join93, parse as parse3, resolve as resolve63 } from "node:path";
|
|
177998
178092
|
function readOptions(argv, cwd, commandIncluded) {
|
|
177999
178093
|
let cursor = 0;
|
|
@@ -178134,7 +178228,7 @@ validate-topbar checks authored source top-bar controls against the migrated con
|
|
|
178134
178228
|
throw new OneAppError("artifact_write_failed", "Could not save the migration evidence. Existing files were kept.", { stage });
|
|
178135
178229
|
}
|
|
178136
178230
|
artifacts[name] = path2;
|
|
178137
|
-
hashes[name] =
|
|
178231
|
+
hashes[name] = createHash47("sha256").update(content).digest("hex");
|
|
178138
178232
|
return path2;
|
|
178139
178233
|
};
|
|
178140
178234
|
const progress = (nextStage) => {
|
|
@@ -182933,9 +183027,9 @@ var init_context = __esm({
|
|
|
182933
183027
|
import { mkdtempSync as mkdtempSync6, readFileSync as readFileSync110, mkdirSync as mkdirSync45, writeFileSync as writeFileSync44, existsSync as existsSync89, rmSync as rmSync24, readdirSync as readdirSync36, statSync as statSync24, lstatSync as lstatSync23, accessSync, constants as constants5, renameSync as renameSync13, cpSync as cpSync3 } from "node:fs";
|
|
182934
183028
|
import { execFile as execFile2, execFileSync as execFileSync7, spawnSync as spawnSync5, spawn as spawn7 } from "node:child_process";
|
|
182935
183029
|
import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
|
|
182936
|
-
import { createHash as
|
|
183030
|
+
import { createHash as createHash48, randomUUID as randomUUID11 } from "node:crypto";
|
|
182937
183031
|
import { tmpdir as tmpdir7, homedir as homedir15, hostname as hostname2 } from "node:os";
|
|
182938
|
-
import { join as join95, resolve as resolve66, relative as
|
|
183032
|
+
import { join as join95, resolve as resolve66, relative as relative17, basename as basename22, dirname as dirname51 } from "node:path";
|
|
182939
183033
|
import { fileURLToPath as fileURLToPath30 } from "node:url";
|
|
182940
183034
|
|
|
182941
183035
|
// ../serve-cli/src/client.ts
|
|
@@ -187164,7 +187258,7 @@ function shellShaDivergenceWarnings(jobs) {
|
|
|
187164
187258
|
}
|
|
187165
187259
|
async function templatePublishName(sourceDir) {
|
|
187166
187260
|
const id = await appId(sourceDir);
|
|
187167
|
-
return IDENTITY_SENTINELS.some((s2) => id.includes(s2)) ?
|
|
187261
|
+
return IDENTITY_SENTINELS.some((s2) => id.includes(s2)) ? basename22(sourceDir) : id;
|
|
187168
187262
|
}
|
|
187169
187263
|
function templateNameError(name, from) {
|
|
187170
187264
|
if (name.startsWith(TEMPLATE_APP_PREFIX)) {
|
|
@@ -187224,7 +187318,7 @@ async function appId(dir) {
|
|
|
187224
187318
|
if (m2.name) return m2.name;
|
|
187225
187319
|
} catch {
|
|
187226
187320
|
}
|
|
187227
|
-
return
|
|
187321
|
+
return basename22(dir);
|
|
187228
187322
|
}
|
|
187229
187323
|
async function contentVisibility(dir) {
|
|
187230
187324
|
try {
|
|
@@ -188547,7 +188641,7 @@ ${doNow.map((l2) => ` ${l2}`).join("\n")}`);
|
|
|
188547
188641
|
try {
|
|
188548
188642
|
const bytes2 = readFileSync110(iconPath);
|
|
188549
188643
|
payload.icon = bytes2.toString("base64");
|
|
188550
|
-
iconHash =
|
|
188644
|
+
iconHash = createHash48("sha256").update(bytes2).digest("hex");
|
|
188551
188645
|
} catch {
|
|
188552
188646
|
}
|
|
188553
188647
|
}
|
|
@@ -189031,7 +189125,7 @@ ${doNow.map((l2) => ` ${l2}`).join("\n")}`);
|
|
|
189031
189125
|
const { openUrl: openUrl2 } = await Promise.resolve().then(() => (init_open_url(), open_url_exports));
|
|
189032
189126
|
openUrl2(url2);
|
|
189033
189127
|
}
|
|
189034
|
-
const handover = { file: out2, hint: `hand ${
|
|
189128
|
+
const handover = { file: out2, hint: `hand ${basename22(out2)} to the owner at the handover \u2014 one self-contained page of their app taking shape; send it beside the preview link, never instead of it` };
|
|
189035
189129
|
const report3 = {
|
|
189036
189130
|
ok: true,
|
|
189037
189131
|
file: out2,
|
|
@@ -190364,7 +190458,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
190364
190458
|
const manifest = outcome.manifest;
|
|
190365
190459
|
const payload = await loadReleaseFromDir(declared, out2);
|
|
190366
190460
|
const { shellQuote: shellQuote3 } = await Promise.resolve().then(() => (init_shell_quote(), shell_quote_exports));
|
|
190367
|
-
const contentRel =
|
|
190461
|
+
const contentRel = relative17(process.cwd(), dir) || ".";
|
|
190368
190462
|
const contentArg2 = shellQuote3(contentRel);
|
|
190369
190463
|
if (onlyRaw !== void 0) {
|
|
190370
190464
|
const onlyDraft = flags.draft === true;
|
|
@@ -190426,7 +190520,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
190426
190520
|
let localSourceHash;
|
|
190427
190521
|
try {
|
|
190428
190522
|
const { collectAppSource: collectAppSource2, zipAppSource: zipAppSource2 } = await Promise.resolve().then(() => (init_app_source(), app_source_exports));
|
|
190429
|
-
localSourceHash =
|
|
190523
|
+
localSourceHash = createHash48("sha256").update(zipAppSource2(collectAppSource2(dir).entries).toString("base64")).digest("hex");
|
|
190430
190524
|
} catch {
|
|
190431
190525
|
}
|
|
190432
190526
|
return runReleasePatch({
|
|
@@ -192115,7 +192209,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
192115
192209
|
});
|
|
192116
192210
|
}
|
|
192117
192211
|
const bytes2 = readFileSync110(file2);
|
|
192118
|
-
const sha2 =
|
|
192212
|
+
const sha2 = createHash48("sha256").update(bytes2).digest("hex");
|
|
192119
192213
|
const forScreens = (str10(flags["for-screen"]) ?? "").split(",").map((s2) => s2.trim()).filter(Boolean);
|
|
192120
192214
|
if (flags["no-rebind"] !== void 0 && flags["no-rebind"] !== true) {
|
|
192121
192215
|
io2.error(JSON.stringify({ ok: false, error: "no_rebind_takes_no_value", message: "--no-rebind is a switch and takes no value; pass it bare.", usage: PATCH_USAGE }));
|