@wix/himalaya-cli 0.1043.0 → 0.1045.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 +568 -451
- package/dist/preview-assets.generated.bin +0 -0
- package/guides/designing-himi-screens.md +5 -1
- package/guides/templates.md +16 -0
- package/package.json +2 -2
- package/stdlib/design-kits/README.md +8 -0
- package/templates/beauty-salon/tokens.json +5 -0
- package/templates/beauty-salon-owner/tokens.json +5 -0
- package/templates/community-club/tokens.json +5 -0
- package/templates/community-club-owner/tokens.json +5 -0
- package/templates/events-meetups/tokens.json +5 -0
- package/templates/events-meetups-owner/tokens.json +5 -0
- package/templates/gym-fitness/tokens.json +5 -0
- package/templates/gym-fitness-owner/tokens.json +5 -0
- package/templates/nonprofit-cause/tokens.json +5 -0
- package/templates/nonprofit-cause-owner/tokens.json +5 -0
- package/templates/podcast-creator/tokens.json +5 -0
- package/templates/podcast-creator-owner/tokens.json +5 -0
- package/templates/portfolio-creative/tokens.json +5 -0
- package/templates/portfolio-creative-owner/tokens.json +5 -0
- package/templates/restaurant/tokens.json +5 -0
- package/templates/restaurant-owner/tokens.json +5 -0
- package/templates/retail-store/tokens.json +5 -0
- package/templates/retail-store-owner/tokens.json +5 -0
- package/templates/yoga-studio/tokens.json +5 -0
- package/templates/yoga-studio-owner/tokens.json +5 -0
package/dist/cli.mjs
CHANGED
|
@@ -1357,7 +1357,18 @@ function idSegOf(name) {
|
|
|
1357
1357
|
function substituteIdentity(body, name, slug = name) {
|
|
1358
1358
|
const idSeg = idSegOf(slug);
|
|
1359
1359
|
const cmsPrefix = slug.replace(/[^a-z0-9]+/gi, "_").replace(/^_+|_+$/g, "").toLowerCase() || "app";
|
|
1360
|
-
|
|
1360
|
+
const values = {
|
|
1361
|
+
__HIMI_APP_NAME__: name,
|
|
1362
|
+
__HIMI_APP_SLUG__: slug,
|
|
1363
|
+
__HIMI_APP_DOTID__: `com.example.${idSeg}`,
|
|
1364
|
+
__HIMI_APP_CMS_PREFIX__: cmsPrefix
|
|
1365
|
+
};
|
|
1366
|
+
return body.replace(sentinelPattern(), (m) => values[m] ?? m);
|
|
1367
|
+
}
|
|
1368
|
+
function sentinelPattern() {
|
|
1369
|
+
SENTINEL_RE ??= new RegExp(IDENTITY_SENTINELS.map((m) => escapeRe(m)).join("|"), "g");
|
|
1370
|
+
SENTINEL_RE.lastIndex = 0;
|
|
1371
|
+
return SENTINEL_RE;
|
|
1361
1372
|
}
|
|
1362
1373
|
function sentineledFiles(files) {
|
|
1363
1374
|
return Object.entries(files).filter(([, body]) => IDENTITY_SENTINELS.some((s) => body.includes(s))).map(([rel]) => rel).sort();
|
|
@@ -1699,7 +1710,7 @@ A per-app \`npm i @wix/himalaya\` is optional and only buys your editor local ty
|
|
|
1699
1710
|
);
|
|
1700
1711
|
return finishScaffold({ dir, files, ...kept.length ? { kept: kept.sort() } : {} });
|
|
1701
1712
|
}
|
|
1702
|
-
var PLAN_FILES, PACKAGE_GITIGNORE, MODULE_SOURCE_FILE, TEMPLATES_DIR, SHOWCASE_TEMPLATES_DIR, SHOWCASE_TEMPLATE_NAMES, TEMPLATE_META_FILE, TEMPLATE_ICONS_DIR, HEX_COLOR, PALETTE_KEYS, IDENTITY_SENTINELS, escapeRe, NAME_FIELDS, IDENTITY_FILES, DOTID_RE, BINARY_EXTENSIONS, extOf;
|
|
1713
|
+
var PLAN_FILES, PACKAGE_GITIGNORE, MODULE_SOURCE_FILE, TEMPLATES_DIR, SHOWCASE_TEMPLATES_DIR, SHOWCASE_TEMPLATE_NAMES, TEMPLATE_META_FILE, TEMPLATE_ICONS_DIR, HEX_COLOR, PALETTE_KEYS, IDENTITY_SENTINELS, SENTINEL_RE, escapeRe, NAME_FIELDS, IDENTITY_FILES, DOTID_RE, BINARY_EXTENSIONS, extOf;
|
|
1703
1714
|
var init_scaffold = __esm({
|
|
1704
1715
|
"src/scaffold.ts"() {
|
|
1705
1716
|
init_source_deny();
|
|
@@ -1728,6 +1739,181 @@ var init_scaffold = __esm({
|
|
|
1728
1739
|
}
|
|
1729
1740
|
});
|
|
1730
1741
|
|
|
1742
|
+
// ../../core/serve-storage/src/sha256.ts
|
|
1743
|
+
function sha256(input) {
|
|
1744
|
+
const bytes2 = typeof input === "string" ? new TextEncoder().encode(input) : input;
|
|
1745
|
+
const bitLen = bytes2.length * 8;
|
|
1746
|
+
const padded = new Uint8Array(((bytes2.length + 9 + 63) / 64 | 0) * 64);
|
|
1747
|
+
padded.set(bytes2);
|
|
1748
|
+
padded[bytes2.length] = 128;
|
|
1749
|
+
const view = new DataView(padded.buffer);
|
|
1750
|
+
view.setUint32(padded.length - 8, Math.floor(bitLen / 4294967296));
|
|
1751
|
+
view.setUint32(padded.length - 4, bitLen >>> 0);
|
|
1752
|
+
let h0 = 1779033703, h1 = 3144134277, h2 = 1013904242, h3 = 2773480762;
|
|
1753
|
+
let h4 = 1359893119, h5 = 2600822924, h6 = 528734635, h7 = 1541459225;
|
|
1754
|
+
const w = new Uint32Array(64);
|
|
1755
|
+
for (let off = 0; off < padded.length; off += 64) {
|
|
1756
|
+
for (let i = 0; i < 16; i++) w[i] = view.getUint32(off + i * 4);
|
|
1757
|
+
for (let i = 16; i < 64; i++) {
|
|
1758
|
+
const a0 = w[i - 15];
|
|
1759
|
+
const a1 = w[i - 2];
|
|
1760
|
+
const s0 = (rotr(a0, 7) ^ rotr(a0, 18) ^ a0 >>> 3) >>> 0;
|
|
1761
|
+
const s1 = (rotr(a1, 17) ^ rotr(a1, 19) ^ a1 >>> 10) >>> 0;
|
|
1762
|
+
w[i] = w[i - 16] + s0 + w[i - 7] + s1 >>> 0;
|
|
1763
|
+
}
|
|
1764
|
+
let a = h0, b = h1, c = h2, d = h3, e = h4, f = h5, g = h6, h = h7;
|
|
1765
|
+
for (let i = 0; i < 64; i++) {
|
|
1766
|
+
const S1 = (rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25)) >>> 0;
|
|
1767
|
+
const ch = (e & f ^ ~e & g) >>> 0;
|
|
1768
|
+
const t1 = h + S1 + ch + K[i] + w[i] >>> 0;
|
|
1769
|
+
const S0 = (rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22)) >>> 0;
|
|
1770
|
+
const maj = (a & b ^ a & c ^ b & c) >>> 0;
|
|
1771
|
+
const t2 = S0 + maj >>> 0;
|
|
1772
|
+
h = g;
|
|
1773
|
+
g = f;
|
|
1774
|
+
f = e;
|
|
1775
|
+
e = d + t1 >>> 0;
|
|
1776
|
+
d = c;
|
|
1777
|
+
c = b;
|
|
1778
|
+
b = a;
|
|
1779
|
+
a = t1 + t2 >>> 0;
|
|
1780
|
+
}
|
|
1781
|
+
h0 = h0 + a >>> 0;
|
|
1782
|
+
h1 = h1 + b >>> 0;
|
|
1783
|
+
h2 = h2 + c >>> 0;
|
|
1784
|
+
h3 = h3 + d >>> 0;
|
|
1785
|
+
h4 = h4 + e >>> 0;
|
|
1786
|
+
h5 = h5 + f >>> 0;
|
|
1787
|
+
h6 = h6 + g >>> 0;
|
|
1788
|
+
h7 = h7 + h >>> 0;
|
|
1789
|
+
}
|
|
1790
|
+
const out = new Uint8Array(32);
|
|
1791
|
+
const o = new DataView(out.buffer);
|
|
1792
|
+
o.setUint32(0, h0);
|
|
1793
|
+
o.setUint32(4, h1);
|
|
1794
|
+
o.setUint32(8, h2);
|
|
1795
|
+
o.setUint32(12, h3);
|
|
1796
|
+
o.setUint32(16, h4);
|
|
1797
|
+
o.setUint32(20, h5);
|
|
1798
|
+
o.setUint32(24, h6);
|
|
1799
|
+
o.setUint32(28, h7);
|
|
1800
|
+
return out;
|
|
1801
|
+
}
|
|
1802
|
+
function sha256Hex(input) {
|
|
1803
|
+
return hex(sha256(input));
|
|
1804
|
+
}
|
|
1805
|
+
async function sha256HexAsync(input) {
|
|
1806
|
+
const bytes2 = typeof input === "string" ? new TextEncoder().encode(input) : input;
|
|
1807
|
+
return hex(new Uint8Array(await crypto.subtle.digest("SHA-256", bytes2)));
|
|
1808
|
+
}
|
|
1809
|
+
function hex(bytes2) {
|
|
1810
|
+
let s = "";
|
|
1811
|
+
for (const b of bytes2) s += b.toString(16).padStart(2, "0");
|
|
1812
|
+
return s;
|
|
1813
|
+
}
|
|
1814
|
+
var K, rotr;
|
|
1815
|
+
var init_sha256 = __esm({
|
|
1816
|
+
"../../core/serve-storage/src/sha256.ts"() {
|
|
1817
|
+
K = new Uint32Array([
|
|
1818
|
+
1116352408,
|
|
1819
|
+
1899447441,
|
|
1820
|
+
3049323471,
|
|
1821
|
+
3921009573,
|
|
1822
|
+
961987163,
|
|
1823
|
+
1508970993,
|
|
1824
|
+
2453635748,
|
|
1825
|
+
2870763221,
|
|
1826
|
+
3624381080,
|
|
1827
|
+
310598401,
|
|
1828
|
+
607225278,
|
|
1829
|
+
1426881987,
|
|
1830
|
+
1925078388,
|
|
1831
|
+
2162078206,
|
|
1832
|
+
2614888103,
|
|
1833
|
+
3248222580,
|
|
1834
|
+
3835390401,
|
|
1835
|
+
4022224774,
|
|
1836
|
+
264347078,
|
|
1837
|
+
604807628,
|
|
1838
|
+
770255983,
|
|
1839
|
+
1249150122,
|
|
1840
|
+
1555081692,
|
|
1841
|
+
1996064986,
|
|
1842
|
+
2554220882,
|
|
1843
|
+
2821834349,
|
|
1844
|
+
2952996808,
|
|
1845
|
+
3210313671,
|
|
1846
|
+
3336571891,
|
|
1847
|
+
3584528711,
|
|
1848
|
+
113926993,
|
|
1849
|
+
338241895,
|
|
1850
|
+
666307205,
|
|
1851
|
+
773529912,
|
|
1852
|
+
1294757372,
|
|
1853
|
+
1396182291,
|
|
1854
|
+
1695183700,
|
|
1855
|
+
1986661051,
|
|
1856
|
+
2177026350,
|
|
1857
|
+
2456956037,
|
|
1858
|
+
2730485921,
|
|
1859
|
+
2820302411,
|
|
1860
|
+
3259730800,
|
|
1861
|
+
3345764771,
|
|
1862
|
+
3516065817,
|
|
1863
|
+
3600352804,
|
|
1864
|
+
4094571909,
|
|
1865
|
+
275423344,
|
|
1866
|
+
430227734,
|
|
1867
|
+
506948616,
|
|
1868
|
+
659060556,
|
|
1869
|
+
883997877,
|
|
1870
|
+
958139571,
|
|
1871
|
+
1322822218,
|
|
1872
|
+
1537002063,
|
|
1873
|
+
1747873779,
|
|
1874
|
+
1955562222,
|
|
1875
|
+
2024104815,
|
|
1876
|
+
2227730452,
|
|
1877
|
+
2361852424,
|
|
1878
|
+
2428436474,
|
|
1879
|
+
2756734187,
|
|
1880
|
+
3204031479,
|
|
1881
|
+
3329325298
|
|
1882
|
+
]);
|
|
1883
|
+
rotr = (x, n) => (x >>> n | x << 32 - n) >>> 0;
|
|
1884
|
+
}
|
|
1885
|
+
});
|
|
1886
|
+
|
|
1887
|
+
// ../../core/serve-storage/src/contract.ts
|
|
1888
|
+
function strongEtag(body) {
|
|
1889
|
+
return strongEtagForSha256(sha256Hex(body));
|
|
1890
|
+
}
|
|
1891
|
+
function strongEtagForSha256(hex2) {
|
|
1892
|
+
return `"${hex2.slice(0, 32)}"`;
|
|
1893
|
+
}
|
|
1894
|
+
function isSafeSegment(name) {
|
|
1895
|
+
return !name.includes("/") && !name.includes("..") && name.length > 0;
|
|
1896
|
+
}
|
|
1897
|
+
function isValidAppId(app) {
|
|
1898
|
+
return typeof app === "string" && APP_ID_RE.test(app);
|
|
1899
|
+
}
|
|
1900
|
+
function assertAppId(app, where) {
|
|
1901
|
+
if (!isValidAppId(app)) {
|
|
1902
|
+
throw new Error(`invalid app id at ${where}: ${JSON.stringify(app)}`);
|
|
1903
|
+
}
|
|
1904
|
+
return app;
|
|
1905
|
+
}
|
|
1906
|
+
var BUNDLE_CACHE_CONTROL, DOC_CACHE_CONTROL, PINNED_CACHE_CONTROL, APP_ID_RE;
|
|
1907
|
+
var init_contract = __esm({
|
|
1908
|
+
"../../core/serve-storage/src/contract.ts"() {
|
|
1909
|
+
init_sha256();
|
|
1910
|
+
BUNDLE_CACHE_CONTROL = "public, max-age=31536000, immutable";
|
|
1911
|
+
DOC_CACHE_CONTROL = "public, max-age=60, stale-while-revalidate=86400";
|
|
1912
|
+
PINNED_CACHE_CONTROL = "public, max-age=31536000, immutable";
|
|
1913
|
+
APP_ID_RE = /^(?=.{1,63}$)[a-z0-9][a-z0-9-]*(?:\.[a-z0-9][a-z0-9-]*)?$/;
|
|
1914
|
+
}
|
|
1915
|
+
});
|
|
1916
|
+
|
|
1731
1917
|
// ../../core/ts/src/app-link.ts
|
|
1732
1918
|
function requirePreviewSegment(value, field) {
|
|
1733
1919
|
if (!PLAYER_PREVIEW_SEGMENT_PATTERN.test(value)) {
|
|
@@ -1790,10 +1976,10 @@ function findingId(source, finding) {
|
|
|
1790
1976
|
finding.path ?? finding.at,
|
|
1791
1977
|
finding.ruleCode ?? finding.code ?? finding.invariant ?? finding.pass
|
|
1792
1978
|
].map(asText).join("\0");
|
|
1793
|
-
return `${source}:${
|
|
1979
|
+
return `${source}:${sha256Hex2(identity).slice(0, 12)}`;
|
|
1794
1980
|
}
|
|
1795
1981
|
function gapToFinding(gap) {
|
|
1796
|
-
return { ...gap, id: `gap:${gap.kind}:${
|
|
1982
|
+
return { ...gap, id: `gap:${gap.kind}:${sha256Hex2(gap.key).slice(0, 12)}` };
|
|
1797
1983
|
}
|
|
1798
1984
|
function normalizedFinding(source, finding) {
|
|
1799
1985
|
return {
|
|
@@ -1866,7 +2052,7 @@ function stringField(value) {
|
|
|
1866
2052
|
function numberField(value) {
|
|
1867
2053
|
return typeof value === "number" ? value : void 0;
|
|
1868
2054
|
}
|
|
1869
|
-
function
|
|
2055
|
+
function sha256Hex2(value) {
|
|
1870
2056
|
const bytes2 = new TextEncoder().encode(value);
|
|
1871
2057
|
const K2 = [
|
|
1872
2058
|
1116352408,
|
|
@@ -12759,7 +12945,7 @@ async function fetchUpstreamBytes(url) {
|
|
|
12759
12945
|
return new Uint8Array(await res.arrayBuffer());
|
|
12760
12946
|
}
|
|
12761
12947
|
function writeCachedFace(bytes2) {
|
|
12762
|
-
const hash =
|
|
12948
|
+
const hash = sha256Hex3(bytes2);
|
|
12763
12949
|
mkdirSync9(CACHE_DIR, { recursive: true });
|
|
12764
12950
|
const tmp = join21(CACHE_DIR, `.${hash}.${process.pid}.${Date.now()}.tmp`);
|
|
12765
12951
|
try {
|
|
@@ -12775,7 +12961,7 @@ async function ensureFaceBytes(face, opts = {}) {
|
|
|
12775
12961
|
const local = faceSource(face.file, face.sha256);
|
|
12776
12962
|
if (local) {
|
|
12777
12963
|
const bytes2 = readFileSync18(local);
|
|
12778
|
-
if (local !== join21(CACHE_DIR, face.sha256) ||
|
|
12964
|
+
if (local !== join21(CACHE_DIR, face.sha256) || sha256Hex3(bytes2) === face.sha256) {
|
|
12779
12965
|
return { ok: true, bytes: bytes2, from: "local" };
|
|
12780
12966
|
}
|
|
12781
12967
|
}
|
|
@@ -12802,7 +12988,7 @@ async function fetchVerifyAndCache(url, sha2565, fetcher) {
|
|
|
12802
12988
|
} catch (err) {
|
|
12803
12989
|
return { ok: false, reason: `fetching ${url} failed: ${err.message}` };
|
|
12804
12990
|
}
|
|
12805
|
-
const got =
|
|
12991
|
+
const got = sha256Hex3(bytes2);
|
|
12806
12992
|
if (got !== sha2565) {
|
|
12807
12993
|
return {
|
|
12808
12994
|
ok: false,
|
|
@@ -12862,14 +13048,14 @@ async function catalogFaceBytes(sha2565, opts = {}) {
|
|
|
12862
13048
|
}
|
|
12863
13049
|
return void 0;
|
|
12864
13050
|
}
|
|
12865
|
-
var REPO_ROOT5, VENDORED_DIR, CACHE_DIR,
|
|
13051
|
+
var REPO_ROOT5, VENDORED_DIR, CACHE_DIR, sha256Hex3, RAW, UPSTREAM_DIR, FETCH_TIMEOUT_MS, FAILURE_MEMO_MS, recentFetches;
|
|
12866
13052
|
var init_face_source = __esm({
|
|
12867
13053
|
"../font-bake/face-source.ts"() {
|
|
12868
13054
|
init_catalog();
|
|
12869
13055
|
REPO_ROOT5 = fileURLToPath9(new URL("../..", import.meta.url));
|
|
12870
13056
|
VENDORED_DIR = process.env.HIMI_FONTS_VENDORED_DIR || join21(REPO_ROOT5, "stdlib", "fonts", "vendored", "wix-madefor");
|
|
12871
13057
|
CACHE_DIR = join21(process.env.XDG_CACHE_HOME || join21(homedir3(), ".cache"), "himi", "fonts");
|
|
12872
|
-
|
|
13058
|
+
sha256Hex3 = (bytes2) => createHash6("sha256").update(bytes2).digest("hex");
|
|
12873
13059
|
RAW = ["https://", "raw.", "githubuser", "content.com"].join("");
|
|
12874
13060
|
UPSTREAM_DIR = /^(ofl|apache|ufl)\/[a-z0-9_-]+$/;
|
|
12875
13061
|
FETCH_TIMEOUT_MS = 2e4;
|
|
@@ -13011,8 +13197,17 @@ function hexToRgb2(hex2) {
|
|
|
13011
13197
|
return [int >> 16 & 255, int >> 8 & 255, int & 255];
|
|
13012
13198
|
}
|
|
13013
13199
|
function rgba(color, alpha2) {
|
|
13014
|
-
|
|
13015
|
-
|
|
13200
|
+
let h = color.trim().replace(/^#/, "");
|
|
13201
|
+
let own3 = 1;
|
|
13202
|
+
if (/^[\da-f]{4}$/i.test(h) || /^[\da-f]{8}$/i.test(h)) {
|
|
13203
|
+
const a = h.length === 4 ? h[3] + h[3] : h.slice(6, 8);
|
|
13204
|
+
own3 = parseInt(a, 16) / 255;
|
|
13205
|
+
h = h.length === 4 ? h.slice(0, 3) : h.slice(0, 6);
|
|
13206
|
+
}
|
|
13207
|
+
const rgb = hexToRgb2(`#${h}`);
|
|
13208
|
+
if (!rgb) return color;
|
|
13209
|
+
const composed = own3 === 1 ? clamp(alpha2) : Math.round(clamp(alpha2) * own3 * 1e3) / 1e3;
|
|
13210
|
+
return `rgba(${rgb[0]}, ${rgb[1]}, ${rgb[2]}, ${composed})`;
|
|
13016
13211
|
}
|
|
13017
13212
|
function normalizeSpring(spring, durationMs) {
|
|
13018
13213
|
return {
|
|
@@ -18383,151 +18578,6 @@ var init_wix_gateway = __esm({
|
|
|
18383
18578
|
}
|
|
18384
18579
|
});
|
|
18385
18580
|
|
|
18386
|
-
// ../../core/serve-storage/src/sha256.ts
|
|
18387
|
-
function sha2562(input) {
|
|
18388
|
-
const bytes2 = typeof input === "string" ? new TextEncoder().encode(input) : input;
|
|
18389
|
-
const bitLen = bytes2.length * 8;
|
|
18390
|
-
const padded = new Uint8Array(((bytes2.length + 9 + 63) / 64 | 0) * 64);
|
|
18391
|
-
padded.set(bytes2);
|
|
18392
|
-
padded[bytes2.length] = 128;
|
|
18393
|
-
const view = new DataView(padded.buffer);
|
|
18394
|
-
view.setUint32(padded.length - 8, Math.floor(bitLen / 4294967296));
|
|
18395
|
-
view.setUint32(padded.length - 4, bitLen >>> 0);
|
|
18396
|
-
let h0 = 1779033703, h1 = 3144134277, h2 = 1013904242, h3 = 2773480762;
|
|
18397
|
-
let h4 = 1359893119, h5 = 2600822924, h6 = 528734635, h7 = 1541459225;
|
|
18398
|
-
const w = new Uint32Array(64);
|
|
18399
|
-
for (let off = 0; off < padded.length; off += 64) {
|
|
18400
|
-
for (let i = 0; i < 16; i++) w[i] = view.getUint32(off + i * 4);
|
|
18401
|
-
for (let i = 16; i < 64; i++) {
|
|
18402
|
-
const a0 = w[i - 15];
|
|
18403
|
-
const a1 = w[i - 2];
|
|
18404
|
-
const s0 = (rotr(a0, 7) ^ rotr(a0, 18) ^ a0 >>> 3) >>> 0;
|
|
18405
|
-
const s1 = (rotr(a1, 17) ^ rotr(a1, 19) ^ a1 >>> 10) >>> 0;
|
|
18406
|
-
w[i] = w[i - 16] + s0 + w[i - 7] + s1 >>> 0;
|
|
18407
|
-
}
|
|
18408
|
-
let a = h0, b = h1, c = h2, d = h3, e = h4, f = h5, g = h6, h = h7;
|
|
18409
|
-
for (let i = 0; i < 64; i++) {
|
|
18410
|
-
const S1 = (rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25)) >>> 0;
|
|
18411
|
-
const ch = (e & f ^ ~e & g) >>> 0;
|
|
18412
|
-
const t1 = h + S1 + ch + K[i] + w[i] >>> 0;
|
|
18413
|
-
const S0 = (rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22)) >>> 0;
|
|
18414
|
-
const maj = (a & b ^ a & c ^ b & c) >>> 0;
|
|
18415
|
-
const t2 = S0 + maj >>> 0;
|
|
18416
|
-
h = g;
|
|
18417
|
-
g = f;
|
|
18418
|
-
f = e;
|
|
18419
|
-
e = d + t1 >>> 0;
|
|
18420
|
-
d = c;
|
|
18421
|
-
c = b;
|
|
18422
|
-
b = a;
|
|
18423
|
-
a = t1 + t2 >>> 0;
|
|
18424
|
-
}
|
|
18425
|
-
h0 = h0 + a >>> 0;
|
|
18426
|
-
h1 = h1 + b >>> 0;
|
|
18427
|
-
h2 = h2 + c >>> 0;
|
|
18428
|
-
h3 = h3 + d >>> 0;
|
|
18429
|
-
h4 = h4 + e >>> 0;
|
|
18430
|
-
h5 = h5 + f >>> 0;
|
|
18431
|
-
h6 = h6 + g >>> 0;
|
|
18432
|
-
h7 = h7 + h >>> 0;
|
|
18433
|
-
}
|
|
18434
|
-
const out = new Uint8Array(32);
|
|
18435
|
-
const o = new DataView(out.buffer);
|
|
18436
|
-
o.setUint32(0, h0);
|
|
18437
|
-
o.setUint32(4, h1);
|
|
18438
|
-
o.setUint32(8, h2);
|
|
18439
|
-
o.setUint32(12, h3);
|
|
18440
|
-
o.setUint32(16, h4);
|
|
18441
|
-
o.setUint32(20, h5);
|
|
18442
|
-
o.setUint32(24, h6);
|
|
18443
|
-
o.setUint32(28, h7);
|
|
18444
|
-
return out;
|
|
18445
|
-
}
|
|
18446
|
-
function sha256Hex3(input) {
|
|
18447
|
-
return hex(sha2562(input));
|
|
18448
|
-
}
|
|
18449
|
-
async function sha256HexAsync(input) {
|
|
18450
|
-
const bytes2 = typeof input === "string" ? new TextEncoder().encode(input) : input;
|
|
18451
|
-
return hex(new Uint8Array(await crypto.subtle.digest("SHA-256", bytes2)));
|
|
18452
|
-
}
|
|
18453
|
-
function hex(bytes2) {
|
|
18454
|
-
let s = "";
|
|
18455
|
-
for (const b of bytes2) s += b.toString(16).padStart(2, "0");
|
|
18456
|
-
return s;
|
|
18457
|
-
}
|
|
18458
|
-
var K, rotr;
|
|
18459
|
-
var init_sha256 = __esm({
|
|
18460
|
-
"../../core/serve-storage/src/sha256.ts"() {
|
|
18461
|
-
K = new Uint32Array([
|
|
18462
|
-
1116352408,
|
|
18463
|
-
1899447441,
|
|
18464
|
-
3049323471,
|
|
18465
|
-
3921009573,
|
|
18466
|
-
961987163,
|
|
18467
|
-
1508970993,
|
|
18468
|
-
2453635748,
|
|
18469
|
-
2870763221,
|
|
18470
|
-
3624381080,
|
|
18471
|
-
310598401,
|
|
18472
|
-
607225278,
|
|
18473
|
-
1426881987,
|
|
18474
|
-
1925078388,
|
|
18475
|
-
2162078206,
|
|
18476
|
-
2614888103,
|
|
18477
|
-
3248222580,
|
|
18478
|
-
3835390401,
|
|
18479
|
-
4022224774,
|
|
18480
|
-
264347078,
|
|
18481
|
-
604807628,
|
|
18482
|
-
770255983,
|
|
18483
|
-
1249150122,
|
|
18484
|
-
1555081692,
|
|
18485
|
-
1996064986,
|
|
18486
|
-
2554220882,
|
|
18487
|
-
2821834349,
|
|
18488
|
-
2952996808,
|
|
18489
|
-
3210313671,
|
|
18490
|
-
3336571891,
|
|
18491
|
-
3584528711,
|
|
18492
|
-
113926993,
|
|
18493
|
-
338241895,
|
|
18494
|
-
666307205,
|
|
18495
|
-
773529912,
|
|
18496
|
-
1294757372,
|
|
18497
|
-
1396182291,
|
|
18498
|
-
1695183700,
|
|
18499
|
-
1986661051,
|
|
18500
|
-
2177026350,
|
|
18501
|
-
2456956037,
|
|
18502
|
-
2730485921,
|
|
18503
|
-
2820302411,
|
|
18504
|
-
3259730800,
|
|
18505
|
-
3345764771,
|
|
18506
|
-
3516065817,
|
|
18507
|
-
3600352804,
|
|
18508
|
-
4094571909,
|
|
18509
|
-
275423344,
|
|
18510
|
-
430227734,
|
|
18511
|
-
506948616,
|
|
18512
|
-
659060556,
|
|
18513
|
-
883997877,
|
|
18514
|
-
958139571,
|
|
18515
|
-
1322822218,
|
|
18516
|
-
1537002063,
|
|
18517
|
-
1747873779,
|
|
18518
|
-
1955562222,
|
|
18519
|
-
2024104815,
|
|
18520
|
-
2227730452,
|
|
18521
|
-
2361852424,
|
|
18522
|
-
2428436474,
|
|
18523
|
-
2756734187,
|
|
18524
|
-
3204031479,
|
|
18525
|
-
3329325298
|
|
18526
|
-
]);
|
|
18527
|
-
rotr = (x, n) => (x >>> n | x << 32 - n) >>> 0;
|
|
18528
|
-
}
|
|
18529
|
-
});
|
|
18530
|
-
|
|
18531
18581
|
// ../../core/serve-runtime/src/wix-bridge.ts
|
|
18532
18582
|
function absoluteUrlRejection(path2) {
|
|
18533
18583
|
let host = "";
|
|
@@ -18670,7 +18720,7 @@ var init_wix_bridge = __esm({
|
|
|
18670
18720
|
* header with no session cookie falls back to itself — callers refuse that case before here. */
|
|
18671
18721
|
key(msid, cookieHeader) {
|
|
18672
18722
|
const session = /(?:^|;\s*)wixSession2=([^;]*)/.exec(cookieHeader)?.[1] ?? cookieHeader;
|
|
18673
|
-
return
|
|
18723
|
+
return sha256Hex(`${msid}
|
|
18674
18724
|
${session}`);
|
|
18675
18725
|
}
|
|
18676
18726
|
async instance(msid, cookieHeader, now = Date.now()) {
|
|
@@ -18745,7 +18795,7 @@ ${session}`);
|
|
|
18745
18795
|
}
|
|
18746
18796
|
cache = /* @__PURE__ */ new Map();
|
|
18747
18797
|
key(cookieHeader, limit) {
|
|
18748
|
-
return
|
|
18798
|
+
return sha256Hex(`${limit}
|
|
18749
18799
|
${cookieHeader}`);
|
|
18750
18800
|
}
|
|
18751
18801
|
async sites(cookieHeader, limit, now = Date.now()) {
|
|
@@ -21250,7 +21300,6 @@ function shouldRevealError(args) {
|
|
|
21250
21300
|
var EMAIL_RE, URL_HOST_RE, INTEGER_RE, NUMBER_RE;
|
|
21251
21301
|
var init_validation = __esm({
|
|
21252
21302
|
"../../core/ts/src/validation.ts"() {
|
|
21253
|
-
"use strict";
|
|
21254
21303
|
EMAIL_RE = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*\.[A-Za-z]{2,}$/;
|
|
21255
21304
|
URL_HOST_RE = /^[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*(:[0-9]+)?$/;
|
|
21256
21305
|
INTEGER_RE = /^[+-]?[0-9]+$/;
|
|
@@ -24851,7 +24900,6 @@ function validateWorkerSubtree(raw, slotId, policy, actionCatalog) {
|
|
|
24851
24900
|
var WORKER_SUBTREE_CEILINGS, ID_PART, ACTION_ID;
|
|
24852
24901
|
var init_worker_subtree = __esm({
|
|
24853
24902
|
"../../core/ts/src/worker-subtree.ts"() {
|
|
24854
|
-
"use strict";
|
|
24855
24903
|
init_worker_subtree_safe_types_generated();
|
|
24856
24904
|
WORKER_SUBTREE_CEILINGS = Object.freeze({
|
|
24857
24905
|
maxEncodedBytes: 65536,
|
|
@@ -24927,6 +24975,7 @@ function withTheme(ctx, theme) {
|
|
|
24927
24975
|
const base = ctx.tokens;
|
|
24928
24976
|
const colors = { ...base.colors ?? {} };
|
|
24929
24977
|
if (theme.colors) for (const [k, v] of Object.entries(theme.colors)) colors[k] = v;
|
|
24978
|
+
if (theme.colors && "accentPrimary" in theme.colors && !("accentText" in theme.colors)) delete colors.accentText;
|
|
24930
24979
|
const typography = { ...base.typography ?? {} };
|
|
24931
24980
|
if (theme.typography) for (const [k, v] of Object.entries(theme.typography)) typography[k] = v;
|
|
24932
24981
|
const kit = { ...base.kit ?? {} };
|
|
@@ -26104,6 +26153,9 @@ function actionClick(ctx, action) {
|
|
|
26104
26153
|
ctx.onAction(resolveItemDeep2(action, ctx));
|
|
26105
26154
|
};
|
|
26106
26155
|
}
|
|
26156
|
+
function accentTextColor(ctx) {
|
|
26157
|
+
return ctx.color("accentText", ctx.color("accentPrimary", "#116DFF"));
|
|
26158
|
+
}
|
|
26107
26159
|
function actionTextButton(ctx, action, label2, color, extra) {
|
|
26108
26160
|
if (action == null) return null;
|
|
26109
26161
|
const onClick = actionClick(ctx, action);
|
|
@@ -28994,7 +29046,7 @@ var init_renderNode = __esm({
|
|
|
28994
29046
|
e?.stopPropagation?.();
|
|
28995
29047
|
ctx.onAction(resolveItemDeep2(props.action, ctx));
|
|
28996
29048
|
} : void 0;
|
|
28997
|
-
const fg = primary ? C("textOnAccent", "#fff") :
|
|
29049
|
+
const fg = primary ? C("textOnAccent", "#fff") : accentTextColor(ctx);
|
|
28998
29050
|
const pillRadius = props.cornerRadius != null ? props.cornerRadius : ctx.radius("pill", 24);
|
|
28999
29051
|
const vPad = props.iconOnly ? 11 : props.size === "sm" ? 8 : props.size === "lg" ? 16 : 13;
|
|
29000
29052
|
const hPadBase = props.iconOnly ? 11 : props.size === "sm" ? 13 : props.size === "lg" ? 22 : 16;
|
|
@@ -29063,14 +29115,14 @@ var init_renderNode = __esm({
|
|
|
29063
29115
|
fontSize: f.remSize,
|
|
29064
29116
|
background: primary ? accent : "transparent",
|
|
29065
29117
|
color: fg,
|
|
29066
|
-
border: outlined ? `1px solid ${
|
|
29118
|
+
border: outlined ? `1px solid ${fg}` : "none",
|
|
29067
29119
|
cursor: disabled ? "default" : "pointer",
|
|
29068
29120
|
opacity: disabled ? 0.55 : 1,
|
|
29069
29121
|
boxSizing: "border-box",
|
|
29070
29122
|
...wrap
|
|
29071
29123
|
}, rowStretch, "fit-content"),
|
|
29072
29124
|
children: [
|
|
29073
|
-
props.loading && /* @__PURE__ */ jsx6("span", { style: { width: glyph, height: glyph, borderRadius: "50%", border: `2px solid ${primary ?
|
|
29125
|
+
props.loading && /* @__PURE__ */ jsx6("span", { style: { width: glyph, height: glyph, borderRadius: "50%", border: `2px solid ${rgba(fg, primary ? 0.4 : 0.35)}`, borderTopColor: fg, animation: ctx.empty ? void 0 : "himalaya-spin .7s linear infinite" } }),
|
|
29074
29126
|
!props.loading && resolvedLeadingIcon && ic(String(resolvedLeadingIcon)),
|
|
29075
29127
|
!props.iconOnly && (resolvedTitle != null && resolvedTitle !== "" ? String(resolvedTitle) : txt(props.title, ctx) || "Button"),
|
|
29076
29128
|
!props.loading && !props.iconOnly && resolvedTrailingIcon && ic(String(resolvedTrailingIcon))
|
|
@@ -33288,36 +33340,6 @@ var init_errors = __esm({
|
|
|
33288
33340
|
}
|
|
33289
33341
|
});
|
|
33290
33342
|
|
|
33291
|
-
// ../../core/serve-storage/src/contract.ts
|
|
33292
|
-
function strongEtag(body) {
|
|
33293
|
-
return strongEtagForSha256(sha256Hex3(body));
|
|
33294
|
-
}
|
|
33295
|
-
function strongEtagForSha256(hex2) {
|
|
33296
|
-
return `"${hex2.slice(0, 32)}"`;
|
|
33297
|
-
}
|
|
33298
|
-
function isSafeSegment(name) {
|
|
33299
|
-
return !name.includes("/") && !name.includes("..") && name.length > 0;
|
|
33300
|
-
}
|
|
33301
|
-
function isValidAppId(app) {
|
|
33302
|
-
return typeof app === "string" && APP_ID_RE.test(app);
|
|
33303
|
-
}
|
|
33304
|
-
function assertAppId(app, where) {
|
|
33305
|
-
if (!isValidAppId(app)) {
|
|
33306
|
-
throw new Error(`invalid app id at ${where}: ${JSON.stringify(app)}`);
|
|
33307
|
-
}
|
|
33308
|
-
return app;
|
|
33309
|
-
}
|
|
33310
|
-
var BUNDLE_CACHE_CONTROL, DOC_CACHE_CONTROL, PINNED_CACHE_CONTROL, APP_ID_RE;
|
|
33311
|
-
var init_contract = __esm({
|
|
33312
|
-
"../../core/serve-storage/src/contract.ts"() {
|
|
33313
|
-
init_sha256();
|
|
33314
|
-
BUNDLE_CACHE_CONTROL = "public, max-age=31536000, immutable";
|
|
33315
|
-
DOC_CACHE_CONTROL = "public, max-age=60, stale-while-revalidate=86400";
|
|
33316
|
-
PINNED_CACHE_CONTROL = "public, max-age=31536000, immutable";
|
|
33317
|
-
APP_ID_RE = /^(?=.{1,63}$)[a-z0-9][a-z0-9-]*(?:\.[a-z0-9][a-z0-9-]*)?$/;
|
|
33318
|
-
}
|
|
33319
|
-
});
|
|
33320
|
-
|
|
33321
33343
|
// ../../core/serve-control/src/config.ts
|
|
33322
33344
|
var config_exports2 = {};
|
|
33323
33345
|
__export(config_exports2, {
|
|
@@ -49502,7 +49524,7 @@ function makeServeHandler(opts) {
|
|
|
49502
49524
|
}
|
|
49503
49525
|
const PINNED_MANIFEST_CACHE_CAP = 100;
|
|
49504
49526
|
const pinnedManifestCache = /* @__PURE__ */ new Map();
|
|
49505
|
-
const sha256hex = (b) =>
|
|
49527
|
+
const sha256hex = (b) => sha256Hex(b);
|
|
49506
49528
|
function resolvePin(request, url) {
|
|
49507
49529
|
return request.headers.get("x-himalaya-release") || url.searchParams.get("release") || null;
|
|
49508
49530
|
}
|
|
@@ -50819,21 +50841,21 @@ var init_preview_assets_generated = __esm({
|
|
|
50819
50841
|
"../../packages/serve/src/preview-assets.generated.ts"() {
|
|
50820
50842
|
init_preview_assets_format();
|
|
50821
50843
|
PREVIEW_ASSET_MANIFEST = [
|
|
50822
|
-
{ key: "assets/index-
|
|
50823
|
-
{ key: "fonts/Roboto-LICENSE.txt", contentType: "application/octet-stream", offset:
|
|
50824
|
-
{ key: "fonts/Roboto-Variable.ttf", contentType: "font/ttf", offset:
|
|
50825
|
-
{ key: "fonts/WixMadeforDisplay-Bold.ttf", contentType: "font/ttf", offset:
|
|
50826
|
-
{ key: "fonts/WixMadeforDisplay-ExtraBold.ttf", contentType: "font/ttf", offset:
|
|
50827
|
-
{ key: "fonts/WixMadeforDisplay-Medium.ttf", contentType: "font/ttf", offset:
|
|
50828
|
-
{ key: "fonts/WixMadeforDisplay-Regular.ttf", contentType: "font/ttf", offset:
|
|
50829
|
-
{ key: "fonts/WixMadeforDisplay-SemiBold.ttf", contentType: "font/ttf", offset:
|
|
50830
|
-
{ key: "fonts/WixMadeforText-Bold.ttf", contentType: "font/ttf", offset:
|
|
50831
|
-
{ key: "fonts/WixMadeforText-ExtraBold.ttf", contentType: "font/ttf", offset:
|
|
50832
|
-
{ key: "fonts/WixMadeforText-Medium.ttf", contentType: "font/ttf", offset:
|
|
50833
|
-
{ key: "fonts/WixMadeforText-Regular.ttf", contentType: "font/ttf", offset:
|
|
50834
|
-
{ key: "fonts/WixMadeforText-SemiBold.ttf", contentType: "font/ttf", offset:
|
|
50835
|
-
{ key: "index.html", contentType: "text/html; charset=utf-8", offset:
|
|
50836
|
-
{ key: "t5-frame.html", contentType: "text/html; charset=utf-8", offset:
|
|
50844
|
+
{ key: "assets/index-C8FaHVmV.js", contentType: "application/javascript; charset=utf-8", offset: 8, length: 1052014, sha256: "607f0eff78c1f286d1d94f6d6c08868e2deec8d39ace8176b374f0117026998a" },
|
|
50845
|
+
{ key: "fonts/Roboto-LICENSE.txt", contentType: "application/octet-stream", offset: 1052022, length: 4610, sha256: "994062dd7af4186a739de55dd9e151c63b6301f8e2cbafc608d35c2e87da0cd2" },
|
|
50846
|
+
{ key: "fonts/Roboto-Variable.ttf", contentType: "font/ttf", offset: 1056632, length: 488584, sha256: "d7598e12c5dbef095ff8272cfc55da0250bd07fbdecbac8a530b9b277872a134" },
|
|
50847
|
+
{ key: "fonts/WixMadeforDisplay-Bold.ttf", contentType: "font/ttf", offset: 1545216, length: 90924, sha256: "ec4c7d63772d980d6e147b2df6215fd2737e4b04cebe0cf7e11dc695fb63cdcf" },
|
|
50848
|
+
{ key: "fonts/WixMadeforDisplay-ExtraBold.ttf", contentType: "font/ttf", offset: 1636140, length: 90984, sha256: "bf4c16a2774edd38a921edf3099469866cd74c094fd596f3fa4e81f54a04dfaa" },
|
|
50849
|
+
{ key: "fonts/WixMadeforDisplay-Medium.ttf", contentType: "font/ttf", offset: 1727124, length: 90980, sha256: "368faca44fb9f7207e4af784e94750b1ee59c1098b8689e0f4a918926f244fb5" },
|
|
50850
|
+
{ key: "fonts/WixMadeforDisplay-Regular.ttf", contentType: "font/ttf", offset: 1818104, length: 90872, sha256: "97ed8f1a6772abe26e3d8af5cecfc4b02faa94497d585b0398b5053b739a70c1" },
|
|
50851
|
+
{ key: "fonts/WixMadeforDisplay-SemiBold.ttf", contentType: "font/ttf", offset: 1908976, length: 90980, sha256: "642feab8a48ddf6c7a89d7c2a7c0edfa0e6e773f671287e460e222703563191e" },
|
|
50852
|
+
{ key: "fonts/WixMadeforText-Bold.ttf", contentType: "font/ttf", offset: 1999956, length: 108636, sha256: "37c179b4fefb63ea9637322b84583a2df53aa226c150294eea1675c14b1b8e29" },
|
|
50853
|
+
{ key: "fonts/WixMadeforText-ExtraBold.ttf", contentType: "font/ttf", offset: 2108592, length: 109084, sha256: "62e2fe4718129f36ecdb0ae4de385bd6b81ecc876146447167c6c140fad699a9" },
|
|
50854
|
+
{ key: "fonts/WixMadeforText-Medium.ttf", contentType: "font/ttf", offset: 2217676, length: 109048, sha256: "4ecf270136af928612c76fe4ebade91d8156975e5ea4c0cf9225501dd1788e02" },
|
|
50855
|
+
{ key: "fonts/WixMadeforText-Regular.ttf", contentType: "font/ttf", offset: 2326724, length: 107700, sha256: "dee56f09fd3efc127c1ea95557edc74110c1460a46287da36e0af25efd341ef5" },
|
|
50856
|
+
{ key: "fonts/WixMadeforText-SemiBold.ttf", contentType: "font/ttf", offset: 2434424, length: 88108, sha256: "dced97a77624bc5f8b1ae65850360908297f4588e09feb6f22792d29dc7e765b" },
|
|
50857
|
+
{ key: "index.html", contentType: "text/html; charset=utf-8", offset: 2522532, length: 4947, sha256: "3fd26f396a5b472e603185fb99d5b905f37b98615b2bf95456e4e9b03ae05429" },
|
|
50858
|
+
{ key: "t5-frame.html", contentType: "text/html; charset=utf-8", offset: 2527479, length: 17209, sha256: "dffc9718e2faa63ae2cc919e0a842f585ed565aaaa7c53778e90379442c731b6" }
|
|
50837
50859
|
];
|
|
50838
50860
|
}
|
|
50839
50861
|
});
|
|
@@ -54478,6 +54500,35 @@ function tuneHighContrastAccent(brand, surface) {
|
|
|
54478
54500
|
}
|
|
54479
54501
|
return candidate;
|
|
54480
54502
|
}
|
|
54503
|
+
function deriveAccentText(accent, surfaces) {
|
|
54504
|
+
const all = (typeof surfaces === "string" ? [surfaces] : [...surfaces]).map((s) => s.slice(0, 7));
|
|
54505
|
+
const page = all[0];
|
|
54506
|
+
const worst = (color) => Math.min(...all.map((s) => contrastRatio3(color, s)));
|
|
54507
|
+
const opaque = accent.length === 9 ? mix2(accent.slice(0, 7), page, channel2(accent, 7) / 255) : accent;
|
|
54508
|
+
if (worst(opaque) >= ACCENT_TEXT_MIN_CONTRAST) return opaque;
|
|
54509
|
+
const pole = worst("#FFFFFF") >= worst("#000000") ? "#FFFFFF" : "#000000";
|
|
54510
|
+
for (let step = 1; step <= 100; step++) {
|
|
54511
|
+
const candidate = mix2(pole, opaque, step / 100);
|
|
54512
|
+
if (worst(candidate) >= ACCENT_TEXT_MIN_CONTRAST) return candidate;
|
|
54513
|
+
}
|
|
54514
|
+
if (all.length > 1) {
|
|
54515
|
+
const side2 = (hex2) => relativeLuminance2(hex2) > MID_GREY_LUMINANCE;
|
|
54516
|
+
const sameSide = all.filter((s) => side2(s) === side2(page));
|
|
54517
|
+
return deriveAccentText(accent, sameSide.length < all.length ? sameSide : [page]);
|
|
54518
|
+
}
|
|
54519
|
+
return pole;
|
|
54520
|
+
}
|
|
54521
|
+
function textSurfacesOf(colors) {
|
|
54522
|
+
const out = { light: [], dark: [], highContrast: [] };
|
|
54523
|
+
for (const name of TEXT_BACKDROP_TOKENS) {
|
|
54524
|
+
const value = colors[name];
|
|
54525
|
+
for (const arm of ["light", "dark", "highContrast"]) {
|
|
54526
|
+
const hex2 = typeof value === "string" ? value : value && typeof value === "object" && !Array.isArray(value) ? value[arm] ?? value.light : void 0;
|
|
54527
|
+
if (typeof hex2 === "string" && hex2.startsWith("#") && hex2.length >= 7) out[arm].push(hex2);
|
|
54528
|
+
}
|
|
54529
|
+
}
|
|
54530
|
+
return out;
|
|
54531
|
+
}
|
|
54481
54532
|
function stripBrandFromIdiom(tokens) {
|
|
54482
54533
|
const idiom = tokens.idiom;
|
|
54483
54534
|
if (!idiom || typeof idiom !== "object" || Array.isArray(idiom)) return;
|
|
@@ -54498,7 +54549,7 @@ function stripBrandFromIdiom(tokens) {
|
|
|
54498
54549
|
}
|
|
54499
54550
|
}
|
|
54500
54551
|
}
|
|
54501
|
-
function deriveAccentFamily(primary, secondary, surfaces) {
|
|
54552
|
+
function deriveAccentFamily(primary, secondary, surfaces, textSurfaces = {}) {
|
|
54502
54553
|
const primaryDark = tuneDarkAccent(primary, surfaces.dark, surfaces.light);
|
|
54503
54554
|
const secondaryDark = tuneDarkAccent(secondary, surfaces.dark, surfaces.light);
|
|
54504
54555
|
const primaryHigh = tuneHighContrastAccent(primary, surfaces.highContrast);
|
|
@@ -54515,10 +54566,15 @@ function deriveAccentFamily(primary, secondary, surfaces) {
|
|
|
54515
54566
|
light: textOnArm(primary),
|
|
54516
54567
|
dark: textOnArm(primaryDark),
|
|
54517
54568
|
highContrast: textOn(primaryHigh)
|
|
54569
|
+
},
|
|
54570
|
+
accentText: {
|
|
54571
|
+
light: deriveAccentText(primary, [surfaces.light, ...textSurfaces.light ?? []]),
|
|
54572
|
+
dark: deriveAccentText(primaryDark, [surfaces.dark, ...textSurfaces.dark ?? []]),
|
|
54573
|
+
highContrast: deriveAccentText(primaryHigh, [surfaces.highContrast, ...textSurfaces.highContrast ?? []])
|
|
54518
54574
|
}
|
|
54519
54575
|
};
|
|
54520
54576
|
}
|
|
54521
|
-
var ACCENT_SURFACE_MIN_DELTA, ACCENT_SURFACE_LIGHT_WEIGHT, SECONDARY_SHADE_WEIGHT, SECONDARY_MIN_LSTAR, DARK_ARM_MIN_LIFT, DARK_ARM_TARGET_CONTRAST, DARK_ARM_FLOOR_CONTRAST, DARK_ARM_LSTAR_CAP, HIGH_CONTRAST_TARGET, BRAND_COLOR_TOKENS, BRAND_GLOW_SHADOW;
|
|
54577
|
+
var ACCENT_SURFACE_MIN_DELTA, ACCENT_SURFACE_LIGHT_WEIGHT, SECONDARY_SHADE_WEIGHT, SECONDARY_MIN_LSTAR, DARK_ARM_MIN_LIFT, DARK_ARM_TARGET_CONTRAST, DARK_ARM_FLOOR_CONTRAST, DARK_ARM_LSTAR_CAP, HIGH_CONTRAST_TARGET, ACCENT_TEXT_MIN_CONTRAST, MID_GREY_LUMINANCE, TEXT_BACKDROP_TOKENS, BRAND_COLOR_TOKENS, BRAND_GLOW_SHADOW;
|
|
54522
54578
|
var init_brand_color_math = __esm({
|
|
54523
54579
|
"../../core/ts/src/brand-color-math.ts"() {
|
|
54524
54580
|
ACCENT_SURFACE_MIN_DELTA = 1.08;
|
|
@@ -54530,7 +54586,10 @@ var init_brand_color_math = __esm({
|
|
|
54530
54586
|
DARK_ARM_FLOOR_CONTRAST = 3;
|
|
54531
54587
|
DARK_ARM_LSTAR_CAP = 80;
|
|
54532
54588
|
HIGH_CONTRAST_TARGET = 8.5;
|
|
54533
|
-
|
|
54589
|
+
ACCENT_TEXT_MIN_CONTRAST = 4.5;
|
|
54590
|
+
MID_GREY_LUMINANCE = 0.179;
|
|
54591
|
+
TEXT_BACKDROP_TOKENS = ["surfaceSecondary", "surfaceElevated", "surfaceSubtle", "surfaceTertiary"];
|
|
54592
|
+
BRAND_COLOR_TOKENS = ["accentPrimary", "accentSecondary", "accentSurface", "textOnAccent", "accentText"];
|
|
54534
54593
|
BRAND_GLOW_SHADOW = "glow";
|
|
54535
54594
|
}
|
|
54536
54595
|
});
|
|
@@ -54566,7 +54625,9 @@ function withDerivedAccents(tokensOverlay, wst) {
|
|
|
54566
54625
|
light: lightArm2(surfacePrimary) ?? "#FFFFFF",
|
|
54567
54626
|
dark: armOf(surfacePrimary, "dark") ?? "#0D1117",
|
|
54568
54627
|
highContrast: armOf(surfacePrimary, "highContrast") ?? "#000000"
|
|
54569
|
-
|
|
54628
|
+
// #3275 — the crawl knows only the site's LIGHT surfaces; a light card judged against a dark
|
|
54629
|
+
// arm would fight that arm's page, and `--apply` re-derives every arm after the merge anyway.
|
|
54630
|
+
}, { light: textSurfacesOf(tokensOverlay.colors ?? {}).light });
|
|
54570
54631
|
const keepCrawledLight = (derived, existing) => {
|
|
54571
54632
|
const crawled = lightArm2(existing);
|
|
54572
54633
|
return crawled ? { ...derived, light: crawled } : derived;
|
|
@@ -54575,6 +54636,7 @@ function withDerivedAccents(tokensOverlay, wst) {
|
|
|
54575
54636
|
colors.accentSecondary = keepCrawledLight(family.accentSecondary, tokensOverlay.colors?.accentSecondary);
|
|
54576
54637
|
colors.accentSurface = keepCrawledLight(family.accentSurface, tokensOverlay.colors?.accentSurface);
|
|
54577
54638
|
colors.textOnAccent = keepCrawledLight(family.textOnAccent, tokensOverlay.colors?.textOnAccent);
|
|
54639
|
+
colors.accentText = keepCrawledLight(family.accentText, tokensOverlay.colors?.accentText);
|
|
54578
54640
|
return { ...tokensOverlay, colors };
|
|
54579
54641
|
}
|
|
54580
54642
|
function mergedArm(colors, name, arm, fallback) {
|
|
@@ -54597,11 +54659,12 @@ function alignAccentsToSurfaces(mergedColors, overlayColors) {
|
|
|
54597
54659
|
light: mergedArm(colors, "surfacePrimary", "light", "#FFFFFF"),
|
|
54598
54660
|
dark: mergedArm(colors, "surfacePrimary", "dark", "#0D1117"),
|
|
54599
54661
|
highContrast: mergedArm(colors, "surfacePrimary", "highContrast", "#000000")
|
|
54600
|
-
});
|
|
54662
|
+
}, textSurfacesOf(colors));
|
|
54601
54663
|
colors.accentPrimary = family.accentPrimary;
|
|
54602
54664
|
colors.accentSecondary = family.accentSecondary;
|
|
54603
54665
|
colors.accentSurface = family.accentSurface;
|
|
54604
54666
|
colors.textOnAccent = family.textOnAccent;
|
|
54667
|
+
colors.accentText = family.accentText;
|
|
54605
54668
|
return colors;
|
|
54606
54669
|
}
|
|
54607
54670
|
function deriveBranding(input) {
|
|
@@ -63214,6 +63277,7 @@ async function loadReleaseFromDir(app, dir) {
|
|
|
63214
63277
|
// src/cli.ts
|
|
63215
63278
|
init_scaffold();
|
|
63216
63279
|
init_store();
|
|
63280
|
+
init_contract();
|
|
63217
63281
|
init_app_link();
|
|
63218
63282
|
init_himi_report();
|
|
63219
63283
|
|
|
@@ -63619,7 +63683,7 @@ function screenshotArtifactPath(contentDir2, hash) {
|
|
|
63619
63683
|
return join6(resolve6(contentDir2), ".himi", "attestations", "artifacts", `${hash}.png`);
|
|
63620
63684
|
}
|
|
63621
63685
|
var GIT_HASH_MAX_BUFFER = 128 * 1024 * 1024;
|
|
63622
|
-
var
|
|
63686
|
+
var sha2562 = (bytes2) => createHash3("sha256").update(bytes2).digest("hex");
|
|
63623
63687
|
function canonical(value) {
|
|
63624
63688
|
if (value === null || typeof value !== "object") return JSON.stringify(value);
|
|
63625
63689
|
if (Array.isArray(value)) return `[${value.map(canonical).join(",")}]`;
|
|
@@ -63627,21 +63691,21 @@ function canonical(value) {
|
|
|
63627
63691
|
return `{${Object.keys(record2).filter((key2) => record2[key2] !== void 0).sort().map((key2) => `${JSON.stringify(key2)}:${canonical(record2[key2])}`).join(",")}}`;
|
|
63628
63692
|
}
|
|
63629
63693
|
function releasePayloadHash(payload) {
|
|
63630
|
-
if (!payload || typeof payload !== "object" || Array.isArray(payload)) return
|
|
63694
|
+
if (!payload || typeof payload !== "object" || Array.isArray(payload)) return sha2562(canonical(payload));
|
|
63631
63695
|
const record2 = payload;
|
|
63632
63696
|
const manifest = record2.manifest;
|
|
63633
|
-
if (!manifest || typeof manifest !== "object" || Array.isArray(manifest)) return
|
|
63697
|
+
if (!manifest || typeof manifest !== "object" || Array.isArray(manifest)) return sha2562(canonical(payload));
|
|
63634
63698
|
const manifestRecord = manifest;
|
|
63635
63699
|
const widgets = manifestRecord.widgets;
|
|
63636
|
-
if (!widgets || typeof widgets !== "object" || Array.isArray(widgets)) return
|
|
63637
|
-
return
|
|
63700
|
+
if (!widgets || typeof widgets !== "object" || Array.isArray(widgets)) return sha2562(canonical(payload));
|
|
63701
|
+
return sha2562(canonical({ ...record2, manifest: { ...manifestRecord, widgets: stableWidgets(widgets) } }));
|
|
63638
63702
|
}
|
|
63639
63703
|
function withoutSelfHash(attestation) {
|
|
63640
63704
|
const { selfHash: _selfHash, ...body } = attestation;
|
|
63641
63705
|
return body;
|
|
63642
63706
|
}
|
|
63643
63707
|
function selfHashFor(attestation) {
|
|
63644
|
-
return
|
|
63708
|
+
return sha2562(canonical(withoutSelfHash(attestation)));
|
|
63645
63709
|
}
|
|
63646
63710
|
function repoRoot(contentDir2) {
|
|
63647
63711
|
try {
|
|
@@ -63755,7 +63819,7 @@ function readRetainedAttestations(contentDir2) {
|
|
|
63755
63819
|
for (const expected of Object.values(run2.screenshots)) {
|
|
63756
63820
|
const path2 = screenshotArtifactPath(contentDir2, expected);
|
|
63757
63821
|
if (!existsSync3(path2)) errors.push(`missing screenshot for retained run ${run2.runId}: ${basename2(path2)}`);
|
|
63758
|
-
else if (
|
|
63822
|
+
else if (sha2562(readFileSync5(path2)) !== expected) errors.push(`screenshot hash does not match retained run ${run2.runId}: ${basename2(path2)}`);
|
|
63759
63823
|
}
|
|
63760
63824
|
}
|
|
63761
63825
|
const runs = [];
|
|
@@ -63814,11 +63878,11 @@ function writeAttestation(input, opts = {}) {
|
|
|
63814
63878
|
const previous = readLatestAttestation(contentDir2);
|
|
63815
63879
|
const runId = `${(opts.now ?? (() => /* @__PURE__ */ new Date()))().toISOString()}-${(opts.randomSuffix ?? (() => randomBytes(3).toString("hex")))()}`;
|
|
63816
63880
|
const descriptorHashes = Object.fromEntries(
|
|
63817
|
-
Object.entries(input.descriptors).sort(([a], [b]) => a.localeCompare(b)).map(([screen, bytes2]) => [screen,
|
|
63881
|
+
Object.entries(input.descriptors).sort(([a], [b]) => a.localeCompare(b)).map(([screen, bytes2]) => [screen, sha2562(bytes2)])
|
|
63818
63882
|
);
|
|
63819
63883
|
const screenshotEntries = Object.entries(input.screenshots ?? {}).sort(([a], [b]) => a.localeCompare(b)).filter(([, path2]) => existsSync3(path2)).map(([screen, path2]) => {
|
|
63820
63884
|
const bytes2 = readFileSync5(path2);
|
|
63821
|
-
return { screen, bytes: bytes2, hash:
|
|
63885
|
+
return { screen, bytes: bytes2, hash: sha2562(bytes2) };
|
|
63822
63886
|
});
|
|
63823
63887
|
const screenshots = Object.fromEntries(screenshotEntries.map(({ screen, hash }) => [screen, hash]));
|
|
63824
63888
|
for (const { bytes: bytes2, hash } of screenshotEntries) {
|
|
@@ -63941,7 +64005,7 @@ function verifyAttestation(attestation, contentDir2, descriptors, expectedApp, r
|
|
|
63941
64005
|
errors.push(`missing baked descriptor for ${screen}`);
|
|
63942
64006
|
continue;
|
|
63943
64007
|
}
|
|
63944
|
-
if (
|
|
64008
|
+
if (sha2562(bytes2) !== expected) errors.push(`descriptor hash does not match for ${screen}`);
|
|
63945
64009
|
}
|
|
63946
64010
|
for (const [screen, expected] of Object.entries(attestation.screenshots)) {
|
|
63947
64011
|
const path2 = screenshotArtifactPath(contentDir2, expected);
|
|
@@ -63949,7 +64013,7 @@ function verifyAttestation(attestation, contentDir2, descriptors, expectedApp, r
|
|
|
63949
64013
|
errors.push(`missing screenshot for ${screen}: ${basename2(path2)}`);
|
|
63950
64014
|
continue;
|
|
63951
64015
|
}
|
|
63952
|
-
if (
|
|
64016
|
+
if (sha2562(readFileSync5(path2)) !== expected) errors.push(`screenshot hash does not match for ${screen}: ${basename2(path2)}`);
|
|
63953
64017
|
}
|
|
63954
64018
|
return { ok: errors.length === 0, errors };
|
|
63955
64019
|
}
|
|
@@ -67584,8 +67648,26 @@ function shellShaDivergenceWarnings(jobs) {
|
|
|
67584
67648
|
([release, built]) => `\u26A0 this build compiles the native shell at ${built.slice(0, 12)}, not release ${release.slice(0, 12)} \u2014 the release was pushed from a branch whose HEAD is not on the default branch, so the Mac pool checks out the nearest default-branch ancestor. A native-shell or tools/mobile-dist/** change on that branch is NOT in this binary even if the job reports SUCCESS; re-push from a checkout whose HEAD is on origin/master to validate it.`
|
|
67585
67649
|
);
|
|
67586
67650
|
}
|
|
67651
|
+
async function templatePublishName(sourceDir) {
|
|
67652
|
+
const id = await appId(sourceDir);
|
|
67653
|
+
return IDENTITY_SENTINELS.some((s) => id.includes(s)) ? basename14(sourceDir) : id;
|
|
67654
|
+
}
|
|
67655
|
+
function templateNameError(name, from) {
|
|
67656
|
+
if (name.startsWith(TEMPLATE_APP_PREFIX)) {
|
|
67657
|
+
const stripped = name.slice(TEMPLATE_APP_PREFIX.length);
|
|
67658
|
+
const hint = stripped && !stripped.startsWith(TEMPLATE_APP_PREFIX) && !templateNameError(stripped, from) ? `pass --name ${stripped}` : "pass --name <kebab-id>";
|
|
67659
|
+
return `template name "${name}" (${from}) already starts with "${TEMPLATE_APP_PREFIX}", which would publish to "${TEMPLATE_APP_PREFIX}${name}"; ${hint}`;
|
|
67660
|
+
}
|
|
67661
|
+
if (!TEMPLATE_NAME_PATTERN.test(name)) {
|
|
67662
|
+
return `template name "${name}" (${from}) is not a lowercase kebab id (lowercase letters and digits, hyphens only between them); pass --name <kebab-id> (it becomes ${TEMPLATE_APP_PREFIX}<name>)`;
|
|
67663
|
+
}
|
|
67664
|
+
const composed = TEMPLATE_APP_PREFIX + name;
|
|
67665
|
+
return isValidAppId(composed) ? null : `template name "${name}" (${from}) makes app id "${composed}", which is over the serve plane's app-id length limit; pass a shorter --name`;
|
|
67666
|
+
}
|
|
67587
67667
|
function materializeForPreview(appDir2, slug, displayName) {
|
|
67588
67668
|
if (!isTemplateSourceTree(appDir2)) return appDir2;
|
|
67669
|
+
const slugError = templateNameError(slug, "preview slug");
|
|
67670
|
+
if (slugError) throw Object.assign(new Error(slugError), { exitCode: 2 });
|
|
67589
67671
|
const files = readTemplateFiles(appDir2);
|
|
67590
67672
|
const forBuild = Object.fromEntries(
|
|
67591
67673
|
Object.entries(files).map(([rel, body]) => [rel, rel === "himalaya.content.json" ? substituteIdentity(body, slug) : body])
|
|
@@ -67613,7 +67695,12 @@ function materializeForPreview(appDir2, slug, displayName) {
|
|
|
67613
67695
|
const dest = join60(root, `${slug}-${process.pid}`);
|
|
67614
67696
|
rmSync14(dest, { recursive: true, force: true });
|
|
67615
67697
|
mkdirSync31(dest, { recursive: true });
|
|
67616
|
-
|
|
67698
|
+
try {
|
|
67699
|
+
materializeSource(forBuild, displayName, dest, slug);
|
|
67700
|
+
} catch (e) {
|
|
67701
|
+
rmSync14(dest, { recursive: true, force: true });
|
|
67702
|
+
throw e;
|
|
67703
|
+
}
|
|
67617
67704
|
return dest;
|
|
67618
67705
|
}
|
|
67619
67706
|
async function appId(dir) {
|
|
@@ -68479,253 +68566,281 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
68479
68566
|
return outcome.code;
|
|
68480
68567
|
}
|
|
68481
68568
|
if (sub === "publish") {
|
|
68482
|
-
const
|
|
68483
|
-
const sourceDir = resolve47(str6(flags["source-dir"]) ?? appDir2);
|
|
68484
|
-
let meta;
|
|
68485
|
-
try {
|
|
68486
|
-
meta = JSON.parse(readFileSync75(join60(sourceDir, TEMPLATE_META_FILE), "utf8"));
|
|
68487
|
-
} catch {
|
|
68488
|
-
io.error(JSON.stringify({ error: `no ${TEMPLATE_META_FILE} in ${sourceDir} \u2014 a template must declare { title, description, tags } to be published`, hint: `add ${TEMPLATE_META_FILE} next to himalaya.content.json (or pass --source-dir <dir>)` }));
|
|
68489
|
-
return 2;
|
|
68490
|
-
}
|
|
68491
|
-
if (!meta || typeof meta.title !== "string" || typeof meta.description !== "string" || !Array.isArray(meta.tags)) {
|
|
68492
|
-
io.error(JSON.stringify({ error: `${TEMPLATE_META_FILE} must be { title: string, description: string, tags: string[], category?: string }` }));
|
|
68493
|
-
return 2;
|
|
68494
|
-
}
|
|
68569
|
+
const publishScratch = [];
|
|
68495
68570
|
try {
|
|
68496
|
-
const
|
|
68497
|
-
|
|
68498
|
-
|
|
68499
|
-
|
|
68500
|
-
|
|
68501
|
-
|
|
68502
|
-
|
|
68503
|
-
|
|
68504
|
-
|
|
68505
|
-
const force = flags.force === true;
|
|
68506
|
-
const { buildContentForValidation: buildContentForValidation2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
68507
|
-
const bres = await buildContentForValidation2(buildDir, { resolution: resolutionFlag(flags) });
|
|
68508
|
-
const out = mkdtempSync4(join60(tmpdir5(), "himi-template-"));
|
|
68509
|
-
const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
|
|
68510
|
-
const outcome = await buildReleaseFromContent2(buildDir, out, {
|
|
68511
|
-
...hasWorkers ? { tier5Dir: bundleOutDir2(buildDir) } : {},
|
|
68512
|
-
collect: { lint: true, strict }
|
|
68513
|
-
});
|
|
68514
|
-
const scaffoldSourceFindings = resolve47(sourceDir) === resolve47(appDir2) ? [] : [
|
|
68515
|
-
...tokenColorIssues(sourceDir),
|
|
68516
|
-
...surfaceIssues(sourceDir, void 0, strict),
|
|
68517
|
-
...await fontIssues(sourceDir, strict),
|
|
68518
|
-
...storesV1Issues(sourceDir, strict)
|
|
68519
|
-
].map((issue2) => ({
|
|
68520
|
-
...issue2,
|
|
68521
|
-
// Say WHICH tree. The same message against two trees means two different fixes,
|
|
68522
|
-
// and the scaffold source is the one the author is least likely to be looking at.
|
|
68523
|
-
message: `scaffold source (--source-dir ${sourceDir}): ${issue2.message}`
|
|
68524
|
-
}));
|
|
68525
|
-
const { navIssues: navIssues2 } = await Promise.resolve().then(() => (init_nav_lint(), nav_lint_exports));
|
|
68526
|
-
const { report: report2, hasErrors } = summarizeLint(app, bres, outcome, strict, [
|
|
68527
|
-
...await cmsIssues(buildDir, app, strict, { local: true }),
|
|
68528
|
-
...surfaceIssues(buildDir, outcome.surfaceNav, strict),
|
|
68529
|
-
...tokenColorIssues(buildDir),
|
|
68530
|
-
...await fontIssues(buildDir, strict),
|
|
68531
|
-
...storesV1Issues(buildDir, strict),
|
|
68532
|
-
...await navIssues2(buildDir, strict),
|
|
68533
|
-
...scaffoldSourceFindings
|
|
68534
|
-
]);
|
|
68535
|
-
if (hasErrors && !force) {
|
|
68536
|
-
print({ ...report2, published: false, hint: "lint found errors \u2014 fix them, or re-run with --force to publish anyway" });
|
|
68537
|
-
return 1;
|
|
68538
|
-
}
|
|
68539
|
-
const payload = await loadReleaseFromDir(app, out);
|
|
68540
|
-
const previewAuthError = templatePreviewAuthError(payload.appConfig);
|
|
68541
|
-
if (previewAuthError) {
|
|
68542
|
-
io.error(JSON.stringify({ error: previewAuthError, published: false }));
|
|
68543
|
-
return 1;
|
|
68544
|
-
}
|
|
68545
|
-
const leaked = sentineledFiles({
|
|
68546
|
-
...payload.screens,
|
|
68547
|
-
...payload.appConfig ? { "app-config.json": payload.appConfig } : {},
|
|
68548
|
-
...payload.tokens ? { "tokens.json": payload.tokens } : {}
|
|
68549
|
-
});
|
|
68550
|
-
if (leaked.length > 0) {
|
|
68551
|
-
io.error(JSON.stringify({
|
|
68552
|
-
error: `built release still contains __HIMI_APP_*__ scaffold markers in: ${leaked.join(", ")}`,
|
|
68553
|
-
hint: "point --dir at a concrete app (e.g. apps/himi-branded-lite), or fix the template so its identity fields are sentineled only in files himi init substitutes"
|
|
68554
|
-
}));
|
|
68555
|
-
return 1;
|
|
68556
|
-
}
|
|
68557
|
-
const iconPath = str6(flags.icon) ? resolve47(str6(flags.icon)) : templateIconPath(name);
|
|
68558
|
-
let iconHash;
|
|
68559
|
-
if (iconPath) {
|
|
68571
|
+
for (const f of ["dir", "source-dir", "name", "icon"]) {
|
|
68572
|
+
if (flags[f] === true) {
|
|
68573
|
+
io.error(JSON.stringify({ error: `--${f} needs a value`, published: false }));
|
|
68574
|
+
return 2;
|
|
68575
|
+
}
|
|
68576
|
+
}
|
|
68577
|
+
const appDir2 = resolve47(str6(flags.dir) ?? process.cwd());
|
|
68578
|
+
const sourceDir = resolve47(str6(flags["source-dir"]) ?? appDir2);
|
|
68579
|
+
let meta;
|
|
68560
68580
|
try {
|
|
68561
|
-
|
|
68562
|
-
payload.icon = bytes2.toString("base64");
|
|
68563
|
-
iconHash = createHash27("sha256").update(bytes2).digest("hex");
|
|
68581
|
+
meta = JSON.parse(readFileSync75(join60(sourceDir, TEMPLATE_META_FILE), "utf8"));
|
|
68564
68582
|
} catch {
|
|
68583
|
+
io.error(JSON.stringify({ error: `no ${TEMPLATE_META_FILE} in ${sourceDir} \u2014 a template must declare { title, description, tags } to be published`, hint: `add ${TEMPLATE_META_FILE} next to himalaya.content.json (or pass --source-dir <dir>)` }));
|
|
68584
|
+
return 2;
|
|
68565
68585
|
}
|
|
68566
|
-
|
|
68567
|
-
|
|
68568
|
-
|
|
68569
|
-
const files = sentinelizeArchive(readTemplateFiles(sourceDir), app);
|
|
68570
|
-
if (Object.keys(files).length === 0) {
|
|
68571
|
-
io.error(JSON.stringify({ error: `no source files collected from ${sourceDir}` }));
|
|
68572
|
-
return 1;
|
|
68573
|
-
}
|
|
68574
|
-
payload.source = { files, meta };
|
|
68575
|
-
const { collectAppSource: collectAppSource2, secretFindings: secretFindings2, zipAppSource: zipAppSource2, largestEntries: largestEntries2, MAX_APP_SOURCE_BYTES: MAX_APP_SOURCE_BYTES2 } = await Promise.resolve().then(() => (init_app_source(), app_source_exports));
|
|
68576
|
-
const templateArchive = collectAppSource2(sourceDir);
|
|
68577
|
-
const templateSecrets = secretFindings2(templateArchive.entries);
|
|
68578
|
-
if (templateSecrets.length > 0) {
|
|
68579
|
-
io.error(JSON.stringify({
|
|
68580
|
-
error: `refusing to publish: ${templateSecrets[0].path} looks like it contains ${templateSecrets[0].reason}`,
|
|
68581
|
-
file: templateSecrets[0].path,
|
|
68582
|
-
hint: "a template's source is served PUBLICLY \u2014 remove it from the tree before publishing"
|
|
68583
|
-
}));
|
|
68584
|
-
return 1;
|
|
68585
|
-
}
|
|
68586
|
-
const templateZip = zipAppSource2(templateArchive.entries);
|
|
68587
|
-
const templateSourceB64 = templateZip.toString("base64");
|
|
68588
|
-
if (templateSourceB64.length > MAX_APP_SOURCE_BYTES2) {
|
|
68589
|
-
const templateLargest = largestEntries2(templateArchive.entries);
|
|
68590
|
-
io.error(JSON.stringify({
|
|
68591
|
-
ok: false,
|
|
68592
|
-
template: name,
|
|
68593
|
-
app: templateAppId,
|
|
68594
|
-
published: false,
|
|
68595
|
-
error: "app_source_too_large",
|
|
68596
|
-
archivedBytes: templateZip.length,
|
|
68597
|
-
encodedBytes: templateSourceB64.length,
|
|
68598
|
-
limit: MAX_APP_SOURCE_BYTES2,
|
|
68599
|
-
files: templateArchive.entries.length,
|
|
68600
|
-
largest: templateLargest,
|
|
68601
|
-
// No `--no-source` here, deliberately: a template's archive is not optional the way
|
|
68602
|
-
// a push's is. `himi pull` restores templates through it, so a flag that dropped it
|
|
68603
|
-
// would publish a template nobody can restore — the failure #2423 exists to prevent.
|
|
68604
|
-
hint: `trim the template's source tree \u2014 the largest entries are ${templateLargest.map((e) => `${e.path} (${Math.round(e.compressed / 1024)} KB compressed)`).join(", ")}. Build output and dependencies are already excluded, and a template's archive is not optional, so there is no flag that publishes without it`
|
|
68605
|
-
}));
|
|
68606
|
-
return 1;
|
|
68607
|
-
}
|
|
68608
|
-
payload.appSource = templateSourceB64;
|
|
68609
|
-
const tplVis = visibilityFlag(flags, io);
|
|
68610
|
-
if (!tplVis) return 2;
|
|
68611
|
-
const publishMeta = {
|
|
68612
|
-
...str6(flags.label) ? { label: str6(flags.label) } : {},
|
|
68613
|
-
...str6(flags.notes) ? { notes: str6(flags.notes) } : {},
|
|
68614
|
-
...tplVis.value ? { visibility: tplVis.value } : {}
|
|
68615
|
-
};
|
|
68616
|
-
let sendPayload = payload;
|
|
68617
|
-
let templateBodyBytes = publishReleaseBodyBytes(payload, publishMeta);
|
|
68618
|
-
let sourceGzChars;
|
|
68619
|
-
if (templateBodyBytes > MAX_PUBLISH_BODY_BYTES) {
|
|
68620
|
-
const { gzipSync: gzipSync2 } = await import("node:zlib");
|
|
68621
|
-
const { source: plainSource, ...rest } = payload;
|
|
68622
|
-
const sourceGz = gzipSync2(Buffer.from(JSON.stringify(plainSource), "utf8"), { level: 9 }).toString("base64");
|
|
68623
|
-
sourceGzChars = sourceGz.length;
|
|
68624
|
-
const gzipped = { ...rest, sourceGz };
|
|
68625
|
-
const gzBytes = publishReleaseBodyBytes(gzipped, publishMeta);
|
|
68626
|
-
if (gzBytes <= MAX_PUBLISH_BODY_BYTES) {
|
|
68627
|
-
sendPayload = gzipped;
|
|
68628
|
-
templateBodyBytes = gzBytes;
|
|
68586
|
+
if (!meta || typeof meta.title !== "string" || typeof meta.description !== "string" || !Array.isArray(meta.tags)) {
|
|
68587
|
+
io.error(JSON.stringify({ error: `${TEMPLATE_META_FILE} must be { title: string, description: string, tags: string[], category?: string }` }));
|
|
68588
|
+
return 2;
|
|
68629
68589
|
}
|
|
68630
|
-
|
|
68631
|
-
|
|
68632
|
-
|
|
68633
|
-
|
|
68634
|
-
|
|
68635
|
-
|
|
68636
|
-
|
|
68637
|
-
|
|
68638
|
-
|
|
68639
|
-
|
|
68640
|
-
|
|
68641
|
-
|
|
68642
|
-
|
|
68643
|
-
|
|
68644
|
-
|
|
68645
|
-
|
|
68646
|
-
|
|
68647
|
-
|
|
68648
|
-
|
|
68649
|
-
|
|
68650
|
-
|
|
68651
|
-
|
|
68652
|
-
|
|
68653
|
-
|
|
68590
|
+
try {
|
|
68591
|
+
const appearance = extractTemplateAppearance(JSON.parse(readFileSync75(join60(sourceDir, "tokens.json"), "utf8")));
|
|
68592
|
+
meta = { ...appearance, ...meta };
|
|
68593
|
+
} catch {
|
|
68594
|
+
}
|
|
68595
|
+
const nameFlag = str6(flags.name);
|
|
68596
|
+
const name = nameFlag ?? await templatePublishName(sourceDir);
|
|
68597
|
+
const nameError = templateNameError(
|
|
68598
|
+
name,
|
|
68599
|
+
nameFlag !== void 0 ? "from --name" : `from ${sourceDir}'s himalaya.content.json, or its directory name when that is a scaffold marker`
|
|
68600
|
+
);
|
|
68601
|
+
if (nameError) {
|
|
68602
|
+
io.error(JSON.stringify({ error: nameError, published: false }));
|
|
68603
|
+
return 2;
|
|
68604
|
+
}
|
|
68605
|
+
const templateAppId = TEMPLATE_APP_PREFIX + name;
|
|
68606
|
+
const buildDir = materializeForPreview(appDir2, name, meta.title);
|
|
68607
|
+
if (buildDir !== appDir2) publishScratch.push(buildDir);
|
|
68608
|
+
const app = await appId(buildDir);
|
|
68609
|
+
const strict = flags.strict === true;
|
|
68610
|
+
const force = flags.force === true;
|
|
68611
|
+
const { buildContentForValidation: buildContentForValidation2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
68612
|
+
const bres = await buildContentForValidation2(buildDir, { resolution: resolutionFlag(flags) });
|
|
68613
|
+
const out = mkdtempSync4(join60(tmpdir5(), "himi-template-"));
|
|
68614
|
+
publishScratch.push(out);
|
|
68615
|
+
const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
|
|
68616
|
+
const outcome = await buildReleaseFromContent2(buildDir, out, {
|
|
68617
|
+
...hasWorkers ? { tier5Dir: bundleOutDir2(buildDir) } : {},
|
|
68618
|
+
collect: { lint: true, strict }
|
|
68619
|
+
});
|
|
68620
|
+
const scaffoldSourceFindings = resolve47(sourceDir) === resolve47(appDir2) ? [] : [
|
|
68621
|
+
...tokenColorIssues(sourceDir),
|
|
68622
|
+
...surfaceIssues(sourceDir, void 0, strict),
|
|
68623
|
+
...await fontIssues(sourceDir, strict),
|
|
68624
|
+
...storesV1Issues(sourceDir, strict)
|
|
68625
|
+
].map((issue2) => ({
|
|
68626
|
+
...issue2,
|
|
68627
|
+
// Say WHICH tree. The same message against two trees means two different fixes,
|
|
68628
|
+
// and the scaffold source is the one the author is least likely to be looking at.
|
|
68629
|
+
message: `scaffold source (--source-dir ${sourceDir}): ${issue2.message}`
|
|
68654
68630
|
}));
|
|
68655
|
-
|
|
68656
|
-
|
|
68657
|
-
|
|
68658
|
-
|
|
68659
|
-
|
|
68660
|
-
|
|
68631
|
+
const { navIssues: navIssues2 } = await Promise.resolve().then(() => (init_nav_lint(), nav_lint_exports));
|
|
68632
|
+
const { report: report2, hasErrors } = summarizeLint(app, bres, outcome, strict, [
|
|
68633
|
+
...await cmsIssues(buildDir, app, strict, { local: true }),
|
|
68634
|
+
...surfaceIssues(buildDir, outcome.surfaceNav, strict),
|
|
68635
|
+
...tokenColorIssues(buildDir),
|
|
68636
|
+
...await fontIssues(buildDir, strict),
|
|
68637
|
+
...storesV1Issues(buildDir, strict),
|
|
68638
|
+
...await navIssues2(buildDir, strict),
|
|
68639
|
+
...scaffoldSourceFindings
|
|
68640
|
+
]);
|
|
68641
|
+
if (hasErrors && !force) {
|
|
68642
|
+
print({ ...report2, published: false, hint: "lint found errors \u2014 fix them, or re-run with --force to publish anyway" });
|
|
68643
|
+
return 1;
|
|
68644
|
+
}
|
|
68645
|
+
const payload = await loadReleaseFromDir(app, out);
|
|
68646
|
+
const previewAuthError = templatePreviewAuthError(payload.appConfig);
|
|
68647
|
+
if (previewAuthError) {
|
|
68648
|
+
io.error(JSON.stringify({ error: previewAuthError, published: false }));
|
|
68649
|
+
return 1;
|
|
68650
|
+
}
|
|
68651
|
+
const leaked = sentineledFiles({
|
|
68652
|
+
...payload.screens,
|
|
68653
|
+
...payload.appConfig ? { "app-config.json": payload.appConfig } : {},
|
|
68654
|
+
...payload.tokens ? { "tokens.json": payload.tokens } : {}
|
|
68655
|
+
});
|
|
68656
|
+
if (leaked.length > 0) {
|
|
68657
|
+
io.error(JSON.stringify({
|
|
68658
|
+
error: `built release still contains __HIMI_APP_*__ scaffold markers in: ${leaked.join(", ")}`,
|
|
68659
|
+
hint: "point --dir at a concrete app (e.g. apps/himi-branded-lite), or fix the template so its identity fields are sentineled only in files himi init substitutes"
|
|
68660
|
+
}));
|
|
68661
|
+
return 1;
|
|
68662
|
+
}
|
|
68663
|
+
const iconPath = str6(flags.icon) ? resolve47(str6(flags.icon)) : templateIconPath(name);
|
|
68664
|
+
let iconHash;
|
|
68665
|
+
if (iconPath) {
|
|
68666
|
+
try {
|
|
68667
|
+
const bytes2 = readFileSync75(iconPath);
|
|
68668
|
+
payload.icon = bytes2.toString("base64");
|
|
68669
|
+
iconHash = createHash27("sha256").update(bytes2).digest("hex");
|
|
68670
|
+
} catch {
|
|
68671
|
+
}
|
|
68672
|
+
}
|
|
68673
|
+
payload.app = templateAppId;
|
|
68674
|
+
payload.manifest = { ...payload.manifest, app: templateAppId, ...iconHash ? { iconHash } : {} };
|
|
68675
|
+
const files = sentinelizeArchive(readTemplateFiles(sourceDir), app);
|
|
68676
|
+
if (Object.keys(files).length === 0) {
|
|
68677
|
+
io.error(JSON.stringify({ error: `no source files collected from ${sourceDir}` }));
|
|
68678
|
+
return 1;
|
|
68679
|
+
}
|
|
68680
|
+
payload.source = { files, meta };
|
|
68681
|
+
const { collectAppSource: collectAppSource2, secretFindings: secretFindings2, zipAppSource: zipAppSource2, largestEntries: largestEntries2, MAX_APP_SOURCE_BYTES: MAX_APP_SOURCE_BYTES2 } = await Promise.resolve().then(() => (init_app_source(), app_source_exports));
|
|
68682
|
+
const templateArchive = collectAppSource2(sourceDir);
|
|
68683
|
+
const templateSecrets = secretFindings2(templateArchive.entries);
|
|
68684
|
+
if (templateSecrets.length > 0) {
|
|
68685
|
+
io.error(JSON.stringify({
|
|
68686
|
+
error: `refusing to publish: ${templateSecrets[0].path} looks like it contains ${templateSecrets[0].reason}`,
|
|
68687
|
+
file: templateSecrets[0].path,
|
|
68688
|
+
hint: "a template's source is served PUBLICLY \u2014 remove it from the tree before publishing"
|
|
68689
|
+
}));
|
|
68690
|
+
return 1;
|
|
68691
|
+
}
|
|
68692
|
+
const templateZip = zipAppSource2(templateArchive.entries);
|
|
68693
|
+
const templateSourceB64 = templateZip.toString("base64");
|
|
68694
|
+
if (templateSourceB64.length > MAX_APP_SOURCE_BYTES2) {
|
|
68695
|
+
const templateLargest = largestEntries2(templateArchive.entries);
|
|
68696
|
+
io.error(JSON.stringify({
|
|
68697
|
+
ok: false,
|
|
68698
|
+
template: name,
|
|
68699
|
+
app: templateAppId,
|
|
68700
|
+
published: false,
|
|
68701
|
+
error: "app_source_too_large",
|
|
68702
|
+
archivedBytes: templateZip.length,
|
|
68703
|
+
encodedBytes: templateSourceB64.length,
|
|
68704
|
+
limit: MAX_APP_SOURCE_BYTES2,
|
|
68705
|
+
files: templateArchive.entries.length,
|
|
68706
|
+
largest: templateLargest,
|
|
68707
|
+
// No `--no-source` here, deliberately: a template's archive is not optional the way
|
|
68708
|
+
// a push's is. `himi pull` restores templates through it, so a flag that dropped it
|
|
68709
|
+
// would publish a template nobody can restore — the failure #2423 exists to prevent.
|
|
68710
|
+
hint: `trim the template's source tree \u2014 the largest entries are ${templateLargest.map((e) => `${e.path} (${Math.round(e.compressed / 1024)} KB compressed)`).join(", ")}. Build output and dependencies are already excluded, and a template's archive is not optional, so there is no flag that publishes without it`
|
|
68711
|
+
}));
|
|
68712
|
+
return 1;
|
|
68713
|
+
}
|
|
68714
|
+
payload.appSource = templateSourceB64;
|
|
68715
|
+
const tplVis = visibilityFlag(flags, io);
|
|
68716
|
+
if (!tplVis) return 2;
|
|
68717
|
+
const publishMeta = {
|
|
68718
|
+
...str6(flags.label) ? { label: str6(flags.label) } : {},
|
|
68719
|
+
...str6(flags.notes) ? { notes: str6(flags.notes) } : {},
|
|
68720
|
+
...tplVis.value ? { visibility: tplVis.value } : {}
|
|
68721
|
+
};
|
|
68722
|
+
let sendPayload = payload;
|
|
68723
|
+
let templateBodyBytes = publishReleaseBodyBytes(payload, publishMeta);
|
|
68724
|
+
let sourceGzChars;
|
|
68725
|
+
if (templateBodyBytes > MAX_PUBLISH_BODY_BYTES) {
|
|
68726
|
+
const { gzipSync: gzipSync2 } = await import("node:zlib");
|
|
68727
|
+
const { source: plainSource, ...rest } = payload;
|
|
68728
|
+
const sourceGz = gzipSync2(Buffer.from(JSON.stringify(plainSource), "utf8"), { level: 9 }).toString("base64");
|
|
68729
|
+
sourceGzChars = sourceGz.length;
|
|
68730
|
+
const gzipped = { ...rest, sourceGz };
|
|
68731
|
+
const gzBytes = publishReleaseBodyBytes(gzipped, publishMeta);
|
|
68732
|
+
if (gzBytes <= MAX_PUBLISH_BODY_BYTES) {
|
|
68733
|
+
sendPayload = gzipped;
|
|
68734
|
+
templateBodyBytes = gzBytes;
|
|
68735
|
+
}
|
|
68736
|
+
}
|
|
68737
|
+
if (templateBodyBytes > MAX_PUBLISH_BODY_BYTES) {
|
|
68738
|
+
io.error(JSON.stringify({
|
|
68739
|
+
ok: false,
|
|
68740
|
+
template: name,
|
|
68741
|
+
app: templateAppId,
|
|
68742
|
+
published: false,
|
|
68743
|
+
error: "publish_body_too_large",
|
|
68744
|
+
bodyBytes: templateBodyBytes,
|
|
68745
|
+
limit: MAX_PUBLISH_BODY_BYTES,
|
|
68746
|
+
// Both halves, because "the body is too big" does not say which one to cut, and the
|
|
68747
|
+
// two answer to different edits: `sourceChars` shrinks by removing FILES from the
|
|
68748
|
+
// tree, `appSourceBytes` by removing bytes (an image, a fixture) that may not be
|
|
68749
|
+
// text at all. They overlap by design — the same tree, twice — so they are reported
|
|
68750
|
+
// separately rather than summed into a figure that double-counts it.
|
|
68751
|
+
sourceChars: JSON.stringify(payload.source).length,
|
|
68752
|
+
appSourceBytes: templateSourceB64.length,
|
|
68753
|
+
// The catalog view is reported COMPRESSED as well, because "trim the tree" was the
|
|
68754
|
+
// wrong instruction and cost real time: the collector already drops binaries,
|
|
68755
|
+
// symlinks and dist/node_modules/.git/.himi, so there is rarely anything to trim.
|
|
68756
|
+
// What the two figures actually say is whether compression can still save you --
|
|
68757
|
+
// `sourceGzChars` is what this publish already tried and what remains after it.
|
|
68758
|
+
sourceGzChars,
|
|
68759
|
+
hint: "the catalog view is already sent gzipped when the plain body would not fit, and it still does not: the remainder is the release itself (screens, bundles, assets) plus the private archive, which no flag omits. Cut what the app ships, not the source tree \u2014 the collector already excludes binaries, symlinks, dist/, node_modules/, .git/ and .himi/."
|
|
68760
|
+
}));
|
|
68761
|
+
return 1;
|
|
68762
|
+
}
|
|
68763
|
+
if (sendPayload.sourceGz) {
|
|
68764
|
+
const { gzipSync: gz } = await import("node:zlib");
|
|
68765
|
+
const probeApp = templateAppId;
|
|
68766
|
+
let probeErr;
|
|
68767
|
+
try {
|
|
68768
|
+
const probe = await client2().publishRelease({
|
|
68769
|
+
app: probeApp,
|
|
68770
|
+
manifest: { releaseId: "preflight", gitSha: "0".repeat(40), app: probeApp, minBinaryVersion: null, screens: {}, bundles: {} },
|
|
68771
|
+
screens: {},
|
|
68772
|
+
sourceGz: gz(Buffer.from("null")).toString("base64")
|
|
68773
|
+
});
|
|
68774
|
+
probeErr = probe.json?.error ?? probe.status;
|
|
68775
|
+
} catch (e) {
|
|
68776
|
+
const target = targetName();
|
|
68777
|
+
io.error(JSON.stringify(serveUnreachableError(target, serveBase(), e.message)));
|
|
68778
|
+
return 1;
|
|
68779
|
+
}
|
|
68780
|
+
if (probeErr !== "source_gz_not_an_object") {
|
|
68781
|
+
io.error(JSON.stringify({
|
|
68782
|
+
ok: false,
|
|
68783
|
+
template: name,
|
|
68784
|
+
app: templateAppId,
|
|
68785
|
+
published: false,
|
|
68786
|
+
error: "serve_plane_lacks_source_gz",
|
|
68787
|
+
probe: probeErr,
|
|
68788
|
+
bodyBytes: templateBodyBytes,
|
|
68789
|
+
limit: MAX_PUBLISH_BODY_BYTES,
|
|
68790
|
+
hint: `this template only fits with a compressed catalog view, and this plane does not accept one \u2014 it answered ${JSON.stringify(probeErr)} to the capability probe instead of "source_gz_not_an_object". NOTHING was published. Upgrade the serve plane and run this again.`
|
|
68791
|
+
}));
|
|
68792
|
+
return 1;
|
|
68793
|
+
}
|
|
68794
|
+
}
|
|
68795
|
+
let r;
|
|
68661
68796
|
try {
|
|
68662
|
-
|
|
68663
|
-
app: probeApp,
|
|
68664
|
-
manifest: { releaseId: "preflight", gitSha: "0".repeat(40), app: probeApp, minBinaryVersion: null, screens: {}, bundles: {} },
|
|
68665
|
-
screens: {},
|
|
68666
|
-
sourceGz: gz(Buffer.from("null")).toString("base64")
|
|
68667
|
-
});
|
|
68668
|
-
probeErr = probe.json?.error ?? probe.status;
|
|
68797
|
+
r = await client2().publishRelease(sendPayload, publishMeta);
|
|
68669
68798
|
} catch (e) {
|
|
68670
68799
|
const target = targetName();
|
|
68671
68800
|
io.error(JSON.stringify(serveUnreachableError(target, serveBase(), e.message)));
|
|
68672
68801
|
return 1;
|
|
68673
68802
|
}
|
|
68674
|
-
if (
|
|
68803
|
+
if (!r.ok) {
|
|
68804
|
+
print({ ok: false, status: r.status, body: r.json ?? r.text });
|
|
68805
|
+
return 1;
|
|
68806
|
+
}
|
|
68807
|
+
if (sendPayload.sourceGz && r.json?.template !== true) {
|
|
68675
68808
|
io.error(JSON.stringify({
|
|
68676
68809
|
ok: false,
|
|
68677
68810
|
template: name,
|
|
68678
68811
|
app: templateAppId,
|
|
68679
68812
|
published: false,
|
|
68680
|
-
error: "
|
|
68681
|
-
|
|
68682
|
-
bodyBytes: templateBodyBytes,
|
|
68683
|
-
limit: MAX_PUBLISH_BODY_BYTES,
|
|
68684
|
-
hint: `this template only fits with a compressed catalog view, and this plane does not accept one \u2014 it answered ${JSON.stringify(probeErr)} to the capability probe instead of "source_gz_not_an_object". NOTHING was published. Upgrade the serve plane and run this again.`
|
|
68813
|
+
error: "serve_plane_ignored_source_gz",
|
|
68814
|
+
hint: `this plane accepted the publish but did not score it as a template, which means it predates compressed catalog views (\`sourceGz\`). A release WAS created for ${templateAppId} as an ordinary app \u2014 it carries no template source and will not appear in \`himi template list --remote\`. Upgrade the serve plane, then publish again; the republish repairs it.`
|
|
68685
68815
|
}));
|
|
68686
68816
|
return 1;
|
|
68687
68817
|
}
|
|
68688
|
-
|
|
68689
|
-
|
|
68690
|
-
|
|
68691
|
-
|
|
68692
|
-
} catch (e) {
|
|
68693
|
-
const target = targetName();
|
|
68694
|
-
io.error(JSON.stringify(serveUnreachableError(target, serveBase(), e.message)));
|
|
68695
|
-
return 1;
|
|
68696
|
-
}
|
|
68697
|
-
if (!r.ok) {
|
|
68698
|
-
print({ ok: false, status: r.status, body: r.json ?? r.text });
|
|
68699
|
-
return 1;
|
|
68700
|
-
}
|
|
68701
|
-
if (sendPayload.sourceGz && r.json?.template !== true) {
|
|
68702
|
-
io.error(JSON.stringify({
|
|
68703
|
-
ok: false,
|
|
68818
|
+
const releaseId = r.json?.releaseId ?? payload.manifest.releaseId;
|
|
68819
|
+
const targetFlag = str6(flags.target) ? ` --target ${str6(flags.target)}` : "";
|
|
68820
|
+
print({
|
|
68821
|
+
ok: true,
|
|
68704
68822
|
template: name,
|
|
68705
68823
|
app: templateAppId,
|
|
68706
|
-
|
|
68707
|
-
|
|
68708
|
-
|
|
68709
|
-
|
|
68710
|
-
|
|
68824
|
+
releaseId,
|
|
68825
|
+
title: meta.title,
|
|
68826
|
+
tags: meta.tags,
|
|
68827
|
+
icon: Boolean(iconHash),
|
|
68828
|
+
...meta.accent ? { accent: meta.accent } : {},
|
|
68829
|
+
...meta.palette ? { palette: meta.palette } : {},
|
|
68830
|
+
sourceFiles: Object.keys(files).length,
|
|
68831
|
+
...hasErrors && force ? { forcedPastErrors: true } : {},
|
|
68832
|
+
initWith: `himi init <new-app-name> --template ${name} --remote${targetFlag}`
|
|
68833
|
+
});
|
|
68834
|
+
return 0;
|
|
68835
|
+
} finally {
|
|
68836
|
+
for (const dir of publishScratch) {
|
|
68837
|
+
try {
|
|
68838
|
+
rmSync14(dir, { recursive: true, force: true });
|
|
68839
|
+
} catch (e) {
|
|
68840
|
+
io.error(JSON.stringify({ warning: `could not remove temp dir ${dir}: ${e.message}` }));
|
|
68841
|
+
}
|
|
68842
|
+
}
|
|
68711
68843
|
}
|
|
68712
|
-
const releaseId = r.json?.releaseId ?? payload.manifest.releaseId;
|
|
68713
|
-
const targetFlag = str6(flags.target) ? ` --target ${str6(flags.target)}` : "";
|
|
68714
|
-
print({
|
|
68715
|
-
ok: true,
|
|
68716
|
-
template: name,
|
|
68717
|
-
app: templateAppId,
|
|
68718
|
-
releaseId,
|
|
68719
|
-
title: meta.title,
|
|
68720
|
-
tags: meta.tags,
|
|
68721
|
-
icon: Boolean(iconHash),
|
|
68722
|
-
...meta.accent ? { accent: meta.accent } : {},
|
|
68723
|
-
...meta.palette ? { palette: meta.palette } : {},
|
|
68724
|
-
sourceFiles: Object.keys(files).length,
|
|
68725
|
-
...hasErrors && force ? { forcedPastErrors: true } : {},
|
|
68726
|
-
initWith: `himi init <new-app-name> --template ${name} --remote${targetFlag}`
|
|
68727
|
-
});
|
|
68728
|
-
return 0;
|
|
68729
68844
|
}
|
|
68730
68845
|
io.error(JSON.stringify({ error: "template needs a subcommand", usage: "himi template list [--remote] | himi template prompt <name> | himi template publish [--dir <app>] [--source-dir <dir>] [--name <n>] [--icon <png>] [--target <t>] | himi template trim --keep <id,id,\u2026> [--content <dir>] [--links follow|drop] [--dry-run] [--force]" }));
|
|
68731
68846
|
return 2;
|
|
@@ -73513,7 +73628,9 @@ export {
|
|
|
73513
73628
|
spawnUpdateRefresh,
|
|
73514
73629
|
staleUpdateLockFile,
|
|
73515
73630
|
switchFlagErrors,
|
|
73631
|
+
templateNameError,
|
|
73516
73632
|
templatePreviewAuthError,
|
|
73633
|
+
templatePublishName,
|
|
73517
73634
|
tokenCoversApp,
|
|
73518
73635
|
trustedConfiguredRegistry,
|
|
73519
73636
|
updateCachePath,
|